Skip to content

Commit

Permalink
formation.cpp: Use PerPlayerObjectLists
Browse files Browse the repository at this point in the history
  • Loading branch information
past-due committed Jun 22, 2024
1 parent 4661e20 commit ebc8637
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 39 deletions.
65 changes: 33 additions & 32 deletions src/formation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include "formationdef.h"
#include "formation.h"
#include "objmem.h"

// radius for the different body sizes
static SDWORD fmLtRad = 80, fmMedRad = 100, fmHvyRad = 110;
Expand All @@ -59,15 +60,18 @@ static SDWORD fmLtRad = 80, fmMedRad = 100, fmHvyRad = 110;
#define FORMATION_SPEED_INIT 100000L

// The list of allocated formations
static FORMATION *psFormationList = nullptr;
static PerPlayerObjectLists<FORMATION, MAX_PLAYERS> psFormationLists;

static SDWORD formationObjRadius(const DROID* psDroid);

/** Initialise the formation system
*/
bool formationInitialise()
{
psFormationList = nullptr;
for (auto &psFormationList : psFormationLists)
{
psFormationList.clear();
}

return true;
}
Expand All @@ -76,22 +80,24 @@ bool formationInitialise()
*/
void formationShutDown()
{
FORMATION *psNext;

while (psFormationList)
for (auto &psFormationList : psFormationLists)
{
debug(LOG_NEVER, "formation with %d units still attached", psFormationList->refCount);
psNext = psFormationList->psNext;
delete psFormationList;
psFormationList = psNext;
for (const auto& psCurr : psFormationList)
{
debug(LOG_NEVER, "formation with %d units still attached", psCurr->refCount);
delete psCurr;
}
psFormationList.clear();
}
}

/** Create a new formation
*/
bool formationNew(FORMATION **ppsFormation, FORMATION_TYPE type,
bool formationNew(FORMATION **ppsFormation, uint32_t player, FORMATION_TYPE type,
SDWORD x, SDWORD y, uint16_t dir)
{
ASSERT_OR_RETURN(false, player < MAX_PLAYERS, "Invalid player: %" PRIu32, player);

SDWORD i;
FORMATION *psNew = new FORMATION();

Expand All @@ -107,6 +113,7 @@ bool formationNew(FORMATION **ppsFormation, FORMATION_TYPE type,
psNew->y = y;
psNew->free = 0;
psNew->iSpeed = FORMATION_SPEED_INIT;
psNew->player = player;
memset(psNew->asMembers, 0, sizeof(psNew->asMembers));
for(i=0; i<F_MAXMEMBERS; i++)
{
Expand Down Expand Up @@ -143,8 +150,7 @@ bool formationNew(FORMATION **ppsFormation, FORMATION_TYPE type,
return false;
}

psNew->psNext = psFormationList;
psFormationList = psNew;
psFormationLists[player].push_front(psNew);

*ppsFormation = psNew;

Expand All @@ -154,11 +160,11 @@ bool formationNew(FORMATION **ppsFormation, FORMATION_TYPE type,

/** Try to find a formation near a location
*/
FORMATION* formationFind(int x, int y)
FORMATION* formationFind(uint32_t player, int x, int y)
{
FORMATION* psFormation;
ASSERT_OR_RETURN(nullptr, player < MAX_PLAYERS, "Invalid player: %" PRIu32, player);

for (psFormation = psFormationList; psFormation; psFormation = psFormation->psNext)
for (auto psFormation : psFormationLists[player])
{
// see if the position is close to the formation
const int xdiff = psFormation->x - x;
Expand All @@ -170,7 +176,7 @@ FORMATION* formationFind(int x, int y)
}
}

return NULL;
return nullptr;
}

/** Find formation speed.
Expand All @@ -181,7 +187,7 @@ static void formationUpdateSpeed(FORMATION *psFormation, const DROID* psNew)
SDWORD iUnit;
F_MEMBER *asMembers = psFormation->asMembers;

if (psNew != NULL)
if (psNew != nullptr)
{
ASSERT(psNew->type == OBJ_DROID, "We've been passed a DROID that really isn't a DROID");
if ( psFormation->iSpeed > psNew->baseSpeed)
Expand Down Expand Up @@ -210,7 +216,8 @@ void formationJoin(FORMATION *psFormation, const DROID* psDroid)
{
SDWORD rankDist, size;

ASSERT_OR_RETURN(, psFormation != NULL, "Invalid formation");
ASSERT_OR_RETURN(, psFormation != nullptr, "Invalid formation");
ASSERT_OR_RETURN(, psFormation->player == psDroid->player, "Formation player (%d) does not match droid player (%d)", psFormation->player, psDroid->player);

psFormation->refCount += 1;

Expand All @@ -237,9 +244,8 @@ void formationLeave(FORMATION *psFormation, const DROID* psDroid)
SDWORD prev, curr, unit, line;
F_LINE *asLines;
F_MEMBER *asMembers;
FORMATION *psCurr, *psPrev;

ASSERT_OR_RETURN(, psFormation != NULL, "Invalid formation");
ASSERT_OR_RETURN(, psFormation != nullptr, "Invalid formation");
if (!psDroid)
{
return;
Expand Down Expand Up @@ -279,28 +285,23 @@ void formationLeave(FORMATION *psFormation, const DROID* psDroid)
asMembers[prev].next = asMembers[unit].next;
}
asMembers[unit].next = psFormation->free;
asMembers[unit].psDroid = NULL;
asMembers[unit].psDroid = nullptr;
psFormation->free = (SBYTE)unit;

/* update formation speed */
formationUpdateSpeed(psFormation, NULL);
formationUpdateSpeed(psFormation, nullptr);
}

psFormation->refCount -= 1;
if (psFormation->refCount == 0)
{
if (psFormation == psFormationList)
if (psFormation->player < MAX_PLAYERS)
{
psFormationList = psFormationList->psNext;
psFormationLists[psFormation->player].remove(psFormation);
}
else
{
psPrev = NULL;
for(psCurr=psFormationList; psCurr && psCurr!= psFormation; psCurr=psCurr->psNext)
{
psPrev = psCurr;
}
psPrev->psNext = psFormation->psNext;
ASSERT(psFormation->player < MAX_PLAYERS, "Formation->player is invalid?: %d", psFormation->player);
}
delete psFormation;
}
Expand Down Expand Up @@ -481,7 +482,7 @@ static void formationReorder(FORMATION *psFormation)
for(i=0; i<F_MAXMEMBERS; i++)
{
DROID* psDroid = asMembers[i].psDroid;
if (psDroid != NULL)
if (psDroid != nullptr)
{
asDroids[numObj].psDroid = psDroid;
xdiff = psDroid->pos.x - psFormation->x;
Expand Down Expand Up @@ -555,7 +556,7 @@ bool formationGetPos( FORMATION *psFormation, DROID* psDroid,
SDWORD member, x,y;
F_MEMBER *asMembers;

ASSERT_OR_RETURN(false, psFormation != NULL, "Invalid formation pointer");
ASSERT_OR_RETURN(false, psFormation != nullptr, "Invalid formation pointer");

/* if (psFormation->refCount == 1)
{
Expand Down
4 changes: 2 additions & 2 deletions src/formation.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ bool formationInitialise();
void formationShutDown();

// Create a new formation
bool formationNew(FORMATION **ppsFormation, FORMATION_TYPE type,
bool formationNew(FORMATION **ppsFormation, uint32_t player, FORMATION_TYPE type,
SDWORD x, SDWORD y, uint16_t dir);

// Try and find a formation near to a location
FORMATION* formationFind(int x, int y);
FORMATION* formationFind(uint32_t player, int x, int y);

// Associate a unit with a formation
void formationJoin(FORMATION *psFormation, const DROID* psDroid);
Expand Down
2 changes: 1 addition & 1 deletion src/formationdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,5 @@ struct FORMATION
// formation speed (currently speed of slowest member) - GJ - sorry.
UDWORD iSpeed;

FORMATION *psNext;
uint32_t player;
};
4 changes: 2 additions & 2 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5684,7 +5684,7 @@ static bool loadSaveDroid(const char *pFileName, PerPlayerDroidLists& ppsCurrent
auto formationX = json_variant(it_x.value()).toInt();
auto formationY = json_variant(it_y.value()).toInt();

psDroid->sMove.psFormation = formationFind(formationX, formationY);
psDroid->sMove.psFormation = formationFind(psDroid->player, formationX, formationY);
// join a formation if it exists at the destination
if (psDroid->sMove.psFormation)
{
Expand All @@ -5694,7 +5694,7 @@ static bool loadSaveDroid(const char *pFileName, PerPlayerDroidLists& ppsCurrent
{
// no formation so create a new one
auto formationDirection = json_variant(it_direction.value()).toUInt();
if (formationNew(&psDroid->sMove.psFormation, FT_LINE, formationX, formationY,
if (formationNew(&psDroid->sMove.psFormation, psDroid->player, FT_LINE, formationX, formationY,
static_cast<uint16_t>(formationDirection)))
{
formationJoin(psDroid->sMove.psFormation, psDroid);
Expand Down
4 changes: 2 additions & 2 deletions src/move.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ static bool moveDroidToBase(DROID *psDroid, UDWORD x, UDWORD y, bool bFormation,
if (bFormation)
{
// join a formation if it exists at the destination
FORMATION* psFormation = formationFind(x, y);
FORMATION* psFormation = formationFind(psDroid->player, x, y);
SDWORD fmx1, fmy1, fmx2, fmy2;

if (psFormation)
Expand All @@ -294,7 +294,7 @@ static bool moveDroidToBase(DROID *psDroid, UDWORD x, UDWORD y, bool bFormation,
}

// no formation so create a new one
if (formationNew(&psDroid->sMove.psFormation, FT_LINE, (SDWORD)x,(SDWORD)y,
if (formationNew(&psDroid->sMove.psFormation, psDroid->player, FT_LINE, (SDWORD)x,(SDWORD)y,
calcDirection(fmx1,fmy1, fmx2,fmy2)))
{
formationJoin(psDroid->sMove.psFormation, psDroid);
Expand Down

0 comments on commit ebc8637

Please sign in to comment.