Skip to content

Commit a341d71

Browse files
authored
Add ability to disable player movement/rotation/fire via scripting (#517)
1 parent 789b216 commit a341d71

File tree

4 files changed

+130
-27
lines changed

4 files changed

+130
-27
lines changed

TheForceEngine/TFE_DarkForces/Scripting/gs_player.cpp

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ namespace TFE_DarkForces
2222
AMMO_MISSILE,
2323
};
2424

25+
enum ActionFlags : u32
26+
{
27+
ACTION_NONE = 0u,
28+
ACTION_MOVE = FLAG_BIT(0),
29+
ACTION_ROTATE = FLAG_BIT(1),
30+
ACTION_FIRE = FLAG_BIT(2),
31+
ACTION_ALL = ACTION_MOVE | ACTION_ROTATE | ACTION_FIRE,
32+
33+
// Others that could be implemented if desired?
34+
// ACTION_PITCH
35+
// ACTION_CROUCH
36+
// ACTION_USE
37+
// ACTION_HEADLAMP
38+
};
39+
2540
void killPlayer()
2641
{
2742
sound_play(s_playerDeathSoundSource);
@@ -546,6 +561,48 @@ namespace TFE_DarkForces
546561
}
547562
}
548563

564+
void disableActions(u32 flags)
565+
{
566+
if (flags & ACTION_MOVE)
567+
{
568+
s_disablePlayerMovement = JTRUE;
569+
}
570+
if (flags & ACTION_ROTATE)
571+
{
572+
s_disablePlayerRotation = JTRUE;
573+
}
574+
if (flags & ACTION_FIRE)
575+
{
576+
s_disablePlayerFire = JTRUE;
577+
}
578+
}
579+
580+
void enableActions(u32 flags)
581+
{
582+
if (flags & ACTION_MOVE)
583+
{
584+
s_disablePlayerMovement = JFALSE;
585+
}
586+
if (flags & ACTION_ROTATE)
587+
{
588+
s_disablePlayerRotation = JFALSE;
589+
}
590+
if (flags & ACTION_FIRE)
591+
{
592+
s_disablePlayerFire = JFALSE;
593+
}
594+
}
595+
596+
u32 getDisabledActions()
597+
{
598+
u32 result = 0;
599+
if (s_disablePlayerMovement) { result |= ACTION_MOVE; }
600+
if (s_disablePlayerRotation) { result |= ACTION_ROTATE; }
601+
if (s_disablePlayerFire) { result |= ACTION_FIRE; }
602+
603+
return result;
604+
}
605+
549606
bool GS_Player::scriptRegister(ScriptAPI api)
550607
{
551608
ScriptClassBegin("Player", "player", api);
@@ -577,8 +634,17 @@ namespace TFE_DarkForces
577634
ScriptEnumStr(AMMO_MINE);
578635
ScriptEnumStr(AMMO_MISSILE);
579636

637+
ScriptEnumRegister("PlayerActions");
638+
ScriptEnumStr(ACTION_MOVE);
639+
ScriptEnumStr(ACTION_ROTATE);
640+
ScriptEnumStr(ACTION_FIRE);
641+
ScriptEnumStr(ACTION_ALL);
642+
580643
ScriptObjFunc("void kill()", killPlayer);
581-
644+
ScriptObjFunc("void disableActions(uint)", disableActions);
645+
ScriptObjFunc("void enableActions(uint)", enableActions);
646+
ScriptPropertyGetFunc("uint get_disabledActions()", getDisabledActions);
647+
582648
// Position and velocity
583649
ScriptPropertyGetFunc("float3 get_position()", getPlayerPosition);
584650
ScriptPropertySetFunc("void set_position(float3)", setPlayerPosition);

TheForceEngine/TFE_DarkForces/player.cpp

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,11 @@ namespace TFE_DarkForces
299299
// TFE - constants which can be overridden
300300
s32 s_weaponSuperchargeDuration;
301301
s32 s_shieldSuperchargeDuration;
302+
303+
// Scripting
304+
JBool s_disablePlayerMovement = JFALSE;
305+
JBool s_disablePlayerRotation = JFALSE;
306+
JBool s_disablePlayerFire = JFALSE;
302307

303308
///////////////////////////////////////////
304309
// Forward Declarations
@@ -890,6 +895,9 @@ namespace TFE_DarkForces
890895
s_playerPrimaryFire = JFALSE;
891896
s_playerSecFire = JFALSE;
892897
s_playerJumping = JFALSE;
898+
s_disablePlayerMovement = JFALSE;
899+
s_disablePlayerRotation = JFALSE;
900+
s_disablePlayerFire = JFALSE;
893901

894902
s_crushSoundId = 0;
895903
s_kyleScreamSoundId = 0;
@@ -1449,11 +1457,16 @@ namespace TFE_DarkForces
14491457
{
14501458
ProjectileLogic* proj = (ProjectileLogic*)s_msgEntity;
14511459
vec3_fixed pushVel;
1452-
computeDamagePushVelocity(proj, &pushVel);
1460+
1461+
// TFE: Don't push the player if movement disabled
1462+
if (!s_disablePlayerMovement)
1463+
{
1464+
computeDamagePushVelocity(proj, &pushVel);
14531465

1454-
s_playerVelX += pushVel.x;
1455-
s_playerUpVel2 += pushVel.y;
1456-
s_playerVelZ += pushVel.z;
1466+
s_playerVelX += pushVel.x;
1467+
s_playerUpVel2 += pushVel.y;
1468+
s_playerVelZ += pushVel.z;
1469+
}
14571470

14581471
if (s_invincibility || s_config.superShield)
14591472
{
@@ -1474,10 +1487,14 @@ namespace TFE_DarkForces
14741487
vec3_fixed pushDir;
14751488
computeExplosionPushDir(&pos, &pushDir);
14761489

1477-
fixed16_16 force = s_msgArg2;
1478-
s_playerVelX += mul16(force, pushDir.x);
1479-
s_playerUpVel2 += mul16(force, pushDir.y);
1480-
s_playerVelZ += mul16(force, pushDir.z);
1490+
// TFE: Don't push the player if movement disabled
1491+
if (!s_disablePlayerMovement)
1492+
{
1493+
fixed16_16 force = s_msgArg2;
1494+
s_playerVelX += mul16(force, pushDir.x);
1495+
s_playerUpVel2 += mul16(force, pushDir.y);
1496+
s_playerVelZ += mul16(force, pushDir.z);
1497+
}
14811498

14821499
if (s_invincibility || s_config.superShield)
14831500
{
@@ -1534,6 +1551,9 @@ namespace TFE_DarkForces
15341551
s_playerCrouchSpd = 0;
15351552
s_prevDistFromFloor = 0;
15361553
s_playerObject->worldHeight = 0x5cccc; // 5.8
1554+
s_disablePlayerMovement = JFALSE;
1555+
s_disablePlayerRotation = JFALSE;
1556+
s_disablePlayerFire = JFALSE;
15371557
}
15381558

15391559
void player_changeSector(RSector* newSector)
@@ -1707,7 +1727,7 @@ namespace TFE_DarkForces
17071727
InputConfig* inputConfig = TFE_Input::inputMapping_get();
17081728

17091729
// Yaw change
1710-
if (inputConfig->mouseMode == MMODE_TURN || inputConfig->mouseMode == MMODE_LOOK)
1730+
if ((inputConfig->mouseMode == MMODE_TURN || inputConfig->mouseMode == MMODE_LOOK) && !s_disablePlayerRotation)
17111731
{
17121732
s_playerYaw += s32(f32(mdx * PLAYER_MOUSE_TURN_SPD) * inputMapping_getHorzMouseSensitivity());
17131733
s_playerYaw &= ANGLE_MASK;
@@ -1722,7 +1742,7 @@ namespace TFE_DarkForces
17221742
}
17231743

17241744
// Controls
1725-
if (s_automapLocked)
1745+
if (s_automapLocked && !s_disablePlayerMovement)
17261746
{
17271747
if (inputMapping_getActionState(IADF_FORWARD))
17281748
{
@@ -1810,7 +1830,7 @@ namespace TFE_DarkForces
18101830

18111831
JBool wasJumping = s_playerJumping;
18121832
s_playerJumping = JFALSE;
1813-
if (inputMapping_getActionState(IADF_JUMP))
1833+
if (inputMapping_getActionState(IADF_JUMP) && !s_disablePlayerMovement)
18141834
{
18151835
if (!s_onFloor || wasJumping)
18161836
{
@@ -1838,12 +1858,10 @@ namespace TFE_DarkForces
18381858
s_playerUpVel2 = 0;
18391859
}
18401860

1841-
//////////////////////////////////////////
18421861
// Pitch and Roll controls.
1843-
//////////////////////////////////////////
18441862
if (s_automapLocked)
18451863
{
1846-
if (inputMapping_getActionState(IADF_TURN_LT))
1864+
if (inputMapping_getActionState(IADF_TURN_LT) && !s_disablePlayerRotation)
18471865
{
18481866
fixed16_16 turnSpeed = PLAYER_KB_TURN_SPD; // angle units per second.
18491867
fixed16_16 dYaw = mul16(turnSpeed, s_deltaTime);
@@ -1853,7 +1871,7 @@ namespace TFE_DarkForces
18531871
s_playerYaw -= dYaw;
18541872
s_playerYaw &= ANGLE_MASK;
18551873
}
1856-
else if (inputMapping_getActionState(IADF_TURN_RT))
1874+
else if (inputMapping_getActionState(IADF_TURN_RT) && !s_disablePlayerRotation)
18571875
{
18581876
fixed16_16 turnSpeed = PLAYER_KB_TURN_SPD; // angle units per second.
18591877
fixed16_16 dYaw = mul16(turnSpeed, s_deltaTime);
@@ -1863,7 +1881,7 @@ namespace TFE_DarkForces
18631881
s_playerYaw += dYaw;
18641882
s_playerYaw &= ANGLE_MASK;
18651883
}
1866-
else if (inputMapping_getAnalogAxis(AA_LOOK_HORZ))
1884+
else if (inputMapping_getAnalogAxis(AA_LOOK_HORZ) && !s_disablePlayerRotation)
18671885
{
18681886
fixed16_16 turnSpeed = mul16(mul16(PLAYER_CONTROLLER_TURN_SPD, s_deltaTime), floatToFixed16(inputMapping_getAnalogAxis(AA_LOOK_HORZ)));
18691887
s_playerYaw += turnSpeed;
@@ -1901,17 +1919,18 @@ namespace TFE_DarkForces
19011919
s_playerRoll = 0;
19021920
}
19031921

1904-
if (inputMapping_getActionState(IADF_STRAFE_RT))
1922+
// Strafe movement
1923+
if (inputMapping_getActionState(IADF_STRAFE_RT) && !s_disablePlayerMovement)
19051924
{
19061925
fixed16_16 speed = mul16(PLAYER_STRAFE_SPEED, s_deltaTime);
19071926
s_strafeSpd = max(speed, s_strafeSpd);
19081927
}
1909-
else if (inputMapping_getActionState(IADF_STRAFE_LT))
1928+
else if (inputMapping_getActionState(IADF_STRAFE_LT) && !s_disablePlayerMovement)
19101929
{
19111930
fixed16_16 speed = -mul16(PLAYER_STRAFE_SPEED, s_deltaTime);
19121931
s_strafeSpd = min(speed, s_strafeSpd);
19131932
}
1914-
else if (inputMapping_getAnalogAxis(AA_STRAFE))
1933+
else if (inputMapping_getAnalogAxis(AA_STRAFE) && !s_disablePlayerMovement)
19151934
{
19161935
fixed16_16 speed = mul16(mul16(PLAYER_STRAFE_SPEED, s_deltaTime), floatToFixed16(clamp(inputMapping_getAnalogAxis(AA_STRAFE), -1.0f, 1.0f)));
19171936
if (speed < 0)
@@ -1930,11 +1949,11 @@ namespace TFE_DarkForces
19301949
s_playerUse = JTRUE;
19311950
}
19321951

1933-
if (inputMapping_getActionState(IADF_PRIMARY_FIRE))
1952+
if (inputMapping_getActionState(IADF_PRIMARY_FIRE) && !s_disablePlayerFire)
19341953
{
19351954
s_playerPrimaryFire = JTRUE;
19361955
}
1937-
else if (inputMapping_getActionState(IADF_SECONDARY_FIRE))
1956+
else if (inputMapping_getActionState(IADF_SECONDARY_FIRE) && !s_disablePlayerFire)
19381957
{
19391958
s_playerSecFire = JTRUE;
19401959
}
@@ -2141,8 +2160,16 @@ namespace TFE_DarkForces
21412160
// Then convert from player velocity to per-frame movement.
21422161
fixed16_16 moveX = adjustForwardSpeed(s_playerVelX);
21432162
fixed16_16 moveZ = adjustForwardSpeed(s_playerVelZ);
2144-
s_playerLogic.move.x = mul16(moveX, s_deltaTime) + mul16(s_externalVelX, s_deltaTime);
2145-
s_playerLogic.move.z = mul16(moveZ, s_deltaTime) + mul16(s_externalVelZ, s_deltaTime);
2163+
if (s_disablePlayerMovement) // TFE scripting option
2164+
{
2165+
s_playerLogic.move.x = 0;
2166+
s_playerLogic.move.z = 0;
2167+
}
2168+
else // normal behaviour
2169+
{
2170+
s_playerLogic.move.x = mul16(moveX, s_deltaTime) + mul16(s_externalVelX, s_deltaTime);
2171+
s_playerLogic.move.z = mul16(moveZ, s_deltaTime) + mul16(s_externalVelZ, s_deltaTime);
2172+
}
21462173
s_playerLogic.stepHeight = s_limitStepHeight ? PLAYER_STEP : PLAYER_INF_STEP;
21472174
fixed16_16 width = (s_smallModeEnabled) ? PLAYER_SIZE_SMALL : PLAYER_WIDTH;
21482175
player->worldWidth = width;
@@ -3329,6 +3356,10 @@ namespace TFE_DarkForces
33293356
setProjectileGravityAccel(projectileGravity);
33303357
}
33313358

3359+
SERIALIZE(ObjState_DisablePlayerMovement, s_disablePlayerMovement, JFALSE);
3360+
SERIALIZE(ObjState_DisablePlayerMovement, s_disablePlayerRotation, JFALSE);
3361+
SERIALIZE(ObjState_DisablePlayerMovement, s_disablePlayerFire, JFALSE);
3362+
33323363
s32 invSavedSize = 0;
33333364
if (serialization_getMode() == SMODE_WRITE && s_playerInvSaved)
33343365
{
@@ -3437,4 +3468,4 @@ namespace TFE_DarkForces
34373468
}
34383469
}
34393470
}
3440-
} // TFE_DarkForces
3471+
} // TFE_DarkForces

TheForceEngine/TFE_DarkForces/player.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ namespace TFE_DarkForces
170170
extern s32 s_weaponSuperchargeDuration;
171171
extern s32 s_shieldSuperchargeDuration;
172172

173+
// Scripting
174+
extern JBool s_disablePlayerMovement;
175+
extern JBool s_disablePlayerRotation;
176+
extern JBool s_disablePlayerFire;
177+
173178
void player_init();
174179
void player_readInfo(u8* inv, s32* ammo);
175180
void player_writeInfo(u8* inv, s32* ammo);
@@ -213,4 +218,4 @@ namespace TFE_DarkForces
213218

214219
// Serialization
215220
void playerLogic_serialize(Logic*& logic, SecObject* obj, Stream* stream);
216-
} // namespace TFE_DarkForces
221+
} // namespace TFE_DarkForces

TheForceEngine/TFE_Jedi/Level/robjData.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ enum ObjStateVersion : u32
6464
ObjState_CrouchToggle = 5,
6565
ObjState_CustomLogics = 6,
6666
ObjState_ConstOverrides = 7,
67-
ObjState_CurVersion = ObjState_ConstOverrides,
67+
ObjState_DisablePlayerMovement = 8,
68+
ObjState_CurVersion = ObjState_DisablePlayerMovement,
6869
};
6970

7071
#define SPRITE_SCALE_FIXED FIXED(10)

0 commit comments

Comments
 (0)