1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
/**
Animal Library
Handles reproduction and growth for animals. If included the Construction()
call must return _inherited(...) for this library to work.
@author Maikel
*/
// This object is an animal.
public func IsAnimal() { return true; }
protected func Construction(...)
{
// Add a reproduction timer.
AddReproductionEffect();
// Add a growth effect.
StartGrowth(GrowthSpeed());
_inherited(...);
}
private func AddReproductionEffect()
{
if (!GetEffect("IntReproduction", this))
return AddEffect("IntReproduction", this, 100, 72, this);
}
private func RemoveReproductionEffect()
{
return RemoveEffect("IntReproduction", this);
}
/*-- Growth --*/
// Speed of the growth of an animal.
private func GrowthSpeed() { return 5; }
/*-- Reproduction --*/
local animal_reproduction_area_size = 800;
local animal_reproduction_rate = 67;
local animal_max_count = 10;
// Population control is handled through these variables.
// The area, in which new animals of this kind can appear.
public func ReproductionAreaSize() { return animal_reproduction_area_size; }
public func SetReproductionAreaSize(int v) { animal_reproduction_area_size = v; return true; }
// The chance that reproduction takes place in one timer interval. From 0 to 10000.
// The higher this value the more likely it is to reproduce. Special: If it is zero, reproduction is off.
public func ReproductionRate() { return animal_reproduction_rate; }
public func SetReproductionRate(int v)
{
animal_reproduction_rate = v;
if (v) AddReproductionEffect(); else RemoveReproductionEffect();
return true;
}
// The maximal animal count in the area.
public func MaxAnimalCount() { return animal_max_count; }
public func SetMaxAnimalCount(int v) { animal_max_count = v; return true; }
// Special reproduction method (e.g. with egg).
private func SpecialReproduction()
{
// You can have a special kind of reproduction implemented here.
// If you do so return true in this function.
return false;
}
// Standard conditions for reproduction.
private func ReproductionCondition()
{
return GetAlive() && GetCon() >= 100;
}
// Special conditions which needs to be fulfilled (e.g. a fish should have the swim action).
private func SpecialReproductionCondition()
{
// You can implement a special condition for reproduction here.
// Return false if this condition is not satisfied.
return true;
}
// Count animals in the reproduction area.
private func CountAnimalsInArea()
{
var reprod_size = ReproductionAreaSize();
var reprod_size_half = reprod_size / 2;
return ObjectCount(Find_ID(GetID()), Find_InRect(-reprod_size_half, -reprod_size_half, reprod_size , reprod_size), Find_OCF(OCF_Alive));
}
public func FxIntReproductionTimer(object target, proplist effect, int time)
{
// Already dead or not full grown? Don't do anything.
if (!ReproductionCondition())
return FX_OK;
// Apply the reproduction rate.
if (Random(10000) >= ReproductionRate())
return FX_OK;
// Special conditions not fulfilled? Don't do anything either.
if (!SpecialReproductionCondition())
return FX_OK;
// Check whether there are already enough animals of this kind.
if (CountAnimalsInArea() >= MaxAnimalCount())
return FX_OK;
// Reproduction: first try special reproduction, otherwise normal.
if (!SpecialReproduction())
{
// Normal reproduction.
var child = CreateConstruction(GetID(), 0, 0, NO_OWNER, 40);
child->~Birth(this);
}
return FX_OK;
}
// Callback in the animal on its birth.
public func Birth(object parent)
{
SetAction("Walk");
if (Random(2))
SetComDir(COMD_Left);
else
SetComDir(COMD_Right);
return;
}
/*-- Collection --*/
protected func RejectEntrance(object container)
{
// From one container to another is not blocked by this library.
if (Contained())
return _inherited(container, ...);
// Neither are dead animals.
if (!GetAlive())
return _inherited(container, ...);
// For all other cases the entrance is blocked.
return true;
}
/* Editor */
public func Definition(def, ...)
{
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.animal_reproduction_area_size = { Name="$ReproductionAreaSize$", EditorHelp="$ReproductionAreaSizeHelp$", Type="int", Min=0, AsyncGet="ReproductionAreaSize", Set="SetReproductionAreaSize", Save="Reproduction" };
def.EditorProps.animal_reproduction_rate = { Name="$ReproductionRate$", EditorHelp="$ReproductionRateHelp$", Type="int", Min=0, Max=10000, AsyncGet="ReproductionRate", Set="SetReproductionRate", Save="Reproduction" };
def.EditorProps.animal_max_count = { Name="$MaxCount$", EditorHelp="$MaxCountHelp$", Type="int", Min=1, AsyncGet="MaxAnimalCount", Set="SetMaxAnimalCount", Save="Reproduction" };
return _inherited(def, ...);
}
|