diff --git a/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/Script.c b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/Script.c index f1685d2e8..3fcb6203e 100644 --- a/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/Script.c +++ b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Libraries.ocd/CableStation.ocd/Script.c @@ -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. // Return true if there are means to collect the required amount. -public func IsAvailable(proplist order) -{ - return false; -} +public func IsAvailable(proplist order) { return false; } + +// Called to get idle cable cars at this station. +public func GetIdleCars() { return []; } + /*--- Callbacks ---*/ @@ -101,6 +102,8 @@ public func GetCablePosition(array coordinates, int prec) { if (!prec) prec = 1; + if (!coordinates) + coordinates = []; coordinates[0] = GetX(prec); coordinates[1] = GetY(prec); if (this.LineAttach) @@ -108,6 +111,7 @@ public func GetCablePosition(array coordinates, int prec) coordinates[0] += this.LineAttach[0] * prec; coordinates[1] += this.LineAttach[1] * prec; } + return coordinates; } // Called by cable cars to retrieve selectable destinations for the destination selection menu. @@ -563,3 +567,51 @@ public func RemoveRequest(proplist order) return true; } + +/*-- Misc Queries --*/ + +// Returns the closest object satisfying find_crit that can be found on the cables of this network. +// Returns {obj = , station1 = , station2 = }. +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; +} diff --git a/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Script.c b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Script.c index 1b7c847eb..2c507e5ef 100644 --- a/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Script.c +++ b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Structures.ocd/Crossing.ocd/Script.c @@ -110,7 +110,7 @@ public func GetAvailableCableCar(proplist order, object requesting_station) // Find closest cars first. var destinations = GetDestinations(); SortArrayByArrayElement(destinations, this.const_distance, false); - for (dest in destinations) + for (var dest in destinations) { var station = dest[this.const_finaldestination]; var best = station->~GetAvailableCableCar(order, station); @@ -466,6 +466,8 @@ public func OnCableCarDestruction(object car) RemoveArrayValue(arrived_cars, car, true); } +public func GetIdleCars() { return arrived_cars; } + /*-- Visuals --*/ diff --git a/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Hoist.ocd/Script.c b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Hoist.ocd/Script.c index 7359b1b3e..27d2b41ed 100644 --- a/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Hoist.ocd/Script.c +++ b/planet/Experimental.ocf/CableLorrys.ocs/CableCars.ocd/Vehicles.ocd/Hoist.ocd/Script.c @@ -119,7 +119,7 @@ public func OnCableCarHover(symbol, extra_data, desc_menu_target, menu_id) /*-- Picking up vehicles --*/ -public func PickupVehicle(object vehicle) +public func PickupVehicle(object vehicle, bool no_rotation_copy) { if (!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(GetY(), vehicle->GetY() - height, vehicle->GetY() + height)) return; - vehicle->CreateEffect(FxCableHoistPickup, 1, 1, this); + vehicle->CreateEffect(FxCableHoistPickup, 1, 1, this, no_rotation_copy); pickup = vehicle; UpdateInteractionMenus(this.GetCableCarMenuEntries); } @@ -143,7 +143,7 @@ public func DropVehicle() local FxCableHoistPickup = new Effect { - Construction = func(object hoist) + Construction = func(object hoist, bool no_rotation_copy) { this.hoist = hoist; this.vehicle_touchable = Target.Touchable; @@ -152,8 +152,11 @@ local FxCableHoistPickup = new Effect this.movement_prec = 100; Target->SetPosition(this.hoist->GetX(this.movement_prec), this.hoist->GetY(this.movement_prec) + 4, false, this.movement_prec); Target->SetSpeed(0, 0); - Target->SetR(this.hoist->GetR()); - Target->SetRDir(0); + if (!no_rotation_copy) + { + Target->SetR(this.hoist->GetR()); + Target->SetRDir(0); + } }, Timer = func(int time) diff --git a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Script.c index 986c66a9a..6af6b85e2 100644 --- a/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Sawmill.ocd/Script.c @@ -62,19 +62,14 @@ public func CollectTrees() { if (GetCon() < 100) 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)); + // If there is no tree in front of the sawmill try to get one from the cable car network. if (!tree) - return; - - return Saw(tree); + RequestTree(); + // Only take one tree at a time. + if (!ContentsCount(Wood) && tree) + Saw(tree); + return; } // 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); } + +/*-- 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 --*/ local ActMap = { diff --git a/planet/Tests.ocf/CableCars.ocs/Script.c b/planet/Tests.ocf/CableCars.ocs/Script.c index 20a417e1e..24fe2056c 100644 --- a/planet/Tests.ocf/CableCars.ocs/Script.c +++ b/planet/Tests.ocf/CableCars.ocs/Script.c @@ -57,7 +57,7 @@ protected func InitializePlayer(int plr) // Add test control effect. var fx = AddEffect("IntTestControl", nil, 100, 2); - fx.testnr = 1; + fx.testnr = 9; fx.launched = false; fx.plr = plr; return; @@ -672,11 +672,19 @@ global func Test9_OnStart(int plr) crossing14->CombineWith(steam_engine); 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); 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(); + hoist = crossing4->CreateObject(CableHoist); + hoist->EngageRail(crossing4); crossing5->CreateObject(Hammer); crossing5->CreateObject(Metal); @@ -705,6 +713,50 @@ global func Test9_OnFinished() 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 hgt = LandscapeHeight(); @@ -751,65 +803,20 @@ global func Test10_OnStart(int plr) return true; } -global func Test10_Completed() +global func Test100_Completed() { if (IsSymmetricCableCarNetwork()) return true; return false; } -global func Test10_OnFinished() +global func Test100_OnFinished() { RemoveTestObjects(); 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 --*/ global func CreateCableCrossingsConnection(object c1, object c2)