diff --git a/data/events.tsx b/data/events.tsx index 35ed01c..a6713dd 100644 --- a/data/events.tsx +++ b/data/events.tsx @@ -9,7 +9,8 @@ - + + diff --git a/data/example.tmx b/data/example.tmx index cda08ae..71bde78 100644 --- a/data/example.tmx +++ b/data/example.tmx @@ -48,6 +48,7 @@ + @@ -178,9 +179,10 @@ - + - + + diff --git a/src/actor/actor.cpp b/src/actor/actor.cpp index 4a0c17f..be3914f 100644 --- a/src/actor/actor.cpp +++ b/src/actor/actor.cpp @@ -37,7 +37,6 @@ Actor::Actor(const ActorTemplate& templ, MapData* map) : m_map {map}, m_type {templ.template_name}, m_base_speed {templ.speed}, - m_AI {templ.AI}, m_direction {templ.direction}, m_hitbox {templ.hitbox}, m_animations {templ.animations} @@ -78,7 +77,7 @@ tinyxml2::XMLError Actor::init_actor(tinyxml2::XMLElement* source) { XMLElement* p_tile_properties = source->FirstChildElement("properties"); if(p_tile_properties != nullptr) { XMLElement* p_property = p_tile_properties->FirstChildElement("property"); - eResult = parse_actor_properties(p_property, m_base_speed, m_AI, m_direction); + eResult = m_map->parse_actor_properties(p_property, m_base_speed, m_direction, m_response); if(eResult != XML_SUCCESS) { std::cerr << "Failed at parsing actor properties for actor: " << m_name << "\n"; return eResult; @@ -181,8 +180,9 @@ bool Actor::process_events() { else if(signal == EventSignal::die) {return false;} } } - else { - animate(AnimationType::idle, m_direction); + if(m_event_pipeline.empty()) { + respond(Response::on_idle); + //animate(AnimationType::idle, m_direction); // AI and Player behaviour stuff } return true; diff --git a/src/actor/actor.hpp b/src/actor/actor.hpp index cff27e8..89e630a 100644 --- a/src/actor/actor.hpp +++ b/src/actor/actor.hpp @@ -51,7 +51,6 @@ class Actor{ bool collide(const SDL_Rect* rect, int& x_depth, int& y_depth) const; bool respond(Response r, Actor* cause = nullptr, SDL_Keysym key = SDL_Keysym()); - Behaviour get_behaviour() const {return m_AI;} AnimationType get_animation() const {return m_anim_state;} Direction get_direction() const {return m_direction;} std::string get_name() const {return m_name;} @@ -69,6 +68,8 @@ class Actor{ bool is_blocked(std::string event_type) const; bool in_cooldown(std::string event_type) const; + + private: MapData* m_map; @@ -80,12 +81,12 @@ class Actor{ std::string m_type; float m_base_speed; - Behaviour m_AI; AnimationType m_anim_state = AnimationType::idle; ///< Currently active animation Direction m_direction; ///< Current direction facing SDL_Rect m_hitbox; std::map> m_animations; ///< 2D Map which stores all animation tiles std::map m_response; ///< Map which yields events for response values + std::map m_timestamp; ///< Map holding timestamps for use as cooldown functionality std::map m_block; ///< Map determinig if the event pipeline is blocked for a specific event type std::vector m_event_pipeline; ///< Vector of current events to be processed diff --git a/src/core/gameinfo.cpp b/src/core/gameinfo.cpp index 8b36fb2..5c0b3f3 100644 --- a/src/core/gameinfo.cpp +++ b/src/core/gameinfo.cpp @@ -111,14 +111,13 @@ bool GameInfo::load_map(std::string mapfile) { } bool GameInfo::fetch_player() { - Behaviour B = Behaviour::player; - std::vector actor_list = m_map.get_actors(std::string(""),B); + std::vector actor_list = m_map.get_actors(std::string("PLAYER")); if(actor_list.size() > 1) { - std::cerr << "Error: More than one actor with player behaviour!\n"; + std::cerr << "Error: More than one actor called PLAYER!\n"; return false; } else if(actor_list.size() == 0) { - std::cerr << "Error: No actor with player behaviour found!\n"; + std::cerr << "Error: No actor called PLAYER found!\n"; return false; } else { diff --git a/src/map/layer.cpp b/src/map/layer.cpp index dcae730..bca9292 100644 --- a/src/map/layer.cpp +++ b/src/map/layer.cpp @@ -353,14 +353,13 @@ void Layer::update() { * @return Vector of conforming actors * @note "invalid" value indicates that a parameter is ignored */ -std::vector Layer::get_actors(std::string name, Behaviour behaviour, Direction direction, AnimationType animation) { +std::vector Layer::get_actors(std::string name, Direction direction, AnimationType animation) { std::vector actor_list; if(m_type == LayerType::object) { for(Actor& actor : m_obj_grid) { bool match = true; if(name != "" && actor.get_name() != name) {match = false;} - if(behaviour != Behaviour::invalid && actor.get_behaviour() != behaviour) {match = false;} if(direction != Direction::invalid && actor.get_direction() != direction) {match = false;} if(animation != AnimationType::invalid && actor.get_animation() != animation) {match = false;} diff --git a/src/map/layer.hpp b/src/map/layer.hpp index 298e2ae..fd87326 100644 --- a/src/map/layer.hpp +++ b/src/map/layer.hpp @@ -55,7 +55,7 @@ class Layer{ bool render(SDL_Rect* camera, const MapData& base_map) const; void update(); - std::vector get_actors(std::string name = "", Behaviour behaviour = Behaviour::invalid, Direction direction = Direction::invalid, + std::vector get_actors(std::string name = "", Direction direction = Direction::invalid, AnimationType animation = AnimationType::invalid); bool collide(const SDL_Rect* rect, int& x_max, int& y_max, const MapData& base_map, std::vector& collided); diff --git a/src/map/mapdata.cpp b/src/map/mapdata.cpp index 3e97d30..9c79fd1 100644 --- a/src/map/mapdata.cpp +++ b/src/map/mapdata.cpp @@ -189,10 +189,10 @@ void MapData::update() { * @return Vector of conforming actors * @note "invalid" value indicates that a parameter is ignored */ -std::vector MapData::get_actors(std::string name, Behaviour behaviour, Direction direction, AnimationType animation) { +std::vector MapData::get_actors(std::string name, Direction direction, AnimationType animation) { std::vector actor_list; for(Layer& layer : m_layers) { - std::vector sublist = layer.get_actors(name, behaviour, direction, animation); + std::vector sublist = layer.get_actors(name, direction, animation); actor_list.insert(actor_list.end(),sublist.begin(),sublist.end()); } return actor_list; @@ -457,7 +457,7 @@ tinyxml2::XMLError MapData::add_actor_template(tinyxml2::XMLElement* source, Til // Parse user specified properties of the ActorTemplate ActorTemplate& a = m_templates[actor_name]; - eResult = parse_actor_properties(p_property, a.speed, a.AI, a.direction); + eResult = parse_actor_properties(p_property, a.speed, a.direction, a.response); if(eResult != XML_SUCCESS) { std::cerr << "Failed at parsing actor properties for actor template of actor: " << actor_name << "\n"; return eResult; @@ -515,3 +515,68 @@ bool MapData::collide(const SDL_Rect* rect, int& x_max, int& y_max, std::vector< } return collide; } + +tinyxml2::XMLError MapData::parse_actor_properties(tinyxml2::XMLElement* source, float& speed, Direction& dir, std::map& resp) { + using namespace tinyxml2; + XMLError eResult; + while(source != nullptr) { + const char* p_name; + p_name = source->Attribute("name"); + std::string name(p_name); + if(p_name == nullptr) return XML_ERROR_PARSING_ATTRIBUTE; + + // Parse base speed + else if(name == "BASE_SPEED") { + eResult = source->QueryFloatAttribute("value", &speed); + if(eResult != XML_SUCCESS) { + std::cerr << "Failed at loading speed value\n"; + return eResult; + } + } + + // Parse current direction facing + else if(name == "DIRECTION") { + const char* p_direction = source->Attribute("value"); + if(p_direction != nullptr) { + dir = str_to_direction(std::string(p_direction)); + if(dir == Direction::invalid) { + std::cerr << "Invalid direction type \"" << p_direction << "\"specified\n"; + return XML_WRONG_ATTRIBUTE_TYPE; + } + } + else { + std::cerr << "Empty direction value specified\n"; + return XML_NO_ATTRIBUTE; + } + + } + + // Parse response values + else if(str_to_response(name) != Response::invalid) { + const char* p_event = source->Attribute("value"); + if(p_event != nullptr) { + std::string event(p_event); + if(check_event(event)) { + resp[str_to_response(name)] = get_event(event); + } + else { + std::cerr << "An event called: " << event << " does not exist/ never got parsed!"; + return XML_ERROR_PARSING_ATTRIBUTE; + } + } + else { + std::cerr << "Empty response event specified\n"; + return XML_NO_ATTRIBUTE; + } + } + + else { + std::cerr << "Unknown actor property \"" << p_name << "\" specified\n"; + return XML_ERROR_PARSING_ATTRIBUTE; + } + // Move to next property + source = source->NextSiblingElement("property"); + } + return XML_SUCCESS; +} + diff --git a/src/map/mapdata.hpp b/src/map/mapdata.hpp index 4db342a..3e27749 100644 --- a/src/map/mapdata.hpp +++ b/src/map/mapdata.hpp @@ -53,9 +53,10 @@ class MapData { unsigned get_tile_w() const {return m_tile_w;} void register_event(std::pair event) {m_events.insert(event);} ActorEvent* get_event(std::string name) const {return m_events.at(name)->copy();} ///< Returns copy of named event + bool check_event(std::string name) const {if(m_events.find(name) != m_events.end()) {return true;} else {return false;}} const ActorTemplate& get_actor_template(Uint16 gid) const {return m_templates.at(m_gid_to_temp_name.at(gid));} - std::vector get_actors(std::string name = "", Behaviour behaviour = Behaviour::invalid, Direction direction = Direction::invalid, + std::vector get_actors(std::string name = "", Direction direction = Direction::invalid, AnimationType animation = AnimationType::invalid); bool collide(const SDL_Rect* rect, int& x_max, int& y_max, std::vector& collided); @@ -73,6 +74,8 @@ class MapData { bool render(Uint16 tile_id, int x, int y) const; bool render(Uint16 tile_id, SDL_Rect& dest) const; + tinyxml2::XMLError parse_actor_properties(tinyxml2::XMLElement* source, float& speed, Direction& dir, std::map& resp); + private: tinyxml2::XMLDocument m_mapfile{true, tinyxml2::COLLAPSE_WHITESPACE}; ///< Contains the .tmx map file std::string m_base_path = "../data/"; ///< Path to folder where .tmx map files are diff --git a/src/util/game_types.cpp b/src/util/game_types.cpp index b669bae..ee6a8f8 100644 --- a/src/util/game_types.cpp +++ b/src/util/game_types.cpp @@ -52,20 +52,13 @@ EventSignal str_to_event_signal(const std::string& name) { else return EventSignal::invalid; } -/// Converts a @c string to an @c enum of @c Behaviour -Behaviour str_to_behaviour(const std::string& name) { - if(name == "PLAYER") return Behaviour::player; - if(name == "IDLE") return Behaviour::idle; - if(name == "WALK_AROUND") return Behaviour::walk_around; - else return Behaviour::invalid; -} - /// Converts a @c string to an @c enum of @c Response Response str_to_response(const std::string& name) { if(name == "ON_HIT") return Response::on_hit; if(name == "ON_COLLISION") return Response::on_collision; if(name == "ON_ACTIVATION") return Response::on_activation; if(name == "ON_DEATH") return Response::on_death; + if(name == "ON_IDLE") return Response::on_idle; else return Response::invalid; } @@ -137,64 +130,3 @@ tinyxml2::XMLError parse_blendmode(tinyxml2::XMLElement* source, Texture& img) { } return XML_SUCCESS; } - -tinyxml2::XMLError parse_actor_properties(tinyxml2::XMLElement* source, float& speed, Behaviour& beh, Direction& dir) { - using namespace tinyxml2; - XMLError eResult; - while(source != nullptr) { - const char* p_name; - p_name = source->Attribute("name"); - std::string name(p_name); - if(p_name == nullptr) return XML_ERROR_PARSING_ATTRIBUTE; - - // Parse base speed - else if(name == "BASE_SPEED") { - eResult = source->QueryFloatAttribute("value", &speed); - if(eResult != XML_SUCCESS) { - std::cerr << "Failed at loading speed value\n"; - return eResult; - } - } - - //Parse current direction facing - else if(name == "DIRECTION") { - const char* p_direction = source->Attribute("value"); - if(p_direction != nullptr) { - dir = str_to_direction(std::string(p_direction)); - if(dir == Direction::invalid) { - std::cerr << "Invalid direction type \"" << p_direction << "\"specified\n"; - return XML_WRONG_ATTRIBUTE_TYPE; - } - } - else { - std::cerr << "Empty direction value specified\n"; - return XML_NO_ATTRIBUTE; - } - - } - - // Parse the AI type - else if(name == "BEHAVIOUR") { - const char* p_behaviour = source->Attribute("value"); - if(p_behaviour != nullptr) { - beh = str_to_behaviour(std::string(p_behaviour)); - if(beh == Behaviour::invalid) { - std::cerr << "Invalid behaviour type \"" << p_behaviour << "\"specified\n"; - return XML_WRONG_ATTRIBUTE_TYPE; - } - } - else { - std::cerr << "Empty behaviour value specified\n"; - return XML_NO_ATTRIBUTE; - } - } - - else { - std::cerr << "Unknown actor property \"" << p_name << "\" specified\n"; - return XML_ERROR_PARSING_ATTRIBUTE; - } - // Move to next property - source = source->NextSiblingElement("property"); - } - return XML_SUCCESS; -} diff --git a/src/util/game_types.hpp b/src/util/game_types.hpp index 94768b6..5f49924 100644 --- a/src/util/game_types.hpp +++ b/src/util/game_types.hpp @@ -28,18 +28,12 @@ #include "map/tile.hpp" #include "util/tinyxml2.h" +class ActorEvent; /** * @brief A collection of various enums */ -enum class Behaviour { - player, - idle, - walk_around, - invalid, -}; - enum class Direction { up, down, @@ -74,27 +68,26 @@ enum class Response{ on_collision, on_activation, on_death, + on_idle, invalid, }; struct ActorTemplate { std::string template_name = "_"; float speed = 250.0f; // Pixel per second - Behaviour AI = Behaviour::idle; Direction direction = Direction::down; SDL_Rect hitbox = {0,0,0,0}; std::map> animations; + std::map response; ///< Map which yields events for response values }; AnimationType str_to_anim_type(const std::string& name); Direction str_to_direction(const std::string& name); -Behaviour str_to_behaviour(const std::string& name); Priority str_to_priority(const std::string& name); EventSignal str_to_event_signal(const std::string& name); Response str_to_response(const std::string& name); tinyxml2::XMLError parse_hitbox(tinyxml2::XMLElement* source, SDL_Rect& rect); tinyxml2::XMLError parse_blendmode(tinyxml2::XMLElement* source, Texture& img); -tinyxml2::XMLError parse_actor_properties(tinyxml2::XMLElement* source, float& speed, Behaviour& beh, Direction& dir); std::vector dir_to_mov(const Direction dir);