forked from Mirrors/openclonk
126 lines
2.8 KiB
C
126 lines
2.8 KiB
C
/*--
|
|
Moss
|
|
Authors: Mimmo, Clonkonaut
|
|
--*/
|
|
|
|
static const MOSS_MAXWETNESS = 30; // Moisture the moss can achieve. Dries out within 36*MOSS_MAXWETNESS frames
|
|
static const MOSS_MAXDIST = 50; // Used for various distance checks
|
|
local wetness;
|
|
local graphic;
|
|
local lastpos;
|
|
|
|
func Initialize()
|
|
{
|
|
graphic = Random(3);
|
|
if (graphic)
|
|
SetGraphics(Format("%d",graphic));
|
|
|
|
wetness = MOSS_MAXWETNESS;
|
|
lastpos = CreateArray();
|
|
AddEffect("MossMoisture",this,100,36,this);
|
|
}
|
|
|
|
public func ControlUse(object clonk, int x, int y, bool box)
|
|
{
|
|
if(!clonk->~IsWalking()) return true;
|
|
// Search for ground
|
|
x = 0; y = 0;
|
|
if (GBackSemiSolid(x,y)) return true;
|
|
if (GetMaterial(x,y) != Material("Tunnel")) return true;
|
|
var i = 0;
|
|
while (!GBackSolid(x,y) && i < 15) { ++y; ++i; }
|
|
if (!GBackSolid(x,y)) return true;
|
|
if (GetMaterialVal("Soil", "Material", GetMaterial(x,y)) == 1)
|
|
{
|
|
// Plant!
|
|
clonk->DoKneel();
|
|
CreateObjectAbove(Lichen, x, y, clonk->GetOwner());
|
|
RemoveObject();
|
|
}
|
|
else
|
|
clonk->Message("$NoSuitableGround$");
|
|
|
|
return true;
|
|
}
|
|
|
|
/*-- Reproduction --*/
|
|
|
|
private func FxMossMoistureTimer(target, effect, time)
|
|
{
|
|
if (GetMaterial() == Material("Water"))
|
|
{
|
|
|
|
if (wetness < MOSS_MAXWETNESS)
|
|
{
|
|
wetness = MOSS_MAXWETNESS;
|
|
if(graphic)
|
|
SetGraphics(Format("%d",graphic));
|
|
else
|
|
SetGraphics();
|
|
}
|
|
}
|
|
else if (!Contained() && !GBackSolid() && !GBackLiquid())
|
|
if (wetness)
|
|
{
|
|
wetness--;
|
|
// Fire nearby -> dry faster
|
|
if (FindObject(Find_Distance(100), Find_OCF(OCF_OnFire))) wetness--;
|
|
if (wetness <= 0)
|
|
{
|
|
wetness = 0;
|
|
if (graphic)
|
|
SetGraphics(Format("%dDry",graphic));
|
|
else
|
|
SetGraphics("Dry");
|
|
}
|
|
if ([GetX(),GetY()]==lastpos)
|
|
{
|
|
if (FindNearWater())
|
|
TryToLichen();
|
|
}
|
|
else
|
|
lastpos = [GetX(), GetY()];
|
|
}
|
|
}
|
|
|
|
protected func TryToLichen()
|
|
{
|
|
if (GetMaterial() != Material("Tunnel")) return false;
|
|
var y = 0;
|
|
while (!GBackSolid(0,y) && y < 10) y++;
|
|
if (!GBackSolid(0,y)) return false;
|
|
if (!GetMaterialVal("Soil", "Material", GetMaterial(0,y))) return false;
|
|
if (FindObject(Find_ID(Lichen), Find_Distance(MOSS_MAXDIST))) return false;
|
|
|
|
CreateObjectAbove(Lichen, 0, y, NO_OWNER);
|
|
RemoveObject();
|
|
return true;
|
|
}
|
|
|
|
// Moss only grows (on itself) if close to water
|
|
private func FindNearWater()
|
|
{
|
|
// Take a random hit within the target area
|
|
var y = RandomX(-MOSS_MAXDIST, MOSS_MAXDIST);
|
|
for (var i = 0; i < MOSS_MAXDIST; i+=2)
|
|
{
|
|
if (GetMaterial(i, y) == Material("Water")) return true;
|
|
if (GetMaterial(-i,y) == Material("Water")) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*-- Status --*/
|
|
|
|
public func IsFuel() { return !wetness; }
|
|
public func GetFuelAmount(bool get_partial) { return 100; }
|
|
|
|
local Collectible = 1;
|
|
local Name = "$Name$";
|
|
local Description = "$Description$";
|
|
local UsageHelp = "$UsageHelp$";
|
|
local Placement = 3;
|
|
local BlastIncinerate = 1;
|
|
local ContactIncinerate = 1;
|
|
local Plane = 470;
|