1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-02-04 10:34:01 +00:00

Map element code refactoring. Allow other entities to influence map elements (EFX_WAVY).

Reduce Element memory; as most elements do not have any effect set,
this saves more than 50 bytes per element.
This commit is contained in:
fgenesis 2013-09-24 17:00:06 +02:00
parent ab74abe903
commit 6f9063ce6d
8 changed files with 163 additions and 240 deletions

View file

@ -1629,7 +1629,7 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF
break;
}
elementEffectMult = 1;
state.abilityDelay = 0;
formAbilityDelay = 0;
dsq->continuity.form = form;
@ -1731,6 +1731,7 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF
collideRadius = COLLIDE_RADIUS_FISH;
setCanLockToWall(false);
setCollisionAvoidanceData(COLLIDE_RANGE_FISH, COLLIDE_MOD_FISH);
elementEffectMult = 0.4f;
}
break;
case FORM_SUN:
@ -1780,6 +1781,7 @@ void Avatar::changeForm(FormType form, bool effects, bool onInit, FormType lastF
setCanLockToWall(false);
setCanBurst(false);
setDamageTarget(DT_WALLHURT, false);
elementEffectMult = 0;
if (onInit)
{
@ -4076,6 +4078,7 @@ Avatar::Avatar() : Entity(), ActionMapper()
_seeMapMode = SEE_MAP_DEFAULT;
blockBackFlip = false;
elementEffectMult = 1;
}
void Avatar::revert()
@ -7133,6 +7136,16 @@ void Avatar::onUpdate(float dt)
if(canCollideWithShots())
dsq->game->handleShotCollisions(this, (activeAura == AURA_SHIELD));
if(!core->particlesPaused && elementEffectMult > 0)
{
ElementUpdateList& elems = dsq->game->elementUpdateList;
for (ElementUpdateList::iterator it = elems.begin(); it != elems.end(); ++it)
{
(*it)->doInteraction(this, elementEffectMult, 16);
}
}
}

View file

@ -346,6 +346,7 @@ public:
int leaches;
float shieldPoints;
float elementEffectMult;
bool blockBackFlip;

View file

@ -359,7 +359,7 @@ ElementEffect DSQ::getElementEffectByIndex(int e)
return empty;
}
/*
Element *DSQ::getSolidElementNear(Vector pos, int rad)
{
Element *closestE = 0;
@ -376,26 +376,12 @@ Element *DSQ::getSolidElementNear(Vector pos, int rad)
}
return closestE;
}
*/
Vector DSQ::getCameraCenter()
{
return cameraPos; //+ Vector(400*(1.0f/core->globalScale.x),300*(1.0f/core->globalScale.x));
}
void DSQ::doScript(const std::string &script)
{
/*
this->script.loadScriptFile(script);
this->script.run("void main()");
*/
}
void DSQ::print(int x, int y, const std::string &text)
{
// CTextDrawer::GetSingleton().PrintText(x, y, text.c_str());
}
void DSQ::centerMessage(const std::string &text, float y, int type)
{
Vector pos(400,y);
@ -4559,6 +4545,7 @@ void DSQ::onUpdate(float dt)
os << dsq->sound->getVolumeString() << std::endl;
os << "runInBG: " << core->settings.runInBackground << " nested: " << core->getNestedMains() << std::endl;
os << core->globalResolutionScale.x << ", " << core->globalResolutionScale.y << std::endl;
os << "elemu: " << game->elementUpdateList.size() << " elemi: " << game->elementInteractionList.size() << std::endl;
os << "Lua mem: " << scriptInterface.gcGetStats() << " KB" << std::endl;
cmDebug->setText(os.str());

View file

@ -1270,10 +1270,7 @@ public:
void setTexturePointers();
void doScript(const std::string &script);
void fade(float alpha, float time);
void print(int x, int y, const std::string &text);
void applyParallaxUserSettings();
@ -1380,7 +1377,7 @@ public:
std::string getDialogueFilename(const std::string &f);
bool isShakingCamera();
Element *getSolidElementNear(Vector pos, int rad);
//Element *getSolidElementNear(Vector pos, int rad);
std::string languagePack;

View file

@ -20,169 +20,150 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "Element.h"
#include "Game.h"
#include "Avatar.h"
ElementEffectData::ElementEffectData()
: elementEffectIndex(-1)
, wavyAngleOffset(0)
, wavyMagnitude(0)
, wavyLerpIn(0)
, wavyMin(0)
, wavyMax(0)
, hitPerc(0)
, effectMult(0)
, wavyWaving(false)
, wavyFlip(false)
, touching(false)
, elementEffectType(EFX_NONE)
{
}
Element::Element() : Quad()
{
elementFlag = EF_NONE;
wavyFlip = false;
elementEffectIndex = -1;
elementActive = true;
bgLayer = 0;
wavyAngleOffset=0;
wavyMagnitude=0;
wavyLerpIn=0;
wavyWaving=false;
wavyFlip=false;
elementEffectType = 0;
wavyRadius = 0;
wavyMin = 0;
wavyMax = 0;
templateIdx = -1;
eff = NULL;
setStatic(true);
}
void Element::wavyPull(int to, int from, float dt)
void Element::ensureEffectData()
{
Vector diff = wavy[to] - wavy[from];
if (!diff.isZero())
if (!eff)
eff = new ElementEffectData;
}
void Element::freeEffectData()
{
if (eff)
{
diff.capLength2D(wavyMax);
if (diff.isLength2DIn(wavyMin))
{
diff.setLength2D(wavyMin);
}
wavy[to] = wavy[from] + diff;
delete eff;
eff = NULL;
}
}
void Element::doInteraction(Entity *ent, float mult, float touchWidth)
{
ElementEffectData *eff = this->eff;
Vector pos = position;
pos.y -= (height*scale.y)/2;
float hitPerc=0;
Vector p = ent->position;
if (p.x > position.x-touchWidth && p.x < position.x+touchWidth)
{
float h2 = (height*scale.y)/2.0f;
if (p.y < position.y+h2 && p.y > position.y-h2)
{
eff->touching = true;
eff->wavyWaving = true;
hitPerc = pos.y - p.y;
hitPerc /= float(height*scale.y);
hitPerc = (1.0f-hitPerc)-1.0f;
eff->hitPerc = hitPerc;
eff->touchVel = ent->vel;
eff->effectMult = mult;
return;
}
}
//eff->touchVel = Vector(0, 0);
//eff->hitPerc = 0;
eff->touching = false;
}
void Element::updateEffects(float dt)
{
switch (elementEffectType)
switch (eff->elementEffectType)
{
case EFX_ALPHA:
alpha.update(dt);
break;
break;
case EFX_WAVY:
//debugLog("EXF_WAVY update");
/// check player position
{
// if a big wavy doesn't work, this is probably why
//if ((position - dsq->game->avatar->position).isLength2DIn(1024))
//if ((position - ent->position).isLength2DIn(1024))
{
int touchIdx = -1;
Vector pos = position;
pos.y = position.y - (height*scale.y)/2;
ElementEffectData *eff = this->eff;
float hitPerc=0;
Vector p = dsq->game->avatar->position;// + Vector(200,0);
if (p.x > position.x-16 && p.x < position.x+16)
if (eff->touching)
{
float h2 = (height*scale.y)/2.0f;
if (p.y < position.y+h2 && p.y > position.y-h2)
{
touchIdx = 0;
hitPerc = pos.y - p.y;
hitPerc /= float(height*scale.y);
hitPerc = (1.0f-hitPerc)-1.0f;
//std::cout << "hit!\n";
/*
std::ostringstream os;
os << "hit perc: " << hitPerc;
debugLog(os.str());
*/
}
}
/*
for (int i = 0; i < wavy.size()-1; i++)
{
if (isTouchingLine(wavy[0]+pos, wavy[i+1]+pos, dsq->game->avatar->position, wavyRadius))
{
//wavy[i+1] = dsq->game->avatar->position;
touchIdx = i+1;
break;
}
}
*/
if (touchIdx != -1)
{
// start pull
wavyWaving = true;
wavyAngleOffset = 0;
float ramp = dsq->game->avatar->vel.getLength2D()/800.0f;
float ramp = eff->touchVel.getLength2D()/800.0f;
if (ramp < 0) ramp = 0;
if (ramp > 1) ramp = 1;
wavyMagnitude = 100 * ramp + 16;
eff->wavyMagnitude = 100 * ramp + 16;
if (dsq->game->avatar->vel.x < 0)
wavyMagnitude = -wavyMagnitude;
if (eff->touchVel.x < 0)
eff->wavyMagnitude = -eff->wavyMagnitude;
/*
if (hitPerc > 0.35f)
wavyMagnitude = -wavyMagnitude;
*/
eff->wavyAngleOffset = (eff->hitPerc-0.5f)*PI;
wavyAngleOffset = (hitPerc-0.5f)*PI;
wavySave = wavy;
wavyLerpIn = 0;
eff->wavySave = eff->wavy;
eff->wavyLerpIn = 0;
}
if (wavyWaving)
if (eff->wavyWaving)
{
/*
float wavyMagnitude = wavyMagnitude;
if (dsq->continuity.form == FORM_FISH)
wavyMagnitude *= 0.1f;
*/
float wavyMagMult = 1;
if (dsq->continuity.form == FORM_FISH)
wavyMagMult = 0.4;
float spd = PI*1.1f;
float magRedSpd = 48;
float lerpSpd = 5.0;
for (int i = 0; i < wavy.size(); i++)
float wavySz = float(eff->wavy.size());
for (int i = 0; i < eff->wavy.size(); i++)
{
float weight = float(i)/float(wavy.size());
if (wavyFlip)
float weight = float(i)/wavySz;
if (eff->wavyFlip)
weight = 1.0f-weight;
if (weight < 0.125f)
weight *= 0.5f;
wavy[i].x = sinf(wavyAngleOffset + (float(i)/float(wavy.size()))*PI)*float(wavyMagnitude*wavyMagMult)*weight;
if (!wavySave.empty())
eff->wavy[i].x = sinf(eff->wavyAngleOffset + (float(i)/wavySz)*PI)*float(eff->wavyMagnitude*eff->effectMult)*weight;
if (!eff->wavySave.empty())
{
if (wavyLerpIn < 1)
wavy[i].x = wavy[i].x*wavyLerpIn + (wavySave[i].x*(1.0f-wavyLerpIn));
if (eff->wavyLerpIn < 1)
eff->wavy[i].x = eff->wavy[i].x*eff->wavyLerpIn + (eff->wavySave[i].x*(1.0f-eff->wavyLerpIn));
}
}
if (wavyLerpIn < 1)
if (eff->wavyLerpIn < 1)
{
wavyLerpIn += dt*lerpSpd;
if (wavyLerpIn > 1)
wavyLerpIn = 1;
eff->wavyLerpIn += dt*lerpSpd;
if (eff->wavyLerpIn > 1)
eff->wavyLerpIn = 1;
}
wavyAngleOffset += dt*spd;
if (wavyMagnitude > 0)
eff->wavyAngleOffset += dt*spd;
if (eff->wavyMagnitude > 0)
{
wavyMagnitude -= magRedSpd*dt;
if (wavyMagnitude < 0)
wavyMagnitude = 0;
eff->wavyMagnitude -= magRedSpd*dt;
if (eff->wavyMagnitude < 0)
eff->wavyMagnitude = 0;
}
else
{
wavyMagnitude += magRedSpd*dt;
if (wavyMagnitude > 0)
wavyMagnitude = 0;
eff->wavyMagnitude += magRedSpd*dt;
if (eff->wavyMagnitude > 0)
eff->wavyMagnitude = 0;
}
//std::cout << "setting grid from wav w/ wavyWaving\n";
@ -194,24 +175,6 @@ void Element::updateEffects(float dt)
//std::cout << "not waving";
setGridFromWavy();
}
/*
for (int i = touchIdx; i < wavy.size()-1; i++)
{
wavyPull(i, i+1, dt);
}
for (int i = touchIdx; i >= 0; i--)
{
wavyPull(i, i-1, dt);
}
*/
// normal down pull
/*
for (int i = 0; i < wavy.size()-1; i++)
{
wavyPull(i, i+1, dt);
}
*/
}
}
break;
@ -224,16 +187,16 @@ void Element::update(float dt)
if (!core->particlesPaused)
{
updateLife(dt);
updateEffects(dt);
if (eff)
updateEffects(dt);
if (drawGrid)
updateGrid(dt);
}
// updateCullVariables();
}
Element::~Element()
{
freeEffectData();
}
void Element::destroy()
@ -243,7 +206,7 @@ void Element::destroy()
int Element::getElementEffectIndex()
{
return elementEffectIndex;
return eff ? eff->elementEffectIndex : -1;
}
void Element::setGridFromWavy()
@ -251,16 +214,18 @@ void Element::setGridFromWavy()
if (drawGrid)
{
//std::cout << "set grid from wavy (" << xDivs << ", " << yDivs << ")\n"
const float w = float(getWidth());
for (int x = 0; x < xDivs-1; x++)
{
for (int y = 0; y < yDivs; y++)
{
int wavy_y = (yDivs - y)-1;
if (wavy_y < wavy.size())
const int wavy_y = (yDivs - y)-1;
const float tmp = eff->wavy[wavy_y].x / w;
if (wavy_y < eff->wavy.size())
{
drawGrid[x][y].x = (wavy[wavy_y].x/float(getWidth()) - 0.5f);
drawGrid[x+1][y].x = (wavy[wavy_y].x/float(getWidth()) + 0.5f);
drawGrid[x][y].x = tmp - 0.5f;
drawGrid[x+1][y].x = tmp + 0.5f;
}
}
}
@ -279,9 +244,9 @@ void Element::setElementEffectByIndex(int eidx)
alpha.stop();
alpha = 1;
elementEffectIndex = eidx;
ElementEffect e = dsq->getElementEffectByIndex(eidx);
if(e.type != EFX_NONE)
ensureEffectData();
switch(e.type)
{
@ -305,37 +270,32 @@ void Element::setElementEffectByIndex(int eidx)
sprintf(buf, "setting wavy segsy: %d radius: %d min: %d max: %d", e.segsy, e.wavy_radius, e.wavy_min, e.wavy_max);
debugLog(buf);
*/
wavy.resize(e.segsy);
eff->wavy.resize(e.segsy);
float bity = float(getHeight())/float(e.segsy);
for (int i = 0; i < wavy.size(); i++)
for (int i = 0; i < eff->wavy.size(); i++)
{
wavy[i] = Vector(0, -(i*bity));
eff->wavy[i] = Vector(0, -(i*bity));
}
//wavySave = wavy;
wavyRadius = e.wavy_radius;
wavyFlip = e.wavy_flip;
wavyMin = bity;
wavyMax = bity*1.2f;
//wavyRadius = 8;
eff->wavyFlip = e.wavy_flip;
eff->wavyMin = bity;
eff->wavyMax = bity*1.2f;
createGrid(2, e.segsy);
setGridFromWavy();
//createGrid(8,8);
/*
wavyMin = e.wavy_min;
wavyMax = e.wavy_max;
*/
setStatic(false);
}
break;
default:
freeEffectData();
setStatic(true);
break;
}
elementEffectType = e.type;
if (eff)
{
eff->elementEffectIndex = eidx;
eff->elementEffectType = e.type;
}
}
void Element::render()
@ -364,32 +324,8 @@ void Element::render()
}
#endif
if (this->elementEffectType == EFX_WAVY)
{
//debugLog("rendering efx_wavy");
}
Quad::render();
/*
if (!wavy.empty())
{
glDisable(GL_BLEND);
Vector pos = position;
pos.y = position.y + (getHeight()*scale.y)/2.0f;
glBegin(GL_LINES);
for (int i = 0; i < wavy.size()-1; i++)
{
glColor4f(1, 0, 0, 1);
glVertex3f(wavy[i].x+pos.x, wavy[i].y+pos.y, 0);
glVertex3f(wavy[i+1].x+pos.x, wavy[i+1].y+pos.y, 0);
}
glEnd();
glEnable(GL_BLEND);
}
*/
renderBorder = false;
}
@ -416,19 +352,3 @@ void Element::fillGrid()
}
}
// override this functionality as needed
bool Element::canSeeAvatar(Avatar *avatar)
{
return false;
}
bool Element::isActive()
{
return true;
}
float Element::getSortDepth()
{
return Quad::getSortDepth() - bgLayer*0.01f;
}

View file

@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../BBGE/Quad.h"
class Avatar;
class Entity;
enum ElementFlag
@ -42,50 +42,48 @@ enum ElementFlag
*/
};
struct ElementEffectData
{
ElementEffectData();
int elementEffectType;
float wavyAngleOffset, wavyMagnitude, wavyLerpIn;
float wavyMin, wavyMax;
float hitPerc, effectMult;
bool wavyWaving, wavyFlip, touching;
Vector touchVel;
std::vector<Vector> wavy, wavySave;
int elementEffectIndex; // used by editor only
};
class Element : public Quad
{
public:
Element();
~Element();
void destroy();
//void interact(Interaction::Type interactionType, Avatar *avatar);
bool canSeeAvatar(Avatar *avatar);
void update(float dt);
bool isActive();
//InteractionContainer interactions;
int templateIdx;
int bgLayer;
Element *bgLayerNext;
float getSortDepth();
void render();
//Flags elementFlags;
ElementFlag elementFlag;
void fillGrid();
bool isElementActive() { return elementActive; }
int getElementEffectIndex();
void setElementEffectByIndex(int e);
void setElementActive(bool v) { elementActive = v; }
void doInteraction(Entity *ent, float mult, float touchWidth);
protected:
void ensureEffectData();
void freeEffectData();
void setGridFromWavy();
float wavyAngleOffset, wavyMagnitude, wavyLerpIn;
bool wavyWaving, wavyFlip;
void wavyPull(int to, int from, float dt);
std::vector<Vector> wavy, wavySave;
float wavyRadius, wavyMin, wavyMax;
ElementEffectData *eff;
void updateEffects(float dt);
int elementEffectIndex, elementEffectType;
bool elementActive;
};
/*
class BoxElement : public Element
{
public:
BoxElement(int width, int height);
//bool isOnScreen();
protected:
int ww,hh;
};
*/
typedef std::vector<Element*> ElementContainer;

View file

@ -5789,6 +5789,7 @@ void Game::rebuildElementUpdateList()
dsq->getRenderObjectLayer(i)->update = false;
elementUpdateList.clear();
elementInteractionList.clear();
for (int i = 0; i < dsq->getNumElements(); i++)
//for (int i = LR_ELEMENTS1; i <= LR_ELEMENTS8; i++)
{
@ -5800,6 +5801,11 @@ void Game::rebuildElementUpdateList()
{
elementUpdateList.push_back(e);
}
ElementEffect ee = dsq->getElementEffectByIndex(e->getElementEffectIndex());
if(ee.type == EFX_WAVY)
{
elementInteractionList.push_back(e);
}
}
}
}

View file

@ -568,7 +568,7 @@ protected:
typedef std::vector<Quad*> QuadList;
typedef std::vector<QuadList> QuadArray;
typedef std::list<Element*> ElementUpdateList;
typedef std::vector<Element*> ElementUpdateList;
// Note: although this is a bitmask, only one of these values may be set at a time!
enum ObsType
@ -961,6 +961,7 @@ public:
GridRender *gridRender, *gridRender2, *gridRender3, *edgeRender, *gridRenderEnt;
void toggleGridRender();
ElementUpdateList elementUpdateList;
ElementUpdateList elementInteractionList;
bool invinciblity;