forked from Mirrors/openclonk
178 lines
4.2 KiB
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};
|