Fix grenades going backwards when the player is moving.
authorGuus Sliepen <guus@debian.org>
Sun, 9 Aug 2015 18:19:31 +0000 (20:19 +0200)
committerGuus Sliepen <guus@debian.org>
Sun, 9 Aug 2015 18:19:31 +0000 (20:19 +0200)
Most weapon bullets have a speed which is much higher than the player
can move, but grenades are relatively slow. Since Bob started moving
faster many versions ago, grenades were actually slower than Bob
himself. Since there was no concept of bullets inheriting the speed of
the entity shooting them, that meant that when Bob was moving forward
and tried to throw a grenade, the grenade would actually move backwards
relative to Bob.

We fix that now by making grenades inherit the velocity of the entity
throwing them. Unfortunately, a player that is on a moving platform is
considered not to have any velocity, even if the platform is moving. In
stead of rewriting everything to track the actual velocity of entities
on platforms, we just check if the grenade throwing entity is on a
platform, and if so add the platform's velocity to the grenade.

With the old starting velocity of grenades plus Bob's own speed,
grenades could actually be thrown very fast. Compensate that by making
the starting velocity of grenades much lower. It might make some puzzles
involving grenades a bit harder.

data/weapons
src/bullets.cpp
src/bullets.h
src/trains.cpp

index 829bfecf2de8e3e50ce5a399f52ef2c781901323..ccf9a32e791afc186cc500426177c57106486b23 100644 (file)
@@ -1,7 +1,7 @@
 0 "Pistol"                                     0 1 60 10 0 15 FlameBulletRight FlameBulletLeft 3 ENT_WEIGHTLESS
 1 "Machine Gun"                                1 1 60 10 0 4 FlameBulletRight FlameBulletLeft 6 ENT_WEIGHTLESS
 2 "Laser Cannon"                       2 1 120 13 0 40 LaserBolt LaserBolt 19 ENT_WEIGHTLESS+ENT_BOUNCES
-3 "Grenades"                           3 50 240 3 -2 20 Grenade Grenade 31 ENT_BOUNCES+ENT_EXPLODES
+3 "Grenades"                           3 50 240 1 -2 20 Grenade Grenade 31 ENT_BOUNCES+ENT_EXPLODES
 4 "Spread Gun"                         4 1 240 15 0 15 PlasmaBolt PlasmaBolt 34 ENT_WEIGHTLESS+ENT_PARTICLETRAIL
 
 5 "Rocket Launcher"                    5 75 240 8 8 45 FlameBulletRight FlameBulletLeft 11 ENT_WEIGHTLESS+ENT_FIRETRAIL+ENT_EXPLODES
index fb846423619f294222b60db9f06f273947c22413..b8a416fa1d3ee6f894201416ffff2dd38d8a8b2e 100644 (file)
@@ -49,6 +49,16 @@ void addBullet(Entity *owner, float dx, float dy)
        bullet->id = owner->currentWeapon->id;
        bullet->dx = dx;
        bullet->dy = owner->currentWeapon->dy + dy;
+
+       // Add motion of the player and any platform he/she is on to grenades
+       if (owner->currentWeapon->dy)
+       {
+               int tdx, tdy;
+               getTrainMotion(owner, tdx, tdy);
+               bullet->dx += owner->dx - tdx;
+               bullet->dy += -tdy;
+       }
+
        bullet->next = NULL;
        bullet->health = owner->currentWeapon->health;
        bullet->damage = owner->currentWeapon->damage;
index 7605734abe9a45e6702a7b9169906b4327228252..653c1c95e1a247134c8e8400428ff28c9e1d0924 100644 (file)
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "headers.h"
 
 extern bool checkTrainContact(Entity *ent, int dir);
+extern void getTrainMotion(Entity *ent, int &dx, int &dy);
 extern bool checkObstacleContact(Entity *ent, int dir);
 extern void enemyBulletCollisions(Entity *bullet);
 extern void checkPlayerBulletCollisions(Entity *bullet);
index 9853123fd9ca1c418dc8aa5faa06ec5e79ab4bf8..d2a43cba9b9559a82a7c0140458b5127e8a9b897 100644 (file)
@@ -104,6 +104,22 @@ void trainBlockEntity(Entity *ent, const char *message, Train *train, int dir)
        }
 }
 
+void getTrainMotion(Entity *ent, int &dx, int &dy)
+{
+       dx = 0;
+       dy = 0;
+       Train *train = (Train*)map.trainList.getHead();
+       while (train->next != NULL) {
+               train = (Train*)train->next;
+               bool collision = (Collision::collision(ent->x, ent->y + ent->dy, ent->width, ent->height - 1, train->x, train->y, train->width, train->height));
+               if(collision) {
+                       dx = train->getDX();
+                       dy = train->getDY();
+                       break;
+               }
+       }
+}
+
 /**
 * Checks to see if an entity has touched this train. Depending on
 * the trains status certain other functions will be invoked