2012-04-02 21:57:27 +00:00
|
|
|
/**
|
|
|
|
ConstructionSite
|
|
|
|
Needs material put into it, then constructs the set building.
|
|
|
|
|
|
|
|
@author boni
|
|
|
|
*/
|
|
|
|
|
|
|
|
local definition;
|
2012-04-17 16:08:23 +00:00
|
|
|
local direction;
|
2012-04-21 23:00:41 +00:00
|
|
|
local stick_to;
|
2012-04-02 21:57:27 +00:00
|
|
|
local full_material; // true when all needed material is in the site
|
|
|
|
|
2012-04-17 16:08:23 +00:00
|
|
|
public func IsContainer() { return !full_material; }
|
2012-04-15 16:32:38 +00:00
|
|
|
// disallow taking stuff out
|
|
|
|
public func RefuseTransfer(object toMove) { return true; }
|
|
|
|
|
2012-04-14 20:30:02 +00:00
|
|
|
// we have 2 interaction modes
|
2012-04-17 16:08:23 +00:00
|
|
|
public func IsInteractable(object obj) { return definition != nil && !full_material; }
|
2012-04-14 20:53:02 +00:00
|
|
|
public func GetInteractionCount() { return 2; }
|
2012-04-14 20:30:02 +00:00
|
|
|
public func GetInteractionMetaInfo(object obj, int num)
|
|
|
|
{
|
|
|
|
if(num == 0)
|
2012-04-17 16:18:28 +00:00
|
|
|
return {IconName=nil, IconID=Hammer, Description="$TxtTransfer$"};
|
2012-04-14 20:30:02 +00:00
|
|
|
if(num == 1)
|
2012-04-17 16:18:28 +00:00
|
|
|
return {IconName=nil, IconID=Icon_Cancel, Description="$TxtAbort$"};
|
2012-04-14 20:30:02 +00:00
|
|
|
}
|
2012-04-02 21:57:27 +00:00
|
|
|
|
|
|
|
public func Construction()
|
|
|
|
{
|
|
|
|
this.visibility = VIS_None;
|
|
|
|
definition = nil;
|
|
|
|
full_material = false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-04-21 23:00:41 +00:00
|
|
|
public func Set(id def, int dir, object stick)
|
2012-04-02 21:57:27 +00:00
|
|
|
{
|
|
|
|
definition = def;
|
2012-04-17 16:08:23 +00:00
|
|
|
direction = dir;
|
2012-04-21 23:00:41 +00:00
|
|
|
stick_to = stick;
|
|
|
|
|
2012-04-17 16:08:23 +00:00
|
|
|
var xw = (1-dir*2)*1000;
|
2012-04-02 21:57:27 +00:00
|
|
|
|
|
|
|
var w,h;
|
|
|
|
w = def->GetDefWidth();
|
|
|
|
h = def->GetDefHeight();
|
|
|
|
|
2012-04-17 16:08:23 +00:00
|
|
|
SetGraphics(nil, def, 1, GFXOV_MODE_Base);
|
2012-04-23 21:19:52 +00:00
|
|
|
SetClrModulation(RGBa(255,255,255,50), 1);
|
2012-04-17 16:08:23 +00:00
|
|
|
SetObjDrawTransform(xw,0,0,0,1000, -h*500,1);
|
2012-04-17 16:08:39 +00:00
|
|
|
SetGraphics(nil, def, 2, GFXOV_MODE_Base, nil, GFX_BLIT_Wireframe);
|
|
|
|
SetObjDrawTransform(xw,0,0,0,1000, -h*500,2);
|
2012-04-02 21:57:27 +00:00
|
|
|
SetShape(-w/2, -h, w, h);
|
|
|
|
|
2012-04-17 16:18:28 +00:00
|
|
|
SetName(Format("TxtConstruction",def->GetName()));
|
2012-04-02 21:57:27 +00:00
|
|
|
|
|
|
|
this.visibility = VIS_Owner | VIS_Allies;
|
|
|
|
|
|
|
|
ShowMissingComponents();
|
|
|
|
}
|
|
|
|
|
|
|
|
// only allow collection if needed
|
|
|
|
public func RejectCollect(id def, object obj)
|
|
|
|
{
|
|
|
|
var max = GetComponent(def, nil, nil, definition);
|
|
|
|
|
|
|
|
// not a component?
|
|
|
|
if(max == 0)
|
|
|
|
return true;
|
|
|
|
if(ContentsCount(def) < max)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if full
|
|
|
|
public func Collection2(object obj)
|
|
|
|
{
|
|
|
|
// update message
|
|
|
|
ShowMissingComponents();
|
|
|
|
|
|
|
|
// check if we're done?
|
|
|
|
if(full_material)
|
|
|
|
StartConstructing();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Interacting removes the Construction site
|
2012-04-14 20:30:02 +00:00
|
|
|
public func Interact(object clonk, int num)
|
2012-04-02 21:57:27 +00:00
|
|
|
{
|
2012-04-14 20:30:02 +00:00
|
|
|
// Open Contents-Menu
|
|
|
|
if(num == 0)
|
|
|
|
{
|
|
|
|
clonk->CreateContentsMenus();
|
|
|
|
}
|
|
|
|
// Remove Site
|
|
|
|
if(num == 1)
|
|
|
|
{
|
|
|
|
// test
|
|
|
|
for(var obj in FindObjects(Find_Container(this)))
|
|
|
|
obj->Exit();
|
2012-04-02 21:57:27 +00:00
|
|
|
|
2012-04-14 20:30:02 +00:00
|
|
|
RemoveObject();
|
|
|
|
}
|
2012-04-02 21:57:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private func ShowMissingComponents()
|
|
|
|
{
|
|
|
|
if(definition == nil)
|
|
|
|
{
|
|
|
|
Message("");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var stuff = GetMissingComponents();
|
2012-04-17 16:18:28 +00:00
|
|
|
//var msg = "Construction Needs:";
|
|
|
|
var msg = "@";
|
2012-04-02 21:57:27 +00:00
|
|
|
for(var s in stuff)
|
|
|
|
if(s.count > 0)
|
2012-04-17 16:18:28 +00:00
|
|
|
msg = Format("%s %dx{{%i}}", msg, s.count, s.id);
|
2012-04-02 21:57:27 +00:00
|
|
|
|
2012-04-17 16:18:28 +00:00
|
|
|
//Message("@%s",msg);
|
|
|
|
CustomMessage(msg, this, 0, 0, 23);
|
2012-04-02 21:57:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private func GetMissingComponents()
|
|
|
|
{
|
|
|
|
if(definition == nil)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(full_material == true)
|
|
|
|
return nil;
|
|
|
|
|
|
|
|
// set false again as soon as we find a missing component
|
|
|
|
full_material = true;
|
|
|
|
|
|
|
|
// check for material
|
|
|
|
var comp, index = 0;
|
|
|
|
var missing_material = CreateArray();
|
|
|
|
while (comp = GetComponent(nil, index, nil, definition))
|
|
|
|
{
|
|
|
|
// find material
|
|
|
|
var max_amount = GetComponent(comp, nil, nil, definition);
|
|
|
|
var c = ContentsCount(comp);
|
|
|
|
var dif = max_amount-c;
|
|
|
|
|
|
|
|
if(dif > 0)
|
|
|
|
{
|
|
|
|
PushBack(missing_material, {id=comp, count=dif});
|
|
|
|
full_material = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return missing_material;
|
|
|
|
}
|
|
|
|
|
|
|
|
private func StartConstructing()
|
|
|
|
{
|
|
|
|
if(!definition)
|
|
|
|
return;
|
|
|
|
if(!full_material)
|
|
|
|
return;
|
|
|
|
|
2012-10-10 17:33:51 +00:00
|
|
|
// find all objects on the bottom of the area that are not 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 - 2, -hgt, wdt + 2, hgt + 12), Find_OCF(OCF_InFree));
|
|
|
|
Log("%d %d: %v", wdt, hgt, lying_around);
|
|
|
|
|
2012-04-02 21:57:27 +00:00
|
|
|
// create the construction
|
|
|
|
var site;
|
|
|
|
if(!(site = CreateConstruction(definition, 0, 0, GetOwner(), 1, 1, 1)))
|
|
|
|
{
|
2012-04-17 16:08:23 +00:00
|
|
|
Interact(nil, 1);
|
2012-04-02 21:57:27 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-04-17 16:08:23 +00:00
|
|
|
if(direction)
|
|
|
|
site->SetDir(direction);
|
2012-04-21 23:00:41 +00:00
|
|
|
// Inform about sticky building
|
|
|
|
if (stick_to)
|
|
|
|
site->CombineWith(stick_to);
|
2012-04-17 16:08:23 +00:00
|
|
|
|
2012-04-02 21:57:27 +00:00
|
|
|
// Autoconstruct 2.0!
|
|
|
|
Schedule(site, "DoCon(2)",1,50);
|
|
|
|
Schedule(this,"RemoveObject()",1);
|
2012-10-10 17:33:51 +00:00
|
|
|
|
|
|
|
// clean up stuck objects
|
|
|
|
for(var o in lying_around)
|
|
|
|
{
|
|
|
|
var x, y;
|
|
|
|
var dif = 0;
|
|
|
|
|
|
|
|
x = o->GetX();
|
|
|
|
y = o->GetY();
|
|
|
|
|
|
|
|
// move living creatures upwards till they stand on top.
|
|
|
|
if(o->GetOCF() & OCF_Alive)
|
|
|
|
{
|
|
|
|
while(o->GetContact(-1, CNAT_Bottom))
|
|
|
|
{
|
|
|
|
// only up to 20 pixel
|
|
|
|
if(dif > 20)
|
|
|
|
{
|
|
|
|
o->SetPosition(x,y);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
dif++;
|
|
|
|
o->SetPosition(x, y-dif);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
while(o->Stuck())
|
|
|
|
{
|
|
|
|
// only up to 20 pixel
|
|
|
|
if(dif > 20)
|
|
|
|
{
|
|
|
|
o->SetPosition(x,y);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
dif++;
|
|
|
|
o->SetPosition(x, y-dif);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-04-02 21:57:27 +00:00
|
|
|
}
|