forked from Mirrors/openclonk
cable cars: let sawmill send empty hoist to pickup trees
parent
a4d20d79d5
commit
899fbaa867
|
@ -49,10 +49,11 @@ public func OnCableCarDelivery(object car, proplist order) { }
|
||||||
|
|
||||||
// Called by other stations to check if a certain object and amount are available for delivery at this station.
|
// Called by other stations to check if a certain object and amount are available for delivery at this station.
|
||||||
// Return true if there are means to collect the required amount.
|
// Return true if there are means to collect the required amount.
|
||||||
public func IsAvailable(proplist order)
|
public func IsAvailable(proplist order) { return false; }
|
||||||
{
|
|
||||||
return false;
|
// Called to get idle cable cars at this station.
|
||||||
}
|
public func GetIdleCars() { return []; }
|
||||||
|
|
||||||
|
|
||||||
/*--- Callbacks ---*/
|
/*--- Callbacks ---*/
|
||||||
|
|
||||||
|
@ -101,6 +102,8 @@ public func GetCablePosition(array coordinates, int prec)
|
||||||
{
|
{
|
||||||
if (!prec)
|
if (!prec)
|
||||||
prec = 1;
|
prec = 1;
|
||||||
|
if (!coordinates)
|
||||||
|
coordinates = [];
|
||||||
coordinates[0] = GetX(prec);
|
coordinates[0] = GetX(prec);
|
||||||
coordinates[1] = GetY(prec);
|
coordinates[1] = GetY(prec);
|
||||||
if (this.LineAttach)
|
if (this.LineAttach)
|
||||||
|
@ -108,6 +111,7 @@ public func GetCablePosition(array coordinates, int prec)
|
||||||
coordinates[0] += this.LineAttach[0] * prec;
|
coordinates[0] += this.LineAttach[0] * prec;
|
||||||
coordinates[1] += this.LineAttach[1] * prec;
|
coordinates[1] += this.LineAttach[1] * prec;
|
||||||
}
|
}
|
||||||
|
return coordinates;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by cable cars to retrieve selectable destinations for the destination selection menu.
|
// Called by cable cars to retrieve selectable destinations for the destination selection menu.
|
||||||
|
@ -563,3 +567,51 @@ public func RemoveRequest(proplist order)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-- Misc Queries --*/
|
||||||
|
|
||||||
|
// Returns the closest object satisfying find_crit that can be found on the cables of this network.
|
||||||
|
// Returns {obj = <closest object>, station1 = <first station>, station2 = <second station>}.
|
||||||
|
public func FindObjectOnNetworkCables(array find_crit)
|
||||||
|
{
|
||||||
|
var destinations = GetDestinations();
|
||||||
|
SortArrayByArrayElement(destinations, this.const_distance, false);
|
||||||
|
PushFront(destinations, [this, this, 0]);
|
||||||
|
for (var dest in destinations)
|
||||||
|
{
|
||||||
|
var station = dest[this.const_finaldestination];
|
||||||
|
// Check all cables to other stations.
|
||||||
|
for (var connection in FindObjects(Find_Func("IsConnectedTo", station)))
|
||||||
|
{
|
||||||
|
if (!connection->~IsCableLine())
|
||||||
|
continue;
|
||||||
|
var other_station = connection->~GetConnectedObject(station);
|
||||||
|
if (!other_station || !other_station->~IsCableCrossing())
|
||||||
|
continue;
|
||||||
|
var sx = station->GetCablePosition()[0];
|
||||||
|
var sy = station->GetCablePosition()[1];
|
||||||
|
var ox = other_station->GetCablePosition()[0];
|
||||||
|
var oy = other_station->GetCablePosition()[1];
|
||||||
|
var obj = Global->FindObject(Find_OnLine(sx, sy, ox, oy), find_crit);
|
||||||
|
if (obj)
|
||||||
|
return [obj, station, other_station];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a free cable car satsfying find_crit on the network closest to this station.
|
||||||
|
public func FindCableCar(array find_crit)
|
||||||
|
{
|
||||||
|
var destinations = GetDestinations();
|
||||||
|
SortArrayByArrayElement(destinations, this.const_distance, false);
|
||||||
|
PushFront(destinations, [this, this, 0]);
|
||||||
|
for (var dest in destinations)
|
||||||
|
{
|
||||||
|
var station = dest[this.const_finaldestination];
|
||||||
|
var car = Global->FindObject(Find_InArray(station->GetIdleCars()), find_crit);
|
||||||
|
if (car)
|
||||||
|
return car;
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ public func GetAvailableCableCar(proplist order, object requesting_station)
|
||||||
// Find closest cars first.
|
// Find closest cars first.
|
||||||
var destinations = GetDestinations();
|
var destinations = GetDestinations();
|
||||||
SortArrayByArrayElement(destinations, this.const_distance, false);
|
SortArrayByArrayElement(destinations, this.const_distance, false);
|
||||||
for (dest in destinations)
|
for (var dest in destinations)
|
||||||
{
|
{
|
||||||
var station = dest[this.const_finaldestination];
|
var station = dest[this.const_finaldestination];
|
||||||
var best = station->~GetAvailableCableCar(order, station);
|
var best = station->~GetAvailableCableCar(order, station);
|
||||||
|
@ -466,6 +466,8 @@ public func OnCableCarDestruction(object car)
|
||||||
RemoveArrayValue(arrived_cars, car, true);
|
RemoveArrayValue(arrived_cars, car, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func GetIdleCars() { return arrived_cars; }
|
||||||
|
|
||||||
|
|
||||||
/*-- Visuals --*/
|
/*-- Visuals --*/
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ public func OnCableCarHover(symbol, extra_data, desc_menu_target, menu_id)
|
||||||
|
|
||||||
/*-- Picking up vehicles --*/
|
/*-- Picking up vehicles --*/
|
||||||
|
|
||||||
public func PickupVehicle(object vehicle)
|
public func PickupVehicle(object vehicle, bool no_rotation_copy)
|
||||||
{
|
{
|
||||||
if (!vehicle) return;
|
if (!vehicle) return;
|
||||||
if (GetEffect("FxCableHoistPickup", vehicle)) return;
|
if (GetEffect("FxCableHoistPickup", vehicle)) return;
|
||||||
|
@ -128,7 +128,7 @@ public func PickupVehicle(object vehicle)
|
||||||
if (!Inside(GetX(), vehicle->GetX() - width, vehicle->GetX() + width))
|
if (!Inside(GetX(), vehicle->GetX() - width, vehicle->GetX() + width))
|
||||||
if (!Inside(GetY(), vehicle->GetY() - height, vehicle->GetY() + height))
|
if (!Inside(GetY(), vehicle->GetY() - height, vehicle->GetY() + height))
|
||||||
return;
|
return;
|
||||||
vehicle->CreateEffect(FxCableHoistPickup, 1, 1, this);
|
vehicle->CreateEffect(FxCableHoistPickup, 1, 1, this, no_rotation_copy);
|
||||||
pickup = vehicle;
|
pickup = vehicle;
|
||||||
UpdateInteractionMenus(this.GetCableCarMenuEntries);
|
UpdateInteractionMenus(this.GetCableCarMenuEntries);
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ public func DropVehicle()
|
||||||
|
|
||||||
local FxCableHoistPickup = new Effect
|
local FxCableHoistPickup = new Effect
|
||||||
{
|
{
|
||||||
Construction = func(object hoist)
|
Construction = func(object hoist, bool no_rotation_copy)
|
||||||
{
|
{
|
||||||
this.hoist = hoist;
|
this.hoist = hoist;
|
||||||
this.vehicle_touchable = Target.Touchable;
|
this.vehicle_touchable = Target.Touchable;
|
||||||
|
@ -152,8 +152,11 @@ local FxCableHoistPickup = new Effect
|
||||||
this.movement_prec = 100;
|
this.movement_prec = 100;
|
||||||
Target->SetPosition(this.hoist->GetX(this.movement_prec), this.hoist->GetY(this.movement_prec) + 4, false, this.movement_prec);
|
Target->SetPosition(this.hoist->GetX(this.movement_prec), this.hoist->GetY(this.movement_prec) + 4, false, this.movement_prec);
|
||||||
Target->SetSpeed(0, 0);
|
Target->SetSpeed(0, 0);
|
||||||
Target->SetR(this.hoist->GetR());
|
if (!no_rotation_copy)
|
||||||
Target->SetRDir(0);
|
{
|
||||||
|
Target->SetR(this.hoist->GetR());
|
||||||
|
Target->SetRDir(0);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Timer = func(int time)
|
Timer = func(int time)
|
||||||
|
|
|
@ -62,19 +62,14 @@ public func CollectTrees()
|
||||||
{
|
{
|
||||||
if (GetCon() < 100)
|
if (GetCon() < 100)
|
||||||
return;
|
return;
|
||||||
// Only take one tree at a time
|
|
||||||
if (!ContentsCount(Wood))
|
|
||||||
FindTrees();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Automatically search for trees in front of sawmill. Temporary solution?
|
|
||||||
private func FindTrees()
|
|
||||||
{
|
|
||||||
var tree = FindObject(Find_AtPoint(), Find_Func("IsTree"), Find_Not(Find_Func("IsStanding")), Find_Func("GetComponent", Wood));
|
var tree = FindObject(Find_AtPoint(), Find_Func("IsTree"), Find_Not(Find_Func("IsStanding")), Find_Func("GetComponent", Wood));
|
||||||
|
// If there is no tree in front of the sawmill try to get one from the cable car network.
|
||||||
if (!tree)
|
if (!tree)
|
||||||
return;
|
RequestTree();
|
||||||
|
// Only take one tree at a time.
|
||||||
return Saw(tree);
|
if (!ContentsCount(Wood) && tree)
|
||||||
|
Saw(tree);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether the object is made purely out of wood.
|
// Returns whether the object is made purely out of wood.
|
||||||
|
@ -284,6 +279,96 @@ private func SpinOff(int call)
|
||||||
ScheduleCall(this, "SpinOff", this.SpinStep * 2, nil, call+1);
|
ScheduleCall(this, "SpinOff", this.SpinStep * 2, nil, call+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-- Cable Network --*/
|
||||||
|
|
||||||
|
local cable_station;
|
||||||
|
|
||||||
|
public func AcceptsCableStationConnection() { return true; }
|
||||||
|
|
||||||
|
public func IsNoCableStationConnected() { return !cable_station; }
|
||||||
|
|
||||||
|
public func ConnectCableStation(object station)
|
||||||
|
{
|
||||||
|
cable_station = station;
|
||||||
|
}
|
||||||
|
|
||||||
|
private func RequestTree()
|
||||||
|
{
|
||||||
|
if (!cable_station)
|
||||||
|
return;
|
||||||
|
// Find a collectible tree on the network.
|
||||||
|
var collectible_tree = cable_station->FindObjectOnNetworkCables(Find_And(Find_Func("IsTree"), Find_Not(Find_Property("is_being_cable_car_collected"))));
|
||||||
|
if (!collectible_tree)
|
||||||
|
return;
|
||||||
|
// Find an available hoist in the network.
|
||||||
|
var hoist = cable_station->FindCableCar(Find_And(Find_Not(Find_Func("GetAttachedVehicle")), Find_Not(Find_Property("is_busy_collecting_tree"))));
|
||||||
|
if (!hoist)
|
||||||
|
return;
|
||||||
|
hoist->CreateEffect(Sawmill.FxCableCarCollectTree, 100, 1, collectible_tree, cable_station);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
local FxCableCarCollectTree = new Effect
|
||||||
|
{
|
||||||
|
Construction = func(array collectible_tree, object sawmill_station)
|
||||||
|
{
|
||||||
|
this.tree = collectible_tree[0];
|
||||||
|
this.station_1 = collectible_tree[1];
|
||||||
|
this.station_2 = collectible_tree[2];
|
||||||
|
this.station_sawmill = sawmill_station;
|
||||||
|
this.tree.is_being_cable_car_collected = true;
|
||||||
|
Target.is_busy_collecting_tree = true;
|
||||||
|
Target->SetDestination(this.station_1);
|
||||||
|
return FX_OK;
|
||||||
|
},
|
||||||
|
Timer = func()
|
||||||
|
{
|
||||||
|
if (!this.station_1 || !this.station_2 || !this.station_sawmill)
|
||||||
|
return FX_Execute_Kill;
|
||||||
|
if (IsValueInArray(this.station_1->GetIdleCars(), Target))
|
||||||
|
Target->SetDestination(this.station_2);
|
||||||
|
if (IsValueInArray(this.station_2->GetIdleCars(), Target))
|
||||||
|
Target->SetDestination(this.station_sawmill);
|
||||||
|
var tree = Target->FindObject(Target->Find_AtPoint(), Find_InArray([this.tree]));
|
||||||
|
if (tree && !tree.has_been_picked_up)
|
||||||
|
{
|
||||||
|
this.tree.has_been_picked_up = true;
|
||||||
|
this.tree->CreateEffect(Sawmill.FxCableCarRotateTree, 100, 1);
|
||||||
|
Target->PickupVehicle(this.tree);
|
||||||
|
}
|
||||||
|
if (IsValueInArray(this.station_sawmill->GetIdleCars(), Target))
|
||||||
|
return FX_Execute_Kill;
|
||||||
|
return FX_OK;
|
||||||
|
},
|
||||||
|
Destruction = func()
|
||||||
|
{
|
||||||
|
//this.tree.is_being_cable_car_collected = false;
|
||||||
|
Target.is_busy_collecting_tree = false;
|
||||||
|
Target->DropVehicle();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
local FxCableCarRotateTree = new Effect
|
||||||
|
{
|
||||||
|
Construction = func(int rotate_goal)
|
||||||
|
{
|
||||||
|
this.rotate_goal = 90;
|
||||||
|
if (Target->GetR() < 0)
|
||||||
|
this.rotate_goal = -90;
|
||||||
|
},
|
||||||
|
Timer = func()
|
||||||
|
{
|
||||||
|
var step = 3;
|
||||||
|
var dr = this.rotate_goal - Target->GetR();
|
||||||
|
if (Inside(dr, -step, step))
|
||||||
|
return FX_Execute_Kill;
|
||||||
|
Target->SetR(Target->GetR() + BoundBy(dr, -step, step));
|
||||||
|
return FX_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*-- Properties --*/
|
/*-- Properties --*/
|
||||||
|
|
||||||
local ActMap = {
|
local ActMap = {
|
||||||
|
|
|
@ -57,7 +57,7 @@ protected func InitializePlayer(int plr)
|
||||||
|
|
||||||
// Add test control effect.
|
// Add test control effect.
|
||||||
var fx = AddEffect("IntTestControl", nil, 100, 2);
|
var fx = AddEffect("IntTestControl", nil, 100, 2);
|
||||||
fx.testnr = 1;
|
fx.testnr = 9;
|
||||||
fx.launched = false;
|
fx.launched = false;
|
||||||
fx.plr = plr;
|
fx.plr = plr;
|
||||||
return;
|
return;
|
||||||
|
@ -672,11 +672,19 @@ global func Test9_OnStart(int plr)
|
||||||
crossing14->CombineWith(steam_engine);
|
crossing14->CombineWith(steam_engine);
|
||||||
steam_engine->CreateContents(Coal);
|
steam_engine->CreateContents(Coal);
|
||||||
|
|
||||||
var sawmill = CreateObjectAbove(Sawmill, 492, 104, plr);
|
var sawmill = CreateObjectAbove(Sawmill, 484, 104, plr);
|
||||||
|
crossing4->CombineWith(sawmill);
|
||||||
sawmill->SetDir(DIR_Right);
|
sawmill->SetDir(DIR_Right);
|
||||||
for (var cnt = 0; cnt < 5; cnt++)
|
for (var cnt = 0; cnt < 5; cnt++)
|
||||||
sawmill->CreateObjectAbove(Tree_Deciduous)->ChopDown();
|
{
|
||||||
|
//sawmill->CreateObjectAbove(Tree_Deciduous)->ChopDown();
|
||||||
|
var tree = CreateObjectAbove(Tree_Deciduous, RandomX(40, 120), 160);
|
||||||
|
tree->ChopDown();
|
||||||
|
tree->SetR(Random(360));
|
||||||
|
}
|
||||||
crossing4->AddResourceChute();
|
crossing4->AddResourceChute();
|
||||||
|
hoist = crossing4->CreateObject(CableHoist);
|
||||||
|
hoist->EngageRail(crossing4);
|
||||||
|
|
||||||
crossing5->CreateObject(Hammer);
|
crossing5->CreateObject(Hammer);
|
||||||
crossing5->CreateObject(Metal);
|
crossing5->CreateObject(Metal);
|
||||||
|
@ -705,6 +713,50 @@ global func Test9_OnFinished()
|
||||||
|
|
||||||
|
|
||||||
global func Test10_OnStart(int plr)
|
global func Test10_OnStart(int plr)
|
||||||
|
{
|
||||||
|
SetWindFixed(0);
|
||||||
|
CreateObjectAbove(WindGenerator, 90, 160, plr);
|
||||||
|
CreateObjectAbove(WindGenerator, 470, 104, plr);
|
||||||
|
|
||||||
|
var crossing1 = CreateObjectAbove(CableCrossing, 70, 160, plr);
|
||||||
|
var crossing2 = CreateObjectAbove(CableCrossing, 216, 64, plr);
|
||||||
|
var crossing3 = CreateObjectAbove(CableCrossing, 244, 64, plr);
|
||||||
|
var crossing4 = CreateObjectAbove(CableCrossing, 272, 64, plr);
|
||||||
|
var crossing5 = CreateObjectAbove(CableCrossing, 450, 104, plr);
|
||||||
|
|
||||||
|
CreateCableCrossingsConnection(crossing1, crossing2);
|
||||||
|
CreateCableCrossingsConnection(crossing2, crossing3);
|
||||||
|
CreateCableCrossingsConnection(crossing3, crossing4);
|
||||||
|
CreateCableCrossingsConnection(crossing4, crossing5);
|
||||||
|
|
||||||
|
var hoist = crossing1->CreateObject(CableHoist);
|
||||||
|
hoist->EngageRail(crossing1);
|
||||||
|
hoist->SetDestination(crossing5);
|
||||||
|
|
||||||
|
ScheduleCall(nil, "SetWindFixed", 20, 0, 50);
|
||||||
|
ScheduleCall(nil, "SetWindFixed", 40, 0, 0);
|
||||||
|
Schedule(nil, "DrawMaterialQuad(\"Rock\", 60, 80, 120, 80, 120, 140, 60, 140)", 60, 0);
|
||||||
|
ScheduleCall(nil, "SetWindFixed", 80, 0, 50);
|
||||||
|
|
||||||
|
// Log what the test is about.
|
||||||
|
Log("Specific network for which power supply fails.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
global func Test10_Completed()
|
||||||
|
{
|
||||||
|
return !!FindObject(Find_ID(CableHoist), Find_Distance(20, 450, 104));
|
||||||
|
}
|
||||||
|
|
||||||
|
global func Test10_OnFinished()
|
||||||
|
{
|
||||||
|
RemoveTestObjects();
|
||||||
|
ClearScheduleCall(nil, "SetWindFixed");
|
||||||
|
ClearFreeRect(60, 80, 60, 60);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
global func Test100_OnStart(int plr)
|
||||||
{
|
{
|
||||||
var wdt = LandscapeWidth();
|
var wdt = LandscapeWidth();
|
||||||
var hgt = LandscapeHeight();
|
var hgt = LandscapeHeight();
|
||||||
|
@ -751,65 +803,20 @@ global func Test10_OnStart(int plr)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
global func Test10_Completed()
|
global func Test100_Completed()
|
||||||
{
|
{
|
||||||
if (IsSymmetricCableCarNetwork())
|
if (IsSymmetricCableCarNetwork())
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
global func Test10_OnFinished()
|
global func Test100_OnFinished()
|
||||||
{
|
{
|
||||||
RemoveTestObjects();
|
RemoveTestObjects();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
global func Test11_OnStart(int plr)
|
|
||||||
{
|
|
||||||
SetWindFixed(0);
|
|
||||||
CreateObjectAbove(WindGenerator, 90, 160, plr);
|
|
||||||
CreateObjectAbove(WindGenerator, 470, 104, plr);
|
|
||||||
|
|
||||||
var crossing1 = CreateObjectAbove(CableCrossing, 70, 160, plr);
|
|
||||||
var crossing2 = CreateObjectAbove(CableCrossing, 216, 64, plr);
|
|
||||||
var crossing3 = CreateObjectAbove(CableCrossing, 244, 64, plr);
|
|
||||||
var crossing4 = CreateObjectAbove(CableCrossing, 272, 64, plr);
|
|
||||||
var crossing5 = CreateObjectAbove(CableCrossing, 450, 104, plr);
|
|
||||||
|
|
||||||
CreateCableCrossingsConnection(crossing1, crossing2);
|
|
||||||
CreateCableCrossingsConnection(crossing2, crossing3);
|
|
||||||
CreateCableCrossingsConnection(crossing3, crossing4);
|
|
||||||
CreateCableCrossingsConnection(crossing4, crossing5);
|
|
||||||
|
|
||||||
var hoist = crossing1->CreateObject(CableHoist);
|
|
||||||
hoist->EngageRail(crossing1);
|
|
||||||
hoist->SetDestination(crossing5);
|
|
||||||
|
|
||||||
ScheduleCall(nil, "SetWindFixed", 20, 0, 50);
|
|
||||||
ScheduleCall(nil, "SetWindFixed", 40, 0, 0);
|
|
||||||
Schedule(nil, "DrawMaterialQuad(\"Rock\", 60, 80, 120, 80, 120, 140, 60, 140)", 60, 0);
|
|
||||||
ScheduleCall(nil, "SetWindFixed", 80, 0, 50);
|
|
||||||
|
|
||||||
// Log what the test is about.
|
|
||||||
Log("Specific network for which power supply fails.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
global func Test11_Completed()
|
|
||||||
{
|
|
||||||
return !!FindObject(Find_ID(CableHoist), Find_Distance(20, 450, 104));
|
|
||||||
}
|
|
||||||
|
|
||||||
global func Test11_OnFinished()
|
|
||||||
{
|
|
||||||
RemoveTestObjects();
|
|
||||||
ClearScheduleCall(nil, "SetWindFixed");
|
|
||||||
ClearFreeRect(60, 80, 60, 60);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-- Cable Network Functions --*/
|
/*-- Cable Network Functions --*/
|
||||||
|
|
||||||
global func CreateCableCrossingsConnection(object c1, object c2)
|
global func CreateCableCrossingsConnection(object c1, object c2)
|
||||||
|
|
Loading…
Reference in New Issue