1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-06-08 01:22:02 +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:
fgenesis 2013-03-06 02:06:52 +01:00
parent eef2289fb2
commit 0784d1b9df
7 changed files with 134 additions and 38 deletions

View file

@ -2921,7 +2921,7 @@ void Avatar::formAbility(int ability)
for (i = Shot::shots.begin(); i != Shot::shots.end(); i++) for (i = Shot::shots.begin(); i != Shot::shots.end(); i++)
{ {
Shot *s = (*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) 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) for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); ++i)
{ {
//&& (*i)->life > 0.2f Shot *s = *i;
if ((*i) && dsq->game->isDamageTypeEnemy((*i)->getDamageType()) && (*i)->firer != this if (s->isActive() && dsq->game->isDamageTypeEnemy(s->getDamageType()) && s->firer != this
&& (!(*i)->shotData || !(*i)->shotData->ignoreShield)) && (!s->shotData || !s->shotData->ignoreShield))
{ {
Vector diff = (*i)->position - shieldPosition; Vector diff = s->position - shieldPosition;
if (diff.getSquaredLength2D() < sqr(AURA_SHIELD_RADIUS)) if (diff.getSquaredLength2D() < sqr(AURA_SHIELD_RADIUS))
{ {
shieldPoints -= (*i)->getDamage(); shieldPoints -= s->getDamage();
auraHitEmitter.start(); auraHitEmitter.start();
dsq->spawnParticleEffect("ReflectShot", (*i)->position); dsq->spawnParticleEffect("ReflectShot", s->position);
core->sound->playSfx("Shield-Hit"); core->sound->playSfx("Shield-Hit");
(*i)->position += diff; s->position += diff;
//(*i)->target = 0; //s->target = 0;
diff.setLength2D((*i)->maxSpeed); diff.setLength2D(s->maxSpeed);
(*i)->velocity = diff; s->velocity = diff;
(*i)->reflectFromEntity(this); s->reflectFromEntity(this);
} }
} }
} }

View file

@ -4665,6 +4665,8 @@ void DSQ::onUpdate(float dt)
lockMouse(); lockMouse();
Network::update(); Network::update();
Shot::clearShotGarbage();
} }
void DSQ::lockMouse() void DSQ::lockMouse()

View file

@ -2912,7 +2912,7 @@ void Entity::doSpellAvoidance(float dt, int range, float mod)
{ {
Shot *s = (Shot*)(*i); 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++) for (int j = 0; j < ignoreShotDamageTypes.size(); j++)
{ {

View file

@ -6253,6 +6253,7 @@ void Game::applyState()
//core->afterEffectManager->addEffect(new RippleEffect()); //core->afterEffectManager->addEffect(new RippleEffect());
} }
Shot::shots.clear(); Shot::shots.clear();
Shot::deleteShots.clear();
backdropQuad = 0; backdropQuad = 0;
clearObsRows(); clearObsRows();
inGameMenu = false; 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++) for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); i++)
{ {
Shot *shot = *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; Vector collidePoint = e->position+e->offset;
if (e->getNumTargetPoints()>0) 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++) for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); i++)
{ {
Shot *shot = *i; Shot *shot = *i;
if (isEntityCollideWithShot(e, shot)) if (shot->isActive() && isEntityCollideWithShot(e, shot))
{ {
Bone *b = collideSkeletalVsCircle(e, shot->position, shot->collideRadius); Bone *b = collideSkeletalVsCircle(e, shot->position, shot->collideRadius);
if (b) 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++) for (Shot::Shots::iterator i = Shot::shots.begin(); i != Shot::shots.end(); i++)
{ {
Shot *shot = *i; Shot *shot = *i;
if (isEntityCollideWithShot(e, shot)) if (shot->isActive() && isEntityCollideWithShot(e, shot))
{ {
bool b = collideHairVsCircle(e, num, shot->position, 8); bool b = collideHairVsCircle(e, num, shot->position, 8);
if (b) if (b)
@ -10886,6 +10887,7 @@ void Game::removeState()
debugLog("killAllShots"); debugLog("killAllShots");
Shot::killAllShots(); Shot::killAllShots();
Shot::clearShotGarbage();
debugLog("killAllBeams"); debugLog("killAllBeams");
Beam::killAllBeams(); Beam::killAllBeams();
debugLog("killAllWebs"); debugLog("killAllWebs");

View file

@ -1811,6 +1811,22 @@ luaFunc(web_getNumPoints)
luaReturnInt(num); 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) luaFunc(shot_setOut)
{ {
Shot *shot = getShot(L); Shot *shot = getShot(L);
@ -1859,11 +1875,26 @@ luaFunc(shot_getFirer)
luaReturnPtr(shot ? shot->firer : NULL); 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) luaFunc(shot_setTarget)
{ {
Shot *shot = getShot(L); Shot *shot = getShot(L);
if(shot) if(shot)
shot->setTarget(entity(L, 2)); {
Entity *e = lua_isuserdata(L, 2) ? entity(L, 2) : NULL;
shot->setTarget(e);
}
luaReturnNil(); luaReturnNil();
} }
@ -1873,6 +1904,32 @@ luaFunc(shot_getTarget)
luaReturnPtr(shot ? shot->target : NULL); 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) luaFunc(entity_setVel)
{ {
Entity *e = entity(L); Entity *e = entity(L);
@ -5275,7 +5332,10 @@ luaFunc(entity_getRandomTargetPoint)
luaFunc(playVisualEffect) 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(); luaReturnNil();
} }
@ -7959,13 +8019,21 @@ static const struct {
luaRegister(createSpore), luaRegister(createSpore),
luaRegister(getFirstShot),
luaRegister(getNextShot),
luaRegister(shot_setAimVector), luaRegister(shot_setAimVector),
luaRegister(shot_setOut), luaRegister(shot_setOut),
luaRegister(shot_getEffectTime), luaRegister(shot_getEffectTime),
luaRegister(shot_isIgnoreShield), luaRegister(shot_isIgnoreShield),
luaRegister(shot_setFirer),
luaRegister(shot_getFirer), luaRegister(shot_getFirer),
luaRegister(shot_setTarget), luaRegister(shot_setTarget),
luaRegister(shot_getTarget), luaRegister(shot_getTarget),
luaRegister(shot_setExtraDamage),
luaRegister(shot_getExtraDamage),
luaRegister(shot_getDamage),
luaRegister(shot_getDamageType),
luaRegister(shot_getName),
luaRegister(entity_pathBurst), luaRegister(entity_pathBurst),
luaRegister(entity_handleShotCollisions), luaRegister(entity_handleShotCollisions),
luaRegister(entity_handleShotCollisionsSkeletal), luaRegister(entity_handleShotCollisionsSkeletal),

View file

@ -26,7 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../BBGE/MathFunctions.h" #include "../BBGE/MathFunctions.h"
Shot::Shots Shot::shots; Shot::Shots Shot::shots;
Shot::Shots Shot::deleteShots;
Shot::ShotBank Shot::shotBank; Shot::ShotBank Shot::shotBank;
unsigned int Shot::shotsIter = 0;
std::string Shot::shotBankPath = ""; std::string Shot::shotBankPath = "";
@ -92,6 +94,9 @@ void ShotData::bankLoad(const std::string &file, const std::string &path)
checkDamageTarget = true; checkDamageTarget = true;
} }
this->name = file;
stringToLower(this->name);
debugLog(usef); debugLog(usef);
char *data = readFile(core->adjustFilenameCase(usef).c_str()); char *data = readFile(core->adjustFilenameCase(usef).c_str());
if (!data) if (!data)
@ -335,6 +340,7 @@ Shot::Shot() : Quad(), Segmented(0,0)
fired = false; fired = false;
target = 0; target = 0;
dead = false; dead = false;
shotIdx = shots.size();
shots.push_back(this); shots.push_back(this);
} }
@ -479,7 +485,9 @@ void Shot::setLifeTime(float l)
void Shot::onEndOfLife() void Shot::onEndOfLife()
{ {
destroySegments(0.2); destroySegments(0.2);
shots.remove(this); deleteShots.push_back(this);
dead = true;
if (emitter) if (emitter)
{ {
emitter->killParticleEffect(); emitter->killParticleEffect();
@ -531,24 +539,31 @@ void Shot::onHitWall()
void Shot::killAllShots() void Shot::killAllShots()
{ {
std::queue<Shot*>shotDeleteQueue; for (Shots::iterator i = shots.begin(); i != shots.end(); ++i)
for (Shots::iterator i = shots.begin(); i != shots.end(); i++) (*i)->safeKill();
{
shotDeleteQueue.push(*i);
}
Shot *s = 0;
while (!shotDeleteQueue.empty())
{
s = shotDeleteQueue.front();
if (s)
{
s->safeKill();
}
shotDeleteQueue.pop();
}
shots.clear();
} }
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) void Shot::reflectFromEntity(Entity *e)
{ {
Entity *oldFirer = firer; Entity *oldFirer = firer;

View file

@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
struct ShotData struct ShotData
{ {
ShotData(); ShotData();
std::string texture; std::string texture, name;
std::string hitSfx, bounceSfx, fireSfx; std::string hitSfx, bounceSfx, fireSfx;
std::string hitPrt, trailPrt, firePrt, bouncePrt; std::string hitPrt, trailPrt, firePrt, bouncePrt;
std::string spawnEntity; std::string spawnEntity;
@ -79,11 +79,15 @@ public:
//void destroy(); //void destroy();
void reflectFromEntity(Entity *e); void reflectFromEntity(Entity *e);
void setParticleEffect(const std::string &particleEffect); void setParticleEffect(const std::string &particleEffect);
typedef std::list<Shot*> Shots; typedef std::vector<Shot*> Shots;
static Shots 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 std::string shotBankPath;
static void targetDied(Entity *t); static void targetDied(Entity *t);
static void killAllShots(); static void killAllShots();
static void clearShotGarbage();
Entity *target, *firer; Entity *target, *firer;
int maxSpeed, targetPt; int maxSpeed, targetPt;
@ -117,6 +121,8 @@ public:
void updatePosition(); void updatePosition();
bool isHitEnts() const; bool isHitEnts() const;
bool isObstructed(float dt) 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; float extraDamage;
protected: protected:
@ -136,6 +142,9 @@ protected:
bool dead; bool dead;
void onUpdate(float dt); void onUpdate(float dt);
private:
unsigned int shotIdx;
}; };
class Beam : public Quad class Beam : public Quad