From 8ca64d225e85f4812eb8a804f06ac9aa0507bfc8 Mon Sep 17 00:00:00 2001 From: "Gustavo Rehermann (Gustavo6046)" Date: Thu, 16 May 2019 09:40:02 +0000 Subject: [PATCH] Refactoring code into subroutines (finally!); also added respawn block/encroach check --- KeyConf.txt | 4 +- ZScript.zsc | 772 ++++++++++--------- ZetaCode/Pathing.zsc | 76 +- ZetaCode/PawnClasses/ZetaBotPawn.zsc | 10 +- ZetaCode/PawnClasses/ZetaDoom.zsc | 4 + ZetaCode/Standard.zsc | 2 +- ZetaCode/WeaponSupport/Doom/ZetaChaingun.zsc | 2 +- config | 2 +- 8 files changed, 483 insertions(+), 389 deletions(-) diff --git a/KeyConf.txt b/KeyConf.txt index 08532e9..fe93ff0 100644 --- a/KeyConf.txt +++ b/KeyConf.txt @@ -22,4 +22,6 @@ addmenukey "Kill All Bots" "kill zetadoom; kill zetastrife; kill zetasmushes" alias superzeta "summonfriend ZetaBot 0; wait 3; test $r_superzeta superzeta" alias +superzeta "set r_superzeta 1; superzeta" -alias -superzeta "set r_superzeta 0" \ No newline at end of file +alias -superzeta "set r_superzeta 0" + +alias ztpaths "summon ZTShowAllPaths" \ No newline at end of file diff --git a/ZScript.zsc b/ZScript.zsc index f91032a..de4cc7a 100644 --- a/ZScript.zsc +++ b/ZScript.zsc @@ -344,6 +344,16 @@ class ZTBotController : Actor { while ((pn = ZTPathNode(iter.Next())) != null) { if (pn.nodeType == ZTPathNode.NT_RESPAWN || (CVar.FindCVar("zb_anynoderespawn").GetBool() && pn.nodeType != ZTPathNode.NT_USE && pn.nodeType != ZTPathNode.NT_AVOID)) { + pn.Radius = possessed.Radius; + pn.Height = possessed.Height; + + if (pn.CheckBlock()) { + pn.Radius = pn.default.Radius; + pn.Height = pn.default.Height; + + continue; + } + double prob = FRandom(0, chanceDenom); if (prob <= 1.0) @@ -364,7 +374,7 @@ class ZTBotController : Actor { SetPossessed(ZetaBotPawn(Spawn(possessedType, spawnPos))); possessed.angle = chosen.angle; - Spawn("TeleportFog", spawnPos); + SpawnTeleportFog(spawnPos, false, false); // Telefrag things let telefragIter = ThinkerIterator.Create("Actor", STAT_DEFAULT); @@ -506,22 +516,14 @@ class ZTBotController : Actor { if (!(cur = Actor(iter2.Next()))) break; - Vector2 off = possessed.Vec2To(cur); - - double pdot = 1; - - if (possessed.Distance2D(cur) > 0) { - off.x /= possessed.Distance2D(cur); - off.y /= possessed.Distance2D(cur); // slightly inneficient but works - - Vector2 avec = AngleToVector(possessed.angle); - - double pdot = off.x * avec.x + off.y * avec.y; - } + if (cur == null || cur == from) continue; + if (!(cur.bISMONSTER || cur.CheckClass("PlayerPawn", match_superclass: true))) continue; + if (cur.Health <= 0) continue; + if (cur.bInvisible) continue; + if (!(from.CheckSight(cur) && LineOfSight(cur, from))) continue; + if (!IsEnemy(from, cur)) continue; - if (cur != null && cur != from && (cur.bISMONSTER || cur.CheckClass("PlayerPawn", match_superclass: true)) && LineOfSight(cur, from) && isEnemy(from, cur) && cur.Health > 0 && pdot > 0.3) { - res.Push(cur); - } + res.Push(cur); } return res; @@ -624,11 +626,11 @@ class ZTBotController : Actor { possessed.EndShoot(); } - MoveToward(toward, 15); + MoveToward(toward, 20); } else - MoveToward(toward, 15); + MoveToward(toward, 20); } else @@ -717,7 +719,8 @@ class ZTBotController : Actor { if (other.pos.z + other.height / 2 == from.pos.z + from.height / 2) return 0; - return atan(other.pos.z + other.height / 2 - from.pos.z - from.height / 2); + //return other.pos.z + other.height / 2 - from.pos.z - from.height / 2; + return tan(other.pos.z + other.height / 2 - from.pos.z - from.height / 2); } ZTPathNode ClosestVisibleNode(Actor other) { @@ -875,7 +878,14 @@ class ZTBotController : Actor { } void RandomMove() { // nodeless wandering - angleMomentum += FRandom(-0.03, 0.03); + if (FRandom(0, 1) < 0.3) { + angleMomentum += FRandom(-0.03, 0.03); + + if (FRandom(0, 1) < 0.125) + angleMomentum *= -0.2; + } + + else angleMomentum /= 1.1; if (FRandom(0, 1) < 0.7) MoveForward(); @@ -1036,7 +1046,147 @@ class ZTBotController : Actor { NumBots.Get().value--; } + + void Subroutine_Follow() { + if (possessed.Distance3D(goingAfter) < 400 || possessed.CheckSight(goingAfter)) + SetBotState(BS_WANDERING); + + else { + BotChat("IDLE", 2.25 / 90); + + if (DodgeAndUse()) + SetBotState(BS_WANDERING); + + if (goingAfter != null) { + if (possessed.Distance3D(goingAfter) < 1024 && possessed.CheckSight(goingAfter)) + SetBotState(AssessBotAttitude(goingAfter)); + + else if (currNode != null && (navDest == null || Distance3D(navDest) < 512 || navDest == currNode)) { + if (ClosestNode(goingAfter) == currNode) { + SetBotState(BS_WANDERING); + } + + else if (pathCountdown <= 0) { + ActorList path = navDest.findPathTo(ClosestNode(goingAfter), possessed); + + if (path != null && path.Length() > 1) { + navDest = ZTPathNode(path.get(0)); + + DebugLog(LT_INFO, "Next navigation point found at: "..navDest.pos); + SmartMove(navDest); + } + + else + MoveToward(goingAfter, 0.27); + + pathCountdown += 24; + } + + else + pathCountdown--; + } + + else if (navDest != null) + SmartMove(); + + else if (possessed.Distance3D(goingAfter) < 256) + SetBotState(BS_ATTACKING); + + else if (possessed.Distance3D(goingAfter) > 1500 && !possessed.CheckSight(goingAfter)) + SetBotState(BS_WANDERING); + + else + MoveToward(goingAfter, 15); + } + + else + SetBotState(BS_WANDERING); + } + } + + void Subroutine_Hunt() { + if (enemy == null || enemy.Health <= 0) { + enemy = null; + SetBotState(BS_WANDERING); + + if (lastEnemyPos != null) lastEnemyPos.Destroy(); + lastEnemyPos = null; + } + else if (LineOfSight(enemy) || possessed.Distance3D(enemy) < 96) { + AimToward(enemy, 15); + SetBotState(BS_ATTACKING); + possessed.Jump(); + + if (lastEnemyPos != null) lastEnemyPos.Destroy(); + lastEnemyPos = null; + } + + else { + RefreshEnemy() + + if (bstate == BS_HUNTING) { + if (lastEnemyPos == null) { + SetBotState(BS_WANDERING); + return; + } + + double lastPosSqDist = ((possessed.pos.x - lastEnemyPos.pos.x) * (possessed.pos.x - lastEnemyPos.pos.x)) + + ((possessed.pos.y - lastEnemyPos.pos.y) * (possessed.pos.y - lastEnemyPos.pos.y)); + + if (lastPosSqDist < 40 * 40 || (CheckObstructions() && !possessed.CheckSight(lastEnemyPos))) { + enemy = null; + SetBotState(BS_WANDERING); + + if (lastEnemyPos != null) lastEnemyPos.Destroy(); + lastEnemyPos = null; + } + + else if (lastEnemyPos != null) { + if (possessed.CheckSight(lastEnemyPos)) + SmartMove(lastEnemyPos); + + else if (currNode != null && (navDest == null || possessed.Distance2D(navDest) < 64)) { // path to lastEnemyPos + ActorList path = currNode.findPathTo(lastEnemyPos, possessed); + + if (path != null && path.Length() > 0) { + navDest = ZTPathNode(path.get(0)); + SmartMove(navDest); + + DebugLog(LT_INFO, "Next navigation point found at: "..navDest.pos); + } + + if (navDest == null) + SetBotState(BS_WANDERING); + } + + else if (navDest != null) + SmartMove(navDest); + + else + SetBotState(BS_WANDERING); + + if (bstate == BS_HUNTING) { + if (FRandom(0, 1) < 0.12) + possessed.Jump(); + + AutoUseAtAngle(0); + } + } + + else { + enemy = null; + SetBotState(BS_WANDERING); + } + + if (bstate == BS_HUNTING) { + BotChat("ACTV", 0.025); + } + } + } + + return; + } bool DodgeAndUse() { if (currNode == null) @@ -1102,6 +1252,208 @@ class ZTBotController : Actor { return currNode.nodeType == ZTPathNode.NT_USE; } + + void RefreshEnemy() { + ActorList mon = VisibleEnemies(possessed); + + if (mon.length() > 0) { + PriorityQueue targets = new("PriorityQueue"); + + for (uint i = 0; i < mon.length(); i++) + targets.add(mon.get(i), TargetPriority(mon.get(i))); + + Actor newEnemy = Actor(targets.poll()); + + if (enemy == null || TargetPriority(enemy) < TargetPriority(newEnemy)) + enemy = Actor(newEnemy); + + /* + else { + if (retargetCount < 1) { + enemy = Actor(targets.poll()); + retargetCount = 15; + } + + else + retargetCount--; + } + */ + + DebugLog(LT_INFO, "Attacking a "..enemy.GetClassName()); + + BotChat("TARG", 0.8); + + SetBotState(BS_ATTACKING); + } + } + + void Subroutine_Flee() { + if (DodgeAndUse()) { + if (currNode != null) + navDest = currNode.RandomNeighbor(); + + else + navDest = null; + + SetBotState(BS_WANDERING); + } + + if (enemy != null && possessed.Distance3D(enemy) < 1024 && possessed.CheckSight(enemy) && possessed.Health < possessed.default.Health / 7) + MoveAwayFrom(enemy); + + else + SetBotState(BS_WANDERING); + } + + void Subroutine_Attack() { + if (enemy != null && enemy.Health >= 1) { // health is integer + if (bstate != BS_HUNTING && !LineOfSight(enemy)) { + possessed.EndShoot(); + + if (lastEnemyPos != null) lastEnemyPos.Destroy(); + lastEnemyPos = ZTPathNode.plopNode(enemy.pos, ZTPathNode.NT_TARGET); + + navDest = null; + SetBotState(BS_HUNTING); + } + + else { + if (FRandom(0, 1) < 0.06) + possessed.Jump(); + + BotChat("ACTV", 0.05); + + ZetaWeapon w = BestWeaponAllTic(); + + if (w == null) { + enemy = null; + goingAfter = null; + + possessed.EndShoot(); + SetBotState(BS_WANDERING); + } + + else { + if (possessed.Distance3D(enemy) > 256 + enemy.radius || w.IsMelee()) + MoveToward(enemy, 0.282); + + else if (possessed.Distance3D(enemy) < 128 + enemy.radius) + StepBackFrom(enemy); + + RandomStrafe(); + AimToward(enemy, 0.27, 30); + + if (!LineOfSight(enemy)) + possessed.EndShoot(); + + else { + let off = possessed.Vec2To(enemy) / possessed.Distance2D(enemy); + let dir = AngleToVector(possessed.angle); + double ddot = (off.x * dir.x) + (off.y * dir.y); + + if (dDot <= 0) + possessed.EndShoot(); + + else if (FireBestWeapon()) + possessed.BeginShoot(); + + else + possessed.EndShoot(); + } + } + } + } + } + + void Subroutine_Wander() { + enemy = null; + BotChat("IDLE", 2.25 / 90); + + MoveForward(); + + if (commander != null && (possessed.Distance3D(commander) > 400 && !possessed.CheckSight(commander)) && ClosestNode(commander) != currNode) { + SetBotState(BS_WANDERING); + DodgeAndUse(); + + SetBotState(BS_FOLLOWING); + goingAfter = commander; + } + + else if (commander == null) { // get a commander + ActorList friends = VisibleFriends(possessed); + + if (friends.length() > 0) { + commander = friends.get(Random(0, friends.length() - 1)); + + if (!commander.CheckClass("ZetaBotPawn", AAPTR_DEFAULT, true)) { + let ztcom = ZetaBotPawn(commander); + + if (ztcom == null || ztcom.cont == null) + DebugLog(LT_INFO, myName.." is now following a "..commander.GetClassName()); + + else + DebugLog(LT_INFO, myName.." is now following "..ztcom.cont.myName); + } + + BotChat("COMM", 0.8); + } + } + + if (commander == null && bstate != BS_HUNTING) { // wander around + if (currNode == null) + SetCurrentNode(ClosestVisibleNode(possessed)); + + DodgeAndUse(); + + if (currNode != null) + navDest = currNode.RandomNeighbor(); + + else + navDest = null; + + if (currNode != null && possessed.Distance2D(currNode) < 100 && navDest != null) { + MoveToward(navDest, 10); // wander to this random 'neighboring' node + } + + else RandomMove(); + } + } + + void FireAtBarrels() { + let it_barrels = ThinkerIterator.create("ExplosiveBarrel", STAT_DEFAULT); + ExplosiveBarrel bclosest = null, bar = null; + double bdist = 100; + + while (bar = ExplosiveBarrel(it_barrels.Next())) { + if (!LineOfSight(bar)) continue; + if (possessed.Distance2D(bar) < bdist) { + bclosest = bar; + bdist = possessed.Distance2D(bar); + + DebugLog(LT_VERBOSE, String.Format("Considering shootable barrel %fpx away.", bdist)); + } + } + + if (bclosest != null) { + AimToward(bclosest, 15); + + if (possessed.Distance2D(currNode) > 100 && CVar.FindCVar('zb_autonodes').GetBool()) { + SetCurrentNode(ZTPathNode.plopNode(possessed.pos, ZTPathNode.NT_SHOOT, possessed.AngleTo(bclosest))); + + if (currNode != null) + DebugLog(LT_INFO, String.Format("Defining shootable barrel %fpx away: %s", bdist, currNode.NodeName())); + } + + else { + if (AbsAngle(possessed.AngleTo(bclosest), possessed.angle) <= 100) { + if (FireBestWeapon()) possessed.BeginShoot(); + } + + else + possessed.EndShoot(); + } + } + } void A_ZetaTick() { if (possessed == null || possessed.Health <= 0) { @@ -1188,145 +1540,15 @@ class ZTBotController : Actor { AutoUseAtAngle(0); if (bstate != BS_ATTACKING) { - if (bstate == BS_HUNTING) { - if (enemy == null || enemy.Health <= 0) { - enemy = null; - SetBotState(BS_WANDERING); - - if (lastEnemyPos != null) lastEnemyPos.Destroy(); - lastEnemyPos = null; - } - - else if (LineOfSight(enemy) || possessed.Distance3D(enemy) < 96) { - AimToward(enemy, 15); - SetBotState(BS_ATTACKING); - possessed.Jump(); - - if (lastEnemyPos != null) lastEnemyPos.Destroy(); - lastEnemyPos = null; - } - - else { - ActorList mon = VisibleEnemies(possessed); - - if (mon.length() > 0) { - PriorityQueue targets = new("PriorityQueue"); - - for (uint i = 0; i < mon.length(); i++) - targets.add(mon.get(i), TargetPriority(mon.get(i))); - - Actor newEnemy = Actor(targets.poll()); - - if (TargetPriority(newEnemy) > TargetPriority(enemy)) { - if (lastEnemyPos != null) lastEnemyPos.Destroy(); - lastEnemyPos = null; - - enemy = newEnemy; - possessed.Jump(); - SetBotState(BS_WANDERING); - } - } - - if (bstate == BS_HUNTING) { - if (lastEnemyPos == null) { - SetBotState(BS_WANDERING); - return; - } - - double lastPosSqDist = ((possessed.pos.x - lastEnemyPos.pos.x) * (possessed.pos.x - lastEnemyPos.pos.x)) - + ((possessed.pos.y - lastEnemyPos.pos.y) * (possessed.pos.y - lastEnemyPos.pos.y)); - - if (lastPosSqDist < 40 * 40 || (CheckObstructions() && !possessed.CheckSight(lastEnemyPos))) { - enemy = null; - SetBotState(BS_WANDERING); - - if (lastEnemyPos != null) lastEnemyPos.Destroy(); - lastEnemyPos = null; - } - - else if (lastEnemyPos != null) { - if (possessed.CheckSight(lastEnemyPos)) - SmartMove(lastEnemyPos); - - else if (currNode != null && (navDest == null || possessed.Distance2D(navDest) < 64)) { // path to lastEnemyPos - ActorList path = currNode.findPathTo(lastEnemyPos, possessed); - - if (path != null && path.Length() > 0) { - navDest = ZTPathNode(path.get(0)); - SmartMove(navDest); - - DebugLog(LT_INFO, "Next navigation point found at: "..navDest.pos); - } - - if (navDest == null) - SetBotState(BS_WANDERING); - } - - else if (navDest != null) - SmartMove(navDest); - - else - SetBotState(BS_WANDERING); - - if (bstate == BS_HUNTING) { - if (FRandom(0, 1) < 0.12) - possessed.Jump(); - - AutoUseAtAngle(0); - } - } + if (bstate == BS_HUNTING) + Subroutine_Hunt(); - else { - enemy = null; - SetBotState(BS_WANDERING); - } - - if (bstate == BS_HUNTING) { - BotChat("ACTV", 0.025); - } - } - } - - return; - } - - if (bstate != BS_FLEEING) { - ActorList mon = VisibleEnemies(possessed); - - if (mon.length() > 0) { - PriorityQueue targets = new("PriorityQueue"); - - for (uint i = 0; i < mon.length(); i++) - targets.add(mon.get(i), TargetPriority(mon.get(i))); - - Actor newEnemy = Actor(targets.poll()); - - if (enemy == null || TargetPriority(enemy) < TargetPriority(newEnemy)) - enemy = Actor(newEnemy); - - /* - else { - if (retargetCount < 1) { - enemy = Actor(targets.poll()); - retargetCount = 15; - } - - else - retargetCount--; - } - */ - - DebugLog(LT_INFO, "Attacking a "..enemy.GetClassName()); - - BotChat("TARG", 0.8); - - SetBotState(BS_ATTACKING); - } - } + if (bstate != BS_FLEEING) + RefreshEnemy(); if (navDest != null) { if (bstate == BS_WANDERING || bstate == BS_FOLLOWING) - BotChat("IDLE", 2.25 / 90); // talk + BotChat("IDLE", 2.25 / 85); // talk if (currNode != null && possessed.Distance2D(currNode) > 160 && possessed.Distance2D(navDest) > navDest.Distance2D(currNode) && bstate != BS_WANDERING) SmartMove(currNode); // move to current node if too far @@ -1339,8 +1561,11 @@ class ZTBotController : Actor { navDest = null; } + else if (bstate == BS_FOLLOWING || currNode == navDest) + navDest = null; // reset destination node + else - navDest = null; // reset destination node; if BS_FOLLOWING, it'll be set later + RandomMove(); } else { @@ -1350,232 +1575,25 @@ class ZTBotController : Actor { if (navDest == null || bstate == BS_WANDERING) RandomMove(); } - if (bstate == BS_FOLLOWING) { - if (possessed.Distance3D(goingAfter) < 400 || possessed.CheckSight(goingAfter)) - SetBotState(BS_WANDERING); - - else { - BotChat("IDLE", 2.25 / 90); - - if (DodgeAndUse()) - SetBotState(BS_WANDERING); - - if (goingAfter != null) { - if (possessed.Distance3D(goingAfter) < 1024 && possessed.CheckSight(goingAfter)) - SetBotState(AssessBotAttitude(goingAfter)); - - else if (currNode != null && (navDest == null || Distance3D(navDest) < 512 || navDest == currNode)) { - if (ClosestNode(goingAfter) == currNode) { - SetBotState(BS_WANDERING); - } - - else if (pathCountdown <= 0) { - ActorList path = navDest.findPathTo(ClosestNode(goingAfter), possessed); - - if (path != null && path.Length() > 1) { - navDest = ZTPathNode(path.get(0)); - - DebugLog(LT_INFO, "Next navigation point found at: "..navDest.pos); - SmartMove(navDest); - } - - else - MoveToward(goingAfter, 0.27); - - pathCountdown += 24; - } - - else - pathCountdown--; - } - - else if (navDest != null) - SmartMove(); - - else if (possessed.Distance3D(goingAfter) < 256) - SetBotState(BS_ATTACKING); - - else if (possessed.Distance3D(goingAfter) > 1500 && !possessed.CheckSight(goingAfter)) - SetBotState(BS_WANDERING); - - else - MoveToward(goingAfter, 15); - } - - else - SetBotState(BS_WANDERING); - } - } + if (bstate == BS_FOLLOWING) + Subroutine_Follow(); - else if (bstate == BS_FLEEING) { - if (DodgeAndUse()) { - if (currNode != null) - navDest = currNode.RandomNeighbor(); - - else - navDest = null; - - SetBotState(BS_WANDERING); - } + else if (bstate == BS_FLEEING) + Subroutine_Flee(); - if (enemy != null && possessed.Distance3D(enemy) < 1024 && possessed.CheckSight(enemy) && possessed.Health < possessed.default.Health / 7) - MoveAwayFrom(enemy); - - else - SetBotState(BS_WANDERING); - } - - else if (bstate == BS_WANDERING) { - enemy = null; - BotChat("IDLE", 2.25 / 90); - - MoveForward(); - - if (commander != null && (possessed.Distance3D(commander) > 400 && !possessed.CheckSight(commander)) && ClosestNode(commander) != currNode) { - SetBotState(BS_WANDERING); - DodgeAndUse(); - - SetBotState(BS_FOLLOWING); - goingAfter = commander; - } - - else if (commander == null) { // get a commander - ActorList friends = VisibleFriends(possessed); - - if (friends.length() > 0) { - commander = friends.get(Random(0, friends.length() - 1)); - - if (!commander.CheckClass("ZetaBotPawn", AAPTR_DEFAULT, true)) { - let ztcom = ZetaBotPawn(commander); - - if (ztcom == null || ztcom.cont == null) - DebugLog(LT_INFO, myName.." is now following a "..commander.GetClassName()); - - else - DebugLog(LT_INFO, myName.." is now following "..ztcom.cont.myName); - } - - BotChat("COMM", 0.8); - } - } - - if (commander == null && bstate != BS_HUNTING) { // wander around - if (currNode == null) - SetCurrentNode(ClosestVisibleNode(possessed)); - - DodgeAndUse(); - - if (currNode != null) - navDest = currNode.RandomNeighbor(); - - else - navDest = null; - - if (currNode != null && possessed.Distance2D(currNode) < 100 && navDest != null) { - MoveToward(navDest, 10); // wander to this random 'neighboring' node - } - - else RandomMove(); - } - } + else if (bstate == BS_WANDERING) + Subroutine_Wander(); } } - else { - if (enemy != null && enemy.Health >= 1) { // health is integer - if (bstate != BS_HUNTING && !LineOfSight(enemy)) { - possessed.EndShoot(); - - if (lastEnemyPos != null) lastEnemyPos.Destroy(); - lastEnemyPos = ZTPathNode.plopNode(enemy.pos, ZTPathNode.NT_TARGET); - - navDest = null; - SetBotState(BS_HUNTING); - } - - else { - if (FRandom(0, 1) < 0.06) - possessed.Jump(); - - BotChat("ACTV", 0.05); - - ZetaWeapon w = BestWeaponAllTic(); - - if (w == null) { - enemy = null; - goingAfter = null; - - possessed.EndShoot(); - SetBotState(BS_WANDERING); - } - - else { - if (possessed.Distance3D(enemy) > 256 + enemy.radius || w.IsMelee()) - MoveToward(enemy, 0.282); - - else if (possessed.Distance3D(enemy) < 128 + enemy.radius) - StepBackFrom(enemy); - - RandomStrafe(); - AimToward(enemy, 0.27, 30); - - let off = possessed.Vec2To(enemy) / possessed.Distance2D(enemy); - let dir = AngleToVector(possessed.angle); - double ddot = (off.x * dir.x) + (off.y * dir.y); - - if (dDot <= 0) - possessed.EndShoot(); - - else if (FireBestWeapon()) - possessed.BeginShoot(); - - else - possessed.EndShoot(); - } - } - } - } + else Subroutine_Attack(); if ((currNode == null || possessed.Distance2D(currNode) > 300) && CVar.FindCVar('zb_autonodes').GetBool()) { SetCurrentNode(ZTPathNode.plopNode(possessed.pos, ZTPathNode.NT_NORMAL, possessed.angle)); } - else if (currNode != null) { - // barrel shoot check - let it_barrels = ThinkerIterator.create("ExplosiveBarrel", STAT_DEFAULT); - ExplosiveBarrel bclosest = null, bar = null; - double bdist = 100; - - while (bar = ExplosiveBarrel(it_barrels.Next())) { - if (!LineOfSight(bar)) continue; - if (possessed.Distance2D(bar) < bdist) { - bclosest = bar; - bdist = possessed.Distance2D(bar); - - DebugLog(LT_VERBOSE, String.Format("Considering shootable barrel %fpx away.", bdist)); - } - } - - if (bclosest != null) { - AimToward(bclosest, 15); - - if (possessed.Distance2D(currNode) > 64 && CVar.FindCVar('zb_autonodes').GetBool()) { - SetCurrentNode(ZTPathNode.plopNode(possessed.pos, ZTPathNode.NT_SHOOT, possessed.AngleTo(bclosest))); - - if (currNode != null) - DebugLog(LT_INFO, String.Format("Defining shootable barrel %fpx away: %s", bdist, currNode.NodeName())); - } - - else { - if (AbsAngle(possessed.AngleTo(bclosest), possessed.angle) <= 100) { - if (FireBestWeapon()) possessed.BeginShoot(); - } - - else - possessed.EndShoot(); - } - } - } + else if (currNode != null) + FireAtBarrels(); if (angleMomentum > 1) angleMomentum = 1; @@ -1743,12 +1761,14 @@ class ZetaSpirit : Actor { ZetaSpiritEyes zse = ZetaSpiritEyes(Spawn("ZetaSpiritEyes")); zse.SetPlayer(pn); zse.possessed = cont.possessed; + zse.cont = cont; } } } class ZetaSpiritEyes : Actor { ZetaBotPawn possessed; + ZTBotController cont; PlayerPawn playa; void SetPlayer(PlayerPawn pn) { @@ -1770,8 +1790,8 @@ class ZetaSpiritEyes : Actor { playa = null; } - void A_ZetaTick() { - if (possessed.health <= 0) { + override void Tick() { + if (cont == null || cont.possessed == null || possessed == null || possessed.Health <= 0) { FreePlayer(); Destroy(); } @@ -1780,6 +1800,8 @@ class ZetaSpiritEyes : Actor { playa.SetXYZ(possessed.pos); playa.angle = possessed.angle; playa.health = possessed.health; + if (cont.enemy == null) playa.pitch = 0; + else playa.pitch = cont.PitchTo(cont.enemy); } } @@ -1789,7 +1811,7 @@ class ZetaSpiritEyes : Actor { Goto TickLoop; TickLoop: - TNT1 A 1 A_ZetaTick; + TNT1 A 1; Loop; } } diff --git a/ZetaCode/Pathing.zsc b/ZetaCode/Pathing.zsc index d4c0014..6a8b571 100644 --- a/ZetaCode/Pathing.zsc +++ b/ZetaCode/Pathing.zsc @@ -1,10 +1,28 @@ -class PlopResult : Thinker -{ +class PlopResult : Thinker { uint totalNodes; Array mapsFound; Array nodeMaps; } +class PathMarker : Actor { + Default { + Scale 0.2; + RenderStyle "Add"; + Alpha 0.7; + Radius 2; + Height 2; + Gravity 0; + } + + States { + Spawn: + CAND A 200 Bright; + CAND A 20; + MISL CDE 5; + Stop; + } +} + class ZTPositionMarker : Actor { Default { @@ -347,6 +365,34 @@ class ZTPathNode : ZTPositionMarker return ZTPathNode(nb.get(Random(0, nb.Length() - 1))); } + + void ShowPath(ZTPathNode otherNode) { + uint maxSeg = 15; // constant + + Vector3 offs; + offs.xy = AngleToVector(AngleTo(otherNode)); + Vector3 allOffs; + allOffs.xy = AngleToVector(AngleTo(otherNode) + 90); + + for (uint seg = 0; seg < maxSeg; seg++) { + double alpha = 1.0 * seg / maxSeg; + double scaled = alpha * Distance3D(otherNode); + Vector3 pmPos = pos + offs * scaled + allOffs; + pmPos.z += (otherNode.pos.z - pos.z) * alpha; + + PathMarker pm = PathMarker(Spawn("PathMarker", pmPos)); + //pm.pos.z = pm.floorz; + } + } + + void ShowAllPaths() { + ActorList nb = Neighbors(); + + for (uint i = 0; i < nb.Length(); i++) { + ZTPathNode neigh = ZTPathNode(nb.Get(i)); + ShowPath(neigh); + } + } ActorList findPathTo(ZTPathNode other, Actor traveller = null) { @@ -461,7 +507,7 @@ class ZTPathNode : ZTPositionMarker if ((nodeType == NT_USE || next.nodeType == NT_USE) && Distance2D(next) < 64) return true; // for doors that block LOS but are traverseable, etc. - double maxZDiff = 24; + double maxZDiff = 48; double minDist = 64; if ( next.nodeType == NT_JUMP || nodeType == NT_JUMP ) @@ -486,6 +532,14 @@ class ZTPathNode : ZTPositionMarker if ( diffZ > maxZDiff ) return false; + // experimental + if (CheckBlock( + xofs: next.pos.x - pos.x, + yofs: next.pos.y - pos.y, + zofs: next.pos.z - pos.z, + angle: AngleTo(next) + )) continue; + if (!CheckSight(next)) { FLineTraceData sight; LineTrace(AngleTo(next), Distance2D(next), PitchTo(next, 40), TRF_THRUACTORS | TRF_THRUHITSCAN, 40, data: sight); @@ -503,8 +557,8 @@ class ZTPathNode : ZTPositionMarker if (other.pos.z + other.height / 2 == pos.z + height / 2 + offsZ) return 0; - //return atan(offsZ + other.pos.z + other.height / 2 - pos.z - height / 2); - return offsZ + other.pos.z + other.height / 2 - pos.z - height / 2; + //return offsZ + other.pos.z + other.height / 2 - pos.z - height / 2; + return tan(offsZ + other.pos.z + other.height / 2 - pos.z - height / 2); } } @@ -677,3 +731,15 @@ class ZTDeleteNodes : Actor Destroy(); } } + +class ZTShowAllPaths : Actor { + override void BeginPlay() { + ZTPathNode n; + let iter = ThinkerIterator.Create("ZTPathNode", 91); + + while (n = ZTPathNode(iter.Next())) + n.ShowAllPaths(); + + Destroy(); + } +} \ No newline at end of file diff --git a/ZetaCode/PawnClasses/ZetaBotPawn.zsc b/ZetaCode/PawnClasses/ZetaBotPawn.zsc index 68da846..a515966 100644 --- a/ZetaCode/PawnClasses/ZetaBotPawn.zsc +++ b/ZetaCode/PawnClasses/ZetaBotPawn.zsc @@ -138,27 +138,27 @@ class ZetaBotPawn : Actor { void ApplyMovement() { if ( forward > 0 ) { forward = max(forward - 1.0, 0); - RealMoveForward(); + if (z - floorz < 2) RealMoveForward(); } else if ( forward <= -1 ) { forward = min(forward + 1.0, 0); - RealMoveBackward(); + if (z - floorz < 2) RealMoveBackward(); } else if ( forward < 0 ) { forward = min(forward + 0.8, 0); - RealStepBackward(); + if (z - floorz < 2) RealStepBackward(); } if ( rightward > 0 ) { rightward = max(rightward - 1.0, 0); - RealMoveRight(); + if (z - floorz < 2) RealMoveRight(); } else if ( rightward < 0 ) { rightward = max(rightward + 1.0, 0); - RealMoveLeft(); + if (z - floorz < 2) RealMoveLeft(); } forward /= 1.5; diff --git a/ZetaCode/PawnClasses/ZetaDoom.zsc b/ZetaCode/PawnClasses/ZetaDoom.zsc index 203da25..2e89373 100644 --- a/ZetaCode/PawnClasses/ZetaDoom.zsc +++ b/ZetaCode/PawnClasses/ZetaDoom.zsc @@ -9,6 +9,8 @@ class ZetaDoom : ZetaBotPawn { if ( moveType == MM_CROUCH ) { + Height = Default.Height / 2; + if ( bShooting ) return SetStateLabel("CrouchMissile"); @@ -20,6 +22,8 @@ class ZetaDoom : ZetaBotPawn else { + Height = Default.Height; + if ( bShooting ) return SetStateLabel("Missile"); diff --git a/ZetaCode/Standard.zsc b/ZetaCode/Standard.zsc index 8862918..80abd76 100644 --- a/ZetaCode/Standard.zsc +++ b/ZetaCode/Standard.zsc @@ -24,7 +24,7 @@ class Dict int set(Object _key, Object _val) { int index = -1; - int i = 0; + uint i = 0; for ( i = 0; i < keys.Size(); i++ ) { diff --git a/ZetaCode/WeaponSupport/Doom/ZetaChaingun.zsc b/ZetaCode/WeaponSupport/Doom/ZetaChaingun.zsc index a62c2bd..588e910 100644 --- a/ZetaCode/WeaponSupport/Doom/ZetaChaingun.zsc +++ b/ZetaCode/WeaponSupport/Doom/ZetaChaingun.zsc @@ -18,7 +18,7 @@ class ZetaChaingun : ZetaWeapon override double RateSelf(Actor shooter, Actor target) { - return shooter.Distance2D(target) / 1.5; + return sqrt(shooter.Distance2D(target)) * 1.3; } override void Fire(Actor shooter, Actor target) diff --git a/config b/config index 36d9de2..36c523c 100644 --- a/config +++ b/config @@ -1,6 +1,6 @@ #!/bin/bash NAME=ZetaBot -VERSION=0.7.2 +VERSION=0.8.0-pre ADDFOLDER ZetaCode ADDFOLDER sprites