Added transporter patch from Jarod
This commit is contained in:
parent
fd070ea619
commit
8408e1c47c
17 changed files with 133 additions and 50 deletions
|
@ -92,7 +92,7 @@ static int WaitForTransporter(Unit* unit)
|
|||
|
||||
trans = unit->Orders[0].Goal;
|
||||
|
||||
if (!trans || !trans->Type->Transporter) {
|
||||
if (!trans || !CanTransport(trans, unit)) {
|
||||
// FIXME: destination destroyed??
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name action_build.c - The build building action. */
|
||||
//
|
||||
|
|
|
@ -116,7 +116,7 @@ static int ActionMoveGeneric(Unit* unit, const Animation* anim)
|
|||
// Transporter (un)docking?
|
||||
//
|
||||
// FIXME: This is an ugly hack
|
||||
if (unit->Type->Transporter &&
|
||||
if (unit->Type->CanTransport &&
|
||||
((WaterOnMap(unit->X, unit->Y) &&
|
||||
CoastOnMap(unit->X + xd, unit->Y + yd)) ||
|
||||
(CoastOnMap(unit->X, unit->Y) &&
|
||||
|
|
|
@ -67,7 +67,7 @@ void ActionStillGeneric(Unit* unit, int ground)
|
|||
// If unit is not bunkered and removed, wait
|
||||
//
|
||||
if (unit->Removed && (!unit->Container ||
|
||||
!unit->Container->Type->Transporter ||
|
||||
!unit->Container->Type->CanTransport ||
|
||||
!unit->Container->Type->AttackFromTransporter ||
|
||||
unit->Type->Missile.Missile->Class == MissileClassNone)) {
|
||||
// If peon is in building or unit is in transporter it is removed.
|
||||
|
|
|
@ -1489,7 +1489,7 @@ static int FindTransporterOnZone(int waterzone, ZoneSet* destzones,
|
|||
if (UnitUnusable(unit)) {
|
||||
continue;
|
||||
}
|
||||
if ((unsigned)unit->Type->UnitType != unitType || !unit->Type->Transporter) {
|
||||
if ((unsigned)unit->Type->UnitType != unitType || !unit->Type->CanTransport) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -503,6 +503,8 @@ int AiFindWall(AiForce* force)
|
|||
**
|
||||
** @todo Perfect planning.
|
||||
** Only works for water transporter!
|
||||
** @fixme transporter are more selective now (flag with unittypeland).
|
||||
** We must manage it.
|
||||
*/
|
||||
int AiPlanAttack(AiForce* force)
|
||||
{
|
||||
|
@ -526,7 +528,7 @@ int AiPlanAttack(AiForce* force)
|
|||
aiunit = force->Units;
|
||||
state = 1;
|
||||
while (aiunit) {
|
||||
if (aiunit->Unit->Type->Transporter) {
|
||||
if (aiunit->Unit->Type->CanTransport) {
|
||||
DebugPrint("Transporter #%d\n" _C_ UnitNumber(aiunit->Unit));
|
||||
AiMarkWaterTransporter(aiunit->Unit, watermatrix);
|
||||
state = 0;
|
||||
|
@ -543,7 +545,7 @@ int AiPlanAttack(AiForce* force)
|
|||
Unit* unit;
|
||||
|
||||
unit = AiPlayer->Player->Units[i];
|
||||
if (unit->Type->Transporter && UnitIdle(unit)) {
|
||||
if (unit->Type->CanTransport && UnitIdle(unit)) {
|
||||
DebugPrint("Assign any transporter\n");
|
||||
AiMarkWaterTransporter(unit, watermatrix);
|
||||
// FIXME: can be the wrong transporter.
|
||||
|
|
|
@ -874,10 +874,13 @@ extern int ViewPointDistanceToUnit(const Unit* dest);
|
|||
((player)->Allied & (1 << (dest)->Player->Player))
|
||||
/// Return true, if unit is shared vision with the player
|
||||
#define IsSharedVision(player, dest) \
|
||||
(( (player)->SharedVision & (1 << (dest)->Player->Player) ) && \
|
||||
( (dest)->Player->SharedVision & (1 << (player)->Player)))
|
||||
(((player)->SharedVision & (1 << (dest)->Player->Player)) && \
|
||||
((dest)->Player->SharedVision & (1 << (player)->Player)))
|
||||
/// Can this unit-type attack the other (destination)
|
||||
extern int CanTarget(const UnitType* type,const UnitType* dest);
|
||||
/// Can transporter transport the other unit
|
||||
extern int CanTransport(const Unit* transporter,const Unit* unit);
|
||||
|
||||
|
||||
/// Generate a unit reference, a printable unique string for unit
|
||||
extern char* UnitReference(const Unit*);
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name unitsound.h - The unit sounds headerfile. */
|
||||
//
|
||||
// (c) Copyright 1999,2001-2003 by Lutz Sammer, Fabrice Rossi,
|
||||
// and Jimmy Salmon
|
||||
// (c) Copyright 1999-2004 by Lutz Sammer, Fabrice Rossi,
|
||||
// and Jimmy Salmon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
|
@ -27,7 +27,7 @@
|
|||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
// $Id$
|
||||
// $Id$
|
||||
|
||||
#ifndef __UNITSOUND_H__
|
||||
#define __UNITSOUND_H__
|
||||
|
|
|
@ -698,6 +698,7 @@ struct _unit_type_ {
|
|||
int AutoBuildRate; ///< The rate at which the building builds itself
|
||||
int RandomMovementProbability; ///< Probability to move randomly.
|
||||
int ClicksToExplode; ///< Number of consecutive clicks until unit suicides.
|
||||
char* CanTransport; ///< Can transport units with this flag.
|
||||
int MaxOnBoard; ///< Number of Transporter slots.
|
||||
int StartingResources; ///< Amount of Resources on build
|
||||
/// @note original only visual effect, we do more with this!
|
||||
|
@ -733,7 +734,6 @@ struct _unit_type_ {
|
|||
unsigned PermanentCloak : 1; ///< Is only visible by CloakDetectors.
|
||||
unsigned DetectCloak : 1; ///< Can see Cloaked units.
|
||||
unsigned Coward : 1; ///< Unit will only attack if instructed.
|
||||
unsigned Transporter : 1; ///< Can transport units
|
||||
unsigned AttackFromTransporter : 1; ///< Can attack from transporter
|
||||
unsigned Vanishes : 1; ///< Corpes & destroyed places.
|
||||
unsigned GroundAttack : 1; ///< Can do command ground attack.
|
||||
|
|
|
@ -652,7 +652,7 @@ void UpdateButtonPanel(void)
|
|||
UpgradeIdentAllowed(player, buttonaction->ValueStr) == 'R';
|
||||
break;
|
||||
case ButtonUnload:
|
||||
allow = (Selected[0]->Type->Transporter && Selected[0]->BoardCount);
|
||||
allow = (Selected[0]->Type->CanTransport && Selected[0]->BoardCount);
|
||||
break;
|
||||
case ButtonCancel:
|
||||
allow = 1;
|
||||
|
|
|
@ -347,7 +347,7 @@ static void DrawUnitInfo(const Unit* unit)
|
|||
//
|
||||
// Draw unit kills and experience.
|
||||
//
|
||||
if (stats->Level && !(type->Transporter && unit->BoardCount)) {
|
||||
if (stats->Level && !(type->CanTransport && unit->BoardCount)) {
|
||||
sprintf(buf, "XP:~<%d~> Kills:~<%d~>", unit->XP, unit->Kills);
|
||||
VideoDrawTextCentered(x + 114, y + 8 + 15 + 33, GameFont, buf);
|
||||
}
|
||||
|
@ -462,7 +462,7 @@ static void DrawUnitInfo(const Unit* unit)
|
|||
//
|
||||
// Transporting units.
|
||||
//
|
||||
if (type->Transporter && unit->BoardCount) {
|
||||
if (type->CanTransport && unit->BoardCount) {
|
||||
int j;
|
||||
|
||||
if (TheUI.TransportingText) {
|
||||
|
|
|
@ -145,18 +145,21 @@ void DoRightButton(int sx, int sy)
|
|||
dest = NULL;
|
||||
}
|
||||
|
||||
// Don't allow stopping enemy transporters!
|
||||
if (dest && dest->Type->Transporter && !dest->Type->Building &&
|
||||
PlayersTeamed(ThisPlayer->Player, dest->Player->Player)) {
|
||||
// n0b0dy: So we are clicking on a transporter. We have to:
|
||||
// 1) Flush the transporters orders.
|
||||
// 2) Tell the transporter to follow the units. We have to queue all
|
||||
// these follow orders, so the transport will go and pick the up
|
||||
// 3) Tell all selected land units to go board the transporter.
|
||||
//
|
||||
// Here we flush the order queue
|
||||
SendCommandStopUnit(dest);
|
||||
desttransporter = dest;
|
||||
if (dest && dest->Type->CanTransport) {
|
||||
for (i = 0; i < NumSelected; i++) {
|
||||
if (CanTransport(dest, Selected[i])) {
|
||||
// We are clicking on a transporter. We have to:
|
||||
// 1) Flush the transporters orders.
|
||||
// 2) Tell the transporter to follow the units. We have to queue all
|
||||
// these follow orders, so the transport will go and pick them up
|
||||
// 3) Tell all selected land units to go board the transporter.
|
||||
|
||||
// Here we flush the order queue
|
||||
SendCommandStopUnit(dest);
|
||||
desttransporter = dest;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: the next should be rewritten, must select the units with
|
||||
|
@ -190,8 +193,7 @@ void DoRightButton(int sx, int sy)
|
|||
//
|
||||
// Enter transporters?
|
||||
//
|
||||
if (dest && dest->Type->Transporter && dest->Player == unit->Player &&
|
||||
unit->Type->UnitType == UnitTypeLand) {
|
||||
if (dest && CanTransport(dest, unit)) {
|
||||
dest->Blink = 4;
|
||||
DebugPrint("Board transporter\n");
|
||||
// Let the transporter move to the unit. And QUEUE!!!
|
||||
|
@ -427,7 +429,7 @@ static void HandleMouseOn(int x, int y)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (NumSelected == 1 && Selected[0]->Type->Transporter && Selected[0]->BoardCount &&
|
||||
if (NumSelected == 1 && Selected[0]->Type->CanTransport && Selected[0]->BoardCount &&
|
||||
!BigMapMode) {
|
||||
for (i = Selected[0]->BoardCount - 1; i >= 0; --i) {
|
||||
if (x >= TheUI.TransportingButtons[i].X &&
|
||||
|
@ -868,13 +870,18 @@ static int SendMove(int sx, int sy)
|
|||
int ret;
|
||||
|
||||
ret = 0;
|
||||
// Move to a transporter.
|
||||
if ((transporter = UnitUnderCursor) &&
|
||||
transporter->Type->Transporter &&
|
||||
(transporter->Player == ThisPlayer ||
|
||||
PlayersTeamed(ThisPlayer->Player, transporter->Player->Player))) {
|
||||
SendCommandStopUnit(transporter);
|
||||
ret = 1;
|
||||
// Move to a transporter.
|
||||
if ((transporter = UnitUnderCursor) && transporter->Type->CanTransport) {
|
||||
for (i = 0; i < NumSelected; ++i) {
|
||||
if (CanTransport(transporter, Selected[i])) {
|
||||
SendCommandStopUnit(transporter);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == NumSelected) {
|
||||
transporter = NULL;
|
||||
}
|
||||
} else {
|
||||
transporter = NULL;
|
||||
}
|
||||
|
@ -883,7 +890,7 @@ static int SendMove(int sx, int sy)
|
|||
|
||||
for (i = 0; i < NumSelected; ++i) {
|
||||
unit = Selected[i];
|
||||
if (transporter && unit->Type->UnitType == UnitTypeLand) {
|
||||
if (transporter && CanTransport(transporter, unit)) {
|
||||
transporter->Blink = 4;
|
||||
SendCommandFollow(transporter, unit, 0);
|
||||
SendCommandBoard(unit, -1, -1, transporter, flush);
|
||||
|
|
|
@ -497,8 +497,42 @@ static int CclDefineUnitType(lua_State* l)
|
|||
type->PermanentCloak = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(value, "DetectCloak")) {
|
||||
type->DetectCloak = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(value, "Transporter")) {
|
||||
type->Transporter = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(value, "CanTransport")) {
|
||||
//
|
||||
// Warning: CanTransport should only be used AFTER all bool flags
|
||||
// have been defined.
|
||||
//
|
||||
if (!lua_istable(l, -1)) {
|
||||
lua_pushstring(l, "incorrect argument");
|
||||
lua_error(l);
|
||||
}
|
||||
if (type->MaxOnBoard == 0) { // set default value.
|
||||
type->MaxOnBoard = 1;
|
||||
}
|
||||
if (!type->CanTransport) {
|
||||
type->CanTransport = calloc(NumberBoolFlag, sizeof(*type->CanTransport));
|
||||
}
|
||||
// FIXME : add flag for kill/unload units inside.
|
||||
subargs = luaL_getn(l, -1);
|
||||
for (k = 0; k < subargs; ++k) {
|
||||
lua_rawgeti(l, -1, k + 1);
|
||||
value = LuaToString(l, -1);
|
||||
lua_pop(l, 1);
|
||||
++k;
|
||||
for (i = 0; i < NumberBoolFlag; ++i) {
|
||||
if (!strcmp(value, BoolFlagName[i])) {
|
||||
lua_rawgeti(l, -1, k + 1);
|
||||
value = LuaToString(l, -1);
|
||||
lua_pop(l, 1);
|
||||
type->CanTransport[i] = Ccl2Condition(l, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != NumberBoolFlag) {
|
||||
continue;
|
||||
}
|
||||
LuaError(l, "Unsupported flag tag for CanTransport: %s" _C_ value);
|
||||
}
|
||||
} else if (!strcmp(value, "AttackFromTransporter")) {
|
||||
type->AttackFromTransporter = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(value, "Coward")) {
|
||||
|
@ -682,7 +716,6 @@ static int CclDefineUnitType(lua_State* l)
|
|||
if (i != NumberBoolFlag) {
|
||||
continue;
|
||||
}
|
||||
printf("\n%s\n", type->Name);
|
||||
LuaError(l, "Unsupported flag tag for can-target-flag: %s" _C_ value);
|
||||
}
|
||||
} else if (!strcmp(value, "SelectableByRectangle")) {
|
||||
|
|
|
@ -2625,7 +2625,8 @@ void LetUnitDie(Unit* unit)
|
|||
}
|
||||
|
||||
// Transporters lose their units
|
||||
if (unit->Type->Transporter) {
|
||||
if (unit->Type->CanTransport) {
|
||||
// FIXME: destroy or unload : do a flag.
|
||||
DestroyAllInside(unit);
|
||||
}
|
||||
|
||||
|
@ -2664,6 +2665,7 @@ void DestroyAllInside(Unit* source)
|
|||
// No Corpses, we are inside something, and we can't be seen
|
||||
unit = source->UnitInside;
|
||||
for (i = source->InsideCount; i; --i, unit = unit->NextContained) {
|
||||
// Transporter inside a transporter?
|
||||
if (unit->UnitInside) {
|
||||
DestroyAllInside(unit);
|
||||
}
|
||||
|
@ -3084,6 +3086,40 @@ int CanTarget(const UnitType* source, const UnitType* dest)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Can the transporter transport the other unit.
|
||||
**
|
||||
** @param transporter Unit which is the transporter.
|
||||
** @param unit Unit which wants to go in the transporter.
|
||||
**
|
||||
** @return 1 if transporter can transport unit, 0 else.
|
||||
*/
|
||||
int CanTransport(const Unit* transporter, const Unit* unit)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!transporter->Type->CanTransport || unit->Type->Building) {
|
||||
return 0;
|
||||
}
|
||||
if (transporter->BoardCount >= transporter->Type->MaxOnBoard) { // full
|
||||
return 0;
|
||||
}
|
||||
// FIXME: remove UnitTypeLand requirement
|
||||
if (PlayersTeamed(transporter->Player->Player, unit->Player->Player) &&
|
||||
unit->Type->UnitType != UnitTypeLand) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < NumberBoolFlag; i++) {
|
||||
if (transporter->Type->CanTransport[i] != CONDITION_TRUE) {
|
||||
if ((transporter->Type->CanTransport[i] == CONDITION_ONLY) ^
|
||||
unit->Type->BoolFlag[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- SAVE/LOAD
|
||||
----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -983,7 +983,7 @@ static void DrawDecoration(const Unit* unit, const UnitType* type, int x, int y)
|
|||
//
|
||||
// Transporter with units on board.
|
||||
//
|
||||
} else if (unit->Type->Transporter) {
|
||||
} else if (unit->Type->CanTransport) {
|
||||
DrawManaBar(x, y, type, unit->Type->MaxOnBoard, unit->BoardCount);
|
||||
}
|
||||
}
|
||||
|
@ -1051,7 +1051,7 @@ static void DrawDecoration(const Unit* unit, const UnitType* type, int x, int y)
|
|||
//
|
||||
// Transporter with units on board.
|
||||
//
|
||||
} else if (unit->Type->Transporter) {
|
||||
} else if (unit->Type->CanTransport) {
|
||||
DrawManaSprite(x, y, type, unit->Type->MaxOnBoard, unit->BoardCount);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -317,7 +317,7 @@ Unit* TransporterOnMapTile(int tx, int ty)
|
|||
|
||||
n = UnitCacheOnTile(tx, ty, table);
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (table[i]->Type->Transporter) {
|
||||
if (table[i]->Type->CanTransport) {
|
||||
return table[i];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,7 +203,7 @@ void UpdateStats(int reset)
|
|||
MapFieldAirUnit; // already occuppied
|
||||
break;
|
||||
case UnitTypeNaval: // on water
|
||||
if (type->Transporter) {
|
||||
if (type->CanTransport) {
|
||||
type->MovementMask =
|
||||
MapFieldLandUnit |
|
||||
MapFieldSeaUnit |
|
||||
|
@ -481,7 +481,8 @@ void ParsePudUDTA(const char* udta, int length __attribute__((unused)))
|
|||
unittype->ResInfo[OilCost]->WaitAtDepot = 150;
|
||||
unittype->ResInfo[OilCost]->ResourceCapacity = 100;
|
||||
}
|
||||
unittype->Transporter = BIT(10, v);
|
||||
unittype->CanTransport = BIT(10, v) ?
|
||||
calloc(NumberBoolFlag, sizeof(*unittype->CanTransport)) : NULL;
|
||||
unittype->CanStore[GoldCost] = BIT(12, v);
|
||||
unittype->Vanishes = BIT(13, v);
|
||||
unittype->GroundAttack = BIT(14, v);
|
||||
|
@ -931,6 +932,7 @@ void CleanUnitTypes(void)
|
|||
|
||||
free(type->BoolFlag);
|
||||
free(type->CanTargetFlag);
|
||||
free(type->CanTransport);
|
||||
|
||||
if (type->SameSprite) {
|
||||
free(type->SameSprite);
|
||||
|
|
Loading…
Add table
Reference in a new issue