Skip to content

Commit

Permalink
Introducing new main savegame file: main.json
Browse files Browse the repository at this point in the history
Saves all the content of the .gam file to a new main.json
file. None of the existing .gam information is replaced,
with one exception - see below - and while the information
is written out, it is mostly not used yet. The plan is to
phase it in gradually to make testing both easier and more
rigorous.

The information on recycled experience is now stored in
a priority queue, and the number of experience values a player
can store is no longer limited. These values are now stored
and read from the new main.json. Existing experience values
in legacy savegames will still load, but in new savegames they
will be stored in main.json only, and the .gam file will only
contain zeroes in these fields.

A new cheat code is added to easier test this new functionality,
'teach us', which will give all selected units a big experience
boost.
  • Loading branch information
perim committed Jun 13, 2017
1 parent d935f57 commit 6670ce1
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 94 deletions.
5 changes: 5 additions & 0 deletions lib/framework/wzconfig.cpp
Expand Up @@ -346,3 +346,8 @@ void WzConfig::setValue(const QString &key, const QVariant &value)
{
mObj.insert(key, QJsonValue::fromVariant(value));
}

void WzConfig::set(const QString &key, const QJsonValue &value)
{
mObj.insert(key, value);
}
1 change: 1 addition & 0 deletions lib/framework/wzconfig.h
Expand Up @@ -84,6 +84,7 @@ class WzConfig
}

void setValue(const QString &key, const QVariant &value);
void set(const QString &key, const QJsonValue &value);

QString group()
{
Expand Down
1 change: 1 addition & 0 deletions src/cheat.cpp
Expand Up @@ -46,6 +46,7 @@ static CHEAT_ENTRY cheatCodes[] =
{"templates", listTemplates}, // print templates
{"jsload", jsAutogame}, // load an AI script for selectedPlayer
{"jsdebug", jsShowDebug}, // show scripting states
{"teach us", kf_TeachSelected}, // give experience to selected units
{"clone wars", []{ kf_CloneSelected(10); }}, // clone selected units
{"clone wars!", []{ kf_CloneSelected(40); }}, // clone selected units
{"clone wars!!", []{ kf_CloneSelected(135); }}, // clone selected units
Expand Down
57 changes: 22 additions & 35 deletions src/droid.cpp
Expand Up @@ -81,7 +81,7 @@
#define DROID_REPAIR_SPREAD (20 - rand()%40)

// store the experience of recently recycled droids
UWORD aDroidExperience[MAX_PLAYERS][MAX_RECYCLED_DROIDS];
static std::priority_queue<int> recycled_experience[MAX_PLAYERS];

/** Height the transporter hovers at above the terrain. */
#define TRANSPORTER_HOVER_HEIGHT 10
Expand Down Expand Up @@ -152,7 +152,10 @@ static void droidBodyUpgrade(DROID *psDroid)
// initialise droid module
bool droidInit()
{
memset(aDroidExperience, 0, sizeof(UWORD) * MAX_PLAYERS * MAX_RECYCLED_DROIDS);
for (int i = 0; i < MAX_PLAYERS; i++)
{
recycled_experience[i] = std::priority_queue <int>(); // clear it
}
psLastDroidHit = nullptr;

return true;
Expand Down Expand Up @@ -386,32 +389,29 @@ DROID::~DROID()
free(sMove.asPath);
}

std::priority_queue<int> copy_experience_queue(int player)
{
return recycled_experience[player];
}

void add_to_experience_queue(int player, int value)
{
recycled_experience[player].push(value);
}

// recycle a droid (retain it's experience and some of it's cost)
void recycleDroid(DROID *psDroid)
{
UDWORD numKills, minKills;
SDWORD i, cost, storeIndex;
Vector3i position;

CHECK_DROID(psDroid);

// store the droids kills
numKills = psDroid->experience / 65536;
minKills = UWORD_MAX;
storeIndex = 0;
for (i = 0; i < MAX_RECYCLED_DROIDS; i++)
if (psDroid->experience > 0)
{
if (aDroidExperience[psDroid->player][i] < (UWORD)minKills)
{
storeIndex = i;
minKills = aDroidExperience[psDroid->player][i];
}
recycled_experience[psDroid->player].push(psDroid->experience);
}
aDroidExperience[psDroid->player][storeIndex] = (UWORD)numKills;

// return part of the cost of the droid
cost = calcDroidPower(psDroid);
int cost = calcDroidPower(psDroid);
cost = (cost / 2) * psDroid->body / psDroid->originalBody;
addPower(psDroid->player, (UDWORD)cost);

Expand All @@ -423,13 +423,10 @@ void recycleDroid(DROID *psDroid)
psDroid->psGroup->remove(psDroid);
}

position.x = psDroid->pos.x; // Add an effect
position.z = psDroid->pos.y;
position.y = psDroid->pos.z;

triggerEvent(TRIGGER_OBJECT_RECYCLED, psDroid);
vanishDroid(psDroid);

Vector3i position = psDroid->pos.xzy;
addEffect(&position, EFFECT_EXPLOSION, EXPLOSION_TYPE_DISCOVERY, false, nullptr, false, gameTime - deltaGameTime + 1);

CHECK_DROID(psDroid);
Expand Down Expand Up @@ -1624,7 +1621,6 @@ DROID *reallyBuildDroid(DROID_TEMPLATE *pTemplate, Position pos, UDWORD player,
{
DROID *psDroid;
DROID_GROUP *psGrp;
SDWORD i, experienceLoc;

// Don't use this assertion in single player, since droids can finish building while on an away mission
ASSERT(!bMultiPlayer || worldOnMap(pos.x, pos.y), "the build locations are not on the map");
Expand Down Expand Up @@ -1660,20 +1656,11 @@ DROID *reallyBuildDroid(DROID_TEMPLATE *pTemplate, Position pos, UDWORD player,
(psDroid->droidType != DROID_CYBORG_CONSTRUCT) &&
(psDroid->droidType != DROID_REPAIR) &&
(psDroid->droidType != DROID_CYBORG_REPAIR) &&
!isTransporter(psDroid))
!isTransporter(psDroid) &&
!recycled_experience[psDroid->player].empty())
{
uint32_t numKills = 0;
experienceLoc = 0;
for (i = 0; i < MAX_RECYCLED_DROIDS; i++)
{
if (aDroidExperience[player][i] * 65536 > numKills)
{
numKills = aDroidExperience[player][i] * 65536;
experienceLoc = i;
}
}
aDroidExperience[player][experienceLoc] = 0;
psDroid->experience = numKills;
psDroid->experience = recycled_experience[psDroid->player].top();
recycled_experience[psDroid->player].pop();
}
else
{
Expand Down
6 changes: 4 additions & 2 deletions src/droid.h
Expand Up @@ -31,6 +31,8 @@
#include "stats.h"
#include "visibility.h"

#include <queue>

#define OFF_SCREEN 9999 // world->screen check - alex

#define REPAIRLEV_LOW 50 // percentage of body points remaining at which to repair droid automatically.
Expand Down Expand Up @@ -58,8 +60,8 @@ enum PICKTILE
// the structure that was last hit
extern DROID *psLastDroidHit;

extern UWORD aDroidExperience[MAX_PLAYERS][MAX_RECYCLED_DROIDS];

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

// initialise droid module
bool droidInit();
Expand Down

0 comments on commit 6670ce1

Please sign in to comment.