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
|
/**
Seed
Logic for plant seed that will eventually sprout a plant if left alone long enough.
Seeds may also be manually planted by using leftclick.
@author Clonkonaut
*/
// The last known position of the seed
local lib_seed_pos;
// The timer cycles the seed has been lying idly (until it has reached 10)
local lib_seed_idletime = 0;
// The time it takes until a new plant might be created, feel free to reassign
local lib_seed_planttime = 10500;
// ****** Must be the id of the plant to create. Do not leave empty.
local lib_seed_plant;
/* Reproduction control */
/** Distance the seeds checks for plants. Default is 250.
@return the maximum distance.
*/
private func SeedArea()
{
return 250;
}
/** The amount of plants allowed within SeedArea. Default is 10.
@return the maximum amount of plants.
*/
private func SeedAmount()
{
return 10;
}
/** The closest distance a new plant may seed to its nearest neighbour. Default is 20.
@return the maximum amount of plants.
*/
private func SeedOffset()
{
return 20;
}
/* Reproduction */
private func Initialize()
{
AddTimer("CheckSprout", lib_seed_planttime / 10);
lib_seed_pos = { x = GetX(), y = GetY() };
}
// Check whether a plant should be created
private func CheckSprout()
{
if (Contained()) return;
if (OnFire()) return;
if (!CheckPosition()) return;
lib_seed_idletime++;
if (lib_seed_idletime >= 10)
{
// Is this place nice to make a new plant?
if (!CheckPlantConditions())
lib_seed_idletime = 0;
else
Sprout();
}
}
// Check whether the seed was moved
private func CheckPosition()
{
if (GetX() != lib_seed_pos.x || GetY() != lib_seed_pos.y)
{
lib_seed_pos.x = GetX();
lib_seed_pos.y = GetY();
lib_seed_idletime = 0;
return false;
}
return true;
}
/* Sprouting */
// Returns the relative y to the ground from center to max 20 pixels.
// If no ground is found returns -1, also if the center is underground (stuck in material)
private func GetGroundPos()
{
if (GBackSolid()) return -1;
var y = 0;
while (!GBackSolid(0,y) && y < 21)
y++;
if (y >= 21) return -1;
return y;
}
/** Overload as necessary to check for further conditions. Return true if a new plant should be created.
*/
private func CheckPlantConditions()
{
var ground = GetGroundPos();
// No solid ground
if (ground == -1) return false;
// No fertile ground
if (GetMaterialVal("Soil", "Material", GetMaterial(0,ground)) != 1) return false;
// Do not grow underground
if (!GBackSky(0, ground-1) && !GBackSky(0,0) && !GBackSky(0,-30)) return false;
// Too many plants around
var size = SeedArea();
if (ObjectCount(Find_ID(lib_seed_plant), Find_InRect(-size / 2, -size / 2, size, size)) > SeedAmount()) return false;
// Another plant too close
var neighbour = FindObject(Find_ID(lib_seed_plant), Sort_Distance());
if (neighbour)
if (ObjectDistance(neighbour) < SeedOffset())
return false;
return true;
}
/** Overload as necessary. Should remove the seed.
*/
private func Sprout()
{
var ground = GetGroundPos();
var plant = CreateObjectAbove(lib_seed_plant, 0, ground, GetOwner());
if (!plant) return; // What now?
plant->SetCon(1);
RemoveObject();
}
/* Planting */
public func ControlUse(object clonk, int x, int y, bool box)
{
if(!clonk->~IsWalking()) return true;
var ground = GetGroundPos();
if (ground == -1)
return CustomMessage(Format("$TxtBadGround$", GetName()), clonk, clonk->GetController(), 0, 0, 0xff0000);
// Soil is needed
if (GetMaterialVal("Soil", "Material", GetMaterial(0,ground)) != 1)
return CustomMessage(Format("$TxtBadGround$", GetName()), clonk, clonk->GetController(), 0, 0, 0xff0000);
// Plant!
clonk->DoKneel();
Sprout();
return true;
}
local UsageHelp = "$UsageHelp$";
|