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
|
/**
Branch
A single branch from a tree which can be placed attached to ceilings or walls.
@author Maikel, Randrian
*/
protected func Initialize()
{
this.MeshTransformation = Trans_Mul(Trans_Scale(1000, 1400, 1000), Trans_Translate(0, 3500, 0), Trans_Rotate(RandomX(0, 359), 0, 1, 0));
SetR(RandomX(-30, 30));
return;
}
protected func Damage()
{
if (GetDamage() > 15)
{
CastObjects(Wood, 1, 25);
RemoveObject();
}
return;
}
/*-- Placement --*/
// Place an amount of branches in the specified area. Settings:
// size = [min, max]: Random size (con) between min and max.
// underground = true/false: whether to place only underground.
public func Place(int amount, proplist area, proplist settings)
{
// Only allow definition call.
if (this != Branch)
return;
// Default parameters.
if (!settings)
settings = { size = [80, 120] };
if (!settings.size)
settings.size = [80, 120];
var loc_area = nil;
if (area)
loc_area = Loc_InArea(area);
var loc_background;
if (settings.underground == nil)
loc_background = Loc_Or(Loc_Sky(), Loc_Tunnel());
else if (settings.underground)
loc_background = Loc_Tunnel();
else
loc_background = Loc_Sky();
var loc_inmat = Loc_Or(Loc_Material("Granite"), Loc_Material("Rock"), Loc_MaterialVal("Soil", "Material", nil, 1));
if (settings.in_mat)
loc_inmat = Loc_Material(settings.in_mat);
var branches = [];
for (var i = 0; i < amount; i++)
{
var size = RandomX(settings.size[0], settings.size[1]);
var loc = FindLocation(loc_background, Loc_Not(Loc_Liquid()), Loc_Wall(CNAT_Left | CNAT_Right | CNAT_Top, loc_inmat), loc_area);
if (!loc)
continue;
var branch = CreateObject(Branch);
branch->SetPosition(loc.x, loc.y);
branch->SetCon(size);
if (!Random(3))
branch.Plane = 510;
// Adjust orientation and position with respect to landscape.
branch->AdjustOrientation();
branch->AdjustPosition();
// Retry if the center is add a solid location.
if (branch->GBackSolid())
{
branch->RemoveObject();
i--;
continue;
}
PushBack(branches, branch);
}
return branches;
}
// Adjust the orientation of the branch with respect to material.
public func AdjustOrientation()
{
// Make sure it is not stuck in solid with its center.
var dx = 0;
if (GBackSolid(-2, 0) && !GBackSolid(2, 0))
dx = 3;
if (GBackSolid(2, 0) && !GBackSolid(-2, 0))
dx = -3;
var dy = 0;
if (GBackSolid(0, -2) && !GBackSolid(0, 2))
dy = 3;
if (GBackSolid(0, 2) && !GBackSolid(0, -2))
dy = -3;
SetPosition(GetX() + dx, GetY() + dy);
// Check for increasing radius.
for (var d = 0; d < 15 * GetCon() / 100; d++)
// Check 8 directions.
for (var angle = 0; angle < 360; angle += 45)
if (GBackSolid(-Sin(angle, d), Cos(angle, d)))
return SetR(RandomX(angle - 10, angle + 10));
return;
}
// Adjust position with respect to material.
public func AdjustPosition()
{
var angle = GetR();
// Find distance to material.
var d = 0;
while (!GBackSolid(-Sin(angle, d), Cos(angle, d)) && d < 24 * GetCon() / 100)
d++;
// Adjust position.
var size = 12 * GetCon() / 100;
SetPosition(GetX() - Sin(angle, d - size), GetY() + Cos(angle, d - size));
return;
}
/*-- Properties --*/
local Name = "$Name$";
local BlastIncinerate = 1;
local ContactIncinerate = 3;
local Placement = 4;
|