forked from Mirrors/openclonk
improve enemy finding for defense AI
The path finder seems quite slow if a lot of AI enemies are around and can't find a path...install-platforms
parent
26fe0d089a
commit
65c279233e
|
@ -12,6 +12,15 @@
|
||||||
local AltTargetDistance = 400; // Use the scenario given target if normal AI target is further away than this distance.
|
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.
|
// Alternative target finding for defense scenarios: partially controlled by the scenario script.
|
||||||
public func FindTarget(effect fx)
|
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 target can't be attacked just take normal target again.
|
||||||
if (!this->HasWeaponForTarget(fx, target))
|
if (!this->HasWeaponForTarget(fx, target))
|
||||||
target = _inherited(fx, ...);
|
target = _inherited(fx, ...);
|
||||||
if (!target)
|
this->LogAI_Info(fx, Format("Defense AI %v found %v as a target to attack.", fx.Target, target));
|
||||||
this->LogAI_Info(fx, Format("No target found by DefenseAI for %v.", fx.Target));
|
this->LogAI_CallStack(fx);
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +89,16 @@ public func ExecuteBomber(effect fx)
|
||||||
// Still carrying the bomb?
|
// Still carrying the bomb?
|
||||||
if (fx.weapon->Contained() != fx.Target)
|
if (fx.weapon->Contained() != fx.Target)
|
||||||
{
|
{
|
||||||
|
this->LogAI_Info(fx, Format("ExecuteBomber %v lost its bomb.", fx.Target));
|
||||||
fx.weapon = nil;
|
fx.weapon = nil;
|
||||||
return false;
|
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?
|
// 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)
|
if (fx.Target->ObjectDistance(fx.target) < 16 || Distance(fx.Target->GetX(), fx.Target->GetY(), fx.target->GetX(), fx.target->GetY() + fx.target->GetBottom()) < 16)
|
||||||
{
|
{
|
||||||
|
|
|
@ -317,7 +317,7 @@ local Spearman = new DefaultEnemy
|
||||||
local Grenadier = new DefaultEnemy
|
local Grenadier = new DefaultEnemy
|
||||||
{
|
{
|
||||||
Name = "$EnemyGrenadier$",
|
Name = "$EnemyGrenadier$",
|
||||||
Inventory = [GrenadeLauncher, IronBomb, IronBomb, IronBomb, IronBomb, IronBomb],
|
Inventory = [GrenadeLauncher, [IronBomb, 8]],
|
||||||
Energy = 25,
|
Energy = 25,
|
||||||
Bounty = 5,
|
Bounty = 5,
|
||||||
Color = 0xffa0a0ff,
|
Color = 0xffa0a0ff,
|
||||||
|
@ -380,7 +380,7 @@ local Bomber = new DefaultEnemy
|
||||||
local AirshipPilot = new DefaultEnemy
|
local AirshipPilot = new DefaultEnemy
|
||||||
{
|
{
|
||||||
Name = "$EnemyAirshipPilot$",
|
Name = "$EnemyAirshipPilot$",
|
||||||
Inventory = [Rock, Rock, Rock, Rock, Rock],
|
Inventory = [[Rock, 5]],
|
||||||
Energy = 35,
|
Energy = 35,
|
||||||
Bounty = 15,
|
Bounty = 15,
|
||||||
Color = 0xffff00ff,
|
Color = 0xffff00ff,
|
||||||
|
|
|
@ -8,7 +8,7 @@ global func GetRandomAttackTarget(object attacker)
|
||||||
return target;
|
return target;
|
||||||
// Attack structures owned by the enemy of the attacker.
|
// Attack structures owned by the enemy of the attacker.
|
||||||
var controller = attacker->GetController();
|
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()))
|
if (target && PathFree(attacker->GetX(), attacker->GetY(), target->GetX(), target->GetY()))
|
||||||
return target;
|
return target;
|
||||||
// Otherwise return random enemy structure.
|
// Otherwise return random enemy structure.
|
||||||
|
@ -23,9 +23,9 @@ global func GetRandomSiegeTarget(object attacker)
|
||||||
return target;
|
return target;
|
||||||
// Attack structures owned by the enemy of the attacker.
|
// Attack structures owned by the enemy of the attacker.
|
||||||
var controller = attacker->GetController();
|
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()))
|
if (target && PathFree(attacker->GetX(), attacker->GetY(), target->GetX(), target->GetY()))
|
||||||
return target;
|
return target;
|
||||||
// Otherwise return random enemy structure.
|
// 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());
|
||||||
}
|
}
|
|
@ -5,14 +5,15 @@
|
||||||
@author Maikel
|
@author Maikel
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Callback from the Definition()-call
|
// Callback from the Definition()-call.
|
||||||
public func OnDefineAI(proplist def)
|
public func OnDefineAI(proplist def)
|
||||||
{
|
{
|
||||||
_inherited(def);
|
_inherited(def);
|
||||||
|
// Whether or not debug logging is turned on.
|
||||||
def->GetControlEffect().DebugLoggingOn = false; // Whether or not debug logging is turned on.
|
def->GetControlEffect().DebugLoggingOn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logs AI warnings.
|
||||||
public func LogAI_Warning(effect fx, string message)
|
public func LogAI_Warning(effect fx, string message)
|
||||||
{
|
{
|
||||||
if (fx.DebugLoggingOn)
|
if (fx.DebugLoggingOn)
|
||||||
|
@ -20,10 +21,21 @@ public func LogAI_Warning(effect fx, string message)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logs AI info
|
// Logs AI info.
|
||||||
public func LogAI_Info(proplist fx, string message)
|
public func LogAI_Info(proplist fx, string message)
|
||||||
{
|
{
|
||||||
if (fx.DebugLoggingOn)
|
if (fx.DebugLoggingOn)
|
||||||
Log("[%d] AI INFO (%v): %s", FrameCounter(), fx.Target, message);
|
Log("[%d] AI INFO (%v): %s", FrameCounter(), fx.Target, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logs the call stack.
|
||||||
|
public func LogAI_CallStack(proplist fx)
|
||||||
|
{
|
||||||
|
if (fx.DebugLoggingOn)
|
||||||
|
{
|
||||||
|
Log("[%d] AI CALLSTACK", FrameCounter());
|
||||||
|
LogCallStack();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
|
@ -110,8 +110,10 @@ private func ExecuteRanged(effect fx)
|
||||||
return true;
|
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);
|
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.
|
// Might also change target if current is unreachable.
|
||||||
var new_target;
|
var new_target;
|
||||||
if (!Random(3))
|
if (!Random(3))
|
||||||
|
|
|
@ -253,6 +253,11 @@ public func OnRelaunchCreation()
|
||||||
CreateContents(IronBomb);
|
CreateContents(IronBomb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func IsExplosive()
|
||||||
|
{
|
||||||
|
return !!FindObject(Find_Container(this), Find_Func("IsExplosive"));
|
||||||
|
}
|
||||||
|
|
||||||
func Definition(def)
|
func Definition(def)
|
||||||
{
|
{
|
||||||
def.PictureTransformation = Trans_Mul(Trans_Translate(-3000, 1000, 1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1));
|
def.PictureTransformation = Trans_Mul(Trans_Translate(-3000, 1000, 1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1));
|
||||||
|
|
Loading…
Reference in New Issue