Added another sound source child entity to enemy entity and added remaining turret properties to editor and in serialization to file

dev
Shariq Shah 6 years ago
parent 289a480483
commit 08f6518253
  1. 38
      assets/entities/turret.symtres
  2. 3
      src/common/limits.h
  3. 2
      src/common/version.h
  4. 23
      src/game/editor.c
  5. 72
      src/game/enemy.c
  6. 19
      src/game/entity.c
  7. 2
      src/game/entity.h
  8. 6
      src/game/scene.c
  9. 2
      src/game/scene.h
  10. 4
      todo.txt

@ -2,18 +2,27 @@ Entity
{
type : 8
scale : 1.000 1.000 1.000
max_turn_angle : 60.0000
rotation : 0.000 0.423 0.000 0.906
pulsate_height : 1.5000
vision_range : 15.0000
pulsate_speed_scale : 0.1000
rotation : 0.000 0.001 0.000 1.001
health : 116
alert_cooldown : 1.0000
color_alert : 1.000 1.000 0.000 1.000
active : true
position : 5.000 3.000 6.000
turn_speed_when_targetting : 50.0000
max_yaw : 60.0000
position : 0.000 3.000 0.000
bouding_box_min : -0.500 -0.500 -0.500
enemy_type : 0
turn_speed_default : 50.0000
turn_direction_positive : true
attack_cooldown : 0.0500
name : Turret
bouding_box_max : 0.500 0.500 0.500
color_default : 0.000 1.000 1.000 1.000
color_attack : 1.000 0.000 0.000 1.000
damage : 10
turn_speed : 50.0000
}
Entity
@ -37,6 +46,27 @@ Entity
sound_attenuation_type : 2
}
Entity
{
type : 7
scale : 1.000 1.000 1.000
volume : 1.0000
rolloff_factor : 0.9500
rotation : 0.000 0.000 0.000 1.000
loop : true
sound_min_distance : 0.0000
active : true
playing : true
position : 0.000 0.000 0.000
bouding_box_min : -0.500 -0.500 -0.500
source_filename : sounds/windy_ambience.ogg
sound_type : 2
sound_max_distance : 60.0000
name : Turret_Ambient_Sound
bouding_box_max : 0.500 0.500 0.500
sound_attenuation_type : 2
}
Entity
{
type : 6

@ -22,4 +22,7 @@
#define MAX_FRAME_TIME 0.5f
#define MAX_ENEMY_SOUND_SOURCES 2
#define MAX_ENEMY_MESHES 1
#endif

@ -4,7 +4,7 @@
/* Auto generated version file. DO NOT MODIFY */
#define SYMMETRY_VERSION_MAJOR 0
#define SYMMETRY_VERSION_MINOR 1
#define SYMMETRY_VERSION_REVISION 323
#define SYMMETRY_VERSION_REVISION 324
#define SYMMETRY_VERSION_BRANCH "dev"
#endif

@ -41,6 +41,9 @@
#include <limits.h>
#include <math.h>
#define LABEL_FLAGS_ALIGN_LEFT NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_LEFT
#define LABEL_FLAGS_ALIGN_RIGHT NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_RIGHT
enum Editor_Tool
{
EDITOR_TOOL_NORMAL = 0,
@ -2226,7 +2229,25 @@ void editor_window_property_inspector(struct nk_context* context, struct Editor*
{
case ENEMY_TURRET:
{
nk_property_float(context, "Turn Speed", 0.f, &enemy->Turret.turn_speed_default, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Turn Speed Default", 0.f, &enemy->Turret.turn_speed_default, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Turn Speed Targetting", 0.f, &enemy->Turret.turn_speed_when_targetting, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Turn Speed Current", 0.f, &enemy->Turret.turn_speed_current, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Max Yaw", 0.f, &enemy->Turret.max_yaw, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Target Yaw", 0.f, &enemy->Turret.target_yaw, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Pulsate Speed Scale", 0.f, &enemy->Turret.pulsate_speed_scale, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Pulsate Height", 0.f, &enemy->Turret.pulsate_height, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Attack Cooldown", 0.f, &enemy->Turret.attack_cooldown, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Time since attack", 0.f, &enemy->Turret.time_elapsed_since_attack, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Time since alert", 0.f, &enemy->Turret.time_elapsed_since_alert, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Alert Cooldown", 0.f, &enemy->Turret.alert_cooldown, FLT_MAX, 0.5f, 0.1f);
nk_property_float(context, "Vision Range", 0.f, &enemy->Turret.vision_range, FLT_MAX, 0.5f, 0.1f);
nk_layout_row_dynamic(context, row_height, 2);
nk_label(context, "Yaw Positive", LABEL_FLAGS_ALIGN_LEFT); nk_labelf(context, LABEL_FLAGS_ALIGN_LEFT, "%s", enemy->Turret.yaw_direction_positive ? "True" : "False");
nk_label(context, "Pulsate", LABEL_FLAGS_ALIGN_LEFT); nk_labelf(context, LABEL_FLAGS_ALIGN_LEFT, "%s", enemy->Turret.pulsate ? "True" : "False");
nk_label(context, "Scan", LABEL_FLAGS_ALIGN_LEFT); nk_labelf(context, LABEL_FLAGS_ALIGN_LEFT, "%s", enemy->Turret.scan ? "True" : "False");
nk_label(context, "Default Color", LABEL_FLAGS_ALIGN_LEFT); editor_widget_color_combov4(context, &enemy->Turret.color_default, 50, row_height * 2);
nk_label(context, "Alert Color", LABEL_FLAGS_ALIGN_LEFT); editor_widget_color_combov4(context, &enemy->Turret.color_alert, 50, row_height * 2);
nk_label(context, "Attack Color", LABEL_FLAGS_ALIGN_LEFT); editor_widget_color_combov4(context, &enemy->Turret.color_attack, 50, row_height * 2);
}
break;
}

@ -143,8 +143,16 @@ struct Enemy* enemy_read(struct Parser_Object* object, const char* name, struct
{
case ENEMY_TURRET:
{
if(hashmap_value_exists(object->data, "turn_speed")) new_enemy->Turret.turn_speed_default = hashmap_float_get(object->data, "turn_speed");
if(hashmap_value_exists(object->data, "max_turn_angle")) new_enemy->Turret.max_yaw = hashmap_float_get(object->data, "max_turn_angle");
if(hashmap_value_exists(object->data, "turn_speed_default")) new_enemy->Turret.turn_speed_default = hashmap_float_get(object->data, "turn_speed_default");
if(hashmap_value_exists(object->data, "max_yaw")) new_enemy->Turret.max_yaw = hashmap_float_get(object->data, "max_yaw");
if(hashmap_value_exists(object->data, "pulsate_speed_scale")) new_enemy->Turret.pulsate_speed_scale = hashmap_float_get(object->data, "pulsate_speed_scale");
if(hashmap_value_exists(object->data, "pulsate_height")) new_enemy->Turret.pulsate_height = hashmap_float_get(object->data, "pulsate_height");
if(hashmap_value_exists(object->data, "attack_cooldown")) new_enemy->Turret.attack_cooldown = hashmap_float_get(object->data, "attack_cooldown");
if(hashmap_value_exists(object->data, "alert_cooldown")) new_enemy->Turret.alert_cooldown = hashmap_float_get(object->data, "alert_cooldown");
if(hashmap_value_exists(object->data, "vision_range")) new_enemy->Turret.vision_range = hashmap_float_get(object->data, "vision_range");
if(hashmap_value_exists(object->data, "color_default")) new_enemy->Turret.color_default = hashmap_vec4_get(object->data, "color_default");
if(hashmap_value_exists(object->data, "color_alert")) new_enemy->Turret.color_alert = hashmap_vec4_get(object->data, "color_alert");
if(hashmap_value_exists(object->data, "color_attack")) new_enemy->Turret.color_attack = hashmap_vec4_get(object->data, "color_attack");
if(hashmap_value_exists(object->data, "turn_direction_positive")) new_enemy->Turret.yaw_direction_positive = hashmap_bool_get(object->data, "turn_direction_positive");
}
break;
@ -163,8 +171,17 @@ void enemy_write(struct Enemy* enemy, struct Hashmap* entity_data)
{
case ENEMY_TURRET:
{
hashmap_float_set(entity_data, "turn_speed", enemy->Turret.turn_speed_default);
hashmap_float_set(entity_data, "max_turn_angle", enemy->Turret.max_yaw);
hashmap_float_set(entity_data, "turn_speed_default", enemy->Turret.turn_speed_default);
hashmap_float_set(entity_data, "turn_speed_when_targetting", enemy->Turret.turn_speed_default);
hashmap_float_set(entity_data, "max_yaw", enemy->Turret.max_yaw);
hashmap_float_set(entity_data, "pulsate_speed_scale", enemy->Turret.pulsate_speed_scale);
hashmap_float_set(entity_data, "pulsate_height", enemy->Turret.pulsate_height);
hashmap_float_set(entity_data, "attack_cooldown", enemy->Turret.attack_cooldown);
hashmap_float_set(entity_data, "alert_cooldown", enemy->Turret.alert_cooldown);
hashmap_float_set(entity_data, "vision_range", enemy->Turret.vision_range);
hashmap_vec4_set(entity_data, "color_default", &enemy->Turret.color_default);
hashmap_vec4_set(entity_data, "color_alert", &enemy->Turret.color_alert);
hashmap_vec4_set(entity_data, "color_attack", &enemy->Turret.color_attack);
hashmap_bool_set(entity_data, "turn_direction_positive", enemy->Turret.yaw_direction_positive);
}
break;
@ -176,23 +193,26 @@ void enemy_on_scene_loaded(struct Event* event, void* enemy_ptr)
struct Enemy* enemy = (struct Enemy*)enemy_ptr;
// Assign pointers to static_mesh and sound_source child entities
for(int i = 0; i < array_len(enemy->base.transform.children); i++)
struct Entity* enemy_mesh[MAX_ENEMY_MESHES] = { NULL };
struct Entity* enemy_sound_sources[MAX_ENEMY_SOUND_SOURCES] = { NULL };
if(entity_get_num_children_of_type(enemy, ET_STATIC_MESH, &enemy_mesh, MAX_ENEMY_MESHES) == MAX_ENEMY_MESHES)
{
struct Entity* child = enemy->base.transform.children[i];
if(child->type == ET_STATIC_MESH)
enemy->mesh = (struct Static_Mesh*)child;
else if(child->type == ET_SOUND_SOURCE)
enemy->weapon_sound = (struct Sound_Source*)child;
enemy->mesh = enemy_mesh[0];
}
if(enemy->mesh)
enemy->mesh->base.flags |= EF_TRANSIENT;
else
log_error("enemy:on_scene_loaded", "Could not find mesh child entity for enemy %s", enemy->base.name);
if(enemy->weapon_sound)
enemy->weapon_sound->base.flags |= EF_TRANSIENT;
{
log_error("enemy:on_scene_load", "Could not find %d child mesh entities for enemy %s", MAX_ENEMY_MESHES, enemy->base.name);
}
if(entity_get_num_children_of_type(enemy, ET_SOUND_SOURCE, &enemy_sound_sources, MAX_ENEMY_SOUND_SOURCES) == MAX_ENEMY_SOUND_SOURCES)
{
enemy->weapon_sound = enemy_sound_sources[0];
enemy->ambient_sound = enemy_sound_sources[1];
}
else
log_error("enemy:on_scene_loaded", "Could not find weapon_sound child entity for enemy %s", enemy->base.name);
{
log_error("enemy:on_scene_load", "Could not find %d child sound source entities for enemy %s", MAX_ENEMY_SOUND_SOURCES, enemy->base.name);
}
// Do other post-scene-load initialization stuff per enemy type here
switch(enemy->type)
@ -235,10 +255,8 @@ void enemy_update_physics_turret(struct Enemy* enemy, struct Game_State* game_st
float epsilon = 0.5f;
float current_yaw = quat_get_yaw(&enemy->base.transform.rotation);
float difference = enemy->Turret.target_yaw - current_yaw;
//if(fabsf(current_yaw) > enemy->Turret.target_yaw - EPSILON && fabsf(current_yaw) < enemy->Turret.target_yaw + EPSILON)
if(fabsf(difference) > epsilon)
{
//log_message("Difference %.5f", difference);
float yaw = enemy->Turret.turn_speed_current * 1.f * fixed_dt;
if(current_yaw > enemy->Turret.target_yaw)
yaw *= -1.f;
@ -283,7 +301,6 @@ void enemy_update_ai_turret(struct Enemy* enemy, struct Game_State* game_state,
if(distance <= enemy->Turret.vision_range)
{
enemy_state_set_turret(enemy, TURRET_ALERT);
log_message("Player spotted");
}
}
}
@ -304,7 +321,6 @@ void enemy_update_ai_turret(struct Enemy* enemy, struct Game_State* game_state,
if(distance <= enemy->Turret.vision_range)
{
enemy_state_set_turret(enemy, TURRET_ATTACK);
log_message("Player spotted");
}
}
}
@ -336,15 +352,10 @@ void enemy_update_ai_turret(struct Enemy* enemy, struct Game_State* game_state,
float new_target_yaw = current_yaw - yaw_required_to_face_player;
if(fabsf(floorf(new_target_yaw)) > enemy->Turret.max_yaw)
{
log_message("Can't face player");
log_message("New Yaw : %.3f", new_target_yaw);
log_message("Cur yaw : %.3f", current_yaw);
log_message("Ang bet : %.3f", yaw_required_to_face_player);
enemy_state_set_turret(enemy, TURRET_ALERT);
}
else
{
log_message("Acquiring Target...");
float difference = fabsf(enemy->Turret.target_yaw - new_target_yaw);
if(difference > 1.f)
enemy->Turret.target_yaw = new_target_yaw;
@ -352,7 +363,6 @@ void enemy_update_ai_turret(struct Enemy* enemy, struct Game_State* game_state,
}
else
{
log_message("No target in range");
enemy_state_set_turret(enemy, TURRET_ALERT);
}
}
@ -371,17 +381,14 @@ void enemy_update_ai_turret(struct Enemy* enemy, struct Game_State* game_state,
{
enemy->Turret.time_elapsed_since_attack = 0.f;
sound_source_play(game_state->sound, enemy->weapon_sound);
log_message("Player spotted and attacked");
}
else
{
enemy_state_set_turret(enemy, TURRET_ACQUIRE_TARGET);
log_message("Target too far");
}
}
else
{
log_message("Can't find player, cannot attack");
enemy_state_set_turret(enemy, TURRET_ACQUIRE_TARGET);
}
}
@ -402,6 +409,7 @@ void enemy_state_set_turret(struct Enemy* enemy, int state)
case TURRET_DEFAULT:
{
vec4_assign(&model->material_params[MMP_DIFFUSE_COL].val_vec4, &enemy->Turret.color_default);
sound_source_play(game_state_get()->sound, enemy->ambient_sound);
enemy->Turret.time_elapsed_since_alert = 0.f;
enemy->Turret.time_elapsed_since_attack = 0.f;
enemy->Turret.pulsate = true;
@ -424,9 +432,7 @@ void enemy_state_set_turret(struct Enemy* enemy, int state)
break;
case TURRET_ACQUIRE_TARGET:
{
//vec4_assign(&model->material_params[MMP_DIFFUSE_COL].val_vec4, &enemy->Turret.color_attack);
vec4 color = {0.f, 0.f, 1.f, 1.f};
vec4_assign(&model->material_params[MMP_DIFFUSE_COL].val_vec4, &color);
vec4_assign(&model->material_params[MMP_DIFFUSE_COL].val_vec4, &enemy->Turret.color_attack);
enemy->Turret.scan = false;
enemy->Turret.turn_speed_current = enemy->Turret.turn_speed_when_targetting;
}

@ -737,3 +737,22 @@ void entity_rename(struct Entity* entity, const char* new_name)
memset(entity->name, '\0', MAX_ENTITY_NAME_LEN);
snprintf(entity->name, MAX_ENTITY_NAME_LEN, new_name);
}
int entity_get_num_children_of_type(struct Entity* entity, int type, struct Entity** in_children, int max_children)
{
assert(type < ET_MAX && max_children >= 1);
int found_count = -1;
for(int i = 0; i < array_len(entity->transform.children); i++)
{
struct Entity* child = entity->transform.children[i];
if(!(child->flags & EF_MARKED_FOR_DELETION) && (child->flags & EF_ACTIVE) && child->type == type)
{
found_count++;
if(found_count == max_children)
break;
in_children[found_count] = child;
}
}
return found_count + 1;
}

@ -200,6 +200,7 @@ struct Enemy
int current_state;
struct Static_Mesh* mesh;
struct Sound_Source* weapon_sound;
struct Sound_Source* ambient_sound;
union
{
struct
@ -233,6 +234,7 @@ struct Entity* entity_load(const char* filename, int directory_type, bool send_o
bool entity_write(struct Entity* entity, struct Parser_Object* object, bool write_transform);
struct Entity* entity_read(struct Parser_Object* object, struct Entity* parent_entity);
const char* entity_type_name_get(struct Entity* entity);
int entity_get_num_children_of_type(struct Entity* entity, int type, struct Entity** in_children, int max_children);
void entity_rigidbody_on_move(Rigidbody body);
void entity_rigidbody_on_collision(Rigidbody body_A, Rigidbody body_B);
void entity_rigidbody_set(struct Entity* entity, struct Collision* collision, Rigidbody body);

@ -842,7 +842,7 @@ struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* na
return sound_source;
}
struct Enemy* scene_enemy_get(struct Scene* scene, const char* name)
struct Enemy* scene_enemy_find(struct Scene* scene, const char* name)
{
assert(scene && name);
struct Enemy* enemy = NULL;
@ -872,6 +872,7 @@ struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type)
case ET_LIGHT: entity = &scene->lights[id]; break;
case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break;
case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break;
case ET_ENEMY: entity = &scene->enemies[id]; break;
case ET_PLAYER: entity = &scene->player; break;
case ET_ROOT: entity = &scene->root_entity; break;
}
@ -898,6 +899,9 @@ void* scene_find(struct Scene* scene, const char* name)
entity = scene_sound_source_find(scene, name);
if(entity) return entity;
entity = scene_enemy_find(scene, name);
if(entity) return entity;
return entity;
}

@ -53,7 +53,7 @@ struct Camera* scene_camera_find(struct Scene* scene, const char* name);
struct Static_Mesh* scene_static_mesh_find(struct Scene* scene, const char* name);
struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* name);
struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type);
struct Enemy* scene_enemy_get(struct Scene* scene, const char* name);
struct Enemy* scene_enemy_find(struct Scene* scene, const char* name);
void scene_entity_parent_set(struct Scene* scene, struct Entity* entity, struct Entity* parent);
void scene_entity_parent_reset(struct Scene* scene, struct Entity* entity); // Sets root entity as parent

@ -1,8 +1,6 @@
Todo:
- Implement separate property window for player related variables that can be shown in the editor similar to renderer settings etc
- Add all sound source properties to propery inspector
- Add turret properties to property inspector
- Add another ambient sound_source entity as child to enemy entity
- Fix rotate gizmo's origin not being set to the selected entity
- Player shooting
- Player jump cooldown, don't allow jump until a certian time interval has passed, even if we're grounded
@ -415,3 +413,5 @@ Done:
* Made movement framerate independent
* Implement turret state machine
* Fix Turret losing target at diagonals
* Add turret properties to property inspector
* Add another ambient sound_source entity as child to enemy entity
Loading…
Cancel
Save