Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: Warzone2100/warzone2100
base: 19be9fc
...
head fork: Warzone2100/warzone2100
compare: 06e161a
  • 5 commits
  • 8 files changed
  • 0 commit comments
  • 1 contributor
Commits on Feb 28, 2012
@Cyp Cyp Reduce tank dancing.
In moveShuffleDroid(), do not iterate over all of own droids on map (optimisation), but
include other player's droids (change).

In moveReachedWayPoint(), increase tolerance of final waypoint, if the droid's path is
blocked, since the most likely cause of the blockage is other droids trying to going to
the same place.

Patrol is no longer useless in groups of 4-or-so or more droids.

Fixes ticket:2996.
0b7605c
@Cyp Cyp Clean up actionVTOLLandingPos() interface.
Program logic should be unchanged.
ce3e76c
@Cyp Cyp Do not land all 150 VTOLs on the same tile. 9dcf5bd
@Cyp Cyp Make "Go to Transport" button work sensibly.
Droids now go to the nearest transport that they can fit in. Even if they're not
cyborgs. And even if there's a transporter on the other side of the map that they
could go to, instead of going to the one standing right next to them.
2d938a0
@Cyp Cyp Do not complain to all players in game, on attempted loading of tank …
…on cyborg transport.

Announcing to everyone makes surprise attacks with transports harder, if accidentally
telling a tank to go onto a transport.
06e161a
View
33 src/action.cpp
@@ -2120,16 +2120,15 @@ void actionUpdateDroid(DROID *psDroid)
if (DROID_STOPPED(psDroid) ||
(psDroid->action == DACTION_WAITFORREARM))
{
- UDWORD droidX = psDroid->psActionTarget[0]->pos.x;
- UDWORD droidY = psDroid->psActionTarget[0]->pos.y;
- if (!actionVTOLLandingPos(psDroid, &droidX, &droidY))
+ Vector2i pos = removeZ(psDroid->psActionTarget[0]->pos);
+ if (!actionVTOLLandingPos(psDroid, &pos))
{
// totally bunged up - give up
objTrace(psDroid->id, "Couldn't find a clear tile near rearm pad - returning to base");
orderDroid(psDroid, DORDER_RTB, ModeImmediate);
break;
}
- moveDroidToDirect(psDroid, droidX,droidY);
+ moveDroidToDirect(psDroid, pos.x, pos.y);
}
break;
default:
@@ -2174,7 +2173,7 @@ static void actionDroidBase(DROID *psDroid, DROID_ACTION_DATA *psAction)
{
SDWORD pbx,pby;
WEAPON_STATS *psWeapStats = getWeaponStats(psDroid, 0);
- UDWORD droidX,droidY;
+ Vector2i pos;
BASE_OBJECT *psTarget;
//added MinRangeResult;
UBYTE i;
@@ -2304,29 +2303,27 @@ static void actionDroidBase(DROID *psDroid, DROID_ACTION_DATA *psAction)
psDroid->actionPos = psAction->psObj->pos;
psDroid->actionStarted = gameTime;
setDroidActionTarget(psDroid, psAction->psObj, 0);
- droidX = psDroid->psActionTarget[0]->pos.x;
- droidY = psDroid->psActionTarget[0]->pos.y;
- if (!actionVTOLLandingPos(psDroid, &droidX, &droidY))
+ pos = removeZ(psDroid->psActionTarget[0]->pos);
+ if (!actionVTOLLandingPos(psDroid, &pos))
{
// totally bunged up - give up
orderDroid(psDroid, DORDER_RTB, ModeImmediate);
break;
}
- moveDroidToDirect(psDroid, droidX, droidY);
+ moveDroidToDirect(psDroid, pos.x, pos.y);
break;
case DACTION_CLEARREARMPAD:
debug( LOG_NEVER, "Unit %d clearing rearm pad", psDroid->id);
psDroid->action = DACTION_CLEARREARMPAD;
setDroidActionTarget(psDroid, psAction->psObj, 0);
- droidX = psDroid->psActionTarget[0]->pos.x;
- droidY = psDroid->psActionTarget[0]->pos.y;
- if (!actionVTOLLandingPos(psDroid, &droidX, &droidY))
+ pos = removeZ(psDroid->psActionTarget[0]->pos);
+ if (!actionVTOLLandingPos(psDroid, &pos))
{
// totally bunged up - give up
orderDroid(psDroid, DORDER_RTB, ModeImmediate);
break;
}
- moveDroidToDirect(psDroid, droidX, droidY);
+ moveDroidToDirect(psDroid, pos.x, pos.y);
break;
case DACTION_MOVE:
case DACTION_TRANSPORTIN:
@@ -2710,7 +2707,7 @@ static bool vtolLandingTileSearchFunction(int x, int y, void* matchState)
}
// choose a landing position for a VTOL when it goes to rearm
-bool actionVTOLLandingPos(const DROID* psDroid, UDWORD* px, UDWORD* py)
+bool actionVTOLLandingPos(DROID const *psDroid, Vector2i *p)
{
int startX, startY;
DROID* psCurr;
@@ -2720,8 +2717,8 @@ bool actionVTOLLandingPos(const DROID* psDroid, UDWORD* px, UDWORD* py)
CHECK_DROID(psDroid);
/* Initial box dimensions and set iteration count to zero */
- startX = map_coord(*px);
- startY = map_coord(*py);
+ startX = map_coord(p->x);
+ startY = map_coord(p->y);
// set blocking flags for all the other droids
for(psCurr=apsDroidLists[psDroid->player]; psCurr; psCurr = psCurr->psNext)
@@ -2751,8 +2748,8 @@ bool actionVTOLLandingPos(const DROID* psDroid, UDWORD* px, UDWORD* py)
{
debug( LOG_NEVER, "Unit %d landing pos (%d,%d)",
psDroid->id, xyCoords.x, xyCoords.y);
- *px = world_coord(xyCoords.x) + TILE_UNITS / 2;
- *py = world_coord(xyCoords.y) + TILE_UNITS / 2;
+ p->x = world_coord(xyCoords.x) + TILE_UNITS / 2;
+ p->y = world_coord(xyCoords.y) + TILE_UNITS / 2;
}
// clear blocking flags for all the other droids
View
2  src/action.h
@@ -96,7 +96,7 @@ bool actionReachedBuildPos(DROID const *psDroid, int x, int y, uint16_t directio
void moveToRearm(DROID *psDroid);
/** Choose a landing position for a VTOL when it goes to rearm. */
-bool actionVTOLLandingPos(const DROID* psDroid, UDWORD* px, UDWORD* py);
+bool actionVTOLLandingPos(DROID const *psDroid, Vector2i *p);
/** How many frames to skip before looking for a better target. */
#define TARGET_UPD_SKIP_FRAMES 1000
View
100 src/move.cpp
@@ -324,12 +324,10 @@ void moveTurnDroid(DROID *psDroid, UDWORD x, UDWORD y)
// Tell a droid to move out the way for a shuffle
static void moveShuffleDroid(DROID *psDroid, Vector2i s)
{
- DROID *psCurr;
SDWORD mx, my;
bool frontClear = true, leftClear = true, rightClear = true;
SDWORD lvx,lvy, rvx,rvy, svx,svy;
SDWORD shuffleMove;
- SDWORD tarX,tarY;
CHECK_DROID(psDroid);
@@ -344,14 +342,14 @@ static void moveShuffleDroid(DROID *psDroid, Vector2i s)
shuffleMove = SHUFFLE_MOVE;
// calculate the possible movement vectors
- lvx = -s.y * shuffleMove / shuffleMag;
- lvy = s.x * shuffleMove / shuffleMag;
+ svx = s.x * shuffleMove / shuffleMag; // Straight in the direction of s.
+ svy = s.y * shuffleMove / shuffleMag;
- rvx = s.y * shuffleMove / shuffleMag;
- rvy = -s.x * shuffleMove / shuffleMag;
+ lvx = -svy; // 90° to the... right?
+ lvy = svx;
- svx = lvy; // sx * SHUFFLE_MOVE / shuffleMag;
- svy = rvx; // sy * SHUFFLE_MOVE / shuffleMag;
+ rvx = svy; // 90° to the... left?
+ rvy = -svx;
// check for blocking tiles
if (fpathBlockingTile(map_coord((SDWORD)psDroid->pos.x + lvx),
@@ -371,26 +369,24 @@ static void moveShuffleDroid(DROID *psDroid, Vector2i s)
}
// find any droids that could block the shuffle
- // TODO Use mapgrid.h iterator.
- for(psCurr=apsDroidLists[psDroid->player]; psCurr; psCurr=psCurr->psNext)
+ gridStartIterate(psDroid->pos.x, psDroid->pos.y, SHUFFLE_DIST);
+ for (BASE_OBJECT *psCurr_ = gridIterate(); psCurr_ != NULL; psCurr_ = gridIterate())
{
- if (psCurr != psDroid)
+ DROID *psCurr = castDroid(psCurr_);
+ if (psCurr == NULL || psCurr->died || psCurr == psDroid)
{
- int32_t xdiff = psCurr->pos.x - psDroid->pos.x;
- int32_t ydiff = psCurr->pos.y - psDroid->pos.y;
- if (abs(xdiff) < SHUFFLE_DIST && abs(ydiff) < SHUFFLE_DIST && xdiff*xdiff + ydiff*ydiff < SHUFFLE_DIST*SHUFFLE_DIST)
- {
- uint16_t droidDir = iAtan2(xdiff, ydiff);
- int diff = angleDelta(shuffleDir - droidDir);
- if (diff > -DEG(135) && diff < -DEG(45))
- {
- leftClear = false;
- }
- else if (diff > DEG(45) && diff < DEG(135))
- {
- rightClear = false;
- }
- }
+ continue;
+ }
+
+ uint16_t droidDir = iAtan2(removeZ(psCurr->pos - psDroid->pos));
+ int diff = angleDelta(shuffleDir - droidDir);
+ if (diff > -DEG(135) && diff < -DEG(45))
+ {
+ leftClear = false;
+ }
+ else if (diff > DEG(45) && diff < DEG(135))
+ {
+ rightClear = false;
}
}
@@ -417,11 +413,10 @@ static void moveShuffleDroid(DROID *psDroid, Vector2i s)
}
// check the location for vtols
- tarX = (SDWORD)psDroid->pos.x + mx;
- tarY = (SDWORD)psDroid->pos.y + my;
+ Vector2i tar = removeZ(psDroid->pos) + Vector2i(mx, my);
if (isVtolDroid(psDroid))
{
- actionVTOLLandingPos(psDroid, (UDWORD *)&tarX,(UDWORD *)&tarY);
+ actionVTOLLandingPos(psDroid, &tar);
}
@@ -432,8 +427,7 @@ static void moveShuffleDroid(DROID *psDroid, Vector2i s)
}
psDroid->sMove.Status = MOVESHUFFLE;
psDroid->sMove.src = removeZ(psDroid->pos);
- psDroid->sMove.target.x = tarX;
- psDroid->sMove.target.y = tarY;
+ psDroid->sMove.target = tar;
psDroid->sMove.numPoints = 0;
psDroid->sMove.pathIndex = 0;
@@ -629,21 +623,6 @@ static bool moveNextTarget(DROID *psDroid)
return true;
}
-/* Look at the next target point from the route */
-static Vector2i movePeekNextTarget(DROID *psDroid)
-{
- // See if there is anything left in the move list
- if (psDroid->sMove.pathIndex == psDroid->sMove.numPoints)
- {
- // No points left - fudge one to continue the same direction
- return psDroid->sMove.target*2 - psDroid->sMove.src;
- }
- else
- {
- return psDroid->sMove.asPath[psDroid->sMove.pathIndex];
- }
-}
-
// Watermelon:fix these magic number...the collision radius should be based on pie imd radius not some static int's...
static int mvPersRad = 20, mvCybRad = 30, mvSmRad = 40, mvMedRad = 50, mvLgRad = 60;
@@ -1373,19 +1352,12 @@ static bool moveReachedWayPoint(DROID *psDroid)
// Calculate the vector to the droid
const Vector2i droid = removeZ(psDroid->pos) - psDroid->sMove.target;
const bool last = psDroid->sMove.pathIndex == psDroid->sMove.numPoints;
- const int sqprecision = last ? ((TILE_UNITS / 4) * (TILE_UNITS / 4)) : ((TILE_UNITS / 2) * (TILE_UNITS / 2));
+ int sqprecision = last ? ((TILE_UNITS / 4) * (TILE_UNITS / 4)) : ((TILE_UNITS / 2) * (TILE_UNITS / 2));
- // See if we have reached the next waypoint - occasionally happens due to bumping
- if (!last)
+ if (last && psDroid->sMove.bumpTime != 0)
{
- const int nsqprecision = (TILE_UNITS / 2) * (TILE_UNITS / 2);
- const Vector2i next = movePeekNextTarget(psDroid);
- const Vector2i ndroid = removeZ(psDroid->pos) - next;
-
- if (ndroid*ndroid < nsqprecision)
- {
- return true;
- }
+ // Make waypoint tolerance 1 tile after 0 seconds, 2 tiles after 3 seconds, X tiles after (X + 1)² seconds.
+ sqprecision = (gameTime - psDroid->sMove.bumpTime + GAME_TICKS_PER_SEC)*(TILE_UNITS*TILE_UNITS / GAME_TICKS_PER_SEC);
}
// Else check current waypoint
@@ -2507,7 +2479,19 @@ void moveUpdateDroid(DROID *psDroid)
// No more waypoints - finish
if ( psPropStats->propulsionType == PROPULSION_TYPE_LIFT )
{
- psDroid->sMove.Status = MOVEHOVER;
+ // check the location for vtols
+ Vector2i tar = removeZ(psDroid->pos);
+ if (psDroid->order.type != DORDER_PATROL && psDroid->order.type != DORDER_CIRCLE // Not doing an order which means we never land (which means we might want to land).
+ && actionVTOLLandingPos(psDroid, &tar) // Can find a sensible place to land.
+ && map_coord(tar) != map_coord(psDroid->sMove.destination)) // We're not at the right place to land.
+ {
+ psDroid->sMove.destination = tar;
+ moveDroidTo(psDroid, psDroid->sMove.destination.x, psDroid->sMove.destination.y);
+ }
+ else
+ {
+ psDroid->sMove.Status = MOVEHOVER;
+ }
}
else
{
View
70 src/order.cpp
@@ -793,12 +793,15 @@ void orderUpdateDroid(DROID *psDroid)
temp = (DROID*)psDroid->order.psObj;
// FIXME: since we now have 2 transporter types, we should fix this in the scripts for campaign
- if ((temp->droidType == DROID_TRANSPORTER) && !cyborgDroid(psDroid) && game.type != CAMPAIGN && bMultiPlayer)
+ if (temp->droidType == DROID_TRANSPORTER && !cyborgDroid(psDroid) && game.type != CAMPAIGN && bMultiPlayer)
{
psDroid->order = DroidOrder(DORDER_NONE);
actionDroid(psDroid, DACTION_NONE);
- audio_PlayTrack( ID_SOUND_BUILD_FAIL );
- addConsoleMessage(_("We can't do that! We must be a Cyborg unit to use a Cyborg Transport!"), DEFAULT_JUSTIFY, selectedPlayer);
+ if (psDroid->player == selectedPlayer)
+ {
+ audio_PlayTrack(ID_SOUND_BUILD_FAIL);
+ addConsoleMessage(_("We can't do that! We must be a Cyborg unit to use a Cyborg Transport!"), DEFAULT_JUSTIFY, selectedPlayer);
+ }
}
else
{
@@ -1625,16 +1628,15 @@ void orderDroidBase(DROID *psDroid, DROID_ORDER_DATA *psOrder)
{
if (psStruct->pStructureType->type == REF_HQ)
{
- UDWORD droidX = psStruct->pos.x;
- UDWORD droidY = psStruct->pos.y;
+ Vector2i pos = removeZ(psStruct->pos);
psDroid->order = *psOrder;
// Find a place to land for vtols. And Transporters in a multiPlay game.
if (isVtolDroid(psDroid) || (game.type == SKIRMISH && (psDroid->droidType == DROID_TRANSPORTER || psDroid->droidType == DROID_SUPERTRANSPORTER)))
{
- actionVTOLLandingPos(psDroid, &droidX,&droidY);
+ actionVTOLLandingPos(psDroid, &pos);
}
- actionDroid(psDroid, DACTION_MOVE, droidX,droidY);
+ actionDroid(psDroid, DACTION_MOVE, pos.x, pos.y);
break;
}
}
@@ -1718,13 +1720,11 @@ void orderDroidBase(DROID *psDroid, DROID_ORDER_DATA *psOrder)
* repaired, need to find a suitable location to drop down. */
if (game.type == SKIRMISH && (psDroid->droidType == DROID_TRANSPORTER || psDroid->droidType == DROID_SUPERTRANSPORTER))
{
- UDWORD droidX, droidY;
- droidX = psDroid->order.pos.x;
- droidY = psDroid->order.pos.y;
+ Vector2i pos = psDroid->order.pos;
objTrace(psDroid->id, "Repair transport");
- actionVTOLLandingPos(psDroid, &droidX,&droidY);
- actionDroid(psDroid, DACTION_MOVE, droidX,droidY);
+ actionVTOLLandingPos(psDroid, &pos);
+ actionDroid(psDroid, DACTION_MOVE, pos.x, pos.y);
}
else
{
@@ -2909,19 +2909,31 @@ void orderSelectedStatsTwoLocDir(UDWORD player, DROID_ORDER order, STRUCTURE_STA
/** This function runs though all player's droids to check if any of then is a transporter. Returns the transporter droid if any was found, and NULL else.*/
-DROID *FindATransporter(unsigned player)
+DROID *FindATransporter(DROID const *embarkee)
{
- DROID *psDroid;
+ bool isCyborg = cyborgDroid(embarkee) || !bMultiPlayer; // In campaign, any unit can go on a regular transporter, so consider any unit to be a cyborg.
+
+ DROID *bestDroid = NULL;
+ unsigned bestDist = ~0u;
- for (psDroid = apsDroidLists[player]; psDroid != NULL; psDroid = psDroid->psNext)
+ for (DROID *psDroid = apsDroidLists[embarkee->player]; psDroid != NULL; psDroid = psDroid->psNext)
{
- if (psDroid->droidType == DROID_TRANSPORTER || psDroid->droidType == DROID_SUPERTRANSPORTER)
+ if ((isCyborg && psDroid->droidType == DROID_TRANSPORTER) || psDroid->droidType == DROID_SUPERTRANSPORTER)
{
- return psDroid;
+ unsigned dist = iHypot(removeZ(psDroid->pos - embarkee->pos));
+ if (!checkTransporterSpace(psDroid, embarkee, false))
+ {
+ dist += 0x8000000; // Should prefer transports that aren't full.
+ }
+ if (dist < bestDist)
+ {
+ bestDroid = psDroid;
+ bestDist = dist;
+ }
}
}
- return NULL;
+ return bestDroid;
}
@@ -3296,8 +3308,8 @@ bool secondarySetState(DROID *psDroid, SECONDARY_ORDER sec, SECONDARY_STATE Stat
secondarySet = State;
break;
case DSS_RTL_TRANSPORT:
- psTransport = FindATransporter(psDroid->player);
- if (psTransport != NULL && !(bMultiPlayer && !cyborgDroid(psDroid)))
+ psTransport = FindATransporter(psDroid);
+ if (psTransport != NULL)
{
secondarySet = State;
}
@@ -3579,22 +3591,14 @@ bool secondarySetState(DROID *psDroid, SECONDARY_ORDER sec, SECONDARY_STATE Stat
CurrState |= DSS_RTL_BASE;
break;
case DSS_RTL_TRANSPORT:
- psTransport = FindATransporter(psDroid->player);
+ psTransport = FindATransporter(psDroid);
if (psTransport != NULL)
{
- // in multiPlayer can only put cyborgs onto a Transporter
- if (bMultiPlayer && !cyborgDroid(psDroid))
- {
- retVal = false;
- }
- else
+ order = DORDER_EMBARK;
+ CurrState |= DSS_RTL_TRANSPORT;
+ if (!orderState(psDroid, DORDER_EMBARK))
{
- order = DORDER_EMBARK;
- CurrState |= DSS_RTL_TRANSPORT;
- if (!orderState(psDroid, DORDER_EMBARK))
- {
- orderDroidObj(psDroid, DORDER_EMBARK, psTransport, ModeImmediate);
- }
+ orderDroidObj(psDroid, DORDER_EMBARK, psTransport, ModeImmediate);
}
}
else
View
2  src/order.h
@@ -133,7 +133,7 @@ extern void orderGroupMoralCheck(DROID_GROUP *psGroup);
extern const char* getDroidOrderName(DROID_ORDER order);
/** \brief Gets a player's transporter. */
-extern DROID *FindATransporter(unsigned player);
+DROID *FindATransporter(DROID const *embarkee);
/** \brief Checks if there are any damaged buildings to repair. */
extern BASE_OBJECT * checkForDamagedStruct(DROID *psDroid, STRUCTURE *psTarget);
View
7 src/structure.cpp
@@ -2440,11 +2440,10 @@ static bool structPlaceDroid(STRUCTURE *psStructure, DROID_TEMPLATE *psTempl,
if (isVtolDroid(psNewDroid))
{
- UDWORD droidX = psFlag->coords.x;
- UDWORD droidY = psFlag->coords.y;
+ Vector2i pos = removeZ(psFlag->coords);
//find a suitable location near the delivery point
- actionVTOLLandingPos(psNewDroid, &droidX, &droidY);
- orderDroidLoc(psNewDroid, DORDER_MOVE, droidX, droidY, ModeQueue);
+ actionVTOLLandingPos(psNewDroid, &pos);
+ orderDroidLoc(psNewDroid, DORDER_MOVE, pos.x, pos.y, ModeQueue);
}
else
{
View
10 src/transporter.cpp
@@ -158,7 +158,7 @@ static bool intAddTransButtonForm(void);
static bool intAddTransContentsForm(void);
static bool intAddDroidsAvailForm(void);
void intRemoveTransContent(void);
-static UDWORD transporterSpaceRequired(DROID *psDroid);
+static UDWORD transporterSpaceRequired(DROID const *psDroid);
static DROID* transInterfaceDroidList(void);
static void intTransporterAddDroid(UDWORD id);
static void intRemoveTransDroidsAvail(void);
@@ -1442,7 +1442,7 @@ void transporterAddDroid(DROID *psTransporter, DROID *psDroidToAdd)
}
/*check to see if the droid can fit on the Transporter - return true if fits*/
-bool checkTransporterSpace(DROID *psTransporter, DROID *psAssigned)
+bool checkTransporterSpace(DROID const *psTransporter, DROID const *psAssigned, bool mayFlash)
{
DROID *psDroid, *psNext;
UDWORD capacity;
@@ -1462,8 +1462,8 @@ bool checkTransporterSpace(DROID *psTransporter, DROID *psAssigned)
}
if (capacity >= transporterSpaceRequired(psAssigned))
{
- //when full flash the transporter button
- if (capacity - transporterSpaceRequired(psAssigned) == 0)
+ //when full flash the transporter button
+ if (mayFlash && capacity - transporterSpaceRequired(psAssigned) == 0)
{
flashMissionButton(IDTRANS_LAUNCH);
}
@@ -1476,7 +1476,7 @@ bool checkTransporterSpace(DROID *psTransporter, DROID *psAssigned)
}
/*returns the space the droid occupies on a transporter based on the body size*/
-UDWORD transporterSpaceRequired(DROID *psDroid)
+UDWORD transporterSpaceRequired(DROID const *psDroid)
{
UDWORD size;
View
2  src/transporter.h
@@ -48,7 +48,7 @@ extern void intProcessTransporter(UDWORD id);
extern void transporterAddDroid(DROID *psTransporter, DROID *psDroidToAdd);
void transporterRemoveDroid(DROID *psTransport, DROID *psDroid, QUEUE_MODE mode);
/*check to see if the droid can fit on the Transporter - return true if fits*/
-extern bool checkTransporterSpace(DROID *psTransporter, DROID *psAssigned);
+bool checkTransporterSpace(DROID const *psTransporter, DROID const *psAssigned, bool mayFlash = true);
/*calculates how much space is remaining on the transporter - allows droids to take
up different amount depending on their body size - currently all are set to one!*/
extern UDWORD calcRemainingCapacity(DROID *psTransporter);

No commit comments for this range

Something went wrong with that request. Please try again.