Fix for transporters as depots. Proper actions.c Destroyed unit filtering.

This commit is contained in:
nobody_ 2004-01-30 14:02:51 +00:00
parent ef8fb86b5f
commit 7df397f398
13 changed files with 95 additions and 80 deletions

View file

@ -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;
}

View file

@ -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.

View file

@ -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--;
}
}
}
}

View file

@ -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

View file

@ -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);

View file

@ -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. */

View file

@ -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]);

View file

@ -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;

View file

@ -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");

View file

@ -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));

View file

@ -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;

View file

@ -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) {

View file

@ -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',