Skip to content
This repository was archived by the owner on Jan 5, 2024. It is now read-only.

Commit 1ae81e1

Browse files
authored
Merge pull request #404 from cortex-command-community/4zk-content-source
Stuff related to `Arm`s and `ThrownDevice`s.
2 parents ffa5b3d + 9508341 commit 1ae81e1

File tree

7 files changed

+93
-51
lines changed

7 files changed

+93
-51
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
256256

257257
- New `AHuman` Lua functions `GetWalkAngle(layer)` and `SetWalkAngle(layer, angle)`, which can be used to read and override walk path rotation of both Legs/Layers respectively. Note that the walk path rotation is automatically updated on each step to match the curvature of the terrain, so this value resets every update.
258258

259+
- New `AHuman` INI and Lua (R/W) property `ArmSwingRate`, which now controls the arms' walking animation, according to each arm's `IdleOffset`. `1` is the default value, `0` means that the arms stay still.
260+
261+
- New `Attachable` Lua (R) property `JointPos`, which gets the position of the object's joint in scene coordinates.
262+
259263
</details>
260264

261265
<details><summary><b>Changed</b></summary>
262266

267+
- `ThrownDevice`s will now use `StanceOffset`, `SharpStanceOffset` and `SupportOffset` in the same way as any other `HeldDevice`. In addition, `EndThrowOffset` will be used to set the BG hand position while sharp aiming or throwing.
268+
269+
- `AHuman` throwing angle will no longer be affected by the rotation of the body.
270+
263271
- Exposed `MovableObject` property `RestThreshold` to Lua (R/W).
264272

265273
- `ACRocket`s can now function without a full set of thrusters. This also means that "Null Emitter" thrusters are no longer required for rockets.

Entities/AHuman.cpp

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ void AHuman::Clear()
8383
m_BGArmFlailScalar = 0.7F;
8484
m_EquipHUDTimer.Reset();
8585
m_WalkAngle.fill(Matrix());
86+
m_ArmSwingRate = 1.0F;
8687

8788
m_DeviceState = SCANNING;
8889
m_SweepState = NOSWEEP;
@@ -179,6 +180,7 @@ int AHuman::Create(const AHuman &reference) {
179180
m_JetAngleRange = reference.m_JetAngleRange;
180181
m_FGArmFlailScalar = reference.m_FGArmFlailScalar;
181182
m_BGArmFlailScalar = reference.m_BGArmFlailScalar;
183+
m_ArmSwingRate = reference.m_ArmSwingRate;
182184

183185
m_pFGHandGroup = dynamic_cast<AtomGroup *>(reference.m_pFGHandGroup->Clone());
184186
m_pFGHandGroup->SetOwner(this);
@@ -253,6 +255,8 @@ int AHuman::ReadProperty(const std::string_view &propName, Reader &reader) {
253255
reader >> m_FGArmFlailScalar;
254256
} else if (propName == "BGArmFlailScalar") {
255257
reader >> m_BGArmFlailScalar;
258+
} else if (propName == "ArmSwingRate") {
259+
reader >> m_ArmSwingRate;
256260
} else if (propName == "FGArm") {
257261
SetFGArm(dynamic_cast<Arm *>(g_PresetMan.ReadReflectedPreset(reader)));
258262
} else if (propName == "BGArm") {
@@ -352,6 +356,8 @@ int AHuman::Save(Writer &writer) const
352356
writer << m_FGArmFlailScalar;
353357
writer.NewProperty("BGArmFlailScalar");
354358
writer << m_BGArmFlailScalar;
359+
writer.NewProperty("ArmSwingRate");
360+
writer << m_ArmSwingRate;
355361
writer.NewProperty("FGArm");
356362
writer << m_pFGArm;
357363
writer.NewProperty("BGArm");
@@ -3180,7 +3186,8 @@ void AHuman::Update()
31803186
////////////////////////////////////
31813187
// Movement direction
31823188

3183-
bool isStill = m_Vel.GetMagnitude() + m_PrevVel.GetMagnitude() < 1.0F;
3189+
bool isStill = (m_Vel + m_PrevVel).GetMagnitude() < 1.0F;
3190+
bool isSharpAiming = m_Controller.IsState(AIM_SHARP);
31843191

31853192
// If the pie menu is on, try to preserve whatever move state we had before it going into effect.
31863193
if (!m_Controller.IsState(PIE_MENU_ACTIVE)) {
@@ -3211,7 +3218,7 @@ void AHuman::Update()
32113218
}
32123219

32133220
// Walk backwards if the aiming is already focused in the opposite direction of travel.
3214-
if (analogAim.GetMagnitude() != 0 || m_Controller.IsState(AIM_SHARP)) {
3221+
if (analogAim.GetMagnitude() != 0 || isSharpAiming) {
32153222
m_Paths[FGROUND][m_MoveState].SetHFlip(m_Controller.IsState(MOVE_LEFT));
32163223
m_Paths[BGROUND][m_MoveState].SetHFlip(m_Controller.IsState(MOVE_LEFT));
32173224
} else if ((m_Controller.IsState(MOVE_RIGHT) && m_HFlipped) || (m_Controller.IsState(MOVE_LEFT) && !m_HFlipped)) {
@@ -3300,14 +3307,14 @@ void AHuman::Update()
33003307
// Set the timer to a base number so we don't get a sluggish feeling at start.
33013308
if (m_AimState != AIMUP) { m_AimTmr.SetElapsedSimTimeMS(m_AimState == AIMSTILL ? 150 : 300); }
33023309
m_AimState = AIMUP;
3303-
m_AimAngle += m_Controller.IsState(AIM_SHARP) ? std::min(static_cast<float>(m_AimTmr.GetElapsedSimTimeMS()) * 0.00005F, 0.05F) : std::min(static_cast<float>(m_AimTmr.GetElapsedSimTimeMS()) * 0.00015F, 0.15F) * m_Controller.GetDigitalAimSpeed();
3310+
m_AimAngle += isSharpAiming ? std::min(static_cast<float>(m_AimTmr.GetElapsedSimTimeMS()) * 0.00005F, 0.05F) : std::min(static_cast<float>(m_AimTmr.GetElapsedSimTimeMS()) * 0.00015F, 0.15F) * m_Controller.GetDigitalAimSpeed();
33043311
if (m_AimAngle > m_AimRange) { m_AimAngle = m_AimRange; }
33053312

33063313
} else if (m_Controller.IsState(AIM_DOWN) && m_Status != INACTIVE) {
33073314
// Set the timer to a base number so we don't get a sluggish feeling at start.
33083315
if (m_AimState != AIMDOWN) {m_AimTmr.SetElapsedSimTimeMS(m_AimState == AIMSTILL ? 150 : 300); }
33093316
m_AimState = AIMDOWN;
3310-
m_AimAngle -= m_Controller.IsState(AIM_SHARP) ? std::min(static_cast<float>(m_AimTmr.GetElapsedSimTimeMS()) * 0.00005F, 0.05F) : std::min(static_cast<float>(m_AimTmr.GetElapsedSimTimeMS()) * 0.00015F, 0.15F) * m_Controller.GetDigitalAimSpeed();
3317+
m_AimAngle -= isSharpAiming ? std::min(static_cast<float>(m_AimTmr.GetElapsedSimTimeMS()) * 0.00005F, 0.05F) : std::min(static_cast<float>(m_AimTmr.GetElapsedSimTimeMS()) * 0.00015F, 0.15F) * m_Controller.GetDigitalAimSpeed();
33113318
if (m_AimAngle < -m_AimRange) { m_AimAngle = -m_AimRange; }
33123319

33133320
} else if (analogAim.GetMagnitude() != 0 && m_Status != INACTIVE) {
@@ -3343,7 +3350,7 @@ void AHuman::Update()
33433350

33443351
// TODO: make the delay data driven by both the actor and the device!
33453352
//
3346-
if (m_Controller.IsState(AIM_SHARP) && m_Status == STABLE && (m_MoveState == STAND || m_MoveState == CROUCH || m_MoveState == NOMOVE || m_MoveState == WALK) && m_Vel.GetMagnitude() < 5.0F && GetEquippedItem()) {
3353+
if (isSharpAiming && m_Status == STABLE && (m_MoveState == STAND || m_MoveState == CROUCH || m_MoveState == NOMOVE || m_MoveState == WALK) && m_Vel.GetMagnitude() < 5.0F && GetEquippedItem()) {
33473354
float aimMag = analogAim.GetMagnitude();
33483355

33493356
// If aim sharp is being done digitally, then translate to full analog aim mag
@@ -3376,8 +3383,14 @@ void AHuman::Update()
33763383

33773384
ThrownDevice *pThrown = nullptr;
33783385
if (m_pFGArm && m_Status != INACTIVE) {
3379-
// Force arm to idle by reaching toward a virtually inaccessible point.
3380-
m_pFGArm->ReachToward(Vector());
3386+
if (m_pBGLeg && m_MoveState == WALK && m_ArmSwingRate > 0) {
3387+
m_pFGArm->ReachToward(m_pFGArm->GetJointPos() + m_pFGArm->GetIdleOffset().GetXFlipped(m_HFlipped).RadRotate(std::sin(m_pBGLeg->GetRotAngle() + c_HalfPI * GetFlipFactor()) * m_ArmSwingRate));
3388+
} else if (m_pFGLeg && m_ArmSwingRate > 0) {
3389+
m_pFGArm->ReachToward(m_pFGArm->GetJointPos() + m_pFGArm->GetIdleOffset().GetXFlipped(m_HFlipped).RadRotate(std::sin(m_pFGLeg->GetRotAngle() + c_HalfPI * GetFlipFactor()) * m_ArmSwingRate));
3390+
} else {
3391+
// Force arm to idle by reaching toward a virtually inaccessible point.
3392+
m_pFGArm->ReachToward(Vector());
3393+
}
33813394

33823395
// Activate held device, if it's not a thrown device.
33833396
if (m_pFGArm->HoldsHeldDevice() && !m_pFGArm->HoldsThrownDevice()) {
@@ -3392,22 +3405,23 @@ void AHuman::Update()
33923405
else if (m_pFGArm->GetHeldMO()) {
33933406
pThrown = dynamic_cast<ThrownDevice *>(m_pFGArm->GetHeldMO());
33943407
if (pThrown) {
3408+
pThrown->SetSharpAim(isSharpAiming ? 1.0F : 0);
33953409
if (m_Controller.IsState(WEAPON_FIRE)) {
33963410
if (m_ArmsState != THROWING_PREP) {
33973411
m_ThrowTmr.Reset();
33983412
if (!pThrown->ActivatesWhenReleased()) { pThrown->Activate(); }
33993413
}
34003414
m_ArmsState = THROWING_PREP;
3401-
m_pFGArm->ReachToward(m_Pos + (m_pFGArm->GetParentOffset() + pThrown->GetStartThrowOffset().RadRotate(m_AimAngle + m_AngularVel * deltaTime)).GetXFlipped(m_HFlipped) * m_Rotation);
3415+
m_pFGArm->ReachToward(m_pFGArm->GetJointPos() + pThrown->GetStartThrowOffset().RadRotate(m_AimAngle + m_AngularVel * deltaTime).GetXFlipped(m_HFlipped));
34023416
} else if (m_ArmsState == THROWING_PREP) {
34033417
m_ArmsState = THROWING_RELEASE;
34043418
// TODO: figure out how to properly use EndThrowOffset, since it doesn't play much a role for just one frame!
3405-
m_pFGArm->SetHandPos(m_Pos + (m_pFGArm->GetParentOffset() + pThrown->GetEndThrowOffset().RadRotate(adjustedAimAngle)).GetXFlipped(m_HFlipped) * m_Rotation);
3419+
m_pFGArm->SetHandPos(m_pFGArm->GetJointPos() + pThrown->GetEndThrowOffset().RadRotate(adjustedAimAngle).GetXFlipped(m_HFlipped));
34063420

34073421
MovableObject *pMO = m_pFGArm->ReleaseHeldMO();
34083422

34093423
if (pMO) {
3410-
pMO->SetPos(m_Pos + (m_pFGArm->GetParentOffset() + Vector(m_pFGArm->GetMaxLength(), -m_pFGArm->GetMaxLength() * 0.5F)).GetXFlipped(m_HFlipped).RadRotate(adjustedAimAngle) * m_Rotation);
3424+
pMO->SetPos(m_pFGArm->GetJointPos() + Vector(m_pFGArm->GetMaxLength() * GetFlipFactor(), -m_pFGArm->GetMaxLength() * 0.5F).RadRotate(adjustedAimAngle));
34113425
float maxThrowVel = pThrown->GetMaxThrowVel();
34123426
float minThrowVel = pThrown->GetMinThrowVel();
34133427
if (maxThrowVel == 0) {
@@ -3416,8 +3430,7 @@ void AHuman::Update()
34163430
minThrowVel = maxThrowVel * 0.2F;
34173431
}
34183432
Vector tossVec(minThrowVel + (maxThrowVel - minThrowVel) * GetThrowProgress(), 0.5F * RandomNormalNum());
3419-
tossVec.RadRotate(m_AimAngle);
3420-
pMO->SetVel(tossVec.GetXFlipped(m_HFlipped) * m_Rotation);
3433+
pMO->SetVel(m_Vel * 0.5F + tossVec.RadRotate(m_AimAngle).GetXFlipped(m_HFlipped));
34213434
pMO->SetAngularVel(m_AngularVel + RandomNum(-5.0F, 2.5F) * GetFlipFactor());
34223435
pMO->SetRotAngle(adjustedAimAngle);
34233436

@@ -3436,11 +3449,14 @@ void AHuman::Update()
34363449
}
34373450
if (pThrown->ActivatesWhenReleased()) { pThrown->Activate(); }
34383451
m_ThrowTmr.Reset();
3452+
} else {
3453+
m_pFGArm->ReachToward(m_pFGArm->GetJointPos() + pThrown->GetStanceOffset().RadRotate(adjustedAimAngle));
34393454
}
34403455
}
34413456
} else if (m_ArmsState == THROWING_RELEASE && m_ThrowTmr.GetElapsedSimTimeMS() > 100) {
34423457
m_pFGArm->SetHeldMO(SwapNextInventory());
34433458
m_pFGArm->SetHandPos(m_Pos + m_HolsterOffset.GetXFlipped(m_HFlipped));
3459+
EquipShieldInBGArm();
34443460
m_ArmsState = WEAPON_READY;
34453461
} else if (m_ArmsState == THROWING_RELEASE) {
34463462
m_pFGArm->SetHandPos(m_Pos + (m_HolsterOffset + Vector(15, -15)).GetXFlipped(m_HFlipped));
@@ -3546,7 +3562,7 @@ void AHuman::Update()
35463562
// Try to detect a new item
35473563
if (m_pFGArm && m_Status == STABLE) {
35483564
reach += m_pFGArm->GetMaxLength();
3549-
reachPoint = m_pFGArm->GetPos() + m_pFGArm->GetJointOffset().GetXFlipped(m_HFlipped).RadRotate(m_pFGArm->GetRotAngle());
3565+
reachPoint = m_pFGArm->GetJointPos();
35503566
if (!m_pItemInReach) {
35513567
MOID itemMOID = g_SceneMan.CastMORay(reachPoint, Vector(reach * RandomNum(), 0).RadRotate(GetAimAngle(true) + RandomNum(-c_HalfPI, 0.0F) * GetFlipFactor()), m_MOID, Activity::NoTeam, g_MaterialGrass, true, 2);
35523568

@@ -3837,23 +3853,31 @@ void AHuman::Update()
38373853
m_pBGArm->ReachToward(m_pBGHandGroup->GetLimbPos(m_HFlipped));
38383854

38393855
} else {
3840-
if (HeldDevice * heldDevice = dynamic_cast<HeldDevice *>(GetEquippedItem())) {
3856+
HeldDevice *heldDevice = dynamic_cast<HeldDevice *>(GetEquippedItem());
3857+
ThrownDevice *thrownDevice = dynamic_cast<ThrownDevice *>(heldDevice);
3858+
if (thrownDevice && (m_ArmsState == THROWING_PREP || isSharpAiming)) {
3859+
m_pBGArm->ReachToward(m_pBGArm->GetJointPos() + thrownDevice->GetEndThrowOffset().RadRotate(m_AimAngle).GetXFlipped(m_HFlipped));
3860+
} else if (heldDevice) {
38413861
if (GetEquippedBGItem() && !heldDevice->IsOneHanded()) {
38423862
UnequipBGArm();
38433863
} else {
3844-
m_pBGArm->Reach(m_pFGArm->GetHeldDevice()->GetSupportPos());
3864+
m_pBGArm->Reach(heldDevice->GetSupportPos());
38453865
if (m_pBGArm->DidReach()) {
3846-
m_pFGArm->GetHeldDevice()->SetSupported(true);
3847-
m_pBGArm->SetRecoil(m_pFGArm->GetHeldDevice()->GetRecoilForce(), m_pFGArm->GetHeldDevice()->GetRecoilOffset(), m_pFGArm->GetHeldDevice()->IsRecoiled());
3866+
heldDevice->SetSupported(true);
3867+
m_pBGArm->SetRecoil(heldDevice->GetRecoilForce(), heldDevice->GetRecoilOffset(), heldDevice->IsRecoiled());
38483868
} else {
38493869
// BGArm did not reach to support the device. Count device as supported anyway, if crouching.
3850-
m_pFGArm->GetHeldDevice()->SetSupported(m_MoveState == CROUCH || m_ProneState == PRONE);
3870+
heldDevice->SetSupported(m_MoveState == CROUCH || m_ProneState == PRONE);
38513871
m_pBGArm->SetRecoil(Vector(), Vector(), false);
38523872
}
38533873
}
3874+
} else if (m_pFGLeg && m_MoveState == WALK && m_ArmSwingRate > 0) {
3875+
m_pBGArm->ReachToward(m_pBGArm->GetJointPos() + m_pBGArm->GetIdleOffset().GetXFlipped(m_HFlipped).RadRotate(std::sin(m_pFGLeg->GetRotAngle() + c_HalfPI * GetFlipFactor()) * m_ArmSwingRate));
3876+
} else if (m_pBGLeg && m_ArmSwingRate > 0) {
3877+
m_pBGArm->ReachToward(m_pBGArm->GetJointPos() + m_pBGArm->GetIdleOffset().GetXFlipped(m_HFlipped).RadRotate(std::sin(m_pBGLeg->GetRotAngle() + c_HalfPI * GetFlipFactor()) * m_ArmSwingRate));
38543878
} else {
3855-
// Use an unreachable position to force this arm to idle, so it wont bug out where the AtomGroup was left off
3856-
m_pBGArm->Reach(Vector());
3879+
// Force arm to idle by reaching toward a virtually inaccessible point.
3880+
m_pBGArm->ReachToward(Vector());
38573881
}
38583882
}
38593883
} else {
@@ -3981,8 +4005,8 @@ void AHuman::Update()
39814005
}
39824006

39834007
// Rotational balancing spring calc
3984-
if (m_Status == STABLE)
3985-
{
4008+
if (m_Status == STABLE) {
4009+
39864010
// If we're supposed to be laying down on the ground, make the spring pull the body that way until we reach that angle
39874011
if (m_ProneState != NOTPRONE)
39884012
{
@@ -4066,34 +4090,28 @@ void AHuman::Update()
40664090
//////////////////////////////////////////////////////////////////////////////////////////
40674091

40684092
void AHuman::DrawThrowingReticle(BITMAP *targetBitmap, const Vector &targetPos, float progressScalar) const {
4069-
const int pointCount = 9;
4070-
Vector points[pointCount];
4071-
//Color colors[pointCount];
4093+
const int pointCount = 9;
4094+
Vector points[pointCount];
40724095

40734096
for (int index = 0; index < pointCount; index++) {
40744097
points[index].SetXY(static_cast<float>(index * 4), 0.0F);
4075-
//colors[index].SetRGB(255 - index * 3, 225 - index * 20, index);
40764098
}
4099+
Vector outOffset(m_pFGArm->GetMaxLength() * GetFlipFactor(), -m_pFGArm->GetMaxLength() * 0.5F);
4100+
float adjustedAimAngle = m_AimAngle * GetFlipFactor();
40774101

4078-
Vector outOffset(15.0F * GetFlipFactor(), -5.0F);
4079-
4080-
acquire_bitmap(targetBitmap);
4081-
4082-
for (int i = 0; i < pointCount * progressScalar; ++i) {
4083-
points[i].FlipX(m_HFlipped);
4084-
points[i] += outOffset;
4085-
points[i].RadRotate((m_AimAngle * GetFlipFactor()) + m_Rotation.GetRadAngle());
4086-
points[i] += m_Pos;
4087-
if (m_pFGArm)
4088-
points[i] += m_pFGArm->GetParentOffset();
4102+
acquire_bitmap(targetBitmap);
40894103

4090-
// Put the flickering glows on the reticle dots, in absolute scene coordinates
4091-
g_PostProcessMan.RegisterGlowDotEffect(points[i], YellowDot, 55 + RandomNum(0, 100));
4104+
for (int i = 0; i < pointCount * progressScalar; ++i) {
4105+
points[i].FlipX(m_HFlipped);
4106+
points[i] += outOffset;
4107+
points[i].RadRotate(adjustedAimAngle);
4108+
points[i] += m_pFGArm->GetJointPos();
40924109

4093-
putpixel(targetBitmap, points[i].GetFloorIntX() - targetPos.GetFloorIntX(), points[i].GetFloorIntY() - targetPos.GetFloorIntY(), g_YellowGlowColor);
4094-
}
4110+
g_PostProcessMan.RegisterGlowDotEffect(points[i], YellowDot, RandomNum(63, 127));
4111+
putpixel(targetBitmap, points[i].GetFloorIntX() - targetPos.GetFloorIntX(), points[i].GetFloorIntY() - targetPos.GetFloorIntY(), g_YellowGlowColor);
4112+
}
40954113

4096-
release_bitmap(targetBitmap);
4114+
release_bitmap(targetBitmap);
40974115
}
40984116

40994117
//////////////////////////////////////////////////////////////////////////////////////////

Entities/AHuman.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,18 @@ ClassInfoGetters;
925925
/// <param name="newPrepTime">New duration to fully charge a throw in MS.</param>
926926
void SetThrowPrepTime(long newPrepTime) { m_ThrowPrepTime = newPrepTime; }
927927

928+
/// <summary>
929+
/// Gets the rate at which this AHuman is set to swing its arms while walking.
930+
/// </summary>
931+
/// <returns>The arm swing rate of this AHuman.</returns>
932+
float GetArmSwingRate() const { return m_ArmSwingRate; }
933+
934+
/// <summary>
935+
/// Sets the rate at which this AHuman is set to swing its arms while walking.
936+
/// </summary>
937+
/// <param name="newValue">The new arm swing rate for this AHuman.</param>
938+
void SetArmSwingRate(float newValue) { m_ArmSwingRate = newValue; }
939+
928940
/// <summary>
929941
/// Gets this AHuman's stride sound. Ownership is NOT transferred!
930942
/// </summary>
@@ -1030,6 +1042,7 @@ ClassInfoGetters;
10301042
float m_BGArmFlailScalar; //!< The rate at which this AHuman's BG Arm follows the the bodily rotation. Set to a negative value for a "counterweight" effect.
10311043
Timer m_EquipHUDTimer; //!< Timer for showing the name of any newly equipped Device.
10321044
std::array<Matrix, 2> m_WalkAngle; //!< An array of rot angle targets for different movement states.
1045+
float m_ArmSwingRate; //!< Controls the rate at which this AHuman's arms follow the movement of its legs.
10331046

10341047
////////////////
10351048
// AI States

Entities/Arm.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,6 @@ void Arm::Update() {
354354
m_AngularVel = 0.0F;
355355
}
356356

357-
UpdateCurrentHandOffset();
358-
359357
HeldDevice *heldDevice = m_pHeldMO ? dynamic_cast<HeldDevice *>(m_pHeldMO) : nullptr;
360358
const ThrownDevice *thrownDevice = heldDevice ? dynamic_cast<ThrownDevice *>(heldDevice) : nullptr;
361359

@@ -372,6 +370,8 @@ void Arm::Update() {
372370

373371
Attachable::Update();
374372

373+
UpdateCurrentHandOffset();
374+
375375
m_Recoiled = heldDevice && heldDevice->IsRecoiled();
376376

377377
if (heldDevice && !thrownDevice) {
@@ -446,7 +446,8 @@ void Arm::UpdateArmFrame() {
446446
void Arm::Draw(BITMAP *pTargetBitmap, const Vector &targetPos, DrawMode mode, bool onlyPhysical) const {
447447
Attachable::Draw(pTargetBitmap, targetPos, mode, onlyPhysical);
448448

449-
if (!onlyPhysical && (mode == g_DrawColor || mode == g_DrawWhite || mode == g_DrawTrans) && (!m_Parent || m_pHeldMO || (!m_pHeldMO && !m_DidReach))) {
449+
//if (!onlyPhysical && (mode == g_DrawColor || mode == g_DrawWhite || mode == g_DrawTrans) && (!m_Parent || m_pHeldMO || (!m_pHeldMO && !m_DidReach))) {
450+
if (!onlyPhysical && (mode == g_DrawColor || mode == g_DrawWhite || mode == g_DrawTrans)) {
450451
DrawHand(pTargetBitmap, targetPos, mode);
451452
if (m_pHeldMO && m_pHeldMO->IsDrawnAfterParent()) { m_pHeldMO->Draw(pTargetBitmap, targetPos, mode, onlyPhysical); }
452453
}

Entities/Attachable.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,12 @@ namespace RTE {
237237
/// </summary>
238238
/// <param name="newJointOffset">A Vector describing the offset of the joint relative to the this Attachable's origin/center of mass position.</param>
239239
void SetJointOffset(const Vector &newJointOffset) { m_JointOffset = newJointOffset; }
240+
241+
/// <summary>
242+
/// Gets the absolute position of the joint that the parent of this Attachable sets upon Update().
243+
/// </summary>
244+
/// <returns>A Vector describing the current absolute position of the joint.</returns>
245+
const Vector & GetJointPos() const { return m_JointPos; }
240246
#pragma endregion
241247

242248
#pragma region Force Transferral

Entities/ThrownDevice.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,6 @@ namespace RTE {
111111
#pragma endregion
112112

113113
#pragma region Virtual Override Methods
114-
/// <summary>
115-
/// Gets the current position offset of this ThrownDevice's joint relative from the parent Actor's position, if attached.
116-
/// </summary>
117-
/// <returns>A const reference to the current stance parent offset.</returns>
118-
Vector GetStanceOffset() const override { return m_StanceOffset.GetXFlipped(m_HFlipped); }
119-
120114
/// <summary>
121115
/// Resets all the timers used by this (e.g. emitters, etc). This is to prevent backed up emissions from coming out all at once while this has been held dormant in an inventory.
122116
/// </summary>

0 commit comments

Comments
 (0)