A 3d fps game made in OpenGL
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
Symmetry/src/game/door.c

152 lines
5.1 KiB

#include "door.h"
#include "entity.h"
#include "scene.h"
#include "game.h"
#include "transform.h"
#include "trigger.h"
#include "event.h"
#include "sound_source.h"
#include "../common/log.h"
#include "../common/parser.h"
#include "../common/hashmap.h"
static void door_on_scene_loaded(struct Event* event, void* door_ptr);
static void door_on_trigger(struct Event* event, void* door_ptr);
void door_init(struct Door* door, int mask)
{
struct Game_State* game_state = game_state_get();
struct Event_Manager* event_manager = game_state->event_manager;
door->base.type = ET_DOOR;
door->mask = mask;
door->speed = 20.f;
door->open_position = -5.f;
door->close_position = 0.f;
door->state = DOOR_CLOSED;
event_manager_subscribe_with_object(event_manager, EVT_SCENE_LOADED, &door_on_scene_loaded, (void*)door);
}
void door_reset(struct Door* door)
{
door->state = -1;
door->speed = 0.f;
struct Event_Manager* event_manager = game_state_get()->event_manager;
event_manager_unsubscribe_with_object(event_manager, EVT_TRIGGER, &door_on_trigger, (void*)door);
event_manager_unsubscribe_with_object(event_manager, EVT_SCENE_LOADED, &door_on_scene_loaded, (void*)door);
}
struct Door* door_read(struct Parser_Object* object, const char* name, struct Entity* parent_entity)
{
struct Door* new_door = NULL;
struct Scene* scene = game_state_get()->scene;
new_door = scene_door_create(scene, name, parent_entity, DOOR_KEY_MASK_NONE);
if(hashmap_value_exists(object->data, "door_speed")) new_door->speed = hashmap_float_get(object->data, "door_speed");
if(hashmap_value_exists(object->data, "door_state")) new_door->state = hashmap_int_get(object->data, "door_state");
if(hashmap_value_exists(object->data, "door_mask")) new_door->mask = hashmap_int_get(object->data, "door_mask");
if(hashmap_value_exists(object->data, "door_open_position")) new_door->open_position = hashmap_float_get(object->data, "door_open_position");
if(hashmap_value_exists(object->data, "door_close_position")) new_door->close_position = hashmap_float_get(object->data, "door_close_position");
return new_door;
}
void door_write(struct Door* door, struct Hashmap* entity_data)
{
hashmap_int_set(entity_data, "door_state", door->state);
hashmap_int_set(entity_data, "door_mask", door->mask);
hashmap_float_set(entity_data, "door_speed", door->speed);
hashmap_float_set(entity_data, "door_open_position", door->open_position);
hashmap_float_set(entity_data, "door_close_position", door->close_position);
}
void door_update(struct Door* door, struct Scene* scene, float dt)
{
struct Game_State* game_state = game_state_get();
struct Player* player = &game_state->scene->player;
switch(door->state)
{
case DOOR_CLOSED:
if(door->trigger->triggered)
{
if((door->mask & player->key_mask) == door->mask)
{
door->state = DOOR_OPENING;
sound_source_buffer_set(game_state->sound, door->sound, "sounds/door_open.wav", ST_WAV);
sound_source_play(game_state->sound, door->sound);
}
}
break;
case DOOR_OPEN:
if(!door->trigger->triggered)
{
door->state = DOOR_CLOSING;
sound_source_buffer_set(game_state->sound, door->sound, "sounds/door_close.wav", ST_WAV);
sound_source_play(game_state->sound, door->sound);
}
break;
case DOOR_OPENING:
if(door->mesh->base.transform.position.x >= door->open_position)
transform_translate(door->mesh, &(vec3) { door->speed* dt * -1.f, 0.f, 0.f }, TS_LOCAL);
else
door->state = DOOR_OPEN;
break;
case DOOR_CLOSING:
if(door->mesh->base.transform.position.x <= door->close_position)
transform_translate(door->mesh, &(vec3) { door->speed* dt * 1.f, 0.f, 0.f }, TS_LOCAL);
else
door->state = DOOR_CLOSED;
break;
}
}
void door_on_scene_loaded(struct Event* event, void* door_ptr)
{
struct Door* door = (struct Door*)door_ptr;
struct Entity* door_mesh[1] = { NULL };
struct Entity* door_sound[1] = { NULL };
struct Entity* door_trigger[1] = { NULL };
if(entity_get_num_children_of_type(door, ET_STATIC_MESH, &door_mesh, 1) == 1)
door->mesh = door_mesh[0];
else
log_error("door:on_scene_load", "Could not find mesh entity for door %s", door->base.name);
if(entity_get_num_children_of_type(door, ET_SOUND_SOURCE, &door_sound, 1) == 1)
door->sound = door_sound[0];
else
log_error("door:on_scene_load", "Could not find sound entity for door %s", door->base.name);
if(entity_get_num_children_of_type(door, ET_TRIGGER, &door_trigger, 1) == 1)
{
door->trigger = door_trigger[0];
struct Event_Manager* event_manager = game_state_get()->event_manager;
event_manager_subscribe_with_object(event_manager, EVT_TRIGGER, &door_on_trigger, (void*)door);
}
else
{
log_error("door:on_scene_load", "Could not find trigger entity for door %s", door->base.name);
}
}
void door_on_trigger(struct Event* event, void* door_ptr)
{
struct Game_State* game_state = game_state_get();
struct Door* door = (struct Door*)door_ptr;
//log_message("Trigger %s triggered for door %s", door->trigger->base.name, door->base.name);
switch(door->state)
{
case DOOR_CLOSED:
break;
case DOOR_OPEN:
break;
case DOOR_OPENING:
case DOOR_CLOSING:
break;
}
}