kugelblitz electrifies water on contact - electrified water is baaaaaaad
[supertux.git] / src / object / particlesystem_interactive.cpp
index 13064bc..b3da734 100644 (file)
 #include <iostream>
 #include <cmath>
 
-#include "particlesystem_interactive.h"
-#include "video/drawing_context.h"
-#include "lisp/parser.h"
-#include "lisp/lisp.h"
-#include "lisp/writer.h"
-#include "resources.h"
-#include "main.h"
+#include "particlesystem_interactive.hpp"
+#include "video/drawing_context.hpp"
+#include "lisp/parser.hpp"
+#include "lisp/lisp.hpp"
+#include "lisp/writer.hpp"
+#include "resources.hpp"
+#include "main.hpp"
 
-#include "tile.h"
-#include "tilemap.h"
-#include "math/aatriangle.h"
-#include "collision.h"
-#include "collision_hit.h"
-#include "object/camera.h"
-#include "object/rainsplash.h"
-#include "badguy/bomb.h"
+#include "tile.hpp"
+#include "tilemap.hpp"
+#include "math/aatriangle.hpp"
+#include "collision.hpp"
+#include "collision_hit.hpp"
+#include "object/camera.hpp"
+#include "object/rainsplash.hpp"
+#include "badguy/bomb.hpp"
 
-//TODO: Dynamically create splashes at collision spots
-//      Find a way to make rain collide with objects like bonus blocks
+//TODO: Find a way to make rain collide with objects like bonus blocks
 //      Add an option to set rain strength
+//      Fix rain being "respawned" over solid tiles
 ParticleSystem_Interactive::ParticleSystem_Interactive()
 {
     virtual_width = SCREEN_WIDTH;
@@ -69,7 +69,7 @@ void ParticleSystem_Interactive::draw(DrawingContext& context)
     context.pop_transform();
 }
 
-bool
+int
 ParticleSystem_Interactive::collision(Particle* object, Vector movement)
 {
   TileMap* solids = Sector::current()->solids;
@@ -123,14 +123,20 @@ ParticleSystem_Interactive::collision(Particle* object, Vector movement)
   }
   
   // did we collide at all?
-  if(hit.time < 0)
-    return false; else return true;
+  if(hit.time < 0) {
+    return -1; //no collision
+  }
+  else {
+    if ((hit.normal.x == 1) && (hit.normal.y == 0))
+      return 1; //collision from right
+    else return 0; //collision from above
+  }
 }
 
 RainParticleSystem::RainParticleSystem()
 {
-    rainimages[0] = new Surface(datadir+"/images/objects/particles/rain0.png", true);
-    rainimages[1] = new Surface(datadir+"/images/objects/particles/rain1.png", true);
+    rainimages[0] = new Surface("images/objects/particles/rain0.png", true);
+    rainimages[1] = new Surface("images/objects/particles/rain1.png", true);
 
     virtual_width = SCREEN_WIDTH * 2;
 
@@ -182,21 +188,23 @@ void RainParticleSystem::update(float elapsed_time)
         float abs_y = Sector::current()->camera->get_translation().y;
         particle->pos.y += movement;
         particle->pos.x -= movement;
-        if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (collision(particle, Vector(-movement, movement)))) {
+        int col = collision(particle, Vector(-movement, movement));
+        if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
             //Create rainsplash
             if (particle->pos.y <= SCREEN_HEIGHT + abs_y){
-              //TODO: Find out at which side of the tile the collision happens
-              bool vertical = false;
+              bool vertical = (col == 1);
               int splash_x, splash_y;
-              if (vertical) {
-                splash_x = int(particle->pos.x) - (int(particle->pos.x) % 32) + 32;
-                splash_y = int(particle->pos.y);                
-              }
-              else {
+              if (!vertical) { //check if collision happened from above
                 splash_x = int(particle->pos.x);
                 splash_y = int(particle->pos.y) - (int(particle->pos.y) % 32) + 32;
+                Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
               }
-              Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
+              // Uncomment the following to display vertical splashes, too
+              /* else {
+                splash_x = int(particle->pos.x) - (int(particle->pos.x) % 32) + 32;
+                splash_y = int(particle->pos.y);
+                Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
+              } */
             }
             int new_x = (rand() % int(virtual_width)) + int(abs_x);
             int new_y = 0;
@@ -209,8 +217,8 @@ void RainParticleSystem::update(float elapsed_time)
 
 CometParticleSystem::CometParticleSystem()
 {
-    cometimages[0] = new Surface(datadir+"/images/creatures/mr_bomb/exploding-left-0.png", true);
-    cometimages[1] = new Surface(datadir+"/images/creatures/mr_bomb/exploding-left-0.png", true);
+    cometimages[0] = new Surface("images/creatures/mr_bomb/exploding-left-0.png", true);
+    cometimages[1] = new Surface("images/creatures/mr_bomb/exploding-left-0.png", true);
 
     virtual_width = SCREEN_WIDTH * 2;
 
@@ -262,7 +270,7 @@ void CometParticleSystem::update(float elapsed_time)
         float abs_y = Sector::current()->camera->get_translation().y;
         particle->pos.y += movement;
         particle->pos.x -= movement;
-        if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (collision(particle, Vector(-movement, movement)))) {
+        if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (collision(particle, Vector(-movement, movement)) >= 0)) {
             if (particle->pos.y <= SCREEN_HEIGHT + abs_y) {
               Sector::current()->add_object(new Bomb(particle->pos, LEFT));
             }