about summary refs log tree commit diff stats
path: root/data/maps/the_literate/doors.txtpb
blob: d17d02b70a4728670207cb302b65f86a35376d49 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
doors {
  name: "Door"
  type: STANDARD
  receivers: "Components/Doors/entry_1"
  panels { room: "Puzzle Room" name: "WATER" }
  panels { room: "Puzzle Room" name: "JUICE" }
  panels { room: "Puzzle Room" name: "MAGMA" }
  panels { room: "Puzzle Room" name: "CREATURE" }
  panels { room: "Puzzle Room" name: "SAND" }
  panels { room: "Puzzle Room" name: "LIQUID" }
  panels { room: "Puzzle Room" name: "STICK" }
  panels { room: "Puzzle Room" name: "BREAD" }
  location_room: "Puzzle Room"
  location_name: "Puzzles"
}
a> 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211








                                                                                                                                                     
                                            








































































































































































































                                                                                                                                                      
#include "map_collision.h"
#include "map.h"
#include "game.h"

MapCollisionComponent::MapCollisionComponent(const Map& map) : map(map)
{
  addCollision(-6, 0, GAME_WIDTH, Direction::left, (map.getLeftMap() == nullptr) ? Collision::Type::wrap : Collision::Type::teleport);
  addCollision(GAME_WIDTH+6, 0, GAME_WIDTH, Direction::right, (map.getRightMap() == nullptr) ? Collision::Type::reverse : Collision::Type::teleport);
  
  for (int i=0; i<MAP_WIDTH*MAP_HEIGHT; i++)
  {
    int x = i % MAP_WIDTH;
    int y = i / MAP_WIDTH;
    int tile = map.getMapdata()[i];
    
    if ((tile > 0) && (tile < 28) && (!((tile >= 5) && (tile <= 7))))
    {
      addCollision(x*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, Direction::right, Collision::Type::wall);
      addCollision((x+1)*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, Direction::left, Collision::Type::wall);
      addCollision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::down, Collision::Type::wall);
      addCollision((y+1)*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::up, Collision::Type::wall);
    } else if ((tile >= 5) && (tile <= 7))
    {
      addCollision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::down, Collision::Type::platform);
    } else if (tile == 42)
    {
      addCollision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, Direction::down, Collision::Type::danger);
    }
  }
}

void MapCollisionComponent::addCollision(double axis, double lower, double
   upper, Direction dir, Collision::Type type)
{
  std::list<Collision>::iterator it;
  
  switch (dir)
  {
    case Direction::up:
      it = up_collisions.begin();
      for (; it!=up_collisions.end(); it++)
      {
        if (it->axis < axis) break;
      }
    
      up_collisions.insert(it, {axis, lower, upper, type});
      
      break;
    case Direction::down:
      it = down_collisions.begin();
      for (; it!=down_collisions.end(); it++)
      {
        if (it->axis > axis) break;
      }
    
      down_collisions.insert(it, {axis, lower, upper, type});
      
      break;
    case Direction::left:
      it = left_collisions.begin();
      for (; it!=left_collisions.end(); it++)
      {
        if (it->axis < axis) break;
      }
  
      left_collisions.insert(it, {axis, lower, upper, type});
      
      break;
    case Direction::right:
      it = right_collisions.begin();
      for (; it!=right_collisions.end(); it++)
      {
        if (it->axis > axis) break;
      }
  
      right_collisions.insert(it, {axis, lower, upper, type});
      
      break;
  }
}

void MapCollisionComponent::detectCollision(Game& game, Entity&, Entity& collider, std::pair<double, double> old_position)
{
  if (collider.position.first < old_position.first)
  {
    for (auto collision : left_collisions)
    {
      if (collision.axis > old_position.first) continue;
      if (collision.axis < collider.position.first) break;
  
      if ((old_position.second+collider.size.second > collision.lower) && (old_position.second < collision.upper))
      {
        // We have a collision!
        processCollision(game, collider, collision, Direction::left, old_position);
    
        break;
      }
    }
  } else if (collider.position.first > old_position.first)
  {
    for (auto collision : right_collisions)
    {
      if (collision.axis < old_position.first+collider.size.first) continue;
      if (collision.axis > collider.position.first+collider.size.first) break;
  
      if ((old_position.second+collider.size.second > collision.lower) && (old_position.second < collision.upper))
      {
        // We have a collision!
        processCollision(game, collider, collision, Direction::right, old_position);
    
        break;
      }
    }
  }
  
  if (collider.position.second < old_position.second)
  {
    for (auto collision : up_collisions)
    {
      if (collision.axis > old_position.second) continue;
      if (collision.axis < collider.position.second) break;
  
      if ((collider.position.first+collider.size.first > collision.lower) && (collider.position.first < collision.upper))
      {
        // We have a collision!
        processCollision(game, collider, collision, Direction::up, old_position);
    
        break;
      }
    }
  } else if (collider.position.second > old_position.second)
  {
    for (auto collision : down_collisions)
    {
      if (collision.axis < old_position.second+collider.size.second) continue;
      if (collision.axis > collider.position.second+collider.size.second) break;

      if ((collider.position.first+collider.size.first > collision.lower) && (collider.position.first < collision.upper))
      {
        // We have a collision!
        processCollision(game, collider, collision, Direction::down, old_position);
        
        break;
      }
    }
  }
}

void MapCollisionComponent::processCollision(Game& game, Entity& collider, Collision collision, Direction dir, std::pair<double, double> old_position)
{
  if (collision.type == Collision::Type::wall)
  {
    if (dir == Direction::left)
    {
      collider.position.first = collision.axis;
      collider.send(game, Message::Type::stopMovingHorizontally);
    } else if (dir == Direction::right)
    {
      collider.position.first = collision.axis - collider.size.first;
      collider.send(game, Message::Type::stopMovingHorizontally);
    } else if (dir == Direction::up)
    {
      collider.position.second = collision.axis;
      collider.send(game, Message::Type::stopMovingVertically);
    } else if (dir == Direction::down)
    {
      collider.position.second = collision.axis - collider.size.second;
      collider.send(game, Message::Type::hitTheGround);
    }
  } else if (collision.type == Collision::Type::wrap)
  {
    if (dir == Direction::left)
    {
      collider.position.first = GAME_WIDTH-collider.size.first/2;
    } else if (dir == Direction::right)
    {
      collider.position.first = -collider.size.first/2;
    } else if (dir == Direction::up)
    {
      collider.position.second = GAME_HEIGHT-collider.size.second/2-1;
    } else if (dir == Direction::down)
    {
      collider.position.second = -collider.size.second/2;
    }
  } else if (collision.type == Collision::Type::teleport)
  {
    if (dir == Direction::left)
    {
      game.loadMap(*map.getLeftMap(), std::make_pair(GAME_WIDTH-collider.size.first/2, old_position.second));
    } else if (dir == Direction::right)
    {
      game.loadMap(*map.getRightMap(), std::make_pair(-collider.size.first/2, old_position.second));
    }
  } else if (collision.type == Collision::Type::reverse)
  {
    if (dir == Direction::right)
    {
      collider.position.first = collision.axis - collider.size.first;
      collider.send(game, Message::Type::walkLeft);
    }
  } else if (collision.type == Collision::Type::platform)
  {
    Message msg(Message::Type::drop);
    msg.dropAxis = collision.axis;

    collider.send(game, msg);
  } else if (collision.type == Collision::Type::danger)
  {
    game.playerDie();
  }
}