in order Void*Arg1 become a union.

Fix bug#1053283 [Assert]actions.c:417
This commit is contained in:
jarod42 2004-10-25 21:59:32 +00:00
parent 15a3fb511a
commit a0d3dd924e
10 changed files with 112 additions and 155 deletions

View file

@ -75,10 +75,12 @@ void HandleActionPatrol(Unit* unit)
//
// Swap the points.
//
tmp = (int)unit->Orders[0].Arg1;
unit->Orders[0].Arg1 = (void*)((unit->Orders[0].X << 16) | unit->Orders[0].Y);
unit->Orders[0].X = tmp >> 16;
unit->Orders[0].Y = tmp & 0xFFFF;
tmp = unit->Orders[0].Arg1.Patrol.X;
unit->Orders[0].Arg1.Patrol.X = unit->Orders[0].X;
unit->Orders[0].X = tmp;
tmp = unit->Orders[0].Arg1.Patrol.Y;
unit->Orders[0].Arg1.Patrol.Y = unit->Orders[0].Y;
unit->Orders[0].Y = tmp;
NewResetPath(unit);
}

View file

@ -64,7 +64,7 @@ void HandleActionResearch(Unit* unit)
const Upgrade* upgrade;
if (!unit->SubAction) { // first entry
upgrade = unit->Data.Research.Upgrade = unit->Orders[0].Arg1;
upgrade = unit->Data.Research.Upgrade = unit->Orders[0].Arg1.Upgrade;
#if 0
// FIXME: I want to support both, but with network we need this check
// but if want combined upgrades this is worse
@ -72,7 +72,7 @@ void HandleActionResearch(Unit* unit)
//
// Check if an other building has already started?
//
if (unit->Player->UpgradeTimers.Upgrades[upgrade-Upgrades]) {
if (unit->Player->UpgradeTimers.Upgrades[upgrade - Upgrades]) {
DebugPrint("Two researches running\n");
PlayerAddCosts(unit->Player, upgrade->Costs);

View file

@ -289,7 +289,7 @@ static void LoseResource(Unit* unit, const Unit* source)
//
// Remember were it mined, so it can look around for another resource.
//
unit->Orders[0].Arg1 = (void*)((unit->X << 16) | unit->Y);
unit->Orders[0].Arg1.ResourcePos = (unit->X << 16) | unit->Y;
unit->Orders[0].Goal = depot;
RefsIncrease(depot);
NewResetPath(unit);
@ -495,7 +495,7 @@ static int StopGathering(Unit* unit)
// Store resource position.
// FIXME: is this the best way?
unit->Orders[0].Arg1 = (void*)((unit->X << 16) | unit->Y);
unit->Orders[0].Arg1.ResourcePos = (unit->X << 16) | unit->Y;
#ifdef DEBUG
if (!unit->ResourcesHeld) {
@ -636,12 +636,12 @@ static int WaitInDepot(Unit* unit)
Assert(depot);
// Could be destroyed, but then we couldn't be in?
if (unit->Orders[0].Arg1 == (void*)-1) {
if (unit->Orders[0].Arg1.ResourcePos == -1) {
x = unit->X;
y = unit->Y;
} else {
x = (int)unit->Orders[0].Arg1 >> 16;
y = (int)unit->Orders[0].Arg1 & 0xFFFF;
x = unit->Orders[0].Arg1.ResourcePos >> 16;
y = unit->Orders[0].Arg1.ResourcePos & 0xFFFF;
}
// Range hardcoded. don't stray too far though
if (resinfo->TerrainHarvester) {
@ -684,6 +684,10 @@ static int WaitInDepot(Unit* unit)
void ResourceGiveUp(Unit* unit)
{
DebugPrint("Unit %d gave up on resource gathering.\n" _C_ unit->Slot);
if (unit->Orders[0].Goal) {
RefsDecrease(unit->Orders->Goal);
}
memset(unit->Orders, 0, sizeof(*unit->Orders));
unit->Orders[0].Action = UnitActionStill;
unit->Wait = 1;
unit->Reset = 1;
@ -695,10 +699,6 @@ void ResourceGiveUp(Unit* unit)
unit->ResourcesHeld = 0;
unit->CurrentResource = 0;
}
if (unit->Orders[0].Goal) {
RefsDecrease(unit->Orders->Goal);
unit->Orders[0].Goal = NoUnitP;
}
}
/**

View file

@ -36,6 +36,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stratagus.h"
#include "video.h"
@ -73,12 +74,20 @@ void HandleActionReturnGoods(Unit* unit)
unit->Type->ResInfo[unit->CurrentResource]->LoseResources)) {
DebugPrint("Unit can't return resources, it doesn't carry any.\n");
NotifyPlayer(unit->Player, NotifyYellow, unit->X, unit->Y, "No Resources to Return.");
if (unit->Orders[0].Goal) { // Depot (if not destroyed)
RefsDecrease(unit->Orders[0].Goal);
}
memset(unit->Orders, 0, sizeof(*unit->Orders));
unit->Orders[0].Action = UnitActionStill;
return;
}
// If depot was destroyed.
// Search for an another one.
if (!unit->Orders[0].Goal) {
if (!(destu = FindDeposit(unit, unit->X, unit->Y, 1000,
unit->CurrentResource))) {
memset(unit->Orders, 0, sizeof(*unit->Orders));
unit->Orders[0].Action = UnitActionStill;
return;
}
@ -89,9 +98,9 @@ void HandleActionReturnGoods(Unit* unit)
unit->Orders[0].Action = UnitActionResource;
// Somewhere on the way the loaded worker could have change Arg1
// Bummer, go get the closest resource to the depot
unit->Orders[0].Arg1 = (void*)-1;
unit->Orders[0].Arg1.ResourcePos = -1;
NewResetPath(unit);
unit->SubAction = 70;
unit->SubAction = 70; // FIXME : Define value.
unit->Wait = 1;
return;
}

View file

@ -133,9 +133,9 @@ static void SpellMoveToTarget(Unit* unit)
// FIXME: buildings could have directions
UnitHeadingFromDeltaXY(unit,
unit->Orders[0].X +
((SpellType*)unit->Orders[0].Arg1)->Range - unit->X,
unit->Orders[0].Arg1.Spell->Range - unit->X,
unit->Orders[0].Y +
((SpellType*)unit->Orders[0].Arg1)->Range - unit->Y);
unit->Orders[0].Arg1.Spell->Range - unit->Y);
}
unit->SubAction++; // cast the spell
return;
@ -145,7 +145,7 @@ static void SpellMoveToTarget(Unit* unit)
// just as close as possible, since the spell is centered
// on the caster anyway.
//
if ((spell = unit->Orders[0].Arg1)->Target == TargetSelf) {
if ((spell = unit->Orders[0].Arg1.Spell)->Target == TargetSelf) {
DebugPrint("Increase range for spellcast.");
unit->Orders->Range++;
} else {
@ -179,7 +179,7 @@ void HandleActionSpellCast(Unit* unit)
//
// Check if we can cast the spell.
//
spell = unit->Orders[0].Arg1;
spell = unit->Orders[0].Arg1.Spell;
if (!CanCastSpell(unit, spell, unit->Orders[0].Goal,
unit->Orders[0].X, unit->Orders[0].Y)) {
@ -214,7 +214,7 @@ void HandleActionSpellCast(Unit* unit)
unit->SubAction = 1;
// FALL THROUGH
case 1: // Move to the target.
if ((spell = unit->Orders[0].Arg1)->Range != INFINITE_RANGE) {
if ((spell = unit->Orders[0].Arg1.Spell)->Range != INFINITE_RANGE) {
SpellMoveToTarget(unit);
break;
} else {
@ -230,7 +230,7 @@ void HandleActionSpellCast(Unit* unit)
if (unit->Orders[0].Goal && !UnitVisibleAsGoal(unit->Orders->Goal, unit->Player)) {
unit->ReCast = 0;
} else {
spell = unit->Orders[0].Arg1;
spell = unit->Orders[0].Arg1.Spell;
unit->ReCast = SpellCast(unit, spell, unit->Orders[0].Goal,
unit->Orders[0].X, unit->Orders[0].Y);
}
@ -243,7 +243,7 @@ void HandleActionSpellCast(Unit* unit)
if (unit->Orders[0].Goal && !UnitVisibleAsGoal(unit->Orders->Goal, unit->Player)) {
unit->ReCast = 0;
} else {
spell = unit->Orders[0].Arg1;
spell = unit->Orders[0].Arg1.Spell;
unit->ReCast = SpellCast(unit, spell, unit->Orders[0].Goal,
unit->Orders[0].X, unit->Orders[0].Y);
}

View file

@ -130,6 +130,7 @@ static void RemoveOrder(Unit* unit, int order)
{
int i;
Assert(0 <= order && order < unit->OrderCount);
i = order;
while(i < unit->OrderCount - 1) {
unit->Orders[i] = unit->Orders[i + 1];
@ -139,11 +140,10 @@ static void RemoveOrder(Unit* unit, int order)
if (unit->OrderCount > 1) {
--unit->OrderCount;
} else {
Assert(i == 0);
memset(unit->Orders + i, 0, sizeof(*unit->Orders));
unit->Orders[i].Action = UnitActionStill;
unit->Orders[i].X = unit->Orders[i].Y = -1;
unit->SubAction = 0;
unit->Orders[i].Type = NULL;
unit->Orders[i].Arg1 = NULL;
}
}
@ -159,10 +159,9 @@ static void ClearSavedAction(Unit* unit)
{
ReleaseOrder(&unit->SavedOrder);
memset(&unit->SavedOrder, 0, sizeof(unit->SavedOrder));
unit->SavedOrder.Action = UnitActionStill; // clear saved action
unit->SavedOrder.X = unit->SavedOrder.Y = -1;
unit->SavedOrder.Type = NULL;
unit->SavedOrder.Arg1 = NULL;
}
/*----------------------------------------------------------------------------
@ -181,11 +180,11 @@ void CommandStopUnit(Unit* unit)
// Ignore that the unit could be removed.
order = GetNextOrder(unit, FlushCommands); // Flush them.
Assert(order);
memset(order, 0, sizeof(*order));
order->Action = UnitActionStill;
order->X = order->Y = -1;
order->Goal = NoUnitP;
order->Type = NULL;
order->Arg1 = NULL;
ReleaseOrder(&unit->SavedOrder);
ReleaseOrder(&unit->NewOrder);
unit->SavedOrder = unit->NewOrder = *order;
@ -267,11 +266,9 @@ void CommandStandGround(Unit* unit, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionStandGround;
order->X = order->Y = -1;
order->Goal = NoUnitP;
order->Type = NULL;
order->Arg1 = NULL;
ClearSavedAction(unit);
}
@ -297,6 +294,7 @@ void CommandFollow(Unit* unit, Unit* dest, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionFollow;
//
@ -307,16 +305,12 @@ void CommandFollow(Unit* unit, Unit* dest, int flush)
if (dest->Destroyed) {
order->X = dest->X + dest->Type->TileWidth / 2;
order->Y = dest->Y + dest->Type->TileHeight / 2;
order->Goal = NoUnitP;
order->Range = 0;
} else {
order->X = order->Y = -1;
order->Goal = dest;
RefsIncrease(dest);
order->Range = 1;
}
order->Type = NULL;
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -346,14 +340,12 @@ void CommandMove(Unit* unit, int x, int y, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionMove;
order->Goal = NoUnitP;
order->X = x;
order->Y = y;
order->Range = 0;
order->Type = NULL;
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -382,6 +374,7 @@ void CommandRepair(Unit* unit, int x, int y, Unit* dest, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionRepair;
//
@ -393,12 +386,8 @@ void CommandRepair(Unit* unit, int x, int y, Unit* dest, int flush)
if (dest->Destroyed) {
order->X = dest->X + dest->Type->TileWidth / 2;
order->Y = dest->Y + dest->Type->TileHeight / 2;
order->Goal = NoUnitP;
order->Range = 0;
order->Width = order->Height = 0;
} else {
order->X = order->Y = -1;
order->Width = order->Height = 0;
order->Goal = dest;
RefsIncrease(dest);
order->Range = unit->Type->RepairRange;
@ -406,11 +395,7 @@ void CommandRepair(Unit* unit, int x, int y, Unit* dest, int flush)
} else {
order->X = x;
order->Y = y;
order->Goal = NoUnitP;
order->Range = 0;
}
order->Type = NULL;
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -441,6 +426,7 @@ void CommandAttack(Unit* unit, int x, int y, Unit* attack, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionAttack;
if (attack) {
@ -452,8 +438,6 @@ void CommandAttack(Unit* unit, int x, int y, Unit* attack, int flush)
if (attack->Destroyed) {
order->X = attack->X + attack->Type->TileWidth / 2;
order->Y = attack->Y + attack->Type->TileHeight / 2;
order->Goal = NoUnitP;
order->Range = 0;
} else {
// Removed, Dying handled by action routine.
order->X = order->Y = -1;
@ -468,16 +452,12 @@ void CommandAttack(Unit* unit, int x, int y, Unit* attack, int flush)
order->Y = y;
order->Range = unit->Stats->AttackRange;
order->MinRange = unit->Type->MinAttackRange;
order->Goal = NoUnitP;
} else {
order->X = x;
order->Y = y;
order->Range = 0;
order->Goal = NoUnitP;
}
order->Type = NULL;
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -507,15 +487,13 @@ void CommandAttackGround(Unit* unit, int x, int y, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionAttackGround;
order->X = x;
order->Y = y;
order->Range = unit->Stats->AttackRange;
order->MinRange = unit->Type->MinAttackRange;
order->Goal = NoUnitP;
order->Type = NULL;
order->Arg1 = NULL;
DebugPrint("FIXME this next\n");
}
@ -549,16 +527,14 @@ void CommandPatrolUnit(Unit* unit, int x, int y, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionPatrol;
order->Goal = NoUnitP;
order->X = x;
order->Y = y;
order->Range = 0;
order->Type = NULL;
Assert(!(unit->X & ~0xFFFF) && !(unit->Y & ~0xFFFF));
// FIXME: BUG-ALERT: encode source into arg1 as two 16 bit values!
order->Arg1 = (void*)((unit->X << 16) | unit->Y);
order->Arg1.Patrol.X = unit->X;
order->Arg1.Patrol.Y = unit->Y;
}
ClearSavedAction(unit);
}
@ -594,14 +570,13 @@ void CommandBoard(Unit* unit, Unit* dest, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionBoard;
order->X = order->Y = -1;
order->Goal = dest;
RefsIncrease(dest);
order->Range = 1;
order->Type = NULL;
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -626,6 +601,7 @@ void CommandUnload(Unit* unit, int x, int y, Unit* what, int flush)
if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionUnload;
order->X = x;
@ -635,14 +611,10 @@ void CommandUnload(Unit* unit, int x, int y, Unit* what, int flush)
// Should be handled in action, but is not possible!
// Unit::Refs is used as timeout counter.
//
order->Goal = NoUnitP;
if (what && !what->Destroyed) {
order->Goal = what;
RefsIncrease(what);
}
order->Range = 0;
order->Type = NULL;
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -672,9 +644,9 @@ void CommandBuildBuilding(Unit* unit, int x, int y,
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionBuild;
order->Goal = NoUnitP;
order->X = x;
order->Y = y;
order->Width = what->TileWidth;
@ -686,17 +658,12 @@ void CommandBuildBuilding(Unit* unit, int x, int y,
if (what->ShoreBuilding && unit->Type->UnitType == UnitTypeLand) {
// Peon won't dive :-)
order->Range = 1;
} else {
order->Range = 0;
}
}
order->Type = what;
if (what->BuilderOutside) {
order->MinRange = 1;
} else {
order->MinRange = 0;
}
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -745,6 +712,7 @@ void CommandResourceLoc(Unit* unit, int x, int y, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionResource;
@ -769,9 +737,6 @@ void CommandResourceLoc(Unit* unit, int x, int y, int flush)
order->Y = ny;
order->Range = 1;
order->Goal = NoUnitP;
order->Type = NULL;
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -807,14 +772,13 @@ void CommandResource(Unit* unit, Unit* dest, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionResource;
order->X = order->Y = -1;
order->Goal = dest;
RefsIncrease(dest);
order->Range = 1;
order->Type = NULL;
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -847,10 +811,10 @@ void CommandReturnGoods(Unit* unit, Unit* goal, int flush)
} else if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionReturnGoods;
order->X = order->Y = -1;
order->Goal = NoUnitP;
//
// Destination could be killed. NETWORK!
//
@ -859,8 +823,6 @@ void CommandReturnGoods(Unit* unit, Unit* goal, int flush)
RefsIncrease(goal);
}
order->Range = 1;
order->Type = NULL;
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -900,12 +862,11 @@ void CommandTrainUnit(Unit* unit, UnitType* type,
if (!(order = GetNextOrder(unit, 0))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionTrain;
order->Type = type;
order->X = order->Y = -1;
order->Goal = NoUnitP;
order->Arg1 = NULL;
// FIXME: if you give quick an other order, the resources are lost!
PlayerSubUnitType(unit->Player, type);
}
@ -938,7 +899,7 @@ void CommandCancelTraining(Unit* unit, int slot, const UnitType* type)
unit->Orders[0].Type->Stats[unit->Player->Player].Costs,
CancelTrainingCostsFactor);
RemoveOrder(unit, 0);
}
}
unit->Data.Train.Ticks = 0;
unit->Wait = unit->Reset = 1; // immediately start next training
if (unit->Player == ThisPlayer && unit->Selected) {
@ -1007,15 +968,14 @@ void CommandUpgradeTo(Unit* unit, UnitType* type, int flush)
if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
// FIXME: if you give quick an other order, the resources are lost!
PlayerSubUnitType(unit->Player, type);
order->Action = UnitActionUpgradeTo;
order->X = order->Y = -1;
order->Goal = NoUnitP;
order->Type = type;
order->Arg1 = NULL;
}
ClearSavedAction(unit);
}
@ -1038,11 +998,10 @@ void CommandCancelUpgradeTo(Unit* unit)
unit->Orders[0].Type->Stats[unit->Player->Player].Costs,
CancelUpgradeCostsFactor);
memset(unit->Orders, 0, sizeof(*unit->Orders));
unit->Orders[0].Action = UnitActionStill;
unit->Orders[0].X = unit->Orders[0].Y = -1;
unit->Orders[0].Goal = NoUnitP;
unit->Orders[0].Type = NULL;
unit->Orders[0].Arg1 = NULL;
unit->SubAction = 0;
@ -1099,15 +1058,14 @@ void CommandResearch(Unit* unit, Upgrade* what, int flush)
if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
// FIXME: if you give quick an other order, the resources are lost!
PlayerSubCosts(unit->Player, what->Costs);
order->Action = UnitActionResearch;
order->X = order->Y = -1;
order->Goal = NoUnitP;
order->Type = NULL;
order->Arg1 = what;
order->Arg1.Upgrade = what;
}
ClearSavedAction(unit);
}
@ -1132,12 +1090,10 @@ void CommandCancelResearch(Unit* unit)
PlayerAddCostsFactor(unit->Player,upgrade->Costs,
CancelResearchCostsFactor);
memset(unit->Orders, 0, sizeof(*unit->Orders));
unit->Orders[0].Action = UnitActionStill;
unit->Orders[0].X = unit->Orders[0].Y = -1;
unit->Orders[0].Goal = NoUnitP;
unit->Orders[0].Type = NULL;
unit->Orders[0].Arg1 = NULL;
unit->SubAction = 0;
@ -1183,6 +1139,7 @@ void CommandSpellCast(Unit* unit, int x, int y, Unit* dest,
if (!(order = GetNextOrder(unit, flush))) {
return;
}
memset(order, 0, sizeof(*order));
order->Action = UnitActionSpellCast;
order->Range = spell->Range;
@ -1197,9 +1154,7 @@ void CommandSpellCast(Unit* unit, int x, int y, Unit* dest,
// FIXME: dest->Type is now set to 0. maybe we shouldn't bother.
order->X = dest->X /*+ dest->Type->TileWidth / 2*/ - order->Range;
order->Y = dest->Y /*+ dest->Type->TileHeight / 2*/ - order->Range;
order->Goal = NoUnitP;
order->Range <<= 1;
order->Range <<= 1;
order->Range <<= 2;
} else {
order->X = order->Y = -1;
order->Goal = dest;
@ -1210,8 +1165,7 @@ void CommandSpellCast(Unit* unit, int x, int y, Unit* dest,
order->Y = y;
order->Range <<= 1;
}
order->Type = NULL;
order->Arg1 = spell;
order->Arg1.Spell = spell;
}
ClearSavedAction(unit);
}

View file

@ -461,7 +461,16 @@ typedef struct _order_ {
int Y; ///< or Y tile coordinate of destination
struct _unit_type_* Type;///< Unit-type argument
void* Arg1; ///< Extra command argument
union {
struct {
int X; ///< X position for patroling.
int Y; ///< Y position for patroling.
} Patrol; ///< position.
int ResourcePos; ///< ResourcePos == (X<<16 | Y).
struct _spell_type_* Spell; ///< spell when casting.
struct _upgrade_* Upgrade; ///< upgrade.
struct _order_* Order; ///< FIXME : seems to be a hack for free memory.
} Arg1; ///< Extra command argument.
} Order;
/**

View file

@ -282,57 +282,35 @@ void CclParseOrder(lua_State* l, Order* order)
lua_pop(l, 1);
} else if (!strcmp(value, "patrol")) {
int x1;
int x2;
++j;
lua_rawgeti(l, -1, j + 1);
if (!lua_istable(l, -1) || luaL_getn(l, -1) != 2) {
LuaError(l, "incorrect argument");
}
lua_rawgeti(l, -1, 1);
x1 = LuaToNumber(l, -1);
order->Arg1.Patrol.X = LuaToNumber(l, -1);
lua_pop(l, 1);
lua_rawgeti(l, -1, 2);
x2 = LuaToNumber(l, -1);
order->Arg1.Patrol.Y = LuaToNumber(l, -1);
lua_pop(l, 1);
order->Arg1 = (void*)((x1 << 16) | x2);
lua_pop(l, 1);
} else if (!strcmp(value, "spell")) {
++j;
lua_rawgeti(l, -1, j + 1);
order->Arg1 = SpellTypeByIdent(LuaToString(l, -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 = UpgradeByIdent(LuaToString(l, -1));
order->Arg1.Upgrade = UpgradeByIdent(LuaToString(l, -1));
lua_pop(l, 1);
} else if (!strcmp(value, "mine")) {
int x1;
int x2;
++j;
lua_rawgeti(l, -1, j + 1);
if (!lua_istable(l, -1) || luaL_getn(l, -1) != 2) {
LuaError(l, "incorrect argument");
}
lua_rawgeti(l, -1, 1);
x1 = LuaToNumber(l, -1);
lua_pop(l, 1);
lua_rawgeti(l, -1, 2);
x2 = LuaToNumber(l, -1);
lua_pop(l, 1);
order->Arg1 = (void*)((x1 << 16) | x2);
lua_pop(l, 1);
} else if (!strcmp(value, "arg1")) {
++j;
lua_rawgeti(l, -1, j + 1);
order->Arg1 = (void*)(int)LuaToNumber(l, -1);
order->Arg1.ResourcePos = LuaToNumber(l, -1);
lua_pop(l, 1);
} else {

View file

@ -240,12 +240,12 @@ void ReleaseUnit(Unit* unit)
free(unit->CacheLinks);
if (ReleasedOrderHead) {
ReleasedOrderTail->Arg1 = unit->Orders;
ReleasedOrderTail->Arg1.Order = unit->Orders;
ReleasedOrderTail = unit->Orders;
unit->Orders->Arg1 = NULL;
unit->Orders->Arg1.Order = NULL;
} else {
ReleasedOrderHead = ReleasedOrderTail = unit->Orders;
unit->Orders->Arg1 = NULL;
unit->Orders->Arg1.Order = NULL;
}
unit->Orders->X = GameCycle + (NetworkMaxLag << 1); // could be reuse after this time
unit->Orders->Y = unit->TotalOrders; // store order count for when reused
@ -368,7 +368,7 @@ void InitUnit(Unit* unit, UnitType* type)
if (ReleasedOrderHead && (unsigned)ReleasedOrderHead->X < GameCycle) {
unit->Orders = ReleasedOrderHead;
unit->TotalOrders = ReleasedOrderHead->Y;
ReleasedOrderHead = (Order*)ReleasedOrderHead->Arg1;
ReleasedOrderHead = ReleasedOrderHead->Arg1.Order;
} else {
// No Available Orders in Memory, create new ones
unit->TotalOrders = DEFAULT_START_ORDERS;
@ -3547,23 +3547,28 @@ void SaveOrder(const Order* order, CLFile* file)
if (order->Type) {
CLprintf(file, " \"type\", \"%s\",", order->Type->Ident);
}
if (order->Arg1) {
// patrol=pos, research=upgrade, spell=spell
switch (order->Action) {
case UnitActionPatrol:
CLprintf(file, " \"patrol\", {%d, %d},",
(int)order->Arg1 >> 16, (int)order->Arg1 & 0xFFFF);
break;
case UnitActionSpellCast:
CLprintf(file, " \"spell\", \"%s\",", ((SpellType*)order->Arg1)->Ident);
break;
case UnitActionResearch:
CLprintf(file, " \"upgrade\", \"%s\",", ((Upgrade*)order->Arg1)->Ident);
break;
default:
CLprintf(file, " \"arg1\", %d,", (int)order->Arg1);
break;
}
// Extra arg.
switch (order->Action) {
case UnitActionPatrol:
CLprintf(file, " \"patrol\", {%d, %d},",
order->Arg1.Patrol.X, order->Arg1.Patrol.Y);
break;
case UnitActionSpellCast:
if (order->Arg1.Spell) {
CLprintf(file, " \"spell\", \"%s\",", order->Arg1.Spell->Ident);
}
break;
case UnitActionResearch:
if (order->Arg1.Upgrade) {
CLprintf(file, " \"upgrade\", \"%s\",", order->Arg1.Upgrade->Ident);
}
break;
case UnitActionResource :
case UnitActionReturnGoods :
CLprintf(file, " \"mine\", %d,", order->Arg1.ResourcePos);
break;
default:
break;
}
CLprintf(file, "}");
}
@ -3960,7 +3965,7 @@ void CleanUnits(void)
//
// Release memory of Orders in the release queue.
while ((order = ReleasedOrderHead)) {
ReleasedOrderHead = order->Arg1;
ReleasedOrderHead = order->Arg1.Order;
free(order);
}

View file

@ -1438,9 +1438,9 @@ static void ShowSingleOrder(const Unit* unit, int x1, int y1, const Order* order
VideoDrawLineClip(ColorGreen, x1, y1, x2, y2);
e_color = color = ColorBlue;
x1 = Map2ViewportX(CurrentViewport,
((int)order->Arg1) >> 16) + TileSizeX / 2;
order->Arg1.Patrol.X) + TileSizeX / 2;
y1 = Map2ViewportY(CurrentViewport,
((int)order->Arg1) & 0xFFFF) + TileSizeY / 2;
order->Arg1.Patrol.Y) + TileSizeY / 2;
dest = 1;
break;