Skip to content
This repository was archived by the owner on Jan 5, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f849594
Add Green Dummy and AI Box Actors along with new script to display a …
fourZK Jul 25, 2020
8413f58
Minor material edits
fourZK Jul 25, 2020
f9ff472
Minor edits to Actors and Craft: reorganizing, fixed spacing, etc.
fourZK Jul 25, 2020
978b63c
Misc effects edits; Scripted Air Blast now deals .lua damage
fourZK Jul 25, 2020
e0625e3
Activity edits: Brain vs. Brain now spawns faction brain unit, all do…
fourZK Jul 25, 2020
0b15c25
Brain cases are no longer made out of Concrete + minor edits
fourZK Jul 25, 2020
d46bb6d
Edits to HumanAI: default AI skill is now higher, AI bursts jetpack r…
fourZK Jul 25, 2020
84b6a96
Craft price and delivery delay inflation
fourZK Jul 25, 2020
b17ea26
Edits to Dropship bombs: can now be shot in midair
fourZK Jul 25, 2020
37961bc
Remote Explosive rework: now spawns a free Detonator tool for the user
fourZK Jul 25, 2020
33a3b77
Lots of minor device-related edits and cleanup (to-do: preserve legac…
fourZK Jul 25, 2020
05b5b7c
Constructor rework: the cursor is now a Vector rather than a loose Ac…
fourZK Jul 25, 2020
94650a4
Door GibLimit and JointStrength buff (awaiting further door material …
fourZK Jul 25, 2020
850dafc
Added new bunker module: Spikes
fourZK Jul 25, 2020
3d02609
New bunker module: Background Ladder
fourZK Jul 25, 2020
640b6d7
Missed a new file for devices-related commit
fourZK Jul 25, 2020
d127d0b
Rename "FlameBall00.bmp" to "FlameBall.bmp"
fourZK Jul 25, 2020
598c3d3
Missed a few removals for unused files
fourZK Jul 25, 2020
03ccea9
Merge branch '4zk-content-old' into 4zk-content
fourZK Jul 25, 2020
fef71c8
Reverting filepath edit mishap
fourZK Jul 25, 2020
8502ab9
Merge branch 'development' into 4zk-content
Aug 12, 2020
527b68b
Changes requested by Gacyr
fourZK Aug 14, 2020
09846a4
Changes requested by MaximDude
fourZK Aug 14, 2020
478a316
Delete unused files
fourZK Aug 14, 2020
9da51be
Minor changes
fourZK Aug 14, 2020
5324f77
whoops lol
fourZK Aug 14, 2020
84f7a63
Switched constructor collect particle reliance to MOID for now
fourZK Aug 14, 2020
07b5e84
Missions.rte fixes + disable WIP factions
fourZK Aug 14, 2020
72c1f04
Setting the AI Box as unbuyable since it doesn't serve a purpose yet
fourZK Aug 16, 2020
a7c1d4c
Misc changes
fourZK Aug 16, 2020
3f246bc
Merge branch 'development' into 4zk-content
fourZK Aug 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Base.rte/AI/DropShipAI.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,13 @@ end
function UpdateAI(self)
self.AI:Update(self)
end

function Update(self)
--Re-orient the craft at 180 degrees to help rotational AI
if self.RotAngle > math.pi then
self.RotAngle = self.RotAngle - (math.pi * 2);
end
if self.RotAngle < -math.pi then
self.RotAngle = self.RotAngle + (math.pi * 2);
end
end
3 changes: 1 addition & 2 deletions Base.rte/AI/HumanAI.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ function Create(self)
self.visibleInventory = true;
end
function Update(self)

self.controller = self:GetController();

if self.alternativeGib then
Expand All @@ -21,7 +20,7 @@ function Update(self)
HumanFunctions.DoAutomaticEquip(self);
end
if self.armSway then
HumanFunctions.DoArmSway(self, (self.Health / self.MaxHealth)); --Argument: shove strength
HumanFunctions.DoArmSway(self, (self.Health/self.MaxHealth)); --Argument: shove strength
end
if self.visibleInventory then
HumanFunctions.DoVisibleInventory(self, false); --Argument: whether to show all items
Expand Down
70 changes: 32 additions & 38 deletions Base.rte/AI/HumanBehaviors.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,14 @@ function HumanBehaviors.GetTeamShootingSkill(team)
end

local aimSpeed, aimSkill
if skill < Activity.AVERAGESKILL then -- the AI shoot later and tracks the target slower
aimSpeed = -0.025 * skill + 3.3 -- affects the delay before the shooting starts [3.30 .. 1.55]
aimSkill = -0.011 * skill + 2.2 -- affects the precision of the shots [2.20 .. 1.43]
elseif skill >= Activity.UNFAIRSKILL then
aimSpeed = 0.05
aimSkill = 0.05
if skill >= Activity.UNFAIRSKILL then
aimSpeed = 0.04
aimSkill = 0.04
else
-- the AI shoot sooner and with slightly better precision
aimSpeed = 1/(0.55/(2.9-math.exp(skill*0.01))) -- [1.42 .. 0.38]
aimSkill = 1/(0.65/(3.0-math.exp(skill*0.01))) -- [1.36 .. 0.48]
aimSpeed = 1/(0.65/(2.9-math.exp(skill*0.01)))
aimSkill = 1/(0.75/(3.0-math.exp(skill*0.01)))
end

return aimSpeed, aimSkill, skill
end

Expand All @@ -36,10 +32,10 @@ end

-- spot targets by casting a ray in a random direction
function HumanBehaviors.LookForTargets(AI, Owner, Skill)
local viewAngDeg = RangeRand(50, 120) * Owner.Perceptiveness * (0.5 + Skill / 200)
local viewAngDeg = RangeRand(50, 120) * Owner.Perceptiveness * (0.5 + Skill/200)
if AI.deviceState == AHuman.AIMING then
AI.Ctrl:SetState(Controller.AIM_SHARP, true) -- reinforce sharp aim controller state to enable SharpLength in LookForMOs
viewAngDeg = 15 * Owner.Perceptiveness + (Skill / 10)
viewAngDeg = 15 * Owner.Perceptiveness + (Skill/10)
end

local FoundMO = Owner:LookForMOs(viewAngDeg, rte.grassID, false)
Expand Down Expand Up @@ -84,6 +80,8 @@ function HumanBehaviors.CheckEnemyLOS(AI, Owner, Skill)

local LookTarget
if Enemy.ClassName == "ADoor" then
-- TO-DO: use explosive weapons on doors?

local Door = ToADoor(Enemy).Door
if Door and Door:IsAttached() then
LookTarget = Door.Pos
Expand Down Expand Up @@ -500,8 +498,7 @@ function HumanBehaviors.Sentry(AI, Owner, Abort)
elseif AI.SentryFacing and Owner.HFlipped ~= AI.SentryFacing then
Owner.HFlipped = AI.SentryFacing -- turn to the direction we have been order to guard
break -- restart this behavior
elseif math.random() < Owner.Perceptiveness then

elseif AI.Target == nil and math.random() < Owner.Perceptiveness then
-- turn around occasionally if there is open space behind our back
local backAreaRay = Vector(-math.random(FrameMan.PlayerScreenWidth/4, FrameMan.PlayerScreenWidth/2) * Owner.FlipFactor, 0):DegRotate(math.random(-25, 25) * Owner.Perceptiveness)
if not SceneMan:CastStrengthRay(Owner.EyePos, backAreaRay, 10, Vector(), 10, rte.grassID, SceneMan.SceneWrapsX) then
Expand Down Expand Up @@ -1682,13 +1679,12 @@ function HumanBehaviors.GoToWpt(AI, Owner, Abort)
else
nextLatMove = Actor.LAT_STILL
end
if not (Owner.FGLeg and Owner.BGLeg) and not AI.jump then
Owner:GetController():SetState(Controller.BODY_CROUCH,true) -- crawl if no legs
end
end
elseif ((CurrDist.X < -5 and Owner.HFlipped) or (CurrDist.X > 5 and not Owner.HFlipped)) and math.abs(Owner.Vel.X) < 1 then
-- no legs, jump forward
AI.jump = true
elseif not AI.jump then
AI.proneState = AHuman.GOPRONE
end

if Waypoint.Type == "right" then
Expand Down Expand Up @@ -1821,7 +1817,7 @@ function HumanBehaviors.GoToWpt(AI, Owner, Abort)
local delta = SceneMan:ShortestDistance(Waypoint.Pos, FallPos, false).Magnitude - Facings[1].range
if delta < 1 then
AI.jump = false
elseif AI.flying or delta > 15 then
elseif AI.flying or delta > 25 then
AI.jump = true
nextAimAngle = Owner:GetAimAngle(false) * 0.5 + Facings[1].aim * 0.5 -- adjust jetpack nozzle direction
nextLatMove = Actor.LAT_STILL
Expand Down Expand Up @@ -2146,32 +2142,32 @@ function HumanBehaviors.GetProjectileData(Owner)

-- find muzzle velocity
PrjDat.vel = Weapon:GetAIFireVel()

-- half of the theoretical upper limit for the total amount of material strength this weapon can destroy in 250ms
PrjDat.pen = Weapon:GetAIPenetration() * math.max((Weapon.RateOfFire / 240), 1)

PrjDat.g = SceneMan.GlobalAcc.Y * 0.67 * Weapon:GetBulletAccScalar() -- underestimate gravity
PrjDat.vsq = PrjDat.vel^2 -- muzzle velocity squared
PrjDat.vqu = PrjDat.vsq^2 -- muzzle velocity quad
PrjDat.drg = 1 - Projectile.AirResistance * TimerMan.DeltaTimeSecs -- AirResistance is stored as the ini-value times 60
PrjDat.thr = math.min(Projectile.AirThreshold, PrjDat.vel)
PrjDat.pen = (Projectile.Mass * Projectile.Sharpness * PrjDat.vel) * PrjDat.drg

-- estimate theoretical max range with ...
local lifeTime = Weapon:GetAIBulletLifeTime()
if lifeTime < 1 then -- infinite life time
PrjDat.rng = math.huge
elseif PrjDat.drg < 1 then -- AirResistance
PrjDat.rng = 0
local threshold = PrjDat.thr * GetPPM() * TimerMan.DeltaTimeSecs -- AirThreshold in pixels/frame
local vel = PrjDat.vel * GetPPM() * TimerMan.DeltaTimeSecs -- muzzle velocity in pixels/frame
local threshold = PrjDat.thr * rte.PxTravelledPerFrame -- AirThreshold in pixels/frame
local vel = PrjDat.vel * rte.PxTravelledPerFrame -- muzzle velocity in pixels/frame

for _ = 0, math.ceil(lifeTime/TimerMan.DeltaTimeMS) do
PrjDat.rng = PrjDat.rng + vel
if vel > threshold then
vel = vel * PrjDat.drg
end
end
else -- no AirResistance
PrjDat.rng = PrjDat.vel * GetPPM() * TimerMan.DeltaTimeSecs * (lifeTime / TimerMan.DeltaTimeMS)
PrjDat.rng = PrjDat.vel * rte.PxTravelledPerFrame * (lifeTime / TimerMan.DeltaTimeMS)
end

-- Artificially decrease reported range to make sure AI
Expand Down Expand Up @@ -2633,9 +2629,9 @@ function HumanBehaviors.ThrowTarget(AI, Owner, Abort)
local scan = 0
local miss = 0 -- stop scanning after a few missed attempts
local AimPoint, Dist, MO, ID, rootID, LOS, aim

AI.TargetLostTimer:SetSimTimeLimitMS(1500)

while true do
if not MovableMan:ValidMO(AI.Target) then
break
Expand Down Expand Up @@ -2747,7 +2743,7 @@ function HumanBehaviors.ThrowTarget(AI, Owner, Abort)
aim = HumanBehaviors.GetGrenadeAngle(AimPoint, Vector(), Grenade.MuzzlePos, Grenade.MaxThrowVel)
if aim then
ThrowTimer:Reset()
aimTime = RangeRand(1000, 1200)
aimTime = RangeRand(900, 1100)
local maxAim = aim

-- try again with an average throw vel
Expand Down Expand Up @@ -2829,24 +2825,22 @@ function HumanBehaviors.AttackTarget(AI, Owner, Abort)
local meleeDist = 0
local startPos = Vector(Owner.EyePos.X, Owner.EyePos.Y)

if Owner.EquippedItem then
if Owner.EquippedItem:HasObjectInGroup("Tools - Diggers") or Owner.EquippedItem:HasObjectInGroup("Weapons - Melee") then
meleeDist = Owner.Radius + 25
startPos = Vector(Owner.EquippedItem.Pos.X, Owner.EquippedItem.Pos.Y)
end
if Owner:EquipDeviceInGroup("Tools - Diggers", true) or Owner:EquipDeviceInGroup("Weapons - Melee", true) then
meleeDist = Owner.Radius + 25
startPos = Vector(Owner.EquippedItem.Pos.X, Owner.EquippedItem.Pos.Y)
elseif Owner.armSway then
if Owner.FGArm then
meleeDist = Owner.Radius + Owner.FGArm.Radius
startPos = Owner.FGArm.Pos
elseif Owner.BGArm then
meleeDist = Owner.Radius + Owner.BGArm.Radius
startPos = Owner.BGArm.Pos
local arm = Owner.FGArm or Owner.BGArm
if arm then
meleeDist = arm.Radius + arm.Radius
startPos = arm.Pos
end
end
if meleeDist > 0 then
local dist = SceneMan:ShortestDistance(startPos, AI.Target.Pos, false)
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
local dist = SceneMan:ShortestDistance(startPos, attackPos, false)
if dist.Magnitude < meleeDist then
AI.Ctrl.AnalogAim = SceneMan:ShortestDistance(Owner.EyePos, AI.Target.Pos, false).Normalized
AI.lateralMoveState = Actor.LAT_STILL
AI.Ctrl.AnalogAim = SceneMan:ShortestDistance(Owner.EyePos, attackPos, false).Normalized
AI.fire = true
else
AI.fire = false
Expand Down
79 changes: 38 additions & 41 deletions Base.rte/AI/HumanFunctions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,27 @@ HumanFunctions = {};

function HumanFunctions.DoAlternativeGib(actor)
--Detach limbs instead of regular gibbing
if not actor.detachLimit then
actor.detachLimit = actor.GibWoundLimit;
actor.GibWoundLimit = actor.GibWoundLimit * 1.5;
end
if actor.WoundCount > actor.detachLimit then
actor.detachLimit = actor.WoundCount + 1;
local parts = {actor.BGArm, actor.BGLeg, actor.FGArm, actor.FGLeg, actor.Head}; --Piority order
local mostWounds = -1;
local detachLimb;
--Pick the limb with most wounds and detach it
for i = 1, #parts do
local limb = parts[i];
if limb and limb.WoundCount > mostWounds then
detachLimb = limb;
mostWounds = limb.WoundCount;
if actor.detachLimit then
Comment thread
fourZK marked this conversation as resolved.
if actor.WoundCount > actor.detachLimit then
actor.detachLimit = actor.WoundCount + 1;
local parts = {actor.BGArm, actor.BGLeg, actor.FGArm, actor.FGLeg, actor.Head}; --Priority order
local mostWounds = -1;
local detachLimb;
--Pick the limb with most wounds and detach it
for i = 1, #parts do
local limb = parts[i];
if limb and limb.WoundCount > mostWounds then
detachLimb = limb;
mostWounds = limb.WoundCount;
end
end
if detachLimb then
detachLimb.JointStrength = -1;
end
end
if detachLimb then
detachLimb.JointStrength = -1;
end
elseif actor.GibWoundLimit > 0 then
actor.detachLimit = actor.GibWoundLimit;
actor.GibWoundLimit = actor.GibWoundLimit * 1.5;
end
end

Expand All @@ -39,20 +40,15 @@ function HumanFunctions.DoArmSway(actor, pushStrength)
actor.lastAngle = aimAngle;
actor.lastHandPos = {actor.Pos, actor.Pos};
end
if actor.controller:IsMouseControlled() then
--Flail around if moving mouse too fast
local mouseVec = Vector(actor.controller.MouseMovement.X, actor.controller.MouseMovement.Y):SetMagnitude(math.sqrt(actor.controller.MouseMovement.Magnitude));
local ang = actor.lastAngle - aimAngle;

actor.AngularVel = actor.AngularVel - (2 * ang * actor.FlipFactor + mouseVec.Y * actor.FlipFactor /10) /math.sqrt(math.abs(actor.AngularVel) + 1);

actor.lastAngle = aimAngle;
end
--Flail around if aiming around too fast
local angleMovement = actor.lastAngle - aimAngle;
actor.AngularVel = actor.AngularVel - (2 * angleMovement * actor.FlipFactor)/(math.abs(actor.AngularVel)/10 + 1);
actor.lastAngle = aimAngle;
--Shove when unarmed
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
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));
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));
if not actor.shoved then
actor.Vel = actor.Vel + Vector(2 /(1 + actor.Vel.Magnitude), 0):RadRotate(actor:GetAimAngle(true)) * math.abs(math.cos(actor:GetAimAngle(true)));
actor.Vel = actor.Vel + Vector(2/(1 + actor.Vel.Magnitude), 0):RadRotate(actor:GetAimAngle(true)) * math.abs(math.cos(actor:GetAimAngle(true)));
actor.shoved = true;
end
else
Expand All @@ -78,31 +74,31 @@ function HumanFunctions.DoArmSway(actor, pushStrength)
if actor.controller:IsState(Controller.AIM_SHARP) then
arm.IdleOffset = Vector(0, 1):RadRotate(aimAngle);
else
arm.IdleOffset = Vector(0, (armLength + arm.SpriteOffset.X) * 1.1):RadRotate(rotAng * actor.FlipFactor + 1.5 + (i /5));
arm.IdleOffset = Vector(0, (armLength + arm.SpriteOffset.X) * 1.1):RadRotate(rotAng * actor.FlipFactor + 1.5 + (i/5));
end
if actor.shoved or (actor.EquippedItem and IsTDExplosive(actor.EquippedItem) and actor.controller:IsState(Controller.WEAPON_FIRE)) then
arm.IdleOffset = Vector(armLength + (pushStrength * armLength), 0):RadRotate(aimAngle);
local handVector = SceneMan:ShortestDistance(actor.lastHandPos[i], arm.HandPos, SceneMan.SceneWrapsX);
--Diminish hand relocation vector to potentially prevent post-superhuman pushing powers
handVector:SetMagnitude(handVector.Magnitude / (1 + handVector.Magnitude / 100));
handVector:SetMagnitude(handVector.Magnitude/(1 + handVector.Magnitude/100));
--Emphasize the first frames that signify contracted arm = highest potential energy
local dots = math.sqrt(arm.Radius) / (1 + arm.Frame /arm.FrameCount);
local dots = math.sqrt(arm.Radius)/(1 + arm.Frame/arm.FrameCount);
local armStrength = (arm.Mass + arm.Material.StructuralIntegrity) * pushStrength;
for i = 1, dots do
local part = CreateMOPixel("Smack Particle Light");
part.Pos = arm.HandPos - Vector(handVector.X/2, handVector.Y /2);
part.Pos = arm.HandPos - Vector(handVector.X/2, handVector.Y/2);
part.Vel = Vector(handVector.X, handVector.Y):RadRotate(RangeRand(-0.1, 0.1)) + Vector(0, -0.5);
part.Mass = armStrength; part.Sharpness = math.random() * 0.1;
part.Team = actor.Team; part.IgnoresTeamHits = true;
MovableMan:AddParticle(part);
end
--Apply some additional forces if the travel vector of the moving hand is half an arms length
if handVector.Magnitude > (armLength /2) then
if handVector.Magnitude > (armLength/2) then
local moCheck = SceneMan:GetMOIDPixel(arm.HandPos.X, arm.HandPos.Y)
if moCheck ~= rte.NoMOID then
local mo = MovableMan:GetMOFromID(MovableMan:GetMOFromID(moCheck).RootID);
if mo and mo.Team ~= actor.Team and IsActor(mo) and actor.Mass > (mo.Mass / 2) then
mo:AddForce(handVector * (actor.Mass / 2), Vector());
if mo and mo.Team ~= actor.Team and IsActor(mo) and actor.Mass > (mo.Mass/2) then
mo:AddForce(handVector * (actor.Mass/2), Vector());
ToActor(mo).Status = Actor.UNSTABLE;
end
end
Expand All @@ -120,7 +116,6 @@ function HumanFunctions.DoVisibleInventory(actor, showAll)
for i = 1, actor.InventorySize do
local item = actor:Inventory();
if item then
local fixNum = actor.HFlipped and -1 or 0; --Fix offsets slightly when facing left
if item.ClassName == "TDExplosive" then
thrownCount = thrownCount + 1;
elseif item.ClassName == "HDFirearm" or item.ClassName == "HeldDevice" then
Expand All @@ -131,7 +126,7 @@ function HumanFunctions.DoVisibleInventory(actor, showAll)
local isFirearm = item.ClassName == "HeldDevice" and 0 or 1;
local actorSize, itemSize = math.sqrt(actor.Radius), math.sqrt(item.Radius + math.abs(item.Mass));

fixNum = fixNum + item.Radius * 0.2 + math.sqrt(heldCount);
local fixNum = item.Radius * 0.2 + math.sqrt(heldCount);

--Bigger actors carry weapons higher up, smaller weapons are carried lower down
local drawPos = actor.Pos + Vector((-actorSize - fixNum) * actor.FlipFactor, -actorSize - itemSize + 1 + isFirearm * 3):RadRotate(actor.RotAngle);
Expand All @@ -141,11 +136,13 @@ function HumanFunctions.DoVisibleInventory(actor, showAll)
local tallAng = ToMOSprite(item):GetSpriteWidth() > ToMOSprite(item):GetSpriteHeight() and 1.57 or 0;

local tilt = 0.3;
local rotAng = actor.RotAngle + tallAng + (heldCount * tilt - itemCount * tilt + isFirearm /itemSize) /itemCount * actor.FlipFactor;
local rotAng = actor.RotAngle + tallAng + (heldCount * tilt - itemCount * tilt + isFirearm/itemSize)/itemCount * actor.FlipFactor;

for player = Activity.PLAYER_1, Activity.MAXPLAYERCOUNT - 1 do
if not SceneMan:IsUnseen(drawPos.X, drawPos.Y, ActivityMan:GetActivity():GetTeamOfPlayer(player)) then
PrimitiveMan:DrawBitmapPrimitive(ActivityMan:GetActivity():ScreenOfPlayer(player), drawPos, item, rotAng, 0);

local screen = ActivityMan:GetActivity():ScreenOfPlayer(player);
if screen ~= -1 and not SceneMan:IsUnseen(drawPos.X, drawPos.Y, ActivityMan:GetActivity():GetTeamOfPlayer(player)) then
PrimitiveMan:DrawBitmapPrimitive(screen, drawPos, item, rotAng, 0);
end
end
end
Expand Down
Loading