From 6f9063ce6d04d4d9f1c7160a7a5e4a45398a6e3a Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 24 Sep 2013 17:00:06 +0200 Subject: [PATCH] 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. --- Aquaria/Avatar.cpp | 15 ++- Aquaria/Avatar.h | 1 + Aquaria/DSQ.cpp | 19 +-- Aquaria/DSQ.h | 5 +- Aquaria/Element.cpp | 310 ++++++++++++++++---------------------------- Aquaria/Element.h | 44 +++---- Aquaria/Game.cpp | 6 + Aquaria/Game.h | 3 +- 8 files changed, 163 insertions(+), 240 deletions(-) diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index 805f31c..a44207b 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -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); + } + } } diff --git a/Aquaria/Avatar.h b/Aquaria/Avatar.h index 9b922b2..7b3d315 100644 --- a/Aquaria/Avatar.h +++ b/Aquaria/Avatar.h @@ -346,6 +346,7 @@ public: int leaches; float shieldPoints; + float elementEffectMult; bool blockBackFlip; diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index 207aab8..2dc65dc 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -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()); diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 4553fdd..60d178a 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -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; diff --git a/Aquaria/Element.cpp b/Aquaria/Element.cpp index c4a94ef..9c8cc51 100644 --- a/Aquaria/Element.cpp +++ b/Aquaria/Element.cpp @@ -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; -} - diff --git a/Aquaria/Element.h b/Aquaria/Element.h index e3b156b..c2802c3 100644 --- a/Aquaria/Element.h +++ b/Aquaria/Element.h @@ -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 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 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 ElementContainer; diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index f4a105f..301d1f6 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -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); + } } } } diff --git a/Aquaria/Game.h b/Aquaria/Game.h index ed6aa79..0cdf44f 100644 --- a/Aquaria/Game.h +++ b/Aquaria/Game.h @@ -568,7 +568,7 @@ protected: typedef std::vector QuadList; typedef std::vector QuadArray; -typedef std::list ElementUpdateList; +typedef std::vector 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;