openclonk/planet/Objects.ocd/Structures.ocd/Basement.ocd/Script.c

129 lines
2.9 KiB
C

/**
Basement
Provides basements to structures, but can also be built as a single object.
@author Maikel
*/
#include Library_Structure
local parent;
local width;
protected func Construction()
{
// Make sure the basement does not move while constructing.
SetCategory(C4D_StaticBack);
return _inherited(...);
}
protected func Initialize()
{
var wdt = BoundBy(GetObjWidth(), 8, 120);
if (parent)
wdt = BoundBy(parent->GetObjWidth(), 8, 120);
SetWidth(wdt);
// Move objects out of the basement.
MoveOutOfBasement();
return _inherited(...);
}
protected func Destruction()
{
// Cast a single rock.
CastObjects(Rock, 1, 15, 0, -5);
return _inherited(...);
}
// Set the width of the basement.
public func SetWidth(int wdt)
{
width = wdt;
SetShape(-wdt / 2, -4, wdt, 8);
SetSolidMask(0, 0, wdt, 8, 20 - wdt / 2, 0);
SetObjDrawTransform(1000 * wdt / 40, 0, 0, 0, 1000, 0);
return;
}
public func GetWidth() { return width; }
// Set the parent if the basement is attached to a structure.
public func CombineWith(object stick_to)
{
SetParent(stick_to);
return;
}
public func SetParent(object to_parent)
{
parent = to_parent;
SetWidth(BoundBy(parent->GetObjWidth(), 8, 120));
// Notify the parent.
parent->~SetBasement(this);
return;
}
public func GetParent() { return parent; }
// Move objects out of the basement.
private func MoveOutOfBasement()
{
// Find all objects inside the basement which are stuck.
var wdt = GetObjWidth();
var hgt = GetObjHeight();
var lying_around = FindObjects(Find_Or(Find_Category(C4D_Vehicle), Find_Category(C4D_Object), Find_Category(C4D_Living)), Find_InRect(-wdt / 2 - 1, -hgt / 2 - 2, wdt + 2, hgt + 4));
// Move up these objects.
for (var obj in lying_around)
{
var x = obj->GetX();
var y = obj->GetY();
var dif = 0;
// Move up object until it is not stuck any more.
while (obj->Stuck() || obj->GetContact(-1, CNAT_Bottom))
{
// Only up to 32 pixels.
if (dif > 32)
{
obj->SetPosition(x, y);
break;
}
dif++;
obj->SetPosition(x, y - dif);
}
}
return;
}
// Is a construction that is built just below the surface.
public func IsBelowSurfaceConstruction() { return true; }
// Sticking to other structures, at the bottom of that structure.
public func ConstructionCombineWith() { return "IsStructureWithoutBasement"; }
public func ConstructionCombineDirection() { return CONSTRUCTION_STICK_Bottom; }
public func NoConstructionFlip() { return true; }
// Don't stick to itself, so it should not be a structure.
public func IsStructure() { return false; }
/*-- Saving --*/
public func SaveScenarioObject(proplist props)
{
if (!inherited(props, ...))
return false;
if (parent)
props->AddCall("BasementParent", this, "SetParent", parent);
else if (width)
props->AddCall("BasementWidth", this, "SetWidth", width);
return true;
}
/*-- Proplist --*/
local Name = "$Name$";
local Description ="$Description$";
local HitPoints = 80;
local Plane = 190;