forked from Mirrors/openclonk
249 lines
4.0 KiB
C
249 lines
4.0 KiB
C
/*
|
|
Zap
|
|
|
|
Author: Clonkonaut
|
|
|
|
Protects its hive!
|
|
*/
|
|
|
|
#include Library_InsectSwarm
|
|
|
|
local lib_swarm_standard = 5;
|
|
local swarm_enraged = 20;
|
|
local lib_swarm_density = 5;
|
|
local lib_insect_max_dist = 100;
|
|
|
|
local home;
|
|
local enraged;
|
|
local enrage_target;
|
|
local sting_damage = 2;
|
|
|
|
// Called by the zaphive
|
|
public func SetHome(object my_castle)
|
|
{
|
|
home = my_castle;
|
|
this->CreateSwarm(lib_swarm_standard);
|
|
}
|
|
|
|
// Called by the zaphive
|
|
public func SetEnraged()
|
|
{
|
|
this->CreateSwarm(swarm_enraged);
|
|
SwarmCall("SetEnragedSwarm");
|
|
}
|
|
|
|
// Called by swarm helper
|
|
public func SetEnragedSwarm()
|
|
{
|
|
enraged = true;
|
|
SetAction("Attack");
|
|
}
|
|
|
|
private func Initialize()
|
|
{
|
|
SetAction("Fly");
|
|
SetPhase(Random(3));
|
|
|
|
_inherited();
|
|
}
|
|
|
|
private func Death()
|
|
{
|
|
_inherited();
|
|
RemoveObject();
|
|
}
|
|
|
|
private func MissionComplete()
|
|
{
|
|
if (enraged)
|
|
MoveToTarget();
|
|
else
|
|
_inherited();
|
|
}
|
|
|
|
private func Sleep()
|
|
{
|
|
if (enraged) return MoveToTarget();
|
|
if (lib_insect_sleeping) return;
|
|
|
|
if (lib_insect_going2sleep)
|
|
{
|
|
SetAction("Sleep");
|
|
lib_insect_sleeping = true;
|
|
return;
|
|
}
|
|
// One last trip, then become invisible
|
|
MoveToTarget();
|
|
lib_insect_going2sleep = true;
|
|
}
|
|
|
|
private func SleepComplete()
|
|
{
|
|
SetAction("Sleep");
|
|
_inherited();
|
|
}
|
|
|
|
private func WakeUp()
|
|
{
|
|
SetAction("Fly");
|
|
_inherited();
|
|
}
|
|
|
|
private func GetAttraction(proplist coordinates)
|
|
{
|
|
if (enraged) return Enrage(coordinates);
|
|
if (!home)
|
|
{
|
|
HomeIsLost();
|
|
return false;
|
|
}
|
|
// GetAttraction will only be called for the swarm master, perfect to have just one being make sound
|
|
if(!Random(20))
|
|
Sound("Animals::Zap::Zap?", nil,nil,nil,nil, 200, Random(100));
|
|
|
|
coordinates.x = home->GetX() + Random(20)-10;
|
|
coordinates.y = home->GetY() + Random(20)-10;
|
|
return true;
|
|
}
|
|
|
|
private func HomeIsLost()
|
|
{
|
|
if (!Random(2)) Kill();
|
|
}
|
|
|
|
private func Enrage(proplist coordinates)
|
|
{
|
|
if (!enrage_target)
|
|
CheckTarget();
|
|
if (!enrage_target)
|
|
return false;
|
|
if (ObjectDistance(enrage_target) < 10)
|
|
return Sting();
|
|
|
|
if (!(enrage_target->GetAlive())) return Kill();
|
|
if (enrage_target->Contained())
|
|
{
|
|
if (!Random(25)) return Kill();
|
|
return false;
|
|
}
|
|
if (!Random(50)) return Kill();
|
|
if (!GBackSky() && !Random(25)) return Kill();
|
|
|
|
coordinates.x = enrage_target->GetX();
|
|
coordinates.y = enrage_target->GetY();
|
|
return true;
|
|
}
|
|
|
|
private func Sting()
|
|
{
|
|
if (!enrage_target) return false;
|
|
|
|
Punch(enrage_target, sting_damage);
|
|
Kill();
|
|
return true;
|
|
}
|
|
|
|
// Look for a target to attack
|
|
private func CheckTarget()
|
|
{
|
|
var clonk = FindObject(Find_Distance(200), Find_OCF(OCF_CrewMember), Find_OCF(OCF_Alive), Find_NoContainer(), Find_PathFree(), Sort_Distance());
|
|
if (clonk)
|
|
{
|
|
SwarmCall("DoAttack", clonk);
|
|
return;
|
|
}
|
|
if (!Random(10)) Kill();
|
|
}
|
|
|
|
public func DoAttack(object to_kill)
|
|
{
|
|
enrage_target = to_kill;
|
|
}
|
|
|
|
private func CheckTurn()
|
|
{
|
|
if (GetXDir() < 0)
|
|
SetDir(DIR_Left);
|
|
if (GetXDir() > 0)
|
|
SetDir(DIR_Right);
|
|
}
|
|
|
|
private func AngryBuzz()
|
|
{
|
|
Sound("Animals::Zap::Zap?", nil,nil,nil,nil, nil, -Random(100));
|
|
}
|
|
|
|
/*-- Saving --*/
|
|
|
|
public func SaveScenarioObject(proplist props)
|
|
{
|
|
if (!inherited(props, ...)) return false;
|
|
// Ignore some fast-changing stuff
|
|
props->Remove("XDir");
|
|
props->Remove("YDir");
|
|
props->Remove("Command");
|
|
return true;
|
|
}
|
|
|
|
/* Definition */
|
|
|
|
local ActMap = {
|
|
Fly = {
|
|
Prototype = Action,
|
|
Name = "Fly",
|
|
Procedure = DFA_FLOAT,
|
|
Speed = 100,
|
|
Accel = 5,
|
|
Decel = 5,
|
|
Directions = 2,
|
|
FlipDir = 1,
|
|
Length = 3,
|
|
Delay = 2,
|
|
X = 0,
|
|
Y = 0,
|
|
Wdt = 2,
|
|
Hgt = 2,
|
|
NextAction = "Fly",
|
|
EndCall = "CheckTurn",
|
|
},
|
|
Attack = {
|
|
Prototype = Action,
|
|
Name = "Attack",
|
|
Procedure = DFA_FLOAT,
|
|
Speed = 200,
|
|
Accel = 30,
|
|
Decel = 30,
|
|
Directions = 2,
|
|
FlipDir = 1,
|
|
Length = 3,
|
|
Delay = 2,
|
|
X = 0,
|
|
Y = 0,
|
|
Wdt = 2,
|
|
Hgt = 2,
|
|
NextAction = "Attack",
|
|
StartCall = "AngryBuzz",
|
|
EndCall = "CheckTurn",
|
|
},
|
|
Sleep = {
|
|
Prototype = Action,
|
|
Name = "Sleep",
|
|
Procedure = DFA_FLOAT,
|
|
Speed = 0,
|
|
Directions = 2,
|
|
FlipDir = 1,
|
|
Length = 1,
|
|
Delay = 1,
|
|
X = 6,
|
|
Y = 0,
|
|
Wdt = 2,
|
|
Hgt = 2,
|
|
NextAction = "Hold",
|
|
},
|
|
};
|
|
|
|
local Name = "$Name$";
|
|
local MaxEnergy = 30000;
|
|
local MaxBreath = 250;
|
|
local Placement = 2;
|
|
local NoBurnDecay = 1; |