diff --git a/Aquaria/CollideEntity.cpp b/Aquaria/CollideEntity.cpp index 7af48c6..876fb73 100644 --- a/Aquaria/CollideEntity.cpp +++ b/Aquaria/CollideEntity.cpp @@ -32,6 +32,10 @@ CollideEntity::CollideEntity() : Entity() this->updateCull = 4000; } +CollideEntity::~CollideEntity() +{ +} + void CollideEntity::entityDied(Entity *e) { Entity::entityDied(e); diff --git a/Aquaria/CollideEntity.h b/Aquaria/CollideEntity.h index b68213f..48e9885 100644 --- a/Aquaria/CollideEntity.h +++ b/Aquaria/CollideEntity.h @@ -27,6 +27,7 @@ class CollideEntity : public Entity { public: CollideEntity(); + virtual ~CollideEntity(); float bounceAmount; float weight; void updateMovement(float dt); diff --git a/Aquaria/Entity.cpp b/Aquaria/Entity.cpp index 5d547e9..7e3f30c 100644 --- a/Aquaria/Entity.cpp +++ b/Aquaria/Entity.cpp @@ -286,11 +286,17 @@ Entity::Entity() setDamageTarget(DT_AVATAR_SEED, false); stopSoundsOnDeath = false; + minimapIcon = 0; //debugLog("End Entity::Entity()"); } +Entity::~Entity() +{ + delete minimapIcon; +} + void Entity::setDeathScene(bool v) { deathScene = v; @@ -1238,6 +1244,9 @@ void Entity::update(float dt) vel = backupVel; updateSoundPosition(); + + if(minimapIcon) + minimapIcon->update(dt); } void Entity::postUpdate(float dt) @@ -2413,6 +2422,10 @@ void Entity::onEnterState(int action) hair->fadeAlphaWithLife = 1; hair = 0; } + if(minimapIcon) + { + minimapIcon->alpha.interpolateTo(0, 0.1f); + } } break; @@ -3149,3 +3162,10 @@ void Entity::updateSoundPosition() { SoundHolder::updateSoundPosition(position.x + offset.x, position.y + offset.y); } + +MinimapIcon *Entity::ensureMinimapIcon() +{ + if(!minimapIcon) + minimapIcon = new MinimapIcon; + return minimapIcon; +} diff --git a/Aquaria/Entity.h b/Aquaria/Entity.h index 0aff3ed..00efb01 100644 --- a/Aquaria/Entity.h +++ b/Aquaria/Entity.h @@ -35,6 +35,7 @@ using namespace tinyxml2; class ManaBall; class Path; +struct MinimapIcon; struct BoneLock { @@ -202,6 +203,7 @@ class Entity : public Quad, public StateMachine, public SoundHolder { public: Entity(); + virtual ~Entity(); virtual void init(){} virtual void postInit(){} @@ -502,6 +504,9 @@ public: Vector getPushVec() const { return pushVec; } float getPushDamage() const { return pushDamage; } + MinimapIcon *minimapIcon; + MinimapIcon *ensureMinimapIcon(); + protected: bool calledEntityDied; Path *waterBubble; diff --git a/Aquaria/Game.h b/Aquaria/Game.h index 2320345..ff49f85 100644 --- a/Aquaria/Game.h +++ b/Aquaria/Game.h @@ -135,6 +135,20 @@ enum EditTypes }; #endif +// impl is in Minimap.cpp +struct MinimapIcon +{ + MinimapIcon(); + bool setTexture(std::string); + void update(float dt); + CountedPtr tex; + InterpolatedVector color, alpha, size; + float throbMult; + bool scaleWithDistance; + + static const Vector defaultSize; +}; + class ManaBall : public Quad { public: diff --git a/Aquaria/GridRender.h b/Aquaria/GridRender.h index 43e04b3..e3913e2 100644 --- a/Aquaria/GridRender.h +++ b/Aquaria/GridRender.h @@ -63,8 +63,17 @@ protected: float lightLevel; void onUpdate(float dt); void onRender(); + void renderIcon(MinimapIcon *ico, const Vector& pos); InterpolatedVector lerp; + +public: + static bool setWaterBitTex(const std::string& name); + static bool setTopTex(const std::string& name); + static bool setBottomTex(const std::string& name); + static bool setAvatarTex(const std::string& name); + static bool setHealthBarTex(const std::string& name); + static bool setMaxHealthMarkerTex(const std::string& name); }; class WorldMapRender : public RenderObject, public ActionMapper diff --git a/Aquaria/MiniMapRender.cpp b/Aquaria/MiniMapRender.cpp index d952e89..b441348 100644 --- a/Aquaria/MiniMapRender.cpp +++ b/Aquaria/MiniMapRender.cpp @@ -47,8 +47,6 @@ namespace MiniMapRenderSpace const float iconBaseSize = 14; // Additional radius added (or subtracted) by "throb" effect const float iconThrobSize = 6; - // Size of cooking icon (fixed) - const float iconCookSize = 16; // Maximum offset of warp/save/cooking icons from center of minimap const float iconMaxOffset = miniMapRadius * miniMapScale * (7.0f/8.0f); // Distance at which the icon decreases to minimum size @@ -66,11 +64,9 @@ namespace MiniMapRenderSpace const int healthMarkerSize = 20; - CountedPtr texCook = 0; CountedPtr texWaterBit = 0; CountedPtr texMinimapBtm = 0; CountedPtr texMinimapTop = 0; - CountedPtr texRipple = 0; CountedPtr texNaija = 0; CountedPtr texHealthBar = 0; CountedPtr texMarker = 0; @@ -91,6 +87,69 @@ namespace MiniMapRenderSpace using namespace MiniMapRenderSpace; +const Vector MinimapIcon::defaultSize(iconBaseSize, iconBaseSize); + +MinimapIcon::MinimapIcon() +: color(1,1,1), alpha(1), size(defaultSize), throbMult(iconThrobSize), scaleWithDistance(true) +{ +} + +void MinimapIcon::update(float dt) +{ + color.update(dt); + alpha.update(dt); + size.update(dt); +} + + +// pretty much copied from RenderObject::setTexture() +static bool _setTex(CountedPtr &tex, std::string name) +{ + stringToLowerUserData(name); + + if (name.empty()) + { + tex = NULL; + return false; + } + + if(tex && tex->getLoadResult() == TEX_SUCCESS && name == tex->name) + return true; // no texture change + + tex = core->addTexture(name); + return tex && tex->getLoadResult() == TEX_SUCCESS; +} + +bool MinimapIcon::setTexture(std::string name) +{ + return _setTex(tex, name); +} + +bool MiniMapRender::setWaterBitTex(const std::string& name) +{ + return _setTex(texWaterBit, name); +} +bool MiniMapRender::setTopTex(const std::string& name) +{ + return _setTex(texMinimapTop, name); +} +bool MiniMapRender::setBottomTex(const std::string& name) +{ + return _setTex(texMinimapBtm, name); +} +bool MiniMapRender::setAvatarTex(const std::string& name) +{ + return _setTex(texNaija, name); +} +bool MiniMapRender::setHealthBarTex(const std::string& name) +{ + return _setTex(texHealthBar, name); +} +bool MiniMapRender::setMaxHealthMarkerTex(const std::string& name) +{ + return _setTex(texMarker, name); +} + MiniMapRender::MiniMapRender() : RenderObject() { toggleOn = 1; @@ -108,13 +167,11 @@ MiniMapRender::MiniMapRender() : RenderObject() cull = false; lightLevel = 1.0; - texCook = core->addTexture("GUI/ICON-FOOD"); - texWaterBit = core->addTexture("GUI/MINIMAP/WATERBIT"); - texMinimapBtm = core->addTexture("GUI/MINIMAP/BTM"); - texMinimapTop = core->addTexture("GUI/MINIMAP/TOP"); - texRipple = core->addTexture("GUI/MINIMAP/RIPPLE"); - texNaija = core->addTexture("GEMS/NAIJA-TOKEN"); - texHealthBar = core->addTexture("PARTICLES/glow-masked"); + texWaterBit = core->addTexture("gui/minimap/waterbit"); + texMinimapBtm = core->addTexture("gui/minimap/btm"); + texMinimapTop = core->addTexture("gui/minimap/top"); + texNaija = core->addTexture("gems/naija-token"); + texHealthBar = core->addTexture("particles/glow-masked"); texMarker = core->addTexture("gui/minimap/marker"); buttons.clear(); @@ -164,11 +221,9 @@ void MiniMapRender::destroy() { RenderObject::destroy(); - UNREFTEX(texCook); UNREFTEX(texWaterBit); UNREFTEX(texMinimapBtm); UNREFTEX(texMinimapTop); - UNREFTEX(texRipple); UNREFTEX(texNaija); UNREFTEX(texHealthBar); UNREFTEX(texMarker); @@ -541,14 +596,10 @@ void MiniMapRender::onRender() if (!radarHide) { - const float factor = sinf(game->getTimer()*PI); - const float iconSize = iconBaseSize + factor*iconThrobSize; - texRipple->apply(); - // FIXME: use getFirstPathOfType? for (int i = 0; i < dsq->game->getNumPaths(); i++) { Path *p = dsq->game->getPath(i); - if (!p->nodes.empty() && (p->pathType==PATH_COOK || p->pathType==PATH_SAVEPOINT || p->pathType==PATH_WARP)) + if (!p->nodes.empty() && p->minimapIcon) { bool render = true; Path *p2 = dsq->game->getNearestPath(p->nodes[0].position, PATH_RADARHIDE); @@ -562,94 +613,17 @@ void MiniMapRender::onRender() if (render) { - Vector pt(p->nodes[0].position); - Vector d = pt - dsq->game->avatar->position; - const float len = d.getLength2D(); - float iconScale; - if (len < iconMaxOffset) - { - iconScale = 1; - } - else - { - d *= iconMaxOffset / len; - float k; - if (len < iconMaxDistance) - k = ((iconMaxDistance - len) / (iconMaxDistance - iconMaxOffset)); - else - k = 0; - iconScale = iconMinScale + k*(1-iconMinScale); - } - const Vector miniMapPos = Vector(d)*Vector(1.0f/miniMapScale, 1.0f/miniMapScale); - - switch(p->pathType) - { - case PATH_COOK: - { - glColor4f(1, 1, 1, 1); - - glTranslatef(miniMapPos.x, miniMapPos.y, 0); - const float sz = iconCookSize * iconScale; - - texCook->apply(); - - glBegin(GL_QUADS); - glTexCoord2f(0, 1); - glVertex2f(-sz, sz); - glTexCoord2f(1, 1); - glVertex2f(sz, sz); - glTexCoord2f(1, 0); - glVertex2f(sz, -sz); - glTexCoord2f(0, 0); - glVertex2f(-sz, -sz); - glEnd(); - - glTranslatef(-miniMapPos.x, -miniMapPos.y, 0); - texRipple->apply(); - render = false; // Skip common rendering code - } - break; - case PATH_SAVEPOINT: - { - glColor4f(1.0, 0, 0, alphaValue*0.75f); - } - break; - case PATH_WARP: - { - if (p->naijaHome) - { - glColor4f(1.0, 0.9, 0.2, alphaValue*0.75f); - } - else - { - glColor4f(1.0, 1.0, 1.0, alphaValue*0.75f); - } - } - break; - } - - if (render) - { - glTranslatef(miniMapPos.x, miniMapPos.y, 0); - const float sz = iconSize * iconScale; - - glBegin(GL_QUADS); - glTexCoord2f(0, 1); - glVertex2f(-sz, sz); - glTexCoord2f(1, 1); - glVertex2f(sz, sz); - glTexCoord2f(1, 0); - glVertex2f(sz, -sz); - glTexCoord2f(0, 0); - glVertex2f(-sz, -sz); - glEnd(); - - glTranslatef(-miniMapPos.x, -miniMapPos.y, 0); - } + renderIcon(p->minimapIcon, p->nodes[0].position); } } } - texRipple->unbind(); + + FOR_ENTITIES(i) + { + Entity *e = *i; + if(e->minimapIcon) + renderIcon(e->minimapIcon, e->position); + } } glColor4f(1,1,1, alphaValue); @@ -789,3 +763,48 @@ void MiniMapRender::onRender() #endif } +void MiniMapRender::renderIcon(MinimapIcon *ico, const Vector& pos) +{ + if(!ico->tex) + return; + Vector d = pos - dsq->game->avatar->position; + const float len = d.getLength2D(); + float iconScale; + if (len < iconMaxOffset || !ico->scaleWithDistance) + { + iconScale = 1; + } + else + { + d *= iconMaxOffset / len; + float k; + if (len < iconMaxDistance) + k = ((iconMaxDistance - len) / (iconMaxDistance - iconMaxOffset)); + else + k = 0; + iconScale = iconMinScale + k*(1-iconMinScale); + } + + ico->tex->apply(); + const Vector c = ico->color; + const float a = ico->alpha.x * this->alpha.x; + glColor4f(c.x, c.y, c.z, a); + + const Vector miniMapPos = Vector(d)*Vector(1.0f/miniMapScale, 1.0f/miniMapScale); + const float factor = sinf(game->getTimer()*PI); + const float addSize = factor * ico->throbMult; + const Vector sz = (ico->size + Vector(addSize, addSize)) * iconScale; + glPushMatrix(); + glTranslatef(miniMapPos.x, miniMapPos.y, 0); + glBegin(GL_QUADS); + glTexCoord2f(0, 1); + glVertex2f(-sz.x, sz.y); + glTexCoord2f(1, 1); + glVertex2f(sz.x, sz.y); + glTexCoord2f(1, 0); + glVertex2f(sz.x, -sz.y); + glTexCoord2f(0, 0); + glVertex2f(-sz.x, -sz.y); + glEnd(); + glPopMatrix(); +} diff --git a/Aquaria/Path.cpp b/Aquaria/Path.cpp index 5763e91..289a621 100644 --- a/Aquaria/Path.cpp +++ b/Aquaria/Path.cpp @@ -32,7 +32,6 @@ Path::Path() pathShape = PATHSHAPE_RECT; toFlip = -1; replayVox = 0; - naijaHome = false; addEmitter = false; emitter = 0; active = true; @@ -55,6 +54,7 @@ Path::Path() spiritFreeze = true; pauseFreeze = true; activationRange = 800; + minimapIcon = 0; } void Path::clampPosition(Vector *pos, float radius) @@ -207,6 +207,9 @@ int Path::getDown() void Path::destroy() { + delete minimapIcon; + minimapIcon = NULL; + if (emitter) { emitter->safeKill(); @@ -346,6 +349,11 @@ void Path::refreshScript() else if (label == "cook") { pathType = PATH_COOK; + ensureMinimapIcon(); + minimapIcon->setTexture("gui/icon-food"); + minimapIcon->size = Vector(16, 16); + minimapIcon->scaleWithDistance = false; + minimapIcon->throbMult = 0.0f; } else if (label == "zoom") { @@ -371,6 +379,10 @@ void Path::refreshScript() else if (label == "savepoint") { pathType = PATH_SAVEPOINT; + ensureMinimapIcon(); + minimapIcon->setTexture("gui/minimap/ripple"); + minimapIcon->color = Vector(1, 0, 0); + minimapIcon->alpha = 0.75f; } else if (label == "steam") { @@ -405,6 +417,10 @@ void Path::refreshScript() else if (type == "out") localWarpType = LOCALWARP_OUT; pathType = PATH_WARP; + + ensureMinimapIcon(); + minimapIcon->setTexture("gui/minimap/ripple"); + minimapIcon->alpha = 0.75f; } else if (label == "vox" || label == "voice") { @@ -422,10 +438,12 @@ void Path::refreshScript() // warpType is just char, which does not automatically skip spaces like strings would warpType = warpTypeStr.length() ? warpTypeStr[0] : 0; + ensureMinimapIcon(); + minimapIcon->setTexture("gui/minimap/ripple"); + minimapIcon->alpha = 0.75f; if (warpMap.find("vedha")!=std::string::npos) - { - naijaHome = true; - } + minimapIcon->color = Vector(1.0f, 0.9f, 0.2f); + pathType = PATH_WARP; } else if (label == "se") @@ -489,6 +507,9 @@ void Path::init() void Path::update(float dt) { + if(minimapIcon) + minimapIcon->update(dt); + if (!(pauseFreeze && dsq->game->isPaused()) && !(spiritFreeze && dsq->game->isWorldPaused())) { if (addEmitter && emitter) @@ -731,3 +752,10 @@ void Path::luaDebugMsg(const std::string &func, const std::string &msg) { debugLog("luaScriptError: Path [" + name + "]: " + func + " : " + msg); } + +MinimapIcon *Path::ensureMinimapIcon() +{ + if(!minimapIcon) + minimapIcon = new MinimapIcon; + return minimapIcon; +} diff --git a/Aquaria/Path.h b/Aquaria/Path.h index 170ff65..ed04ae3 100644 --- a/Aquaria/Path.h +++ b/Aquaria/Path.h @@ -28,6 +28,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef PATH_MAX // May be set by a system header. +struct MinimapIcon; + class PathNode { public: @@ -107,11 +109,14 @@ public: void activate(Entity *e=0); void refreshScript(); + MinimapIcon *ensureMinimapIcon(); + Script *script; bool updateFunction; bool activateFunction; bool cursorActivation; int replayVox; + MinimapIcon *minimapIcon; std::string warpMap, warpNode, vox, spawnEnemyName, content; float amount, time; @@ -130,7 +135,6 @@ public: LocalWarpType localWarpType; - bool naijaHome; bool catchActions; bool songFunc, songNoteFunc, songNoteDoneFunc; bool neverSpawned; diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index 16fdfae..09d9c50 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -9403,6 +9403,108 @@ luaFunc(getPerformanceFreq) #endif } +// ---------- Minimap related ------------------ + +luaFunc(getMinimapRender) +{ + luaReturnPtr(dsq->game->miniMapRender); +} + +luaFunc(minimap_setWaterBitTex) +{ + luaReturnBool(MiniMapRender::setWaterBitTex(getString(L))); +} +luaFunc(minimap_setTopTex) +{ + luaReturnBool(MiniMapRender::setTopTex(getString(L))); +} +luaFunc(minimap_setBottomTex) +{ + luaReturnBool(MiniMapRender::setBottomTex(getString(L))); +} +luaFunc(minimap_setAvatarIconTex) +{ + luaReturnBool(MiniMapRender::setAvatarTex(getString(L))); +} +luaFunc(minimap_setHealthBarTex) +{ + luaReturnBool(MiniMapRender::setAvatarTex(getString(L))); +} +luaFunc(minimap_setMaxHealthMarkerTex) +{ + luaReturnBool(MiniMapRender::setMaxHealthMarkerTex(getString(L))); +} + +template +int mmicon_delete(lua_State *L, T *obj) +{ + delete obj->minimapIcon; + obj->minimapIcon = NULL; + luaReturnNil(); +} +template +int mmicon_tex(lua_State *L, T *obj) +{ + if(!obj) + luaReturnNil(); + MinimapIcon *ico = obj->ensureMinimapIcon(); + bool good = ico->setTexture(getString(L, 2)); + luaReturnBool(good); +} +template +int mmicon_size(lua_State *L, T *obj) +{ + if(!obj) + luaReturnNil(); + luaReturnNum(interpolateVec2(L, obj->ensureMinimapIcon()->size, 2)); +} +template +int mmicon_color(lua_State *L, T *obj) +{ + if(!obj) + luaReturnNil(); + luaReturnNum(interpolateVec3(L, obj->ensureMinimapIcon()->color, 2)); +} +template +int mmicon_alpha(lua_State *L, T *obj) +{ + if(!obj) + luaReturnNil(); + luaReturnNum(interpolateVec1(L, obj->ensureMinimapIcon()->alpha, 2)); +} +template +int mmicon_scaleWithDistance(lua_State *L, T *obj) +{ + if(!obj) + luaReturnNil(); + obj->ensureMinimapIcon()->scaleWithDistance = getBool(L, 2); + luaReturnNil(); +} +template +int mmicon_throb(lua_State *L, T *obj) +{ + if(!obj) + luaReturnNil(); + obj->ensureMinimapIcon()->throbMult = lua_tonumber(L, 2); + luaReturnNil(); +} + +luaFunc(entity_mmicon_delete) { return mmicon_delete(L, entity(L)); } +luaFunc(entity_mmicon_tex) { return mmicon_tex(L, entity(L)); } +luaFunc(entity_mmicon_size) { return mmicon_size(L, entity(L)); } +luaFunc(entity_mmicon_color) { return mmicon_color(L, entity(L)); } +luaFunc(entity_mmicon_alpha) { return mmicon_alpha(L, entity(L)); } +luaFunc(entity_mmicon_scaleWithDistance) { return mmicon_scaleWithDistance(L, entity(L)); } +luaFunc(entity_mmicon_throb) { return mmicon_throb(L, entity(L)); } + +luaFunc(node_mmicon_delete) { return mmicon_delete(L, path(L)); } +luaFunc(node_mmicon_tex) { return mmicon_tex(L, path(L)); } +luaFunc(node_mmicon_size) { return mmicon_size(L, path(L)); } +luaFunc(node_mmicon_color) { return mmicon_color(L, path(L)); } +luaFunc(node_mmicon_alpha) { return mmicon_alpha(L, path(L)); } +luaFunc(node_mmicon_scaleWithDistance) { return mmicon_scaleWithDistance(L, path(L)); } +luaFunc(node_mmicon_throb) { return mmicon_throb(L, path(L)); } + //-------------------------------------------------------------------------------------------- #define luaRegister(func) {#func, l_##func} @@ -10432,7 +10534,26 @@ static const struct { luaRegister(getPerformanceCounter), luaRegister(getPerformanceFreq), - + luaRegister(getMinimapRender), + luaRegister(minimap_setWaterBitTex), + luaRegister(minimap_setTopTex), + luaRegister(minimap_setBottomTex), + luaRegister(minimap_setAvatarIconTex), + luaRegister(minimap_setHealthBarTex), + luaRegister(entity_mmicon_delete), + luaRegister(entity_mmicon_tex), + luaRegister(entity_mmicon_size), + luaRegister(entity_mmicon_color), + luaRegister(entity_mmicon_alpha), + luaRegister(entity_mmicon_scaleWithDistance), + luaRegister(entity_mmicon_throb), + luaRegister(node_mmicon_delete), + luaRegister(node_mmicon_tex), + luaRegister(node_mmicon_size), + luaRegister(node_mmicon_color), + luaRegister(node_mmicon_alpha), + luaRegister(node_mmicon_scaleWithDistance), + luaRegister(node_mmicon_throb), #undef MK_FUNC #undef MK_ALIAS diff --git a/Aquaria/ScriptedEntity.cpp b/Aquaria/ScriptedEntity.cpp index 6316e5f..3bc00b2 100644 --- a/Aquaria/ScriptedEntity.cpp +++ b/Aquaria/ScriptedEntity.cpp @@ -80,6 +80,10 @@ ScriptedEntity::ScriptedEntity(const std::string &scriptName, Vector position, E } } +ScriptedEntity::~ScriptedEntity() +{ +} + void ScriptedEntity::setAutoSkeletalUpdate(bool v) { skeletalSprite.ignoreUpdate = !v; @@ -814,4 +818,3 @@ void ScriptedEntity::deathNotify(RenderObject *r) } CollideEntity::deathNotify(r); } - diff --git a/Aquaria/ScriptedEntity.h b/Aquaria/ScriptedEntity.h index 55276c4..144a564 100644 --- a/Aquaria/ScriptedEntity.h +++ b/Aquaria/ScriptedEntity.h @@ -30,6 +30,7 @@ class ScriptedEntity : public CollideEntity, public Segmented { public: ScriptedEntity(const std::string &scriptName, Vector position, EntityType et = ET_ENEMY); + virtual ~ScriptedEntity(); void init(); void postInit(); void destroy(); @@ -76,7 +77,7 @@ public: ParticleEffect pullEmitter; float manaBallAmount; - + void initEmitter(int emit, const std::string &file); void startEmitter(int emit); void stopEmitter(int emit);