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

178 lines
4.2 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;
func Construction()
{
// Make sure the basement does not move while constructing.
SetCategory(C4D_StaticBack);
return _inherited(...);
}
func Initialize()
{
var wdt = GetObjWidth();
if (parent)
{
wdt = parent->~GetBasementWidth();
if (wdt == nil)
wdt = parent->GetObjWidth();
}
SetWidth(BoundBy(wdt, 8, 120));
// Move objects out of the basement.
MoveOutOfSolidMask();
return _inherited(...);
}
func Destruction()
{
// Cast a single rock.
CastObjects(Rock, 1, 15, 0, -5);
// Set basement to nil in parent.
if (parent)
parent->~SetBasement(nil);
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; }
public func SetParent(object to_parent)
{
parent = to_parent;
var wdt = parent->~GetBasementWidth();
if (wdt == nil)
wdt = parent->GetObjWidth();
SetWidth(BoundBy(wdt, 8, 120));
// Notify the parent.
parent->~SetBasement(this);
return;
}
public func GetParent() { return parent; }
/*-- Saving --*/
public func SaveScenarioObject(proplist props)
{
if (!inherited(props, ...))
return false;
if (parent)
props->AddCall("BasementParent", this, "SetParent", parent);
else if (width != GetDefWidth())
props->AddCall("BasementWidth", this, "SetWidth", width);
props->Remove("Category");
return true;
}
/*-- Construction --*/
public func IsHammerBuildable() { return true; }
// It should not be a structure.
public func IsStructure() { return false; }
// But a basement!
public func IsBasement() { return true; }
// Is a construction that is built just below the surface.
public func IsBelowSurfaceConstruction() { return true; }
// This makes it possible to combine basements with each other.
public func IsStructureWithoutBasement() { return true; }
// Sticking to other structures.
public func ConstructionCombineWith() { return "IsStructureWithoutBasement"; }
public func ConstructionCombineDirection(object other)
{
// All directions are possible for other basements
if (other && other->~IsBasement())
return CONSTRUCTION_STICK_Left | CONSTRUCTION_STICK_Right | CONSTRUCTION_STICK_Bottom | CONSTRUCTION_STICK_Top;
// For everything else, the basement is below.
return CONSTRUCTION_STICK_Bottom;
}
public func ConstructionCombineOffset(object other)
{
// Some structures like the elevator require the basement to have an offset.
return other->~GetBasementOffset();
}
public func NoConstructionFlip() { return true; }
public func AlternativeConstructionPreview(object previewer, int direction, object combine_with)
{
if (combine_with && combine_with->~IsBasement()) return;
var wdt = GetSiteWidth(direction, combine_with);
previewer->SetObjDrawTransform(1000 * wdt / 40, 0, 0, 0, 1000, 0, previewer.GFX_StructureOverlay);
}
public func GetSiteWidth(int direction, object combine_with)
{
var wdt = GetDefWidth();
if (combine_with)
{
wdt = combine_with->~GetBasementWidth();
if (wdt == nil)
wdt = combine_with->GetObjWidth();
}
return BoundBy(wdt, 8, 120);
}
public func SetConstructionSiteOverlay(object site, int direction, object combine_with)
{
if (combine_with && combine_with->~IsBasement()) return;
var wdt = GetSiteWidth(direction, combine_with);
site->SetGraphics(nil, Basement, 1, GFXOV_MODE_Base);
site->SetClrModulation(RGBa(255, 255, 255, 128), 1);
site->SetObjDrawTransform(1000 * wdt / 40, 0, 0, 0, 1000, -4000, 1);
return true;
}
// Set the parent if the basement is attached to a structure.
public func CombineWith(object stick_to)
{
if (stick_to && stick_to->~IsBasement()) return;
SetParent(stick_to);
}
/*-- Editor --*/
public func Definition(def, ...)
{
_inherited(def, ...);
if (!def.EditorProps) def.EditorProps = {};
def.EditorProps.width = { Name="$Width$", Set="SetWidth", Type="int", Min=8, Max=120 };
}
/*-- Properties --*/
local Name = "$Name$";
local Description ="$Description$";
local HitPoints = 80;
local Plane = 190;
local Components = {Rock = 2};