From 256227dedeead88854a01b312974471781d97781 Mon Sep 17 00:00:00 2001 From: joris <joris.dauphin@gmail.com> Date: Mon, 20 Feb 2012 12:24:22 +0100 Subject: [PATCH] Remove copy of order (use clone instead make new method to parse luaState Now COrder may be derivated :-) --- src/action/action_attack.cpp | 8 +- src/action/action_follow.cpp | 5 +- src/action/action_patrol.cpp | 2 +- src/action/action_still.cpp | 2 +- src/action/action_train.cpp | 3 +- src/action/actions.cpp | 186 +++++++++++++---- src/include/actions.h | 30 ++- src/unit/script_unit.cpp | 386 +++++++++++++++++++---------------- src/unit/unit.cpp | 2 +- 9 files changed, 396 insertions(+), 228 deletions(-) diff --git a/src/action/action_attack.cpp b/src/action/action_attack.cpp index a829b457a..8dfbd3d65 100644 --- a/src/action/action_attack.cpp +++ b/src/action/action_attack.cpp @@ -166,7 +166,7 @@ static int CheckForTargetInRange(CUnit &unit) CUnit *temp = AttackUnitsInReactRange(unit); if (temp && temp->Type->Priority > goal->Type->Priority) { - COrder *savedOrder = new COrder(*order); + COrder *savedOrder = order->Clone(); if (unit.StoreOrder(savedOrder) == false) { delete savedOrder; @@ -324,7 +324,7 @@ static void AttackTarget(CUnit &unit) return; } // Save current command to come back. - COrder *savedOrder = new COrder(*order); + COrder *savedOrder = order->Clone(); if (unit.StoreOrder(savedOrder) == false) { delete savedOrder; @@ -345,7 +345,7 @@ static void AttackTarget(CUnit &unit) if ((unit.SubAction & WEAK_TARGET)) { CUnit *temp = AttackUnitsInReactRange(unit); if (temp && temp->Type->Priority > goal->Type->Priority) { - COrder *savedOrder = new COrder(*order); + COrder *savedOrder = order->Clone(); if (unit.StoreOrder(savedOrder) == false) { delete savedOrder; @@ -366,7 +366,7 @@ static void AttackTarget(CUnit &unit) // int dist = unit.MapDistanceTo(*goal); if (dist > unit.Stats->Variables[ATTACKRANGE_INDEX].Max) { - COrder *savedOrder = new COrder(*order); + COrder *savedOrder = order->Clone(); if (unit.StoreOrder(savedOrder) == false) { delete savedOrder; diff --git a/src/action/action_follow.cpp b/src/action/action_follow.cpp index 34c06b499..ab821e0de 100644 --- a/src/action/action_follow.cpp +++ b/src/action/action_follow.cpp @@ -154,7 +154,8 @@ void HandleActionFollow(COrder& order, CUnit &unit) } } - *(unit.CurrentOrder()) = *dest.NewOrder; + delete unit.CurrentOrder(); + unit.Orders[0] = dest.NewOrder->Clone(); unit.CurrentResource = dest.CurrentResource; } return; @@ -186,7 +187,7 @@ void HandleActionFollow(COrder& order, CUnit &unit) goal = AttackUnitsInReactRange(unit); if (goal) { // Save current command to come back. - COrder *savedOrder = new COrder(order); + COrder *savedOrder = order.Clone(); CommandAttack(unit, goal->tilePos, NULL, FlushCommands); diff --git a/src/action/action_patrol.cpp b/src/action/action_patrol.cpp index 3124199ec..7e5cceafa 100644 --- a/src/action/action_patrol.cpp +++ b/src/action/action_patrol.cpp @@ -129,7 +129,7 @@ void HandleActionPatrol(COrder& order, CUnit &unit) const CUnit *goal = AttackUnitsInReactRange(unit); if (goal) { // Save current command to come back. - COrder *savedOrder = new COrder(order); + COrder *savedOrder = order.Clone(); DebugPrint("Patrol attack %d\n" _C_ UnitNumber(*goal)); CommandAttack(unit, goal->tilePos, NULL, FlushCommands); diff --git a/src/action/action_still.cpp b/src/action/action_still.cpp index c77fef82f..ead9d330d 100644 --- a/src/action/action_still.cpp +++ b/src/action/action_still.cpp @@ -244,7 +244,7 @@ bool AutoRepair(CUnit &unit) if (repairedUnit != NoUnitP) { const Vec2i invalidPos = {-1, -1}; - COrder *savedOrder = new COrder(*unit.CurrentOrder()); + COrder *savedOrder = unit.CurrentOrder()->Clone(); //Command* will clear unit.SavedOrder CommandRepair(unit, invalidPos, repairedUnit, FlushCommands); diff --git a/src/action/action_train.cpp b/src/action/action_train.cpp index af3103c35..93713a40e 100644 --- a/src/action/action_train.cpp +++ b/src/action/action_train.cpp @@ -192,7 +192,8 @@ void HandleActionTrain(COrder& order, CUnit &unit) } if (CanHandleOrder(*nunit, unit.NewOrder) == true) { - *(nunit->CurrentOrder()) = *unit.NewOrder; + delete nunit->CurrentOrder(); + nunit->Orders[0] = unit.NewOrder->Clone(); #if 0 } else { // Tell the unit to move instead of trying any funny stuff. diff --git a/src/action/actions.cpp b/src/action/actions.cpp index c6b299209..775805297 100644 --- a/src/action/actions.cpp +++ b/src/action/actions.cpp @@ -90,24 +90,6 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type); -- Functions ----------------------------------------------------------------------------*/ -COrder::COrder(const COrder &rhs): Goal(rhs.Goal), Range(rhs.Range), - MinRange(rhs.MinRange), Width(rhs.Width), Height(rhs.Height), - Action(rhs.Action), CurrentResource(rhs.CurrentResource), - goalPos(rhs.goalPos) - { - if (Goal) { - Goal->RefsIncrease(); - } - - memcpy(&Arg1, &rhs.Arg1, sizeof(Arg1)); - memcpy(&Data, &rhs.Data, sizeof (Data)); - if (Action == UnitActionResource && Arg1.Resource.Mine) { - Arg1.Resource.Mine->RefsIncrease(); - } -} - - - /* static */ COrder* COrder::NewActionAttack(const CUnit &attacker, CUnit &target) { COrder *order = new COrder; @@ -445,24 +427,158 @@ COrder::COrder(const COrder &rhs): Goal(rhs.Goal), Range(rhs.Range), return order; } -COrder& COrder::operator=(const COrder &rhs) { - if (this != &rhs) { - Action = rhs.Action; - Range = rhs.Range; - MinRange = rhs.MinRange; - Width = rhs.Width; - Height = rhs.Height; - CurrentResource = rhs.CurrentResource; - SetGoal(rhs.Goal); - goalPos = rhs.goalPos; - memcpy(&Arg1, &rhs.Arg1, sizeof(Arg1)); - memcpy(&Data, &rhs.Data, sizeof (Data)); - //FIXME: Hardcoded wood - if (Action == UnitActionResource && Arg1.Resource.Mine) { - Arg1.Resource.Mine->RefsIncrease(); - } +#if 1 // currently needed for parsing +/* static */ COrder* COrder::NewActionAttack() +{ + COrder *order = new COrder; + + order->Action = UnitActionAttack; + return order; +} + +/* static */ COrder* COrder::NewActionAttackGround() +{ + COrder *order = new COrder; + + order->Action = UnitActionAttackGround; + return order; +} + +/* static */ COrder* COrder::NewActionBoard() +{ + COrder *order = new COrder; + + order->Action = UnitActionBoard; + return order; +} + +/* static */ COrder* COrder::NewActionBuild() +{ + COrder *order = new COrder; + + order->Action = UnitActionBuild; + return order; +} + +/* static */ COrder* COrder::NewActionFollow() +{ + COrder *order = new COrder; + + order->Action = UnitActionFollow; + return order; +} + +/* static */ COrder* COrder::NewActionMove() +{ + COrder *order = new COrder; + + order->Action = UnitActionMove; + return order; +} + +/* static */ COrder* COrder::NewActionPatrol() +{ + COrder *order = new COrder; + + order->Action = UnitActionPatrol; + return order; +} + +/* static */ COrder* COrder::NewActionRepair() +{ + COrder *order = new COrder; + + order->Action = UnitActionRepair; + return order; +} + +/* static */ COrder* COrder::NewActionResearch() +{ + COrder *order = new COrder; + + order->Action = UnitActionResearch; + return order; +} + +/* static */ COrder* COrder::NewActionResource() +{ + COrder *order = new COrder; + + order->Action = UnitActionResource; + return order; +} + +/* static */ COrder* COrder::NewActionReturnGoods() +{ + COrder *order = new COrder; + + order->Action = UnitActionReturnGoods; + return order; +} + +/* static */ COrder* COrder::NewActionSpellCast() +{ + COrder *order = new COrder; + + order->Action = UnitActionSpellCast; + return order; +} + +/* static */ COrder* COrder::NewActionTrain() +{ + COrder *order = new COrder; + + order->Action = UnitActionTrain; + return order; +} + +/* static */ COrder* COrder::NewActionTransformInto() +{ + COrder *order = new COrder; + + order->Action = UnitActionTransformInto; + return order; +} + +/* static */ COrder* COrder::NewActionUnload() +{ + COrder *order = new COrder; + + order->Action = UnitActionUnload; + return order; +} + +/* static */ COrder* COrder::NewActionUpgradeTo() +{ + COrder *order = new COrder; + + order->Action = UnitActionUpgradeTo; + return order; +} + +#endif + + + +COrder* COrder::Clone() const +{ + COrder *clone = new COrder(); + + clone->Action = this->Action; + clone->Range = this->Range; + clone->MinRange = this->MinRange; + clone->Width = this->Width; + clone->Height = this->Height; + clone->CurrentResource = this->CurrentResource; + clone->SetGoal(this->Goal); + clone->goalPos = this->goalPos; + memcpy(&clone->Arg1, &this->Arg1, sizeof (clone->Arg1)); + memcpy(&clone->Data, &this->Data, sizeof (clone->Data)); + //FIXME: Hardcoded wood + if (clone->Action == UnitActionResource && clone->Arg1.Resource.Mine) { + clone->Arg1.Resource.Mine->RefsIncrease(); } - return *this; + return clone; } COrder::~COrder() diff --git a/src/include/actions.h b/src/include/actions.h index 5f1bb8dbb..3c6980850 100644 --- a/src/include/actions.h +++ b/src/include/actions.h @@ -95,6 +95,7 @@ class CUnitType; class CUpgrade; class SpellType; class CAnimation; +struct lua_State; /** ** Unit order structure. @@ -110,11 +111,11 @@ public: memset(&Arg1, 0, sizeof (Arg1)); memset(&Data, 0, sizeof (Data)); } - COrder(const COrder &ths); ~COrder(); + COrder *Clone() const; + void ReleaseRefs(CUnit &owner); - COrder& operator=(const COrder &rhs); bool CheckRange() const; void Init() { @@ -175,8 +176,31 @@ public: static COrder* NewActionUnload(const Vec2i &pos, CUnit *what); static COrder* NewActionUpgradeTo(CUnit &unit, CUnitType &type); + bool ParseGenericData(lua_State *l, int &j, const char *value); + bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit); + +#if 1 // currently needed for parsing + static COrder* NewActionAttack(); + static COrder* NewActionAttackGround(); + static COrder* NewActionBoard(); + static COrder* NewActionBuild(); + static COrder* NewActionFollow(); + static COrder* NewActionMove(); + static COrder* NewActionPatrol(); + static COrder* NewActionRepair(); + static COrder* NewActionResearch(); + static COrder* NewActionResource(); + static COrder* NewActionReturnGoods(); + static COrder* NewActionSpellCast(); + static COrder* NewActionTrain(); + static COrder* NewActionTransformInto(); + static COrder* NewActionUnload(); + static COrder* NewActionUpgradeTo(); +#endif + private: - friend void CclParseOrder(lua_State *l, const CUnit &unit, COrder* order); + COrder(const COrder &ths); // no implementation + COrder& operator=(const COrder &rhs); // no implementation CUnit *Goal; public: diff --git a/src/unit/script_unit.cpp b/src/unit/script_unit.cpp index 970aa7961..cdd68ab67 100644 --- a/src/unit/script_unit.cpp +++ b/src/unit/script_unit.cpp @@ -380,6 +380,149 @@ static void CclParseMove(lua_State *l, COrderPtr order) } } +bool COrder::ParseGenericData(lua_State *l, int &j, const char *value) +{ + if (!strcmp(value, "range")) { + ++j; + lua_rawgeti(l, -1, j + 1); + this->Range = LuaToNumber(l, -1); + lua_pop(l, 1); + } else if (!strcmp(value, "min-range")) { + ++j; + lua_rawgeti(l, -1, j + 1); + this->MinRange = LuaToNumber(l, -1); + lua_pop(l, 1); + } else if (!strcmp(value, "width")) { + ++j; + lua_rawgeti(l, -1, j + 1); + this->Width = LuaToNumber(l, -1); + lua_pop(l, 1); + } else if (!strcmp(value, "height")) { + ++j; + lua_rawgeti(l, -1, j + 1); + this->Height = LuaToNumber(l, -1); + lua_pop(l, 1); + } else if (!strcmp(value, "goal")) { + ++j; + lua_rawgeti(l, -1, j + 1); + this->Goal = CclGetUnitFromRef(l); + lua_pop(l, 1); + } else if (!strcmp(value, "tile")) { + ++j; + lua_rawgeti(l, -1, j + 1); + CclGetPos(l, &this->goalPos.x , &this->goalPos.y); + lua_pop(l, 1); + } else { + return false; + } + return true; +} + +bool COrder::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit) +{ + if (!strcmp(value, "type")) { + ++j; + lua_rawgeti(l, -1, j + 1); + this->Arg1.Type = UnitTypeByIdent(LuaToString(l, -1)); + lua_pop(l, 1); + + } else if (!strcmp(value, "patrol")) { + ++j; + lua_rawgeti(l, -1, j + 1); + CclGetPos(l, &this->Arg1.Patrol.x , &this->Arg1.Patrol.y); + lua_pop(l, 1); + } else if (!strcmp(value, "spell")) { + ++j; + lua_rawgeti(l, -1, j + 1); + this->Arg1.Spell = SpellTypeByIdent(LuaToString(l, -1)); + lua_pop(l, 1); + + } else if (!strcmp(value, "upgrade")) { + ++j; + lua_rawgeti(l, -1, j + 1); + this->Arg1.Upgrade = CUpgrade::Get(LuaToString(l, -1)); + lua_pop(l, 1); + } else if (!strcmp(value, "current-resource")) { + ++j; + lua_rawgeti(l, -1, j + 1); + this->CurrentResource = CclGetResourceByName(l); + lua_pop(l, 1); + } else if (!strcmp(value, "resource-pos")) { + ++j; + lua_rawgeti(l, -1, j + 1); + this->Arg1.Resource.Mine = NULL; + CclGetPos(l, &this->Arg1.Resource.Pos.x , &this->Arg1.Resource.Pos.y); + lua_pop(l, 1); + + Assert(this->CurrentResource); + } else if (!strcmp(value, "resource-mine")) { + ++j; + lua_rawgeti(l, -1, j + 1); + Vec2i invalidPos = {-1, -1}; + this->Arg1.Resource.Pos = invalidPos; + this->Arg1.Resource.Mine = CclGetUnitFromRef(l); + lua_pop(l, 1); + } else if (!strcmp(value, "data-built")) { + ++j; + lua_rawgeti(l, -1, j + 1); + CclParseBuilt(l, unit, this); + lua_pop(l, 1); + } else if (!strcmp(value, "data-res-worker")) { + ++j; + lua_rawgeti(l, -1, j + 1); + CclParseResWorker(l, this); + lua_pop(l, 1); + } else if (!strcmp(value, "data-research")) { + ++j; + lua_rawgeti(l, -1, j + 1); + CclParseResearch(l, this); + lua_pop(l, 1); + } else if (!strcmp(value, "data-upgrade-to")) { + ++j; + lua_rawgeti(l, -1, j + 1); + CclParseUpgradeTo(l, this); + lua_pop(l, 1); + } else if (!strcmp(value, "data-train")) { + ++j; + lua_rawgeti(l, -1, j + 1); + CclParseTrain(l, this); + lua_pop(l, 1); + } else if (!strcmp(value, "data-move")) { + ++j; + lua_rawgeti(l, -1, j + 1); + CclParseMove(l, this); + lua_pop(l, 1); + } else if (!strcmp(value, "mine")) { /* old save format */ + int pos; + ++j; + lua_rawgeti(l, -1, j + 1); + pos = LuaToNumber(l, -1); + lua_pop(l, 1); + + const Vec2i mpos = {pos >> 16, pos & 0xFFFF}; + CUnit *mine = NULL; + pos = 0; + do { + pos++; + mine = ResourceOnMap(mpos, pos, true); + } while (!mine && pos < MaxCosts); + if (mine) { + Vec2i invalidPos = {-1, -1}; + this->Arg1.Resource.Pos = invalidPos; + + mine->RefsIncrease(); + this->Arg1.Resource.Mine = mine; + this->CurrentResource = pos; + } else { + this->CurrentResource = WoodCost; + this->Arg1.Resource.Mine = NULL; + this->Arg1.Resource.Pos = mpos; + } + } else { + return false; + } + return true; +} /** ** Parse order @@ -387,184 +530,70 @@ static void CclParseMove(lua_State *l, COrderPtr order) ** @param l Lua state. ** @param order OUT: resulting order. */ -void CclParseOrder(lua_State *l, const CUnit &unit, COrderPtr order) +void CclParseOrder(lua_State *l, const CUnit &unit, COrderPtr *orderPtr) { const int args = lua_objlen(l, -1); - for (int j = 0; j < args; ++j) { + + lua_rawgeti(l, -1, 1); + const char *actiontype = LuaToString(l, -1); + lua_pop(l, 1); + + if (!strcmp(actiontype, "action-still")) { + *orderPtr = COrder::NewActionStill(); + } else if (!strcmp(actiontype, "action-stand-ground")) { + *orderPtr = COrder::NewActionStandGround(); + } else if (!strcmp(actiontype, "action-follow")) { + *orderPtr = COrder::NewActionFollow(); + } else if (!strcmp(actiontype, "action-move")) { + *orderPtr = COrder::NewActionMove(); + } else if (!strcmp(actiontype, "action-attack")) { + *orderPtr = COrder::NewActionAttack(); + } else if (!strcmp(actiontype, "action-attack-ground")) { + *orderPtr = COrder::NewActionAttackGround(); + } else if (!strcmp(actiontype, "action-die")) { + *orderPtr = COrder::NewActionDie(); + } else if (!strcmp(actiontype, "action-spell-cast")) { + *orderPtr = COrder::NewActionSpellCast(); + } else if (!strcmp(actiontype, "action-train")) { + *orderPtr = COrder::NewActionTrain(); + } else if (!strcmp(actiontype, "action-upgrade-to")) { + *orderPtr = COrder::NewActionUpgradeTo(); + } else if (!strcmp(actiontype, "action-research")) { + *orderPtr = COrder::NewActionResearch(); + } else if (!strcmp(actiontype, "action-built")) { + *orderPtr = COrder::NewActionBuilt(); + } else if (!strcmp(actiontype, "action-board")) { + *orderPtr = COrder::NewActionBoard(); + } else if (!strcmp(actiontype, "action-unload")) { + *orderPtr = COrder::NewActionUnload(); + } else if (!strcmp(actiontype, "action-patrol")) { + *orderPtr = COrder::NewActionPatrol(); + } else if (!strcmp(actiontype, "action-build")) { + *orderPtr = COrder::NewActionBuild(); + } else if (!strcmp(actiontype, "action-repair")) { + *orderPtr = COrder::NewActionRepair(); + } else if (!strcmp(actiontype, "action-resource")) { + *orderPtr = COrder::NewActionResource(); + } else if (!strcmp(actiontype, "action-return-goods")) { + *orderPtr = COrder::NewActionReturnGoods(); + } else if (!strcmp(actiontype, "action-transform-into")) { + *orderPtr = COrder::NewActionTransformInto(); + } else { + LuaError(l, "ParseOrder: Unsupported type: %s" _C_ actiontype); + } + + COrder &order = **orderPtr; + + for (int j = 1; j < args; ++j) { lua_rawgeti(l, -1, j + 1); const char *value = LuaToString(l, -1); lua_pop(l, 1); - if (!strcmp(value, "action-none")) { - order->Action = UnitActionNone; - } else if (!strcmp(value, "action-still")) { - order->Action = UnitActionStill; - } else if (!strcmp(value, "action-stand-ground")) { - order->Action = UnitActionStandGround; - } else if (!strcmp(value, "action-follow")) { - order->Action = UnitActionFollow; - } else if (!strcmp(value, "action-move")) { - order->Action = UnitActionMove; - } else if (!strcmp(value, "action-attack")) { - order->Action = UnitActionAttack; - } else if (!strcmp(value, "action-attack-ground")) { - order->Action = UnitActionAttackGround; - } else if (!strcmp(value, "action-die")) { - order->Action = UnitActionDie; - } else if (!strcmp(value, "action-spell-cast")) { - order->Action = UnitActionSpellCast; - } else if (!strcmp(value, "action-train")) { - order->Action = UnitActionTrain; - } else if (!strcmp(value, "action-upgrade-to")) { - order->Action = UnitActionUpgradeTo; - } else if (!strcmp(value, "action-research")) { - order->Action = UnitActionResearch; - } else if (!strcmp(value, "action-built")) { - order->Action = UnitActionBuilt; - } else if (!strcmp(value, "action-board")) { - order->Action = UnitActionBoard; - } else if (!strcmp(value, "action-unload")) { - order->Action = UnitActionUnload; - } else if (!strcmp(value, "action-patrol")) { - order->Action = UnitActionPatrol; - } else if (!strcmp(value, "action-build")) { - order->Action = UnitActionBuild; - } else if (!strcmp(value, "action-repair")) { - order->Action = UnitActionRepair; - } else if (!strcmp(value, "action-resource")) { - order->Action = UnitActionResource; - } else if (!strcmp(value, "action-return-goods")) { - order->Action = UnitActionReturnGoods; - } else if (!strcmp(value, "action-transform-into")) { - order->Action = UnitActionTransformInto; - } else if (!strcmp(value, "range")) { - ++j; - lua_rawgeti(l, -1, j + 1); - order->Range = LuaToNumber(l, -1); - lua_pop(l, 1); - } else if (!strcmp(value, "min-range")) { - ++j; - lua_rawgeti(l, -1, j + 1); - order->MinRange = LuaToNumber(l, -1); - lua_pop(l, 1); - } else if (!strcmp(value, "width")) { - ++j; - lua_rawgeti(l, -1, j + 1); - order->Width = LuaToNumber(l, -1); - lua_pop(l, 1); - } else if (!strcmp(value, "height")) { - ++j; - lua_rawgeti(l, -1, j + 1); - order->Height = LuaToNumber(l, -1); - lua_pop(l, 1); - } else if (!strcmp(value, "goal")) { - ++j; - lua_rawgeti(l, -1, j + 1); - order->Goal = CclGetUnitFromRef(l); - lua_pop(l, 1); - } else if (!strcmp(value, "tile")) { - ++j; - lua_rawgeti(l, -1, j + 1); - CclGetPos(l, &order->goalPos.x , &order->goalPos.y); - lua_pop(l, 1); - } else if (!strcmp(value, "type")) { - ++j; - lua_rawgeti(l, -1, j + 1); - order->Arg1.Type = UnitTypeByIdent(LuaToString(l, -1)); - lua_pop(l, 1); - } else if (!strcmp(value, "patrol")) { - ++j; - lua_rawgeti(l, -1, j + 1); - CclGetPos(l, &order->Arg1.Patrol.x , &order->Arg1.Patrol.y); - lua_pop(l, 1); - } else if (!strcmp(value, "spell")) { - ++j; - lua_rawgeti(l, -1, j + 1); - order->Arg1.Spell = SpellTypeByIdent(LuaToString(l, -1)); - lua_pop(l, 1); - - } else if (!strcmp(value, "upgrade")) { - ++j; - lua_rawgeti(l, -1, j + 1); - order->Arg1.Upgrade = CUpgrade::Get(LuaToString(l, -1)); - lua_pop(l, 1); - } else if (!strcmp(value, "current-resource")) { - ++j; - lua_rawgeti(l, -1, j + 1); - order->CurrentResource = CclGetResourceByName(l); - lua_pop(l, 1); - } else if (!strcmp(value, "resource-pos")) { - ++j; - lua_rawgeti(l, -1, j + 1); - order->Arg1.Resource.Mine = NULL; - CclGetPos(l, &order->Arg1.Resource.Pos.x , &order->Arg1.Resource.Pos.y); - lua_pop(l, 1); - - Assert(order->CurrentResource); - } else if (!strcmp(value, "resource-mine")) { - ++j; - lua_rawgeti(l, -1, j + 1); - Vec2i invalidPos = {-1, -1}; - order->Arg1.Resource.Pos = invalidPos; - order->Arg1.Resource.Mine = CclGetUnitFromRef(l); - lua_pop(l, 1); - } else if (!strcmp(value, "data-built")) { - ++j; - lua_rawgeti(l, -1, j + 1); - CclParseBuilt(l, unit, order); - lua_pop(l, 1); - } else if (!strcmp(value, "data-res-worker")) { - ++j; - lua_rawgeti(l, -1, j + 1); - CclParseResWorker(l, order); - lua_pop(l, 1); - } else if (!strcmp(value, "data-research")) { - ++j; - lua_rawgeti(l, -1, j + 1); - CclParseResearch(l, order); - lua_pop(l, 1); - } else if (!strcmp(value, "data-upgrade-to")) { - ++j; - lua_rawgeti(l, -1, j + 1); - CclParseUpgradeTo(l, order); - lua_pop(l, 1); - } else if (!strcmp(value, "data-train")) { - ++j; - lua_rawgeti(l, -1, j + 1); - CclParseTrain(l, order); - lua_pop(l, 1); - } else if (!strcmp(value, "data-move")) { - ++j; - lua_rawgeti(l, -1, j + 1); - CclParseMove(l, order); - lua_pop(l, 1); - } else if (!strcmp(value, "mine")) { /* old save format */ - int pos; - ++j; - lua_rawgeti(l, -1, j + 1); - pos = LuaToNumber(l, -1); - lua_pop(l, 1); - - const Vec2i mpos = {pos >> 16, pos & 0xFFFF}; - CUnit *mine = NULL; - pos = 0; - do { - pos++; - mine = ResourceOnMap(mpos, pos, true); - } while (!mine && pos < MaxCosts); - if (mine) { - Vec2i invalidPos = {-1, -1}; - order->Arg1.Resource.Pos = invalidPos; - - mine->RefsIncrease(); - order->Arg1.Resource.Mine = mine; - order->CurrentResource = pos; - } else { - order->CurrentResource = WoodCost; - order->Arg1.Resource.Mine = NULL; - order->Arg1.Resource.Pos = mpos; - } - } else { + if (order.ParseGenericData(l, j, value)) { + continue; + } else if (order.ParseSpecificData(l, j, value, unit)) { + continue; + }else { // This leaves a half initialized unit LuaError(l, "ParseOrder: Unsupported tag: %s" _C_ value); } @@ -590,10 +619,10 @@ static void CclParseOrders(lua_State *l, CUnit &unit) for (int j = 0; j < n; ++j) { lua_rawgeti(l, -1, j + 1); - unit.Orders.push_back(new COrder); + unit.Orders.push_back(NULL); COrderPtr* order = &unit.Orders.back(); - CclParseOrder(l, unit, *order); + CclParseOrder(l, unit, order); lua_pop(l, 1); } } @@ -852,18 +881,15 @@ static int CclUnit(lua_State *l) } } else if (!strcmp(value, "critical-order")) { lua_pushvalue(l, j + 1); - unit->CriticalOrder = new COrder; - CclParseOrder(l, *unit , unit->CriticalOrder); + CclParseOrder(l, *unit , &unit->CriticalOrder); lua_pop(l, 1); } else if (!strcmp(value, "saved-order")) { lua_pushvalue(l, j + 1); - unit->SavedOrder = new COrder; - CclParseOrder(l, *unit, unit->SavedOrder); + CclParseOrder(l, *unit, &unit->SavedOrder); lua_pop(l, 1); } else if (!strcmp(value, "new-order")) { lua_pushvalue(l, j + 1); - unit->NewOrder = new COrder; - CclParseOrder(l, *unit, unit->NewOrder); + CclParseOrder(l, *unit, &unit->NewOrder); lua_pop(l, 1); } else if (!strcmp(value, "goal")) { unit->Goal = UnitSlots[(int)LuaToNumber(l, j + 1)]; diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index ae8377081..e6e578e9e 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -3096,7 +3096,7 @@ void HitUnit(CUnit *attacker, CUnit &target, int damage) } } if (goal) { - COrder *savedOrder = new COrder(*target.CurrentOrder()); + COrder *savedOrder = target.CurrentOrder()->Clone(); CommandAttack(target, goal->tilePos, NoUnitP, FlushCommands); if (target.StoreOrder(savedOrder) == false) {