mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-12-26 14:45:48 +00:00
Shot Lua API update + related internal changes.
With this change, shots are no longer stored in a std::list. In the current code, the global shot store may be modified while iterating, this did not cause problems with the list implementation, but would easily crash if a shot is removed while iterating. To fix this, a 2nd vector stores shots to be deleted from the global store and does so when no iteration is in progress and modifying the vector is safe. Added functions: getFirstShot -- for iterating over all shots on the map getNextShot shot_setFirer shot_setExtraDamage shot_getExtraDamage shot_getDamage shot_getDamageType shot_getName
This commit is contained in:
parent
eef2289fb2
commit
0784d1b9df
7 changed files with 134 additions and 38 deletions
|
@ -2921,7 +2921,7 @@ void Avatar::formAbility(int ability)
|
|||
for (i = Shot::shots.begin(); i != Shot::shots.end(); i++)
|
||||
{
|
||||
Shot *s = (*i);
|
||||
if (s->shotData && !s->shotData->invisible)
|
||||
if (s->isActive() && s->shotData && !s->shotData->invisible)
|
||||
{
|
||||
if (!s->firer || s->firer->getEntityType()==ET_ENEMY)
|
||||
{
|
||||
|
@ -4935,23 +4935,23 @@ void Avatar::updateAura(float dt)
|
|||
*/
|
||||
for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); ++i)
|
||||
{
|
||||
//&& (*i)->life > 0.2f
|
||||
if ((*i) && dsq->game->isDamageTypeEnemy((*i)->getDamageType()) && (*i)->firer != this
|
||||
&& (!(*i)->shotData || !(*i)->shotData->ignoreShield))
|
||||
Shot *s = *i;
|
||||
if (s->isActive() && dsq->game->isDamageTypeEnemy(s->getDamageType()) && s->firer != this
|
||||
&& (!s->shotData || !s->shotData->ignoreShield))
|
||||
{
|
||||
|
||||
Vector diff = (*i)->position - shieldPosition;
|
||||
Vector diff = s->position - shieldPosition;
|
||||
if (diff.getSquaredLength2D() < sqr(AURA_SHIELD_RADIUS))
|
||||
{
|
||||
shieldPoints -= (*i)->getDamage();
|
||||
shieldPoints -= s->getDamage();
|
||||
auraHitEmitter.start();
|
||||
dsq->spawnParticleEffect("ReflectShot", (*i)->position);
|
||||
dsq->spawnParticleEffect("ReflectShot", s->position);
|
||||
core->sound->playSfx("Shield-Hit");
|
||||
(*i)->position += diff;
|
||||
//(*i)->target = 0;
|
||||
diff.setLength2D((*i)->maxSpeed);
|
||||
(*i)->velocity = diff;
|
||||
(*i)->reflectFromEntity(this);
|
||||
s->position += diff;
|
||||
//s->target = 0;
|
||||
diff.setLength2D(s->maxSpeed);
|
||||
s->velocity = diff;
|
||||
s->reflectFromEntity(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4665,6 +4665,8 @@ void DSQ::onUpdate(float dt)
|
|||
lockMouse();
|
||||
|
||||
Network::update();
|
||||
|
||||
Shot::clearShotGarbage();
|
||||
}
|
||||
|
||||
void DSQ::lockMouse()
|
||||
|
|
|
@ -2912,7 +2912,7 @@ void Entity::doSpellAvoidance(float dt, int range, float mod)
|
|||
{
|
||||
Shot *s = (Shot*)(*i);
|
||||
|
||||
if ((s->position - this->position).getSquaredLength2D() < sqr(range))
|
||||
if (s->isActive() && (s->position - this->position).getSquaredLength2D() < sqr(range))
|
||||
{
|
||||
for (int j = 0; j < ignoreShotDamageTypes.size(); j++)
|
||||
{
|
||||
|
|
|
@ -6253,6 +6253,7 @@ void Game::applyState()
|
|||
//core->afterEffectManager->addEffect(new RippleEffect());
|
||||
}
|
||||
Shot::shots.clear();
|
||||
Shot::deleteShots.clear();
|
||||
backdropQuad = 0;
|
||||
clearObsRows();
|
||||
inGameMenu = false;
|
||||
|
@ -8491,7 +8492,7 @@ void Game::handleShotCollisions(Entity *e, bool hasShield)
|
|||
for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); i++)
|
||||
{
|
||||
Shot *shot = *i;
|
||||
if (isEntityCollideWithShot(e, shot) && (!hasShield || (!shot->shotData || !shot->shotData->ignoreShield)))
|
||||
if (shot->isActive() && isEntityCollideWithShot(e, shot) && (!hasShield || (!shot->shotData || !shot->shotData->ignoreShield)))
|
||||
{
|
||||
Vector collidePoint = e->position+e->offset;
|
||||
if (e->getNumTargetPoints()>0)
|
||||
|
@ -8523,7 +8524,7 @@ void Game::handleShotCollisionsSkeletal(Entity *e)
|
|||
for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); i++)
|
||||
{
|
||||
Shot *shot = *i;
|
||||
if (isEntityCollideWithShot(e, shot))
|
||||
if (shot->isActive() && isEntityCollideWithShot(e, shot))
|
||||
{
|
||||
Bone *b = collideSkeletalVsCircle(e, shot->position, shot->collideRadius);
|
||||
if (b)
|
||||
|
@ -8540,7 +8541,7 @@ void Game::handleShotCollisionsHair(Entity *e, int num)
|
|||
for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); i++)
|
||||
{
|
||||
Shot *shot = *i;
|
||||
if (isEntityCollideWithShot(e, shot))
|
||||
if (shot->isActive() && isEntityCollideWithShot(e, shot))
|
||||
{
|
||||
bool b = collideHairVsCircle(e, num, shot->position, 8);
|
||||
if (b)
|
||||
|
@ -10886,6 +10887,7 @@ void Game::removeState()
|
|||
|
||||
debugLog("killAllShots");
|
||||
Shot::killAllShots();
|
||||
Shot::clearShotGarbage();
|
||||
debugLog("killAllBeams");
|
||||
Beam::killAllBeams();
|
||||
debugLog("killAllWebs");
|
||||
|
|
|
@ -1811,6 +1811,22 @@ luaFunc(web_getNumPoints)
|
|||
luaReturnInt(num);
|
||||
}
|
||||
|
||||
luaFunc(getFirstShot)
|
||||
{
|
||||
luaReturnPtr(Shot::getFirstShot());
|
||||
}
|
||||
|
||||
luaFunc(getNextShot)
|
||||
{
|
||||
luaReturnPtr(Shot::getNextShot());
|
||||
}
|
||||
|
||||
luaFunc(shot_getName)
|
||||
{
|
||||
Shot *s = getShot(L);
|
||||
luaReturnStr(s ? s->getName() : "");
|
||||
}
|
||||
|
||||
luaFunc(shot_setOut)
|
||||
{
|
||||
Shot *shot = getShot(L);
|
||||
|
@ -1859,11 +1875,26 @@ luaFunc(shot_getFirer)
|
|||
luaReturnPtr(shot ? shot->firer : NULL);
|
||||
}
|
||||
|
||||
luaFunc(shot_setFirer)
|
||||
{
|
||||
Shot *shot = getShot(L);
|
||||
if(shot)
|
||||
{
|
||||
Entity *e = lua_isuserdata(L, 2) ? entity(L, 2) : NULL;
|
||||
shot->firer = e;
|
||||
}
|
||||
|
||||
luaReturnNil();
|
||||
}
|
||||
|
||||
luaFunc(shot_setTarget)
|
||||
{
|
||||
Shot *shot = getShot(L);
|
||||
if(shot)
|
||||
shot->setTarget(entity(L, 2));
|
||||
{
|
||||
Entity *e = lua_isuserdata(L, 2) ? entity(L, 2) : NULL;
|
||||
shot->setTarget(e);
|
||||
}
|
||||
luaReturnNil();
|
||||
}
|
||||
|
||||
|
@ -1873,6 +1904,32 @@ luaFunc(shot_getTarget)
|
|||
luaReturnPtr(shot ? shot->target : NULL);
|
||||
}
|
||||
|
||||
luaFunc(shot_setExtraDamage)
|
||||
{
|
||||
Shot *shot = getShot(L);
|
||||
if(shot)
|
||||
shot->extraDamage = lua_tonumber(L, 2);
|
||||
luaReturnNil();
|
||||
}
|
||||
|
||||
luaFunc(shot_getExtraDamage)
|
||||
{
|
||||
Shot *shot = getShot(L);
|
||||
luaReturnNum(shot ? shot->extraDamage : 0.0f);
|
||||
}
|
||||
|
||||
luaFunc(shot_getDamage)
|
||||
{
|
||||
Shot *shot = getShot(L);
|
||||
luaReturnNum(shot ? shot->getDamage() : 0.0f);
|
||||
}
|
||||
|
||||
luaFunc(shot_getDamageType)
|
||||
{
|
||||
Shot *shot = getShot(L);
|
||||
luaReturnNum(shot ? shot->getDamageType() : DT_NONE);
|
||||
}
|
||||
|
||||
luaFunc(entity_setVel)
|
||||
{
|
||||
Entity *e = entity(L);
|
||||
|
@ -5275,7 +5332,10 @@ luaFunc(entity_getRandomTargetPoint)
|
|||
|
||||
luaFunc(playVisualEffect)
|
||||
{
|
||||
dsq->playVisualEffect(lua_tonumber(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)));
|
||||
Entity *target = NULL;
|
||||
if(lua_isuserdata(L, 4))
|
||||
target = entity(L, 4);
|
||||
dsq->playVisualEffect(lua_tonumber(L, 1), Vector(lua_tonumber(L, 2), lua_tonumber(L, 3)), target);
|
||||
luaReturnNil();
|
||||
}
|
||||
|
||||
|
@ -7959,13 +8019,21 @@ static const struct {
|
|||
|
||||
luaRegister(createSpore),
|
||||
|
||||
luaRegister(getFirstShot),
|
||||
luaRegister(getNextShot),
|
||||
luaRegister(shot_setAimVector),
|
||||
luaRegister(shot_setOut),
|
||||
luaRegister(shot_getEffectTime),
|
||||
luaRegister(shot_isIgnoreShield),
|
||||
luaRegister(shot_setFirer),
|
||||
luaRegister(shot_getFirer),
|
||||
luaRegister(shot_setTarget),
|
||||
luaRegister(shot_getTarget),
|
||||
luaRegister(shot_setExtraDamage),
|
||||
luaRegister(shot_getExtraDamage),
|
||||
luaRegister(shot_getDamage),
|
||||
luaRegister(shot_getDamageType),
|
||||
luaRegister(shot_getName),
|
||||
luaRegister(entity_pathBurst),
|
||||
luaRegister(entity_handleShotCollisions),
|
||||
luaRegister(entity_handleShotCollisionsSkeletal),
|
||||
|
|
|
@ -26,7 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "../BBGE/MathFunctions.h"
|
||||
|
||||
Shot::Shots Shot::shots;
|
||||
Shot::Shots Shot::deleteShots;
|
||||
Shot::ShotBank Shot::shotBank;
|
||||
unsigned int Shot::shotsIter = 0;
|
||||
|
||||
std::string Shot::shotBankPath = "";
|
||||
|
||||
|
@ -92,6 +94,9 @@ void ShotData::bankLoad(const std::string &file, const std::string &path)
|
|||
checkDamageTarget = true;
|
||||
}
|
||||
|
||||
this->name = file;
|
||||
stringToLower(this->name);
|
||||
|
||||
debugLog(usef);
|
||||
char *data = readFile(core->adjustFilenameCase(usef).c_str());
|
||||
if (!data)
|
||||
|
@ -335,6 +340,7 @@ Shot::Shot() : Quad(), Segmented(0,0)
|
|||
fired = false;
|
||||
target = 0;
|
||||
dead = false;
|
||||
shotIdx = shots.size();
|
||||
shots.push_back(this);
|
||||
}
|
||||
|
||||
|
@ -479,7 +485,9 @@ void Shot::setLifeTime(float l)
|
|||
void Shot::onEndOfLife()
|
||||
{
|
||||
destroySegments(0.2);
|
||||
shots.remove(this);
|
||||
deleteShots.push_back(this);
|
||||
dead = true;
|
||||
|
||||
if (emitter)
|
||||
{
|
||||
emitter->killParticleEffect();
|
||||
|
@ -531,24 +539,31 @@ void Shot::onHitWall()
|
|||
|
||||
void Shot::killAllShots()
|
||||
{
|
||||
std::queue<Shot*>shotDeleteQueue;
|
||||
for (Shots::iterator i = shots.begin(); i != shots.end(); i++)
|
||||
{
|
||||
shotDeleteQueue.push(*i);
|
||||
}
|
||||
Shot *s = 0;
|
||||
while (!shotDeleteQueue.empty())
|
||||
{
|
||||
s = shotDeleteQueue.front();
|
||||
if (s)
|
||||
{
|
||||
s->safeKill();
|
||||
}
|
||||
shotDeleteQueue.pop();
|
||||
}
|
||||
shots.clear();
|
||||
for (Shots::iterator i = shots.begin(); i != shots.end(); ++i)
|
||||
(*i)->safeKill();
|
||||
}
|
||||
|
||||
void Shot::clearShotGarbage()
|
||||
{
|
||||
for(size_t i = 0; i < deleteShots.size(); ++i)
|
||||
{
|
||||
Shot *s = deleteShots[i];
|
||||
const unsigned int idx = s->shotIdx;
|
||||
// move last shot to deleted one and shorten vector
|
||||
if(idx < shots.size() && shots[idx] == s)
|
||||
{
|
||||
Shot *lastshot = shots.back();
|
||||
shots[idx] = lastshot;
|
||||
lastshot->shotIdx = idx;
|
||||
shots.pop_back();
|
||||
}
|
||||
else
|
||||
errorLog("Shot::clearShotGarbage(): wrong index in shot vector");
|
||||
}
|
||||
deleteShots.clear();
|
||||
}
|
||||
|
||||
|
||||
void Shot::reflectFromEntity(Entity *e)
|
||||
{
|
||||
Entity *oldFirer = firer;
|
||||
|
|
|
@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
struct ShotData
|
||||
{
|
||||
ShotData();
|
||||
std::string texture;
|
||||
std::string texture, name;
|
||||
std::string hitSfx, bounceSfx, fireSfx;
|
||||
std::string hitPrt, trailPrt, firePrt, bouncePrt;
|
||||
std::string spawnEntity;
|
||||
|
@ -79,11 +79,15 @@ public:
|
|||
//void destroy();
|
||||
void reflectFromEntity(Entity *e);
|
||||
void setParticleEffect(const std::string &particleEffect);
|
||||
typedef std::list<Shot*> Shots;
|
||||
static Shots shots;
|
||||
typedef std::vector<Shot*> Shots;
|
||||
static Shots shots, deleteShots;
|
||||
static unsigned int shotsIter; // for script
|
||||
static Shot *getFirstShot() { shotsIter = 0; return getNextShot(); }
|
||||
static Shot *getNextShot() { return shotsIter < shots.size() ? shots[shotsIter++] : NULL; }
|
||||
static std::string shotBankPath;
|
||||
static void targetDied(Entity *t);
|
||||
static void killAllShots();
|
||||
static void clearShotGarbage();
|
||||
Entity *target, *firer;
|
||||
int maxSpeed, targetPt;
|
||||
|
||||
|
@ -117,6 +121,8 @@ public:
|
|||
void updatePosition();
|
||||
bool isHitEnts() const;
|
||||
bool isObstructed(float dt) const;
|
||||
inline bool isActive() const { return !dead; }
|
||||
inline const char *getName() const { return shotData ? shotData->name.c_str() : ""; }
|
||||
|
||||
float extraDamage;
|
||||
protected:
|
||||
|
@ -136,6 +142,9 @@ protected:
|
|||
|
||||
bool dead;
|
||||
void onUpdate(float dt);
|
||||
|
||||
private:
|
||||
unsigned int shotIdx;
|
||||
};
|
||||
|
||||
class Beam : public Quad
|
||||
|
|
Loading…
Reference in a new issue