1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-07-03 22:44:32 +00:00

Small extension to bone:

+ attrib c="0" in the anim XML to turn off all collision for a bone
  even if collide radius or collision mask is set
+ Lua func: bone_toggleCollision() to change the above setting at runtime
+ Lua func: bone_spawnParticlesFromCollisionMask()
- Fix int truncation in entity_collideSkeletalVsLine()
This commit is contained in:
fgenesis 2022-05-18 01:18:27 +02:00
parent bdd422bd59
commit e33bde0a89
6 changed files with 72 additions and 25 deletions

View file

@ -2333,16 +2333,10 @@ void Entity::warpLastPosition()
position = lastPosition; position = lastPosition;
} }
void Entity::spawnParticlesFromCollisionMask(const std::string &p, int intv) void Entity::spawnParticlesFromCollisionMask(const char *p, unsigned intv, int layer, float rotz)
{ {
for (size_t i = 0; i < skeletalSprite.bones.size(); i++) for (size_t i = 0; i < skeletalSprite.bones.size(); i++)
{ skeletalSprite.bones[i]->spawnParticlesFromCollisionMask(p, intv, layer, rotz);
for (size_t j = 0; j < skeletalSprite.bones[i]->collisionMask.size(); j+=intv)
{
Vector pos = skeletalSprite.bones[i]->getWorldCollidePosition(skeletalSprite.bones[i]->collisionMask[j]);
dsq->spawnParticleEffect(p, pos);
}
}
} }
//Entity *e, Entity *attacker, Bone *bone, SpellType spell, int dmg) //Entity *e, Entity *attacker, Bone *bone, SpellType spell, int dmg)

View file

@ -76,7 +76,7 @@ public:
void render(); void render();
void update(float dt); void update(float dt);
void spawnParticlesFromCollisionMask(const std::string &p, int intv=1); void spawnParticlesFromCollisionMask(const char *p, unsigned intv=1, int layer = LR_PARTICLES, float rotz = 0);
float health; float health;
float maxHealth; float maxHealth;

View file

@ -3885,7 +3885,7 @@ Bone *Game::collideSkeletalVsLine(Entity *skeletal, Vector start, Vector end, fl
Bone *b = skeletal->skeletalSprite.bones[i]; Bone *b = skeletal->skeletalSprite.bones[i];
// MULTIPLE CIRCLES METHOD // MULTIPLE CIRCLES METHOD
if (!b->collisionMask.empty() && b->alpha.x == 1 && b->renderQuad) if (b->canCollide() && !b->collisionMask.empty())
{ {
for (size_t i = 0; i < b->transformedCollisionMask.size(); i++) for (size_t i = 0; i < b->transformedCollisionMask.size(); i++)
{ {
@ -3938,9 +3938,7 @@ Bone *Game::collideSkeletalVsCircle(Entity *skeletal, Vector pos, float radius)
{ {
Bone *b = skeletal->skeletalSprite.bones[i]; Bone *b = skeletal->skeletalSprite.bones[i];
if (b->alpha.x == 1 && b->renderQuad && if (b->canCollide()) // check this here to avoid calculating getWorldCollidePosition() if not necessary
(!b->collisionMask.empty() || b->collideRadius) // check this here to avoid calculating getWorldCollidePosition() if not necessary
)
{ {
float checkRadius = sqr(radius+b->collisionMaskRadius); float checkRadius = sqr(radius+b->collisionMaskRadius);
Vector bonePos = b->getWorldCollidePosition(); Vector bonePos = b->getWorldCollidePosition();

View file

@ -4051,6 +4051,14 @@ luaFunc(bone_lookAtPosition)
luaReturnNil(); luaReturnNil();
} }
luaFunc(bone_toggleCollision)
{
Bone *b = bone(L);
if(b)
b->enableCollision = getBool(L, 2);
luaReturnNil();
}
luaFunc(entity_stopFollowingPath) luaFunc(entity_stopFollowingPath)
{ {
Entity *e = entity(L); Entity *e = entity(L);
@ -4420,17 +4428,36 @@ luaFunc(cam_setPosition)
luaReturnNil(); luaReturnNil();
} }
template<typename T>
void spawnParticlesFromCollisionMask(lua_State *L, T *t)
{
const char *p = getCString(L, 2);
if(!p)
luaL_error(L, "expected string partcle name");
int intv = lua_tointeger(L, 3);
if (intv <= 0)
intv = 1;
int lr = luaL_optinteger(L, 4, LR_PARTICLES);
float rotz = lua_tonumber(L, 5);
t->spawnParticlesFromCollisionMask(p, intv, lr, rotz);
}
luaFunc(entity_spawnParticlesFromCollisionMask) luaFunc(entity_spawnParticlesFromCollisionMask)
{ {
Entity *e = entity(L); Entity *e = entity(L);
if (e) if (e)
{ spawnParticlesFromCollisionMask(L, e);
int intv = lua_tointeger(L, 3);
if (intv <= 0) luaReturnNil();
intv = 1; }
e->spawnParticlesFromCollisionMask(getString(L, 2), intv);
} luaFunc(bone_spawnParticlesFromCollisionMask)
{
Bone *b = bone(L);
if (b)
spawnParticlesFromCollisionMask(L, b);
luaReturnNil(); luaReturnNil();
} }
@ -5527,12 +5554,11 @@ luaFunc(entity_collideSkeletalVsCirclePos)
luaFunc(entity_collideSkeletalVsLine) luaFunc(entity_collideSkeletalVsLine)
{ {
Entity *e = entity(L); Entity *e = entity(L);
int x1, y1, x2, y2, sz; float x1 = lua_tonumber(L, 2);
x1 = lua_tonumber(L, 2); float y1 = lua_tonumber(L, 3);
y1 = lua_tonumber(L, 3); float x2 = lua_tonumber(L, 4);
x2 = lua_tonumber(L, 4); float y2 = lua_tonumber(L, 5);
y2 = lua_tonumber(L, 5); float sz = lua_tonumber(L, 6);
sz = lua_tonumber(L, 6);
Bone *b = 0; Bone *b = 0;
if (e) if (e)
{ {
@ -10041,6 +10067,8 @@ static const struct {
luaRegister(bone_lookAtEntity), luaRegister(bone_lookAtEntity),
luaRegister(bone_lookAtPosition), luaRegister(bone_lookAtPosition),
luaRegister(bone_spawnParticlesFromCollisionMask),
luaRegister(bone_toggleCollision),
luaRegister(entity_partSetSegs), luaRegister(entity_partSetSegs),

View file

@ -71,6 +71,7 @@ Bone::Bone() : Quad()
fileRenderQuad = true; fileRenderQuad = true;
skeleton = 0; skeleton = 0;
generateCollisionMask = true; generateCollisionMask = true;
enableCollision = true;
animated = ANIM_ALL; animated = ANIM_ALL;
originalScale = Vector(1,1); originalScale = Vector(1,1);
boneIdx = pidx = -1; boneIdx = pidx = -1;
@ -101,6 +102,11 @@ void Bone::destroy()
segments.clear(); segments.clear();
} }
bool Bone::canCollide() const
{
return this->enableCollision && this->alpha.x == 1 && this->renderQuad && (!this->collisionMask.empty() || this->collideRadius);
}
void Bone::addSegment(Bone *b) void Bone::addSegment(Bone *b)
{ {
segments.push_back(b); segments.push_back(b);
@ -280,6 +286,16 @@ void Bone::updateSegments()
} }
} }
void Bone::spawnParticlesFromCollisionMask(const char *p, unsigned intv, int layer, float rotz)
{
for (size_t j = 0; j < this->collisionMask.size(); j+=intv)
{
Vector pos = this->getWorldCollidePosition(this->collisionMask[j]);
core->createParticleEffect(p, pos, layer, rotz);
}
}
bool BoneCommand::parse(Bone *b, SimpleIStringStream &is) bool BoneCommand::parse(Bone *b, SimpleIStringStream &is)
{ {
std::string type; std::string type;
@ -895,6 +911,8 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn)
bone->SetAttribute("fv", this->bones[i]->isfv()); bone->SetAttribute("fv", this->bones[i]->isfv());
bone->SetAttribute("gc", this->bones[i]->generateCollisionMask); bone->SetAttribute("gc", this->bones[i]->generateCollisionMask);
bone->SetAttribute("cr", this->bones[i]->collideRadius); bone->SetAttribute("cr", this->bones[i]->collideRadius);
if(!this->bones[i]->enableCollision)
bone->SetAttribute("c", this->bones[i]->enableCollision);
if (!this->bones[i]->fileRenderQuad) if (!this->bones[i]->fileRenderQuad)
{ {
bone->SetAttribute("rq", this->bones[i]->fileRenderQuad); bone->SetAttribute("rq", this->bones[i]->fileRenderQuad);
@ -1368,6 +1386,10 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
{ {
newb->generateCollisionMask = atoi(bone->Attribute("gc")); newb->generateCollisionMask = atoi(bone->Attribute("gc"));
} }
if (bone->Attribute("c"))
{
newb->enableCollision = atoi(bone->Attribute("c"));
}
if (bone->Attribute("rq")) if (bone->Attribute("rq"))
{ {
newb->renderQuad = newb->fileRenderQuad = atoi(bone->Attribute("rq")); newb->renderQuad = newb->fileRenderQuad = atoi(bone->Attribute("rq"));

View file

@ -67,9 +67,12 @@ public:
std::vector<Vector> changeStrip; std::vector<Vector> changeStrip;
bool generateCollisionMask; bool generateCollisionMask;
bool enableCollision;
int animated; int animated;
Vector originalScale; Vector originalScale;
bool canCollide() const;
void addSegment(Bone *b); void addSegment(Bone *b);
ParticleEffect *getEmitter(unsigned slot) const; ParticleEffect *getEmitter(unsigned slot) const;
@ -88,6 +91,8 @@ public:
bool selectable; bool selectable;
int originalRenderPass; // stores the render pass originally set in the XML file. For AC_RESET_PASS. int originalRenderPass; // stores the render pass originally set in the XML file. For AC_RESET_PASS.
void spawnParticlesFromCollisionMask(const char *p, unsigned intv, int layer, float rotz = 0);
protected: protected:
std::vector<ParticleEffect*> emitters; std::vector<ParticleEffect*> emitters;
int minDist, maxDist, reverse; int minDist, maxDist, reverse;