mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-12-25 14:15:46 +00:00
Implement loading/saving some more state data.
This is the final commit for android savegame compatibility. Thanks to Andrew Church for explaining the new attributes and their format.
This commit is contained in:
parent
26d056d924
commit
7dca65351c
4 changed files with 195 additions and 4 deletions
|
@ -345,6 +345,7 @@ public:
|
|||
SeeMapMode getSeeMapMode() const { return _seeMapMode; }
|
||||
|
||||
int leaches;
|
||||
float shieldPoints;
|
||||
|
||||
protected:
|
||||
void setSongIconPositions();
|
||||
|
@ -385,8 +386,6 @@ protected:
|
|||
Vector fallGravity;
|
||||
int lastOutOfWaterMaxSpeed;
|
||||
|
||||
int shieldPoints;
|
||||
|
||||
void onIdle();
|
||||
void onHeal(int type);
|
||||
ParticleEffect biteLeftEmitter, biteRightEmitter, swimEmitter, auraHitEmitter;
|
||||
|
|
|
@ -2580,6 +2580,74 @@ void Continuity::saveFile(int slot, Vector position, unsigned char *scrShotData,
|
|||
}
|
||||
startData.SetAttribute("intFlags", fos.str());
|
||||
|
||||
// Additional data for the android version
|
||||
|
||||
#define SINGLE_FLOAT_ATTR(name, cond, val) \
|
||||
do { if((cond) && (val)) { \
|
||||
std::ostringstream osf; \
|
||||
osf << (val); \
|
||||
startData.SetAttribute(name, osf.str()); \
|
||||
}} while(0)
|
||||
|
||||
SINGLE_FLOAT_ATTR("blind", dsq->game->avatar->state.blind, dsq->game->avatar->state.blindTimer.getValue());
|
||||
SINGLE_FLOAT_ATTR("invincible", invincibleTimer.isActive(), invincibleTimer.getValue());
|
||||
SINGLE_FLOAT_ATTR("regen", regenTimer.isActive(), regenTimer.getValue());
|
||||
SINGLE_FLOAT_ATTR("trip", tripTimer.isActive(), tripTimer.getValue());
|
||||
SINGLE_FLOAT_ATTR("shieldPoints", true, dsq->game->avatar->shieldPoints);
|
||||
SINGLE_FLOAT_ATTR("webTimer", webTimer.isActive(), webTimer.getValue()); // Extension; not present in the android version
|
||||
|
||||
#undef SINGLE_FLOAT_ATTR
|
||||
|
||||
#define TIMER_AND_VALUE_ATTR(name, timer, val) \
|
||||
do { if(((timer).isActive()) && (val)) { \
|
||||
std::ostringstream osf; \
|
||||
osf << (val) << " " << ((timer).getValue()); \
|
||||
startData.SetAttribute((name), osf.str()); \
|
||||
}} while(0)
|
||||
|
||||
TIMER_AND_VALUE_ATTR("biteMult", biteMultTimer, biteMult);
|
||||
TIMER_AND_VALUE_ATTR("speedMult", speedMultTimer, speedMult);
|
||||
TIMER_AND_VALUE_ATTR("defenseMult", defenseMultTimer, defenseMult);
|
||||
TIMER_AND_VALUE_ATTR("energyMult", energyTimer, energyMult);
|
||||
TIMER_AND_VALUE_ATTR("petPower", petPowerTimer, petPower);
|
||||
TIMER_AND_VALUE_ATTR("liPower", liPowerTimer, liPower);
|
||||
TIMER_AND_VALUE_ATTR("light", lightTimer, light);
|
||||
|
||||
#undef TIMER_AND_VALUE_ATTR
|
||||
|
||||
if(poisonTimer.isActive())
|
||||
{
|
||||
std::ostringstream osp;
|
||||
osp << poison << " " << poisonTimer.getValue() << " " << poisonBitTimer.getValue();
|
||||
startData.SetAttribute("poison", osp.str());
|
||||
}
|
||||
|
||||
if(dsq->game->avatar->activeAura != AURA_NONE)
|
||||
{
|
||||
std::ostringstream osa;
|
||||
osa << dsq->game->avatar->activeAura << " " << dsq->game->avatar->auraTimer;
|
||||
startData.SetAttribute("aura", osa.str());
|
||||
}
|
||||
|
||||
// FIXME: Web is a bit weird. There are 2 webBitTimer variables in use, one in Continuity, one in Avatar.
|
||||
// Because the avatar one ticks every 0.5 seconds, it will be hardly noticeable if that timer is off.
|
||||
// So we just use the Continuty timers and hope for the best. -- FG
|
||||
if(webTimer.isActive() && dsq->game->avatar->web)
|
||||
{
|
||||
Web *w = dsq->game->avatar->web;
|
||||
const int nump = w->getNumPoints();
|
||||
std::ostringstream osw;
|
||||
osw << webBitTimer.getValue() << " " << nump << " ";
|
||||
for(int i = 0; i < nump; ++i)
|
||||
{
|
||||
Vector v = w->getPoint(i);
|
||||
osw << v.x << " " << v.y << " ";
|
||||
}
|
||||
startData.SetAttribute("web", osw.str());
|
||||
}
|
||||
|
||||
// end extra android data
|
||||
|
||||
doc.InsertEndChild(startData);
|
||||
|
||||
|
||||
|
@ -3094,9 +3162,124 @@ void Continuity::loadFile(int slot)
|
|||
dsq->continuity.costume = startData->Attribute("costume");
|
||||
}
|
||||
|
||||
//dsq->game->positionToAvatar = Vector(500,400);
|
||||
dsq->game->sceneToLoad = startData->Attribute("scene");
|
||||
//dsq->game->transitionToScene();
|
||||
|
||||
// Additional data introduced in the android version
|
||||
|
||||
if(startData->Attribute("blind"))
|
||||
{
|
||||
float timer = strtof(startData->Attribute("blind"), NULL);
|
||||
if(dsq->game->avatar)
|
||||
dsq->game->avatar->setBlind(timer);
|
||||
}
|
||||
|
||||
if(startData->Attribute("invincible"))
|
||||
{
|
||||
float timer = strtof(startData->Attribute("invincible"), NULL);
|
||||
setInvincible(timer);
|
||||
}
|
||||
|
||||
if(startData->Attribute("regen"))
|
||||
{
|
||||
float timer = strtof(startData->Attribute("regen"), NULL);
|
||||
setRegen(timer);
|
||||
}
|
||||
|
||||
if(startData->Attribute("trip"))
|
||||
{
|
||||
float timer = strtof(startData->Attribute("trip"), NULL);
|
||||
setTrip(timer);
|
||||
}
|
||||
|
||||
if(startData->Attribute("aura"))
|
||||
{
|
||||
std::istringstream is(startData->Attribute("aura"));
|
||||
int type = AURA_NONE;
|
||||
float timer = 0.0f;
|
||||
is >> type >> timer;
|
||||
auraTimer = timer;
|
||||
auraType = (AuraType)type;
|
||||
if(dsq->game->avatar)
|
||||
{
|
||||
dsq->game->avatar->activateAura((AuraType)type);
|
||||
dsq->game->avatar->auraTimer = timer;
|
||||
}
|
||||
}
|
||||
|
||||
if(startData->Attribute("shieldPoints"))
|
||||
{
|
||||
float sp = strtof(startData->Attribute("shieldPoints"), NULL);
|
||||
if(dsq->game->avatar)
|
||||
dsq->game->avatar->shieldPoints = sp;
|
||||
}
|
||||
|
||||
#define LOAD_MULTI_SIMPLE(attr, mth) \
|
||||
do { if(startData->Attribute(attr)) \
|
||||
{ \
|
||||
std::istringstream is(startData->Attribute(attr)); \
|
||||
float value = 0.0f, timer = 0.0f; \
|
||||
is >> value >> timer; \
|
||||
this->mth(value, timer); \
|
||||
}} while(0)
|
||||
|
||||
LOAD_MULTI_SIMPLE("biteMult", setBiteMultiplier);
|
||||
LOAD_MULTI_SIMPLE("speedMult", setSpeedMultiplier);
|
||||
LOAD_MULTI_SIMPLE("defenseMult", setDefenseMultiplier);
|
||||
LOAD_MULTI_SIMPLE("energyMult", setEnergy);
|
||||
LOAD_MULTI_SIMPLE("petPower", setPetPower);
|
||||
LOAD_MULTI_SIMPLE("liPower", setLiPower);
|
||||
LOAD_MULTI_SIMPLE("light", setLight);
|
||||
|
||||
#undef LOAD_MULTI_SIMPLE
|
||||
|
||||
if(startData->Attribute("poison"))
|
||||
{
|
||||
std::istringstream is(startData->Attribute("poison"));
|
||||
float p = 0.0f, pt = 0.0f, pbit = 0.0f;
|
||||
is >> p >> pt >> pbit;
|
||||
setPoison(p, pt);
|
||||
poisonBitTimer.start(pbit);
|
||||
}
|
||||
|
||||
// FIXME: the total web time is seemingly not saved in the file.
|
||||
// Not sure if the calculation of the remaining time is correct.
|
||||
// Especially because there are two webBitTimer variables in use (in Continuity and Avatar),
|
||||
// and both of them access the avatar web. It's thus likely that more points were added than intended. -- FG
|
||||
if(startData->Attribute("web"))
|
||||
{
|
||||
std::istringstream is(startData->Attribute("web"));
|
||||
float wbit = 0.0f;
|
||||
int nump = 0;
|
||||
is >> wbit >> nump;
|
||||
// 2 web points are added in setWeb() by default, so we exclude them from the calculation
|
||||
float remainTime = webTime - (0.5 * (nump - 2)); // Avatar::webBitTimer ticks every 0.5 secs
|
||||
if(nump > 1 && remainTime > 0 && dsq->game->avatar)
|
||||
{
|
||||
if(!dsq->game->avatar->web)
|
||||
dsq->game->avatar->createWeb();
|
||||
Web *w = dsq->game->avatar->web;
|
||||
for(int i = 0; i < nump; ++i)
|
||||
{
|
||||
Vector v;
|
||||
is >> v.x >> v.y;
|
||||
if(i < w->getNumPoints())
|
||||
w->setPoint(i, v);
|
||||
else
|
||||
w->addPoint(v);
|
||||
}
|
||||
webBitTimer.start(wbit);
|
||||
webTimer.start(remainTime);
|
||||
}
|
||||
}
|
||||
|
||||
// This is AFAIK not in the android version, but let's add this for completeness
|
||||
// and to avoid the mess described above.
|
||||
if(startData->Attribute("webTimer"))
|
||||
{
|
||||
float timer = strtof(startData->Attribute("webTimer"), NULL);
|
||||
webTimer.start(timer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,14 @@ void Web::setPoint(int pt, const Vector &v)
|
|||
points[pt] = v;
|
||||
}
|
||||
|
||||
Vector Web::getPoint(int pt) const
|
||||
{
|
||||
Vector v;
|
||||
if (pt >= 0 || pt < points.size())
|
||||
v = points[pt];
|
||||
return v;
|
||||
}
|
||||
|
||||
int Web::getNumPoints()
|
||||
{
|
||||
return points.size();
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
Web();
|
||||
int addPoint(const Vector &point = Vector(0,0));
|
||||
void setPoint(int pt, const Vector &v);
|
||||
Vector getPoint(int pt) const;
|
||||
void setParentEntity(Entity *e);
|
||||
int getNumPoints();
|
||||
typedef std::list<Web*> Webs;
|
||||
|
|
Loading…
Reference in a new issue