Skip to content

Commit

Permalink
show rank for next droid (#2727)
Browse files Browse the repository at this point in the history
  • Loading branch information
gantsevdenis committed Jul 5, 2022
1 parent 21046e5 commit 28dfe21
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 47 deletions.
74 changes: 38 additions & 36 deletions src/display3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3935,47 +3935,49 @@ void showRangeAtPos(SDWORD centerX, SDWORD centerY, SDWORD radius)
bRangeDisplay = false;
}
}
UDWORD getDroidRankGraphicFromLevel(unsigned int level)
{
UDWORD gfxId = UDWORD_MAX;
switch (level)
{
case 0:
break;
case 1:
gfxId = IMAGE_LEV_0;
break;
case 2:
gfxId = IMAGE_LEV_1;
break;
case 3:
gfxId = IMAGE_LEV_2;
break;
case 4:
gfxId = IMAGE_LEV_3;
break;
case 5:
gfxId = IMAGE_LEV_4;
break;
case 6:
gfxId = IMAGE_LEV_5;
break;
case 7:
gfxId = IMAGE_LEV_6;
break;
case 8:
gfxId = IMAGE_LEV_7;
break;
default:
ASSERT(!"out of range droid rank", "Weird droid level in drawDroidRank");
break;
}

return gfxId;
}
/// Get the graphic ID for a droid rank
UDWORD getDroidRankGraphic(DROID *psDroid)
{
UDWORD gfxId = UDWORD_MAX;

/* Establish the numerical value of the droid's rank */
switch (getDroidLevel(psDroid))
{
case 0:
break;
case 1:
gfxId = IMAGE_LEV_0;
break;
case 2:
gfxId = IMAGE_LEV_1;
break;
case 3:
gfxId = IMAGE_LEV_2;
break;
case 4:
gfxId = IMAGE_LEV_3;
break;
case 5:
gfxId = IMAGE_LEV_4;
break;
case 6:
gfxId = IMAGE_LEV_5;
break;
case 7:
gfxId = IMAGE_LEV_6;
break;
case 8:
gfxId = IMAGE_LEV_7;
break;
default:
ASSERT(!"out of range droid rank", "Weird droid level in drawDroidRank");
break;
}

return gfxId;
return getDroidRankGraphicFromLevel(getDroidLevel(psDroid));
}

/** Will render a graphic depiction of the droid's present rank.
Expand Down
1 change: 1 addition & 0 deletions src/display3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ extern const Vector2i visibleTiles;

/*returns the graphic ID for a droid rank*/
UDWORD getDroidRankGraphic(DROID *psDroid);
UDWORD getDroidRankGraphicFromLevel(unsigned int level);

void setSkyBox(const char *page, float mywind, float myscale);

Expand Down
29 changes: 19 additions & 10 deletions src/droid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ static void groupConsoleInformOfRemoval();
static void droidUpdateDroidSelfRepair(DROID *psRepairDroid);
static UDWORD calcDroidBaseBody(DROID *psDroid);

int getTopExperience(int player)
{
if (recycled_experience[player].size() == 0)
{
return 0;
}
return recycled_experience[player].top();
}
void cancelBuild(DROID *psDroid)
{
if (psDroid->order.type == DORDER_NONE || psDroid->order.type == DORDER_PATROL || psDroid->order.type == DORDER_HOLD || psDroid->order.type == DORDER_SCOUT || psDroid->order.type == DORDER_GUARD)
Expand Down Expand Up @@ -2142,17 +2150,13 @@ struct rankMap
const char *name; // name of this rank
};

unsigned int getDroidLevel(const DROID *psDroid)
unsigned int getDroidLevel(unsigned int experience, uint8_t player, uint8_t brainComponent)
{
unsigned int numKills = psDroid->experience / 65536;
unsigned int i;

// Search through the array of ranks until one is found
// which requires more kills than the droid has.
// Then fall back to the previous rank.
const BRAIN_STATS *psStats = getBrainStats(psDroid);
auto &vec = psStats->upgrade[psDroid->player].rankThresholds;
for (i = 1; i < vec.size(); ++i)
unsigned int numKills = experience / 65536;
const BRAIN_STATS *psStats = asBrainStats + brainComponent;
auto &vec = psStats->upgrade[player].rankThresholds;
ASSERT_OR_RETURN(0, vec.size() > 0, "rankThreshold was empty?");
for (int i = 1; i < vec.size(); ++i)
{
if (numKills < vec.at(i))
{
Expand All @@ -2164,6 +2168,11 @@ unsigned int getDroidLevel(const DROID *psDroid)
return vec.size() - 1;
}

unsigned int getDroidLevel(const DROID *psDroid)
{
return getDroidLevel(psDroid->experience, psDroid->player, psDroid->asBits[COMP_BRAIN]);
}

UDWORD getDroidEffectiveLevel(const DROID *psDroid)
{
UDWORD level = getDroidLevel(psDroid);
Expand Down
2 changes: 2 additions & 0 deletions src/droid.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ enum PICKTILE
extern DROID *psLastDroidHit;

std::priority_queue<int> copy_experience_queue(int player);
int getTopExperience(int player);
void add_to_experience_queue(int player, int value);

// initialise droid module
Expand Down Expand Up @@ -183,6 +184,7 @@ bool calcDroidMuzzleBaseLocation(const DROID *psDroid, Vector3i *muzzle, int wea

/* Droid experience stuff */
unsigned int getDroidLevel(const DROID *psDroid);
unsigned int getDroidLevel(unsigned int experience, uint8_t player, uint8_t brainComponent);
UDWORD getDroidEffectiveLevel(const DROID *psDroid);
const char *getDroidLevelName(const DROID *psDroid);

Expand Down
47 changes: 46 additions & 1 deletion src/hci/manufacture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
#include "manufacture.h"
#include "../mission.h"
#include "../qtscript.h"
#include "../display3d.h"

STRUCTURE *ManufactureController::highlightedFactory = nullptr;
static const uint8_t nullBrainComponent = 0; // "0" to reference "NULLxxx" components
static const uint8_t commandBrainComponent = 1; // hmm there is only 1 "CommandBrain01" anyway..

FACTORY *getFactoryOrNullptr(STRUCTURE *factory)
{
Expand Down Expand Up @@ -291,7 +294,6 @@ class ManufactureStatsButton: public StatsButton
auto production = getStats();
auto productionPending = factory && StructureIsManufacturingPending(factory);
auto objectImage = productionPending && production ? ImdObject::DroidTemplate(production): ImdObject::Component(nullptr);

displayIMD(AtlasImage(), objectImage, xOffset, yOffset);

if (productionPending && StructureIsOnHoldPending(factory))
Expand All @@ -302,6 +304,49 @@ class ManufactureStatsButton: public StatsButton
{
displayIfHighlight(xOffset, yOffset);
}
drawNextDroidRank(xOffset, yOffset);
}

// show a little icon on the bottom, indicating what rank next unit will be
// remember that when it's a commander, same rank will require twice experience
void drawNextDroidRank(int xOffset, int yOffset)
{
const auto factory = controller->getObjectAt(objectIndex);
if (!factory)
{
return;
}
const auto player = factory->player;
const auto exp = getTopExperience(player);
unsigned int lvl = 0;
if (!factory->pFunctionality->factory.psSubject)
{
// not showing icon when nothing is being built
return;
}
if (factory->pFunctionality->factory.psSubject->droidType == DROID_COMMAND)
{
lvl = getDroidLevel(exp, player, commandBrainComponent);
}
else if (factory->pFunctionality->factory.psSubject->droidType == DROID_CONSTRUCT
|| factory->pFunctionality->factory.psSubject->droidType == DROID_CYBORG_CONSTRUCT
|| factory->pFunctionality->factory.psSubject->droidType == DROID_CYBORG_REPAIR
|| factory->pFunctionality->factory.psSubject->droidType == DROID_REPAIR
|| factory->pFunctionality->factory.psSubject->droidType == DROID_TRANSPORTER
|| factory->pFunctionality->factory.psSubject->droidType == DROID_SUPERTRANSPORTER)
{
lvl = 0;
}
else
{
lvl = getDroidLevel(exp, player, nullBrainComponent);
}
const auto expgfx = getDroidRankGraphicFromLevel(lvl);
if (expgfx != UDWORD_MAX)
{
// FIXME: use offsets relative to template positon, not hardcoded values ?
iV_DrawImage(IntImages, (UWORD)expgfx, xOffset + 45, yOffset + 4);
}
}

void updateLayout() override
Expand Down

0 comments on commit 28dfe21

Please sign in to comment.