@@ -155,7 +155,7 @@ function HumanBehaviors.CalculateThreatLevel(MO, Owner)
155155 priority = priority + 0.3
156156 end
157157 elseif MO .ClassName == " ADoor" then
158- priority = priority * 0.5
158+ priority = priority * 0.3
159159 end
160160
161161 return priority - MO .Health / 500 -- prioritize damaged targets
@@ -168,24 +168,25 @@ function HumanBehaviors.ProcessAlarmEvent(AI, Owner)
168168 local canSupress = not AI .flying and Owner .FirearmIsReady and Owner .EquippedItem :HasObjectInGroup (" Weapons - Explosive" )
169169 for Event in MovableMan .AlarmEvents do
170170 if Event .Team ~= Owner .Team then -- caused by some other team's activities - alarming!
171- loudness = Owner .AimDistance + FrameMan . PlayerScreenWidth * 0.6 * Owner .Perceptiveness * Event .Range -- adjust the audible range to the screen resolution
171+ loudness = Owner .AimDistance + Owner .Perceptiveness * Event .Range
172172 AlarmVec = SceneMan :ShortestDistance (Owner .EyePos , Event .ScenePos , false ) -- see how far away the alarm situation is
173173 if AlarmVec .Largest < loudness then -- only react if the alarm is within hearing range
174174 -- if our relative position to the alarm location is the same, don't repeat the signal
175175 -- check if we have line of sight to the alarm point
176- if (not AI .LastAlarmVec or SceneMan :ShortestDistance (AI .LastAlarmVec , AlarmVec , false ).Largest > 10 ) then
176+ if (not AI .LastAlarmVec or SceneMan :ShortestDistance (AI .LastAlarmVec , AlarmVec , false ).Magnitude > 25 ) then
177177 AI .LastAlarmVec = AlarmVec
178178
179179 if AlarmVec .Largest < 100 then
180180 -- check more carfully at close range, and allow hearing of partially blocked alarm events
181181 if SceneMan :CastStrengthSumRay (Owner .EyePos , Event .ScenePos , 4 , rte .grassID ) < 100 then
182182 AI .AlarmPos = Vector (Event .ScenePos .X , Event .ScenePos .Y )
183183 end
184- elseif not SceneMan :CastStrengthRay (Owner .EyePos , AlarmVec , 6 , Vector (), 8 , rte .grassID , true ) then
184+ elseif not SceneMan :CastStrengthRay (Owner .EyePos , AlarmVec , 6 , Vector (), 8 , rte .grassID , true ) then
185185 AI .AlarmPos = Vector (Event .ScenePos .X , Event .ScenePos .Y )
186186 end
187187
188188 if AI .AlarmPos then
189+ Owner :SetAlarmPoint (AI .AlarmPos )
189190 AI :CreateFaceAlarmBehavior (Owner )
190191 return true
191192 end
@@ -935,10 +936,7 @@ function HumanBehaviors.WeaponSearch(AI, Owner, Abort)
935936 local itemsFound = 0
936937 for Item in MovableMan .Items do -- store all HeldDevices of the correct type and within a certain range in a table
937938 local HD = ToHeldDevice (Item )
938- if HD and not HD :IsActivated () and HD .Vel .Largest < 3 and
939- SceneMan :ShortestDistance (Owner .Pos , HD .Pos , false ).Largest < minDist and
940- not SceneMan :IsUnseen (HD .Pos .X , HD .Pos .Y , Owner .Team )
941- then
939+ if HD and HD :IsPickupableBy (Owner ) and not HD :IsActivated () and HD .Vel .Largest < 3 and SceneMan :ShortestDistance (Owner .Pos , HD .Pos , SceneMan .SceneWrapsX ).Largest < minDist and not SceneMan :IsUnseen (HD .Pos .X , HD .Pos .Y , Owner .Team ) then
942940 table.insert (Devices , HD )
943941 itemsFound = itemsFound + 1
944942 end
@@ -1176,7 +1174,7 @@ function HumanBehaviors.GoToWpt(AI, Owner, Abort)
11761174 local Facings = {{aim = 0 , facing = 0 }, {aim = 1.4 , facing = 1.4 }, {aim = 1.4 , facing = math.pi - 1.4 }, {aim = 0 , facing = math.pi }}
11771175
11781176 while true do
1179- if Owner .Vel . Largest > 2 then
1177+ if ( Owner .Vel + Owner . PrevVel ). Magnitude > 3 then
11801178 StuckTimer :Reset ()
11811179 end
11821180
@@ -1221,6 +1219,7 @@ function HumanBehaviors.GoToWpt(AI, Owner, Abort)
12211219 Waypoint = nil
12221220 WptList = nil -- update the path
12231221 elseif StuckTimer :IsPastSimTimeLimit () then -- dislodge
1222+ StuckTimer :Reset ()
12241223 if AI .jump then
12251224 if Owner .Jetpack and Owner .JetTimeLeft < AI .minBurstTime then -- out of fuel
12261225 AI .jump = false
@@ -1238,11 +1237,7 @@ function HumanBehaviors.GoToWpt(AI, Owner, Abort)
12381237 end
12391238 else
12401239 if PosRand () < 0.2 then
1241- if AI .lateralMoveState == Actor .LAT_LEFT then
1242- nextLatMove = Actor .LAT_RIGHT
1243- else
1244- nextLatMove = Actor .LAT_LEFT
1245- end
1240+ nextLatMove = AI .lateralMoveState == Actor .LAT_LEFT and Actor .LAT_RIGHT or Actor .LAT_LEFT
12461241 end
12471242
12481243 -- refuelling done
@@ -1669,21 +1664,21 @@ function HumanBehaviors.GoToWpt(AI, Owner, Abort)
16691664
16701665 if Waypoint then -- move towards the waypoint
16711666 -- control horizontal movement
1672- if Owner .FGLeg or Owner .BGLeg then
1673- if not AI .flying then
1674- if CurrDist .X < - 3 then
1675- nextLatMove = Actor .LAT_LEFT
1676- elseif CurrDist .X > 3 then
1677- nextLatMove = Actor .LAT_RIGHT
1678- else
1679- nextLatMove = Actor .LAT_STILL
1667+ if not AI .flying then
1668+ if CurrDist .X < - 3 then
1669+ nextLatMove = Actor .LAT_LEFT
1670+ elseif CurrDist .X > 3 then
1671+ nextLatMove = Actor .LAT_RIGHT
1672+ else
1673+ nextLatMove = Actor .LAT_STILL
1674+ end
1675+ if not (Owner .FGLeg and Owner .BGLeg ) then
1676+ if CurrDist .X * Owner .FlipFactor > 5 and - CurrDist .Y > math.abs (CurrDist .X ) then
1677+ AI .flying = true
1678+ elseif not AI .jump then
1679+ AI .proneState = AHuman .GOPRONE
16801680 end
16811681 end
1682- elseif ((CurrDist .X < - 5 and Owner .HFlipped ) or (CurrDist .X > 5 and not Owner .HFlipped )) and math.abs (Owner .Vel .X ) < 1 then
1683- -- no legs, jump forward
1684- AI .jump = true
1685- elseif not AI .jump then
1686- AI .proneState = AHuman .GOPRONE
16871682 end
16881683
16891684 if Waypoint .Type == " right" then
@@ -2126,25 +2121,21 @@ end
21262121
21272122-- get the projectile properties from the magazine
21282123function HumanBehaviors .GetProjectileData (Owner )
2129- local Weapon , Round , Projectile , PrjDat
2124+ local PrjDat = {MagazineName = " " }
2125+ local Weapon , Round , Projectile
21302126 if Owner .EquippedItem and IsHDFirearm (Owner .EquippedItem ) then
21312127 Weapon = ToHDFirearm (Owner .EquippedItem )
21322128 if Weapon .Magazine then
21332129 Round = Weapon .Magazine .NextRound
21342130 Projectile = Round .NextParticle
2135- PrjDat = { MagazineName = Weapon .Magazine .PresetName }
2131+ PrjDat . MagazineName = Weapon .Magazine .PresetName
21362132 end
21372133 end
21382134 if Round == nil or Round .IsEmpty then -- set default values if there is no particle
21392135 PrjDat .g = 0
21402136 PrjDat .vel = 100
21412137 PrjDat .rng = math.huge
21422138 else
2143- PrjDat .blast = Weapon :GetAIBlastRadius () -- check if this weapon have a blast radius
2144- if PrjDat .blast > 0 then
2145- PrjDat .exp = true -- set this for legacy reasons
2146- end
2147-
21482139 -- find muzzle velocity
21492140 PrjDat .vel = Weapon :GetAIFireVel ()
21502141 -- half of the theoretical upper limit for the total amount of material strength this weapon can destroy in 250ms
@@ -2156,6 +2147,12 @@ function HumanBehaviors.GetProjectileData(Owner)
21562147 PrjDat .thr = math.min (Projectile .AirThreshold , PrjDat .vel )
21572148 PrjDat .pen = (Projectile .Mass * Projectile .Sharpness * PrjDat .vel ) * PrjDat .drg
21582149
2150+ PrjDat .blast = Weapon :GetAIBlastRadius ()
2151+ if PrjDat .blast > 0 or Weapon :IsInGroup (" Weapons - Explosive" ) then
2152+ PrjDat .exp = true -- set this for legacy reasons
2153+ PrjDat .pen = PrjDat .pen + 100
2154+ end
2155+
21592156 -- estimate theoretical max range with ...
21602157 local lifeTime = Weapon :GetAIBulletLifeTime ()
21612158 if lifeTime < 1 then -- infinite life time
@@ -2632,6 +2629,7 @@ function HumanBehaviors.ShootTarget(AI, Owner, Abort)
26322629end
26332630
26342631-- throw a grenade at the selected target
2632+ -- TODO: This behavior should effectively have the actor close in on the target if out of range!
26352633function HumanBehaviors .ThrowTarget (AI , Owner , Abort )
26362634 local ThrowTimer = Timer ()
26372635 local aimTime = Owner .ThrowPrepTime
@@ -2842,25 +2840,18 @@ function HumanBehaviors.AttackTarget(AI, Owner, Abort)
28422840 end
28432841 -- use following sequence to attack either with a suited melee weapon or arms
28442842 local meleeDist = 0
2845- local startPos = Vector (Owner .EyePos .X , Owner .EyePos .Y )
28462843
2847- if Owner :EquipDeviceInGroup (" Tools - Diggers" , true ) or Owner :EquipDeviceInGroup (" Weapons - Melee" , true ) then
2848- meleeDist = Owner .IndividualRadius + 25
2849- startPos = Vector (Owner .EquippedItem .Pos .X , Owner .EquippedItem .Pos .Y )
2850- elseif Owner .armSway then
2851- local arm = Owner .FGArm or Owner .BGArm
2852- if arm then
2853- meleeDist = arm .Radius + arm .Radius
2854- startPos = arm .Pos
2855- end
2844+ if Owner :EquipDeviceInGroup (" Tools - Diggers" , true ) or Owner :EquipDeviceInGroup (" Weapons - Melee" , true ) or Owner :EquipDeviceInGroup (" Tools - Breaching" , true ) then
2845+ meleeDist = Owner .IndividualRadius + (IsThrownDevice (Owner .EquippedItem ) and 50 or 25 )
28562846 end
28572847 if meleeDist > 0 then
2848+ local startPos = Vector (Owner .EquippedItem .Pos .X , Owner .EquippedItem .Pos .Y )
28582849 local attackPos = (AI .Target .ClassName == " ADoor" and ToADoor (AI .Target ).Door and ToADoor (AI .Target ).Door :IsAttached ()) and ToADoor (AI .Target ).Door .Pos or AI .Target .Pos
28592850 local dist = SceneMan :ShortestDistance (startPos , attackPos , false )
28602851 if dist .Magnitude < meleeDist then
28612852 AI .lateralMoveState = Actor .LAT_STILL
28622853 AI .Ctrl .AnalogAim = SceneMan :ShortestDistance (Owner .EyePos , attackPos , false ).Normalized
2863- AI .fire = true
2854+ AI .fire = not ( AI . fire and IsThrownDevice ( Owner . EquippedItem ) and Owner . ThrowProgress == 1 )
28642855 else
28652856 AI .fire = false
28662857 end
0 commit comments