Added Insect Swarm Library.

Have swarming insects, today!
Controls
Clonkonaut 2015-07-25 12:41:17 +02:00
parent 23bbf666c6
commit 3ce3d3604d
6 changed files with 193 additions and 0 deletions

View File

@ -0,0 +1,4 @@
[DefCore]
id=Library_InsectSwarm
Version=6,1
Category=C4D_StaticBack

View File

@ -0,0 +1,135 @@
/**
Insect Swarm Library
Superimpose to any (flying) insect to create an insect swarm.
Always include after Library_Insect!
@author Clonkonaut
--*/
// Places amount swarms with swarm_members individuals each
public func Place(int amount, int swarm_members, proplist rectangle)
{
// No calls to objects, only definitions
if (GetType(this) == C4V_C4Object) return;
if (!swarm_members)
swarm_members = lib_swarm_standard;
for (var insect in _inherited(amount, rectangle))
insect->CreateSwarm(swarm_members - 1); // -1 because one insect already exists
}
/** Standard swarm size (utilised in Place()). Default 10.
*/
local lib_swarm_standard = 10;
/** Maximum distance one individual can be away from another. Default 10 pixels.
*/
local lib_swarm_density = 10;
// The managing object (see SwarmHelper.ocd)
local lib_swarm_helper;
// The next insect that gets promoted to swarm master when the swarm master dies
local lib_swarm_nextinline;
// The previous insect that gets promoted to swarm master before this one
local lib_swarm_previnline;
/** Promotes this to swarm master and will create amount minions
*/
public func CreateSwarm(int amount)
{
if (!amount) return;
// Create a swarm helper
lib_swarm_helper = CreateObject(Library_Swarm_Helper,0,0,NO_OWNER);
lib_swarm_helper->SetMaster(this);
lib_swarm_helper->SetSwarmCount(amount);
var last_created = this, insect;
while(amount)
{
insect = CreateObject(GetID(),0,0,GetOwner());
insect->SetPreviousInLine(last_created);
insect->SetSwarmHelper(lib_swarm_helper);
insect->SetCommand("None");
last_created->SetNextInLine(insect);
last_created = insect;
amount--;
}
}
public func SetNextInLine(object next)
{
lib_swarm_nextinline = next;
}
public func SetPreviousInLine(object next)
{
lib_swarm_previnline = next;
}
public func SetSwarmHelper(object helper)
{
lib_swarm_helper = helper;
}
// Swarm insect need randomized activities to not look odd
private func Initialize()
{
AddTimer("Activity", 10 + Random(25));
SetComDir(COMD_None);
}
// On death or destruction we need to update the line
private func Death()
{
// Death of the master
if (lib_swarm_helper->GetMaster() == this)
lib_swarm_helper->MakeNewMaster(lib_swarm_nextinline);
// Death of a slave
if(lib_swarm_previnline && lib_swarm_nextinline)
{
lib_swarm_nextinline->SetPreviousInLine(lib_swarm_previnline);
lib_swarm_previnline->SetNextInLine(lib_swarm_nextinline);
}
PurgeLine(); // Don't do everything twice in case Destruction() follows
_inherited();
}
private func Destruction()
{
// Destruction of the master
if (lib_swarm_helper->GetMaster() == this)
lib_swarm_helper->MakeNewMaster(lib_swarm_nextinline);
// Destruction of a slave
if(lib_swarm_previnline && lib_swarm_nextinline)
{
lib_swarm_nextinline->SetPreviousInLine(lib_swarm_previnline);
lib_swarm_previnline->SetNextInLine(lib_swarm_nextinline);
}
}
private func PurgeLine()
{
lib_swarm_nextinline = nil;
lib_swarm_previnline = nil;
}
private func MoveToTarget()
{
if (lib_swarm_helper->GetMaster() == this)
return _inherited();
var coordinates = { x=0, y=0 };
// Follow previous in line
if (lib_swarm_previnline && Random(3))
{
coordinates.x = lib_swarm_previnline->GetX();
coordinates.y = lib_swarm_previnline->GetY();
} else { // Go wild and stay around the master!
lib_swarm_helper->GetSwarmCenter(coordinates);
}
coordinates.x = BoundBy(coordinates.x + Random(lib_swarm_density*2) - lib_swarm_density, 10, LandscapeWidth()-10);
coordinates.y = BoundBy(coordinates.y + Random(lib_swarm_density*2) - lib_swarm_density, 10, LandscapeHeight()-10);
SetCommand("MoveTo", nil, coordinates.x, coordinates.y, nil, true);
AppendCommand("Call", this, nil,nil,nil,nil, "MissionComplete");
}

View File

@ -0,0 +1,4 @@
[DefCore]
id=Library_Swarm_Helper
Version=6,1
Category=C4D_StaticBack

View File

@ -0,0 +1,48 @@
/*
For every swarm one of these will be created @0,0 to help manage the swarm.
Keeps track of the swarm master (aka swarm center).
@author Clonkonaut
--*/
local swarm_master;
local swarm_count;
private func Initialize()
{
SetPosition(0,0);
}
public func SetMaster(object new_master)
{
if (!new_master) return;
swarm_master = new_master;
}
public func GetMaster()
{
return swarm_master;
}
public func MakeNewMaster(object next)
{
if (!next) // Swarm destroyed
return RemoveObject();
swarm_count--;
swarm_master = next;
swarm_master->SetPreviousInLine(nil);
}
public func SetSwarmCount(int count)
{
swarm_count = count;
}
public func GetSwarmCenter(proplist coordinates)
{
coordinates.x = swarm_master->GetX();
coordinates.y = swarm_master->GetY();
}
local Name = "$Name$";