diff --git a/planet/Objects.ocd/Goals.ocd/Defense.ocd/DefenseAI.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Defense.ocd/DefenseAI.ocd/Script.c index 7758fc7b1..2f86b4dc9 100644 --- a/planet/Objects.ocd/Goals.ocd/Defense.ocd/DefenseAI.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Defense.ocd/DefenseAI.ocd/Script.c @@ -12,6 +12,15 @@ local AltTargetDistance = 400; // Use the scenario given target if normal AI target is further away than this distance. +// Special settings for the defense AI. +public func AddAI(object clonk, id type) +{ + var fx_ai = inherited(clonk, type, ...); + // Make AI aggressive. + fx_ai.is_aggressive = true; + return fx_ai; +} + // Alternative target finding for defense scenarios: partially controlled by the scenario script. public func FindTarget(effect fx) { @@ -27,8 +36,8 @@ public func FindTarget(effect fx) // If target can't be attacked just take normal target again. if (!this->HasWeaponForTarget(fx, target)) target = _inherited(fx, ...); - if (!target) - this->LogAI_Info(fx, Format("No target found by DefenseAI for %v.", fx.Target)); + this->LogAI_Info(fx, Format("Defense AI %v found %v as a target to attack.", fx.Target, target)); + this->LogAI_CallStack(fx); return target; } @@ -80,9 +89,16 @@ public func ExecuteBomber(effect fx) // Still carrying the bomb? if (fx.weapon->Contained() != fx.Target) { + this->LogAI_Info(fx, Format("ExecuteBomber %v lost its bomb.", fx.Target)); fx.weapon = nil; return false; } + // Find a different target at random times, because the current target could not be the optimal any more. + if (!Random(40) && !PathFree(fx.Target->GetX(), fx.Target->GetY(), fx.target->GetX(), fx.target->GetY())) + { + fx.target = this->FindTarget(fx); + return true; + } // Are we in range? if (fx.Target->ObjectDistance(fx.target) < 16 || Distance(fx.Target->GetX(), fx.Target->GetY(), fx.target->GetX(), fx.target->GetY() + fx.target->GetBottom()) < 16) { diff --git a/planet/Objects.ocd/Goals.ocd/Defense.ocd/DefenseEnemy.ocd/Script.c b/planet/Objects.ocd/Goals.ocd/Defense.ocd/DefenseEnemy.ocd/Script.c index 6ff01e832..bd2ea860e 100644 --- a/planet/Objects.ocd/Goals.ocd/Defense.ocd/DefenseEnemy.ocd/Script.c +++ b/planet/Objects.ocd/Goals.ocd/Defense.ocd/DefenseEnemy.ocd/Script.c @@ -317,7 +317,7 @@ local Spearman = new DefaultEnemy local Grenadier = new DefaultEnemy { Name = "$EnemyGrenadier$", - Inventory = [GrenadeLauncher, IronBomb, IronBomb, IronBomb, IronBomb, IronBomb], + Inventory = [GrenadeLauncher, [IronBomb, 8]], Energy = 25, Bounty = 5, Color = 0xffa0a0ff, @@ -380,7 +380,7 @@ local Bomber = new DefaultEnemy local AirshipPilot = new DefaultEnemy { Name = "$EnemyAirshipPilot$", - Inventory = [Rock, Rock, Rock, Rock, Rock], + Inventory = [[Rock, 5]], Energy = 35, Bounty = 15, Color = 0xffff00ff, diff --git a/planet/Objects.ocd/Goals.ocd/Defense.ocd/System.ocd/System.ocg/AttackTarget.c b/planet/Objects.ocd/Goals.ocd/Defense.ocd/System.ocd/System.ocg/AttackTarget.c index e70dc85c3..a3d34bac6 100644 --- a/planet/Objects.ocd/Goals.ocd/Defense.ocd/System.ocd/System.ocg/AttackTarget.c +++ b/planet/Objects.ocd/Goals.ocd/Defense.ocd/System.ocd/System.ocg/AttackTarget.c @@ -8,7 +8,7 @@ global func GetRandomAttackTarget(object attacker) return target; // Attack structures owned by the enemy of the attacker. var controller = attacker->GetController(); - for (var target in attacker->FindObjects(Find_Category(C4D_Structure), Find_Hostile(controller), Sort_Distance())) + for (var target in attacker->FindObjects(Find_Category(C4D_Structure), Find_Hostile(controller), attacker->Sort_Distance())) if (target && PathFree(attacker->GetX(), attacker->GetY(), target->GetX(), target->GetY())) return target; // Otherwise return random enemy structure. @@ -23,9 +23,9 @@ global func GetRandomSiegeTarget(object attacker) return target; // Attack structures owned by the enemy of the attacker. var controller = attacker->GetController(); - for (var target in attacker->FindObjects(Find_Category(C4D_Structure), Find_Hostile(controller), Sort_Distance())) + for (var target in attacker->FindObjects(Find_Category(C4D_Structure), Find_Hostile(controller), attacker->Sort_Distance())) if (target && PathFree(attacker->GetX(), attacker->GetY(), target->GetX(), target->GetY())) return target; // Otherwise return random enemy structure. - return FindObject(Find_Category(C4D_Structure), Find_Hostile(controller), Sort_Random()); + return attacker->FindObject(Find_Category(C4D_Structure), Find_Hostile(controller), Sort_Random()); } \ No newline at end of file diff --git a/planet/Objects.ocd/Helpers.ocd/AI.ocd/Components.ocd/Debugging.ocd/Script.c b/planet/Objects.ocd/Helpers.ocd/AI.ocd/Components.ocd/Debugging.ocd/Script.c index 47fb82cba..28341235a 100644 --- a/planet/Objects.ocd/Helpers.ocd/AI.ocd/Components.ocd/Debugging.ocd/Script.c +++ b/planet/Objects.ocd/Helpers.ocd/AI.ocd/Components.ocd/Debugging.ocd/Script.c @@ -5,14 +5,15 @@ @author Maikel */ -// Callback from the Definition()-call +// Callback from the Definition()-call. public func OnDefineAI(proplist def) { _inherited(def); - - def->GetControlEffect().DebugLoggingOn = false; // Whether or not debug logging is turned on. + // Whether or not debug logging is turned on. + def->GetControlEffect().DebugLoggingOn = false; } +// Logs AI warnings. public func LogAI_Warning(effect fx, string message) { if (fx.DebugLoggingOn) @@ -20,10 +21,21 @@ public func LogAI_Warning(effect fx, string message) return; } -// Logs AI info +// Logs AI info. public func LogAI_Info(proplist fx, string message) { if (fx.DebugLoggingOn) Log("[%d] AI INFO (%v): %s", FrameCounter(), fx.Target, message); return; } + +// Logs the call stack. +public func LogAI_CallStack(proplist fx) +{ + if (fx.DebugLoggingOn) + { + Log("[%d] AI CALLSTACK", FrameCounter()); + LogCallStack(); + } + return; +} \ No newline at end of file diff --git a/planet/Objects.ocd/Helpers.ocd/AI.ocd/Components.ocd/RangedWeapons.ocd/Script.c b/planet/Objects.ocd/Helpers.ocd/AI.ocd/Components.ocd/RangedWeapons.ocd/Script.c index 499c65da3..8693394f6 100644 --- a/planet/Objects.ocd/Helpers.ocd/AI.ocd/Components.ocd/RangedWeapons.ocd/Script.c +++ b/planet/Objects.ocd/Helpers.ocd/AI.ocd/Components.ocd/RangedWeapons.ocd/Script.c @@ -110,8 +110,10 @@ private func ExecuteRanged(effect fx) return true; } } - // Path not free or out of range. Just wait for enemy to come... + // Path not free or out of range. Just wait for enemy to come or move to it if in agressive mode. fx.aim_weapon->ControlUseHolding(fx.Target, tx - x, ty - y); + if (fx.is_aggressive && d > 40) + fx.Target->SetCommand("MoveTo", nil, fx.target->GetX(), fx.target->GetY()); // Might also change target if current is unreachable. var new_target; if (!Random(3)) diff --git a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c index 3a0f83dca..991325b69 100644 --- a/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c +++ b/planet/Objects.ocd/Items.ocd/Weapons.ocd/GrenadeLauncher.ocd/Script.c @@ -253,6 +253,11 @@ public func OnRelaunchCreation() CreateContents(IronBomb); } +public func IsExplosive() +{ + return !!FindObject(Find_Container(this), Find_Func("IsExplosive")); +} + func Definition(def) { def.PictureTransformation = Trans_Mul(Trans_Translate(-3000, 1000, 1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1));