From 027cf83931d779a3d062c2db56a0e7430d66dbe8 Mon Sep 17 00:00:00 2001 From: Artem Trytiak Date: Sat, 5 Oct 2019 11:29:38 -0700 Subject: [PATCH] Bug with moving too early to building with BUILD command (#43) * Build orders move too early * New buildings phase --- game.h | 1 + monthorders.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ orders.cpp | 1 + orders.h | 1 + parseorders.cpp | 19 ++----------------- 5 files changed, 50 insertions(+), 17 deletions(-) diff --git a/game.h b/game.h index d9f13e24..5bef4334 100644 --- a/game.h +++ b/game.h @@ -560,6 +560,7 @@ class Game void RunUnitProduce(ARegion *, Unit *); void Run1BuildOrder(ARegion *, Object *, Unit *); void RunBuildShipOrder(ARegion *, Object *, Unit *); + void AddNewBuildings(ARegion *); void RunBuildHelpers(ARegion *); int ShipConstruction(ARegion *, Unit *, Unit *, int, int, int); void CreateShip(ARegion *, Unit *, int); diff --git a/monthorders.cpp b/monthorders.cpp index 6dd16081..602083a5 100644 --- a/monthorders.cpp +++ b/monthorders.cpp @@ -715,6 +715,50 @@ void Game::RunBuildShipOrder(ARegion * r,Object * obj,Unit * u) u->monthorders = 0; } +void Game::AddNewBuildings(ARegion *r) +{ + int i; + forlist((&r->objects)) { + Object *obj = (Object *) elem; + forlist ((&obj->units)) { + Unit *u = (Unit *) elem; + if (u->monthorders) { + if (u->monthorders->type == O_BUILD) { + BuildOrder *o = (BuildOrder *)u->monthorders; + + // If BUILD order was marked for creating new building + // in parse phase, it is time to create one now. + if (o->new_building != -1) { + for (i = 1; i < 100; i++) { + if (!r->GetObject(i)) { + break; + } + } + if (i < 100) { + Object * obj = new Object(r); + obj->type = o->new_building; + obj->incomplete = ObjectDefs[obj->type].cost; + obj->num = i; + obj->SetName(new AString("Building")); + u->build = obj->num; + r->objects.Add(obj); + + // This moves unit to a new building. + // This unit might be processed again but from new object. + u->MoveUnit(obj); + // This why we need to unset new_building so it will not + // try to create new object again. + o->new_building = -1; + } else { + u->Error("BUILD: The region is full."); + } + } + } + } + } + } +} + void Game::RunBuildHelpers(ARegion *r) { forlist((&r->objects)) { @@ -996,6 +1040,7 @@ void Game::RunMonthOrders() ARegion * r = (ARegion *) elem; RunIdleOrders(r); RunStudyOrders(r); + AddNewBuildings(r); RunBuildHelpers(r); RunProduceOrders(r); } diff --git a/orders.cpp b/orders.cpp index 18ef75b3..8823ebc8 100644 --- a/orders.cpp +++ b/orders.cpp @@ -228,6 +228,7 @@ AttackOrder::~AttackOrder() BuildOrder::BuildOrder() { type = O_BUILD; + new_building = -1; } BuildOrder::~BuildOrder() diff --git a/orders.h b/orders.h index 9c46768d..0557be67 100644 --- a/orders.h +++ b/orders.h @@ -252,6 +252,7 @@ class BuildOrder : public Order { ~BuildOrder(); UnitId * target; + int new_building; int needtocomplete; }; diff --git a/parseorders.cpp b/parseorders.cpp index f8493087..49dffa40 100644 --- a/parseorders.cpp +++ b/parseorders.cpp @@ -1540,7 +1540,7 @@ void Game::ProcessBuildOrder(Unit *unit, AString *o, OrdersCheck *pCheck) { AString * token = o->gettoken(); BuildOrder * order = new BuildOrder; - int maxbuild, i; + int maxbuild; // 'incomplete' for ships: maxbuild = 0; @@ -1615,22 +1615,7 @@ void Game::ProcessBuildOrder(Unit *unit, AString *o, OrdersCheck *pCheck) ParseError(pCheck, unit, 0, "BUILD: Can't build that."); return; } - for (i = 1; i < 100; i++) - if (!reg->GetObject(i)) - break; - if (i < 100) { - Object * obj = new Object(reg); - obj->type = ot; - obj->incomplete = ObjectDefs[obj->type].cost; - obj->num = i; - obj->SetName(new AString("Building")); - unit->build = obj->num; - unit->object->region->objects.Add(obj); - unit->MoveUnit(obj); - } else { - unit->Error("BUILD: The region is full."); - return; - } + order->new_building = ot; } } order->target = NULL; // Not helping anyone...