1
1
HumanFunctions = {};
2
2
3
3
function HumanFunctions .DoAlternativeGib (actor )
4
- -- Detach limbs instead of regular gibbing
4
+ -- Detach limbs instead of regular gibbing
5
5
if not actor .detachLimit then
6
6
actor .detachLimit = actor .GibWoundLimit ;
7
7
actor .GibWoundLimit = actor .GibWoundLimit * 1.5 ;
8
8
end
9
9
if actor .WoundCount > actor .detachLimit then
10
10
actor .detachLimit = actor .WoundCount + 1 ;
11
- local parts = {actor .BGArm , actor .BGLeg , actor .FGArm , actor .FGLeg , actor .Head }; -- Piority order
11
+ local parts = {actor .BGArm , actor .BGLeg , actor .FGArm , actor .FGLeg , actor .Head }; -- Piority order
12
12
local mostWounds = - 1 ;
13
13
local detachLimb ;
14
- -- Pick the limb with most wounds and detach it
14
+ -- Pick the limb with most wounds and detach it
15
15
for i = 1 , # parts do
16
16
local limb = parts [i ];
17
17
if limb and limb .WoundCount > mostWounds then
@@ -26,87 +26,101 @@ function HumanFunctions.DoAlternativeGib(actor)
26
26
end
27
27
28
28
function HumanFunctions .DoAutomaticEquip (actor )
29
- -- Equip a weapon automatically if the one held by a player is destroyed
29
+ -- Equip a weapon automatically if the one held by a player is destroyed
30
30
if actor :IsPlayerControlled () and actor .EquippedItem == nil and actor .InventorySize > 0 and not actor .controller :IsState (Controller .WEAPON_FIRE ) then
31
31
actor :EquipFirearm (true );
32
32
end
33
33
end
34
34
35
35
function HumanFunctions .DoArmSway (actor , pushStrength )
36
- -- Control arm movements
37
- if not actor .lastHandPos then
38
- actor .lastAngle = actor :GetAimAngle (false );
36
+ -- Control arm movements
37
+ local aimAngle = actor :GetAimAngle (false );
38
+ if not actor .lastHandPos then -- Initialize
39
+ actor .lastAngle = aimAngle ;
39
40
actor .lastHandPos = {actor .Pos , actor .Pos };
40
41
end
41
42
if actor .controller :IsMouseControlled () then
42
- -- Flail around if moving mouse too fast
43
+ -- Flail around if moving mouse too fast
43
44
local mouseVec = Vector (actor .controller .MouseMovement .X , actor .controller .MouseMovement .Y ):SetMagnitude (math.sqrt (actor .controller .MouseMovement .Magnitude ));
44
- local ang = actor .lastAngle - actor : GetAimAngle ( false ) ;
45
+ local ang = actor .lastAngle - aimAngle ;
45
46
46
47
actor .AngularVel = actor .AngularVel - (2 * ang * actor .FlipFactor + mouseVec .Y * actor .FlipFactor / 10 ) / math.sqrt (math.abs (actor .AngularVel ) + 1 );
47
48
48
- actor .lastAngle = actor : GetAimAngle ( false ) ;
49
+ actor .lastAngle = aimAngle ;
49
50
end
50
- -- Shove when unarmed
51
+ -- Shove when unarmed
51
52
if actor .controller :IsState (Controller .WEAPON_FIRE ) and (actor .FGArm or actor .BGArm ) and not (actor .EquippedItem or actor .EquippedBGItem ) and actor .Status == Actor .STABLE then
52
- actor .AngularVel = actor .AngularVel / (actor .shoved and 1.5 or 3 ) + (actor : GetAimAngle ( false ) - actor .RotAngle * actor .FlipFactor - 1.57 ) * (actor .shoved and 0.5 or 3 ) * actor .FlipFactor / (1 + math.abs (actor .RotAngle ));
53
+ actor .AngularVel = actor .AngularVel / (actor .shoved and 1.3 or 3 ) + (aimAngle - actor .RotAngle * actor .FlipFactor - 1.57 ) * (actor .shoved and 0.3 or 3 ) * actor .FlipFactor / (1 + math.abs (actor .RotAngle ));
53
54
if not actor .shoved then
54
- actor .Vel = actor .Vel + Vector (3 / (1 + actor .Vel .Magnitude ), 0 ):RadRotate (actor :GetAimAngle (true )) * math.abs (math.cos (actor :GetAimAngle (true )));
55
+ actor .Vel = actor .Vel + Vector (2 / (1 + actor .Vel .Magnitude ), 0 ):RadRotate (actor :GetAimAngle (true )) * math.abs (math.cos (actor :GetAimAngle (true )));
55
56
actor .shoved = true ;
56
57
end
57
58
else
58
59
actor .shoved = false ;
59
60
end
60
- local arms = {{actor .FGArm , actor .FGLeg , actor .BGLeg }, {actor .BGArm , actor .BGLeg , actor .FGLeg }};
61
- for i = 1 , # arms do
62
- local arm = arms [i ][1 ];
61
+ local armPairs = {{actor .FGArm , actor .FGLeg , actor .BGLeg }, {actor .BGArm , actor .BGLeg , actor .FGLeg }};
62
+ for i = 1 , # armPairs do
63
+ local arm = armPairs [i ][1 ];
63
64
if arm then
64
- local arm = ToArm (arms [i ][1 ]);
65
+ arm = ToArm (arm );
66
+
65
67
local armLength = ToMOSprite (arm ):GetSpriteWidth ();
66
68
local rotAng = actor .RotAngle - (1.57 * actor .FlipFactor );
67
- local legMain = arms [i ][2 ];
68
- local legAlt = arms [i ][3 ];
69
+ local legMain = armPairs [i ][2 ];
70
+ local legAlt = armPairs [i ][3 ];
69
71
70
72
if actor .controller :IsState (Controller .MOVE_LEFT ) or actor .controller :IsState (Controller .MOVE_RIGHT ) then
71
- if legAlt then
72
- rotAng = legAlt .RotAngle ;
73
- elseif legMain then
74
- rotAng = - legMain .RotAngle + math.pi ;
75
- end
73
+ rotAng = (legAlt and legAlt .RotAngle ) or (legMain and (- legMain .RotAngle + math.pi ) or rotAng );
76
74
elseif legMain then
77
75
rotAng = legMain .RotAngle ;
78
76
end
79
- -- Flail arms in tandem with leg movement
80
- ToArm (arm ).IdleOffset = Vector (0 , armLength * 0.7 ):RadRotate (rotAng * actor .FlipFactor + 1.5 + (i / 5 ));
81
-
77
+ -- Flail arms in tandem with leg movement or raise them them up for a push if aiming
78
+ if actor .controller :IsState (Controller .AIM_SHARP ) then
79
+ arm .IdleOffset = Vector (0 , 1 ):RadRotate (aimAngle );
80
+ else
81
+ arm .IdleOffset = Vector (0 , (armLength + arm .SpriteOffset .X ) * 1.1 ):RadRotate (rotAng * actor .FlipFactor + 1.5 + (i / 5 ));
82
+ end
82
83
if actor .shoved or (actor .EquippedItem and IsTDExplosive (actor .EquippedItem ) and actor .controller :IsState (Controller .WEAPON_FIRE )) then
83
- arm .IdleOffset = Vector (armLength , 0 ):RadRotate (actor :GetAimAngle (false ));
84
- local dist = SceneMan :ShortestDistance (actor .lastHandPos [i ], arm .HandPos , SceneMan .SceneWrapsX );
85
-
86
- local dots = math.sqrt (arm .Radius ) * (arm .Frame / arm .FrameCount );
87
-
84
+ arm .IdleOffset = Vector (armLength + (pushStrength * armLength ), 0 ):RadRotate (aimAngle );
85
+ local handVector = SceneMan :ShortestDistance (actor .lastHandPos [i ], arm .HandPos , SceneMan .SceneWrapsX );
86
+ -- Diminish hand relocation vector to potentially prevent post-superhuman pushing powers
87
+ handVector :SetMagnitude (handVector .Magnitude / (1 + handVector .Magnitude / 100 ));
88
+ -- Emphasize the first frames that signify contracted arm = highest potential energy
89
+ local dots = math.sqrt (arm .Radius ) / (1 + arm .Frame / arm .FrameCount );
90
+ local armStrength = (arm .Mass + arm .Material .StructuralIntegrity ) * pushStrength ;
88
91
for i = 1 , dots do
89
92
local part = CreateMOPixel (" Smack Particle Light" );
90
93
part .Pos = arm .HandPos ;
91
- part .Vel = ( actor . Vel + dist ): SetMagnitude ( math.sqrt ( dist . Magnitude * pushStrength + math.abs ( actor . AngularVel ) * actor . Vel . Magnitude )): RadRotate ( 0.8 / dots * i ) + Vector (0 , - 0.5 );
92
- part .Mass = ( arm . Mass + arm . Material . StructuralIntegrity ) * pushStrength ; part .Sharpness = math.random () * 0.1 ;
94
+ part .Vel = Vector ( handVector . X , handVector . Y ): RadRotate ( RangeRand ( - 0.1 , 0.1 )) * pushStrength + Vector (0 , - 0.5 );
95
+ part .Mass = armStrength ; part .Sharpness = math.random () * 0.1 ;
93
96
part .Team = actor .Team ; part .IgnoresTeamHits = true ;
94
97
MovableMan :AddParticle (part );
95
98
end
99
+ -- Apply some additional forces if the travel vector of the moving hand is half an arms length
100
+ if handVector .Magnitude > (armLength / 2 ) then
101
+ local moCheck = SceneMan :GetMOIDPixel (arm .HandPos .X , arm .HandPos .Y )
102
+ if moCheck ~= rte .NoMOID then
103
+ local mo = MovableMan :GetMOFromID (MovableMan :GetMOFromID (moCheck ).RootID );
104
+ if mo and mo .Team ~= actor .Team and IsActor (mo ) and actor .Mass > (mo .Mass / 2 ) then
105
+ mo :AddForce (handVector * (actor .Mass / 2 ), Vector ());
106
+ ToActor (mo ).Status = Actor .UNSTABLE ;
107
+ end
108
+ end
109
+ end
96
110
end
97
111
actor .lastHandPos [i ] = arm .HandPos ;
98
112
end
99
113
end
100
114
end
101
115
102
116
function HumanFunctions .DoVisibleInventory (actor , showAll )
103
- -- Visualize inventory with primitive bitmaps
117
+ -- Visualize inventory with primitive bitmaps
104
118
if actor .Status < Actor .DYING and not actor :IsInventoryEmpty () then
105
119
local heldCount , thrownCount , largestItem = 0 , 0 , 0 ;
106
120
for i = 1 , actor .InventorySize do
107
121
local item = actor :Inventory ();
108
122
if item then
109
- local fixNum = actor .HFlipped and - 1 or 0 ; -- Fix offsets slightly when facing left
123
+ local fixNum = actor .HFlipped and - 1 or 0 ; -- Fix offsets slightly when facing left
110
124
if item .ClassName == " TDExplosive" then
111
125
thrownCount = thrownCount + 1 ;
112
126
elseif item .ClassName == " HDFirearm" or item .ClassName == " HeldDevice" then
@@ -119,16 +133,13 @@ function HumanFunctions.DoVisibleInventory(actor, showAll)
119
133
120
134
fixNum = fixNum + item .Radius * 0.2 + math.sqrt (heldCount );
121
135
122
- -- Bigger actors carry weapons higher up, smaller weapons are carried lower down
136
+ -- Bigger actors carry weapons higher up, smaller weapons are carried lower down
123
137
local drawPos = actor .Pos + Vector ((- actorSize - fixNum ) * actor .FlipFactor , - actorSize - itemSize + 1 + isFirearm * 3 ):RadRotate (actor .RotAngle );
124
138
125
139
local itemCount = math.sqrt (math.abs (actor .InventorySize - thrownCount ));
126
-
127
- -- Display tall objects upright
128
- local tallAng = 1.57 ;
129
- if ToMOSprite (item ):GetSpriteWidth () < ToMOSprite (item ):GetSpriteHeight () then
130
- tallAng = 0 ;
131
- end
140
+ -- Display tall objects upright
141
+ local tallAng = ToMOSprite (item ):GetSpriteWidth () > ToMOSprite (item ):GetSpriteHeight () and 1.57 or 0 ;
142
+
132
143
local tilt = 0.3 ;
133
144
local rotAng = actor .RotAngle + tallAng + (heldCount * tilt - itemCount * tilt + isFirearm / itemSize ) / itemCount * actor .FlipFactor ;
134
145
0 commit comments