Fix for transporters as depots. Proper actions.c Destroyed unit filtering.
This commit is contained in:
parent
ef8fb86b5f
commit
7df397f398
13 changed files with 95 additions and 80 deletions
|
@ -156,8 +156,10 @@ local void EnterTransporter(Unit* unit)
|
|||
// Place the unit inside the transporter.
|
||||
//
|
||||
|
||||
if (transporter->InsideCount < transporter->Type->MaxOnBoard) {
|
||||
RemoveUnit(unit, transporter);
|
||||
if (transporter->BoardCount < transporter->Type->MaxOnBoard) {
|
||||
RemoveUnit(unit, transporter);
|
||||
transporter->BoardCount++;
|
||||
unit->Boarded = 1;
|
||||
if (!unit->Player->AiEnabled) {
|
||||
// Don't make anything funny after going out of the transporter.
|
||||
// FIXME: This is probably wrong, but it works for me (n0b0dy)
|
||||
|
@ -165,7 +167,7 @@ local void EnterTransporter(Unit* unit)
|
|||
unit->Orders[0].Action = UnitActionStill;
|
||||
}
|
||||
|
||||
if (IsOnlySelected(transporter)) {
|
||||
if (IsOnlySelected(transporter)) {
|
||||
SelectedUnitChanged();
|
||||
MustRedraw |= RedrawInfoPanel;
|
||||
}
|
||||
|
|
|
@ -441,7 +441,9 @@ local int GatherResource(Unit* unit)
|
|||
//
|
||||
LoseResource(unit,source);
|
||||
for (i = source->InsideCount; i; --i, uins = uins->NextContained) {
|
||||
LoseResource(uins,source);
|
||||
if (uins->Orders->Action == UnitActionResource) {
|
||||
LoseResource(uins,source);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't destroy the resource twice.
|
||||
|
|
|
@ -156,6 +156,7 @@ global int UnloadUnit(Unit* unit)
|
|||
unit->X = x;
|
||||
unit->Y = y;
|
||||
unit->Wait = 1; // should be correct unit has still action
|
||||
unit->Boarded = 0;
|
||||
PlaceUnit(unit, x, y);
|
||||
return 1;
|
||||
}
|
||||
|
@ -344,15 +345,21 @@ local void LeaveTransporter(Unit* unit)
|
|||
goal->X = unit->X;
|
||||
goal->Y = unit->Y;
|
||||
// Try to unload the unit. If it doesn't work there is no problem.
|
||||
UnloadUnit(goal);
|
||||
if (UnloadUnit(goal)) {
|
||||
unit->BoardCount--;
|
||||
}
|
||||
} else {
|
||||
// Unload all units.
|
||||
goal = unit->UnitInside;
|
||||
for (i = unit->InsideCount; i; --i, goal = goal->NextContained) {
|
||||
goal->X = unit->X;
|
||||
goal->Y = unit->Y;
|
||||
if (!UnloadUnit(goal)) {
|
||||
++stillonboard;
|
||||
if (goal->Boarded) {
|
||||
goal->X = unit->X;
|
||||
goal->Y = unit->Y;
|
||||
if (!UnloadUnit(goal)) {
|
||||
++stillonboard;
|
||||
} else {
|
||||
unit->BoardCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
----------------------------------------------------------------------------*/
|
||||
|
||||
global unsigned SyncHash; /// Hash calculated to find sync failures
|
||||
#define DEBUG_ACTIONS
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
|
@ -494,25 +495,11 @@ global void UnitActions(void)
|
|||
int i;
|
||||
int tabsize;
|
||||
|
||||
buffsthiscycle = regenthiscycle =
|
||||
blinkthiscycle = !(GameCycle % CYCLES_PER_SECOND);
|
||||
buffsthiscycle = regenthiscycle = blinkthiscycle =
|
||||
!(GameCycle % CYCLES_PER_SECOND);
|
||||
|
||||
//
|
||||
// Must copy table, units could be removed.
|
||||
//
|
||||
memcpy(table, Units, sizeof(Unit*) * NumUnits);
|
||||
|
||||
//
|
||||
// Check for dead/destroyed units in table...
|
||||
// Filter them out
|
||||
//
|
||||
for (i = tabsize = 0; i < NumUnits; ++i) {
|
||||
if (!table[i]->Destroyed) { // Ignore destroyed units
|
||||
table[tabsize++] = table[i];
|
||||
} else {
|
||||
DebugLevel3Fn("Destroyed unit %d in table, should be ok\n" _C_ table[i]->Slot);
|
||||
}
|
||||
}
|
||||
memcpy(table, Units, NumUnits * sizeof(Unit*));
|
||||
tabsize = NumUnits;
|
||||
|
||||
//
|
||||
// Check for things that only happen every few cycles
|
||||
|
@ -522,6 +509,9 @@ global void UnitActions(void)
|
|||
// 1) Blink flag.
|
||||
if (blinkthiscycle) {
|
||||
for (i = 0; i < tabsize; ++i) {
|
||||
while(table[i]->Destroyed) {
|
||||
table[i] = table[--tabsize];
|
||||
}
|
||||
if (table[i]->Blink) {
|
||||
--table[i]->Blink;
|
||||
}
|
||||
|
@ -531,22 +521,20 @@ global void UnitActions(void)
|
|||
// 2) Buffs...
|
||||
if (buffsthiscycle) {
|
||||
for (i = 0; i < tabsize; ++i) {
|
||||
HandleBuffs(table[i], CYCLES_PER_SECOND);
|
||||
if (table[i]->Destroyed) {
|
||||
while(table[i]->Destroyed) {
|
||||
table[i] = table[--tabsize];
|
||||
--i;
|
||||
}
|
||||
HandleBuffs(table[i], CYCLES_PER_SECOND);
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Increase health mana, burn and stuff
|
||||
if (regenthiscycle) {
|
||||
for (i = 0; i < tabsize; ++i) {
|
||||
HandleRegenerations(table[i]);
|
||||
if (table[i]->Destroyed) {
|
||||
while(table[i]->Destroyed) {
|
||||
table[i] = table[--tabsize];
|
||||
--i;
|
||||
}
|
||||
HandleRegenerations(table[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -554,6 +542,9 @@ global void UnitActions(void)
|
|||
// Do all actions
|
||||
//
|
||||
for (i = 0; i < tabsize; ++i) {
|
||||
while(table[i]->Destroyed) {
|
||||
table[i] = table[--tabsize];
|
||||
}
|
||||
unit = table[i];
|
||||
|
||||
if (--unit->Wait) { // Wait until counter reached
|
||||
|
|
|
@ -1510,7 +1510,7 @@ local int FindTransporterOnZone(int waterzone, ZoneSet* destzones,
|
|||
|
||||
result = 1;
|
||||
|
||||
if (unit->InsideCount >= unit->Type->MaxOnBoard) {
|
||||
if (unit->BoardCount >= unit->Type->MaxOnBoard) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1531,7 +1531,7 @@ local int FindTransporterOnZone(int waterzone, ZoneSet* destzones,
|
|||
unit->OrderCount < MAX_ORDERS - 1 &&
|
||||
unit->Orders[unit->OrderFlush ? 1 : 0].Action == UnitActionFollow &&
|
||||
unit->Orders[unit->OrderCount - 1].Action == UnitActionUnload &&
|
||||
unit->InsideCount + unit->OrderCount - (unit->OrderFlush ? 1 : 0) <= unit->Type->MaxOnBoard) {
|
||||
unit->BoardCount + unit->OrderCount - (unit->OrderFlush ? 1 : 0) <= unit->Type->MaxOnBoard) {
|
||||
|
||||
// Check that it will unload in the dest zone
|
||||
ZoneSetClear(&TransporterZones);
|
||||
|
|
|
@ -110,10 +110,13 @@
|
|||
**
|
||||
** Unit::InsideCount
|
||||
**
|
||||
** The number of units inside the container. This used to be
|
||||
** Value for transporters, but since gold mines also use this
|
||||
** field, it has changed to InsideCount, to allow counting
|
||||
** units inside a gold mine.)
|
||||
** The number of units inside the container.
|
||||
**
|
||||
** Unit::BoardCount
|
||||
**
|
||||
** The number of units transported inside the container. This
|
||||
** does not include for instance stuff like harvesters returning
|
||||
** cargo.
|
||||
**
|
||||
** Unit::Name
|
||||
**
|
||||
|
@ -243,6 +246,10 @@
|
|||
** 01 The building in being built when last seen.
|
||||
** 10 The building was been upgraded when last seen.
|
||||
**
|
||||
** Unit::Boarded
|
||||
**
|
||||
** This is 1 if the unit is on board a transporter.
|
||||
**
|
||||
** Unit::Mana
|
||||
**
|
||||
**
|
||||
|
@ -516,6 +523,7 @@ struct _unit_ {
|
|||
#endif
|
||||
|
||||
int InsideCount; /// Number of units inside.
|
||||
int BoardCount; /// Number of units transported inside.
|
||||
Unit* UnitInside; /// Pointer to one of the units inside.
|
||||
Unit* Container; /// Pointer to the unit containing it (or 0)
|
||||
Unit* NextContained; /// Next unit in the container.
|
||||
|
@ -547,6 +555,7 @@ struct _unit_ {
|
|||
|
||||
unsigned Constructed : 1; /// Unit is in construction
|
||||
unsigned Active : 1; /// Unit is active for AI
|
||||
unsigned Boarded : 1; /// Unit is on board a transporter.
|
||||
Player* RescuedFrom; /// The original owner of a rescued unit.
|
||||
/// NULL if the unit was not rescued.
|
||||
/* Seen stuff. */
|
||||
|
|
|
@ -742,7 +742,7 @@ local int CclGetPlayerResource(lua_State* l)
|
|||
}
|
||||
if (i == MaxCosts) {
|
||||
// FIXME: this leaves a half initialized player
|
||||
lua_pushfstring(l, "Invalid resource", res);
|
||||
lua_pushfstring(l, "Invalid resource \"%s\"", res);
|
||||
lua_error(l);
|
||||
}
|
||||
lua_pushnumber(l, plyr->Resources[i]);
|
||||
|
|
|
@ -803,7 +803,7 @@ global void UpdateButtonPanel(void)
|
|||
UpgradeIdentAllowed(player, buttonaction->ValueStr) == 'R';
|
||||
break;
|
||||
case ButtonUnload:
|
||||
allow = (Selected[0]->Type->Transporter && Selected[0]->InsideCount);
|
||||
allow = (Selected[0]->Type->Transporter && Selected[0]->BoardCount);
|
||||
break;
|
||||
case ButtonCancel:
|
||||
allow = 1;
|
||||
|
|
|
@ -294,7 +294,7 @@ global void DrawUnitInfo(const Unit* unit)
|
|||
//
|
||||
// Draw unit kills and experience.
|
||||
//
|
||||
if (stats->Level && !(type->Transporter && unit->InsideCount)) {
|
||||
if (stats->Level && !(type->Transporter && unit->BoardCount)) {
|
||||
sprintf(buf, "XP:~<%d~> Kills:~<%d~>", unit->XP, unit->Kills);
|
||||
VideoDrawTextCentered(x + 114, y + 8 + 15 + 33, GameFont, buf);
|
||||
}
|
||||
|
@ -406,6 +406,33 @@ global void DrawUnitInfo(const Unit* unit)
|
|||
}
|
||||
}
|
||||
|
||||
if (type->Transporter && unit->BoardCount) {
|
||||
int j;
|
||||
|
||||
if (TheUI.TransportingText) {
|
||||
VideoDrawText(TheUI.TransportingTextX, TheUI.TransportingTextY,
|
||||
TheUI.TransportingFont, TheUI.TransportingText);
|
||||
}
|
||||
uins = unit->UnitInside;
|
||||
for (i = j = 0; i < unit->InsideCount; ++i, uins = uins->NextContained) {
|
||||
if (uins->Boarded) {
|
||||
DrawUnitIcon(unit->Player,uins->Type->Icon.Icon,
|
||||
(ButtonAreaUnderCursor == ButtonAreaTransporting && ButtonUnderCursor == j) ?
|
||||
(IconActive | (MouseButtons & LeftButton)) : 0,
|
||||
TheUI.TransportingButtons[j].X, TheUI.TransportingButtons[j].Y);
|
||||
UiDrawLifeBar(uins, TheUI.TransportingButtons[j].X, TheUI.TransportingButtons[j].Y);
|
||||
if (uins->Type->CanCastSpell && unit->Type->_MaxMana) {
|
||||
UiDrawManaBar(uins, TheUI.TransportingButtons[j].X, TheUI.TransportingButtons[j].Y);
|
||||
}
|
||||
if (ButtonAreaUnderCursor == ButtonAreaTransporting && ButtonUnderCursor == j) {
|
||||
SetStatusLine(uins->Type->Name);
|
||||
}
|
||||
++j;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vpos = 77; // Start of resource drawing
|
||||
for (i = 1; i < MaxCosts; ++i) {
|
||||
if (type->CanStore[i]) {
|
||||
|
@ -432,28 +459,6 @@ global void DrawUnitInfo(const Unit* unit)
|
|||
return;
|
||||
}
|
||||
|
||||
if (type->Transporter && unit->InsideCount) {
|
||||
if (TheUI.TransportingText) {
|
||||
VideoDrawText(TheUI.TransportingTextX, TheUI.TransportingTextY,
|
||||
TheUI.TransportingFont, TheUI.TransportingText);
|
||||
}
|
||||
uins = unit->UnitInside;
|
||||
for (i = 0; i < unit->InsideCount; ++i, uins = uins->NextContained) {
|
||||
DrawUnitIcon(unit->Player,uins->Type->Icon.Icon,
|
||||
(ButtonAreaUnderCursor == ButtonAreaTransporting && ButtonUnderCursor == i) ?
|
||||
(IconActive | (MouseButtons & LeftButton)) : 0,
|
||||
TheUI.TransportingButtons[i].X, TheUI.TransportingButtons[i].Y);
|
||||
UiDrawLifeBar(uins, TheUI.TransportingButtons[i].X, TheUI.TransportingButtons[i].Y);
|
||||
if (uins->Type->CanCastSpell && unit->Type->_MaxMana) {
|
||||
UiDrawManaBar(uins, TheUI.TransportingButtons[i].X, TheUI.TransportingButtons[i].Y);
|
||||
}
|
||||
if (ButtonAreaUnderCursor == ButtonAreaTransporting && ButtonUnderCursor == i) {
|
||||
SetStatusLine(uins->Type->Name);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (type->Building && !type->CanAttack) {
|
||||
if (type->Supply) { // Supply unit
|
||||
VideoDrawText(x + 16, y + 8 + 63, GameFont, "Usage");
|
||||
|
|
|
@ -431,8 +431,8 @@ local void HandleMouseOn(int x, int y)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (NumSelected == 1 && Selected[0]->Type->Transporter && Selected[0]->InsideCount) {
|
||||
for (i = Selected[0]->InsideCount - 1; i >= 0; --i) {
|
||||
if (NumSelected == 1 && Selected[0]->Type->Transporter && Selected[0]->BoardCount) {
|
||||
for (i = Selected[0]->BoardCount - 1; i >= 0; --i) {
|
||||
if (x >= TheUI.TransportingButtons[i].X &&
|
||||
x < TheUI.TransportingButtons[i].X + TheUI.TransportingButtons[i].Width + 7 &&
|
||||
y >= TheUI.TransportingButtons[i].Y &&
|
||||
|
@ -460,7 +460,7 @@ local void HandleMouseOn(int x, int y)
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < TheUI.NumTrainingButtons; ++i) {
|
||||
for (i = TheUI.NumTrainingButtons; i >= 0; --i) {
|
||||
if (x >= TheUI.TrainingButtons[i].X &&
|
||||
x < TheUI.TrainingButtons[i].X + TheUI.TrainingButtons[i].Width + 7 &&
|
||||
y >= TheUI.TrainingButtons[i].Y &&
|
||||
|
@ -1618,13 +1618,14 @@ global void UIHandleButtonDown(unsigned button)
|
|||
//
|
||||
if (!GameObserve && !GamePaused &&
|
||||
PlayersTeamed(ThisPlayer->Player, Selected[0]->Player->Player)) {
|
||||
if (Selected[0]->InsideCount >= ButtonUnderCursor) {
|
||||
// FIXME: should check if valid here.
|
||||
// n0b0dy: check WHAT?
|
||||
if (Selected[0]->BoardCount >= ButtonUnderCursor) {
|
||||
uins = Selected[0]->UnitInside;
|
||||
for (i = 0; i < ButtonUnderCursor; ++i) {
|
||||
uins = uins->NextContained;
|
||||
for (i = ButtonUnderCursor; i; uins = uins->NextContained) {
|
||||
if (uins->Boarded) {
|
||||
--i;
|
||||
}
|
||||
}
|
||||
DebugCheck(!uins->Boarded);
|
||||
SendCommandUnload(Selected[0],
|
||||
Selected[0]->X, Selected[0]->Y, uins,
|
||||
!(KeyModifiers & ModifierShift));
|
||||
|
|
|
@ -633,7 +633,6 @@ local int CclUnit(lua_State* l)
|
|||
Player* player;
|
||||
int slot;
|
||||
int i;
|
||||
int insidecount;
|
||||
const char* s;
|
||||
int args;
|
||||
int j;
|
||||
|
@ -641,7 +640,6 @@ local int CclUnit(lua_State* l)
|
|||
args = lua_gettop(l);
|
||||
j = 0;
|
||||
|
||||
insidecount = -1;
|
||||
slot = LuaToNumber(l, j + 1);
|
||||
++j;
|
||||
DebugLevel3Fn("parsing unit #%d\n" _C_ slot);
|
||||
|
@ -860,8 +858,8 @@ local int CclUnit(lua_State* l)
|
|||
--j;
|
||||
} else if (!strcmp(value, "rs")) {
|
||||
unit->Rs = LuaToNumber(l, j + 1);
|
||||
} else if (!strcmp(value, "units-contained-count")) {
|
||||
insidecount = LuaToNumber(l, j + 1);
|
||||
} else if (!strcmp(value, "units-boarded-count")) {
|
||||
unit->BoardCount = LuaToNumber(l, j + 1);
|
||||
} else if (!strcmp(value, "units-contained")) {
|
||||
int subargs;
|
||||
int k;
|
||||
|
|
|
@ -3632,7 +3632,7 @@ global void SaveUnit(const Unit* unit, CLFile* file)
|
|||
CLprintf(file, " \"moving\",");
|
||||
}
|
||||
CLprintf(file, " \"rs\", %d,", unit->Rs);
|
||||
CLprintf(file, " \"units-contained-count\", %d,", unit->InsideCount);
|
||||
CLprintf(file, " \"units-boarded-count\", %d,", unit->BoardCount);
|
||||
CLprintf(file, "\n \"units-contained\", {");
|
||||
uins = unit->UnitInside;
|
||||
for (i = unit->InsideCount; i; --i, uins = uins->NextContained) {
|
||||
|
|
|
@ -1041,7 +1041,7 @@ local void DrawDecoration(const Unit* unit, const UnitType* type, int x, int y)
|
|||
// Transporter with units on board.
|
||||
//
|
||||
} else if (unit->Type->Transporter) {
|
||||
DrawManaBar(x, y, type, unit->Type->MaxOnBoard, unit->InsideCount);
|
||||
DrawManaBar(x, y, type, unit->Type->MaxOnBoard, unit->BoardCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1109,7 +1109,7 @@ local void DrawDecoration(const Unit* unit, const UnitType* type, int x, int y)
|
|||
// Transporter with units on board.
|
||||
//
|
||||
} else if (unit->Type->Transporter) {
|
||||
DrawManaSprite(x, y, type, unit->Type->MaxOnBoard, unit->InsideCount);
|
||||
DrawManaSprite(x, y, type, unit->Type->MaxOnBoard, unit->BoardCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1635,7 +1635,7 @@ local void DrawInformations(const Unit* unit, const UnitType* type, int x, int y
|
|||
const UnitStats* stats;
|
||||
int r;
|
||||
|
||||
#if 1 // This is for showing vis counts and refs.
|
||||
#if 0 && DEBUG // This is for showing vis counts and refs.
|
||||
char buf[10];
|
||||
sprintf(buf, "%d%c%c%d", unit->VisCount[ThisPlayer->Player],
|
||||
unit->Seen.ByPlayer & (1 << ThisPlayer->Player) ? 'Y' : 'N',
|
||||
|
|
Loading…
Add table
Reference in a new issue