Index: src/weapon.mm ================================================================== --- src/weapon.mm +++ src/weapon.mm @@ -145,10 +145,15 @@ newprojectile(OFVector3D &from, OFVector3D &to, float speed, bool local, DynamicEntity *owner, int gun) { for (size_t i = 0; i < MAXPROJ; i++) { Projectile *p = projs[i]; + + if (p == nil) { + p = [[Projectile alloc] init]; + projs[i] = p; + } if (p.inuse) continue; p.inuse = true; @@ -203,47 +208,50 @@ splash(Projectile *p, const OFVector3D &v, const OFVector3D &vold, int notthisplayer, int notthismonster, int qdam) { particle_splash(0, 50, 300, v); p.inuse = false; + if (p.gun != GUN_RL) { playsound(S_FEXPLODE, &v); // no push? } else { playsound(S_RLHIT, &v); newsphere(v, RL_RADIUS, 0); dodynlight(vold, v, 0, 0, p.owner); + if (!p.local) return; + radialeffect(player1, v, -1, qdam, p.owner); - size_t i = 0; - for (id player in players) { - if (i == notthisplayer) { - i++; - continue; - } - - if (player != [OFNull null]) - radialeffect(player, v, i, qdam, p.owner); - - i++; - } - - i = 0; - for (DynamicEntity *monster in getmonsters()) + [players enumerateObjectsUsingBlock:^( + id player, size_t i, bool *stop) { + if (i == notthisplayer) + return; + + if (player == [OFNull null]) + return; + + radialeffect(player, v, i, qdam, p.owner); + }]; + + [getmonsters() enumerateObjectsUsingBlock:^( + DynamicEntity *monster, size_t i, bool *stop) { if (i != notthismonster) radialeffect(monster, v, i, qdam, p.owner); + }]; } } inline void projdamage( DynamicEntity *o, Projectile *p, OFVector3D &v, int i, int im, int qdam) { if (o.state != CS_ALIVE) return; + if (intersect(o, p.o, v)) { splash(p, v, p.o, i, im, qdam); hit(i, qdam, o, p.owner); } } @@ -263,12 +271,12 @@ vdist(dist, v, p.o, p.to); float dtime = dist * 1000 / p.speed; if (time > dtime) dtime = time; vmul(v, time / dtime); - vadd(v, p.o) if (p.local) - { + vadd(v, p.o); + if (p.local) { for (id player in players) if (player != [OFNull null]) projdamage(player, p, v, i, -1, qdam); if (p.owner != player1)