mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-04-21 10:51:18 +02:00
ESSEntityWorldSpawner3DArea initial implementation.
This commit is contained in:
parent
12eade8158
commit
2a249c8f25
@ -65,10 +65,12 @@ WorldSpawner3DSpatialGizmoPlugin::WorldSpawner3DSpatialGizmoPlugin() {
|
||||
const Color gizmo_outline_color = EDITOR_DEF("editors/ess/gizmo_colors/world_spawner_outline", Color(0.5, 0.5, 1));
|
||||
const Color gizmo_text_color = EDITOR_DEF("editors/ess/gizmo_colors/world_spawner_text", Color(0.5, 0.5, 1));
|
||||
const Color gizmo_area_outline_color = EDITOR_DEF("editors/ess/gizmo_colors/world_spawner_area_outline", Color(0.7, 0.3, 0.3));
|
||||
const Color gizmo_area_spawn_pos_color = EDITOR_DEF("editors/ess/gizmo_colors/world_spawner_area_spawn_position", Color(0.9, 0.5, 0.3));
|
||||
|
||||
create_material("outline_material", gizmo_outline_color);
|
||||
create_material("text_material", gizmo_text_color);
|
||||
create_material("area_outline_material", gizmo_area_outline_color);
|
||||
create_material("area_spawn_pos_material", gizmo_area_spawn_pos_color);
|
||||
create_handle_material("handles");
|
||||
}
|
||||
|
||||
@ -193,6 +195,28 @@ void WorldSpawner3DSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
|
||||
p_gizmo->add_lines(lines, area_outline_material);
|
||||
p_gizmo->add_collision_segments(lines);
|
||||
p_gizmo->add_handles(handles, handles_material);
|
||||
|
||||
// Spawn positions
|
||||
|
||||
Vector<Vector2> spawn_positions = aws->get_spawn_positions();
|
||||
|
||||
if (spawn_positions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
lines.clear();
|
||||
|
||||
const Ref<Material> area_spawn_pos_material = get_material("area_spawn_pos_material");
|
||||
|
||||
for (int i = 0; i < spawn_positions.size(); ++i) {
|
||||
Vector2 p = spawn_positions[i];
|
||||
|
||||
lines.push_back(Vector3(p.x, -extents.z, p.y));
|
||||
lines.push_back(Vector3(p.x, extents.z, p.y));
|
||||
}
|
||||
|
||||
p_gizmo->add_lines(lines, area_spawn_pos_material);
|
||||
p_gizmo->add_collision_segments(lines);
|
||||
}
|
||||
|
||||
String WorldSpawner3DSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary) const {
|
||||
|
@ -48,27 +48,17 @@ Vector3 ESSEntityWorldSpawner3DArea::get_spawn_area_extents() const {
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::set_spawn_area_extents(const Vector3 &p_extents) {
|
||||
_spawn_area_extents = p_extents;
|
||||
|
||||
_spawn_slots_dirty = true;
|
||||
}
|
||||
|
||||
String ESSEntityWorldSpawner3DArea::get_entity_name() const {
|
||||
return _entity_name;
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::set_entity_name(const String &p_name) {
|
||||
_entity_name = p_name;
|
||||
int ESSEntityWorldSpawner3DArea::get_spawn_slot_count() const {
|
||||
return _spawn_slot_count;
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::set_spawn_slot_count(const int p_spawn_slot_count) {
|
||||
_spawn_slot_count = p_spawn_slot_count;
|
||||
|
||||
Ref<EntityData> ESSEntityWorldSpawner3DArea::get_entity_data() const {
|
||||
return _entity_data;
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::set_entity_data(const Ref<EntityData> &p_data) {
|
||||
_entity_data = p_data;
|
||||
}
|
||||
|
||||
int ESSEntityWorldSpawner3DArea::get_level() const {
|
||||
return _level;
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::set_level(const int p_level) {
|
||||
_level = p_level;
|
||||
_spawn_slots_dirty = true;
|
||||
}
|
||||
|
||||
float ESSEntityWorldSpawner3DArea::get_respawn_time_min() const {
|
||||
@ -85,12 +75,89 @@ void ESSEntityWorldSpawner3DArea::set_respawn_time_max(const float p_respawn_tim
|
||||
_respawn_time_max = p_respawn_time;
|
||||
}
|
||||
|
||||
void ESSEntityWorldSpawner3DArea::_spawn() {
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
return;
|
||||
}
|
||||
String ESSEntityWorldSpawner3DArea::get_entity_name(const int p_index) const {
|
||||
ERR_FAIL_INDEX_V(p_index, _spawn_entries.size(), String());
|
||||
|
||||
if (!_entity_data.is_valid()) {
|
||||
return _spawn_entries[p_index].entity_name;
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::set_entity_name(const int p_index, const String &p_name) {
|
||||
ERR_FAIL_INDEX(p_index, _spawn_entries.size());
|
||||
|
||||
_spawn_entries.write[p_index].entity_name = p_name;
|
||||
|
||||
_spawn_entries_dirty = true;
|
||||
}
|
||||
|
||||
Ref<EntityData> ESSEntityWorldSpawner3DArea::get_entity_data(const int p_index) const {
|
||||
ERR_FAIL_INDEX_V(p_index, _spawn_entries.size(), Ref<EntityData>());
|
||||
|
||||
return _spawn_entries[p_index].entity_data;
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::set_entity_data(const int p_index, const Ref<EntityData> &p_data) {
|
||||
ERR_FAIL_INDEX(p_index, _spawn_entries.size());
|
||||
|
||||
_spawn_entries.write[p_index].entity_data = p_data;
|
||||
|
||||
_spawn_entries_dirty = true;
|
||||
}
|
||||
|
||||
Vector2i ESSEntityWorldSpawner3DArea::get_entity_level_range(const int p_index) const {
|
||||
ERR_FAIL_INDEX_V(p_index, _spawn_entries.size(), Vector2i());
|
||||
|
||||
return _spawn_entries[p_index].level_range;
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::set_entity_level_range(const int p_index, const Vector2i &p_level_range) {
|
||||
ERR_FAIL_INDEX(p_index, _spawn_entries.size());
|
||||
|
||||
_spawn_entries.write[p_index].level_range = p_level_range;
|
||||
|
||||
_spawn_entries_dirty = true;
|
||||
}
|
||||
|
||||
float ESSEntityWorldSpawner3DArea::get_entity_spawn_chance(const int p_index) const {
|
||||
ERR_FAIL_INDEX_V(p_index, _spawn_entries.size(), 0);
|
||||
|
||||
return _spawn_entries[p_index].spawn_chance;
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::set_entity_spawn_chance(const int p_index, const float p_spawn_chance) {
|
||||
ERR_FAIL_INDEX(p_index, _spawn_entries.size());
|
||||
|
||||
_spawn_entries.write[p_index].spawn_chance = p_spawn_chance;
|
||||
|
||||
_spawn_entries_dirty = true;
|
||||
}
|
||||
|
||||
int ESSEntityWorldSpawner3DArea::get_spawn_entry_count() const {
|
||||
return _spawn_entries.size();
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::clear_spawn_entries() {
|
||||
_spawn_entries.clear();
|
||||
_spawn_entries_dirty = true;
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::add_spawn_entry(const String &p_name, const Ref<EntityData> &p_data, const Vector2i &p_level_range, const float p_spawn_chance) {
|
||||
SpawnEntry e;
|
||||
|
||||
e.entity_name = p_name;
|
||||
e.entity_data = p_data;
|
||||
e.level_range = p_level_range;
|
||||
e.spawn_chance = p_spawn_chance;
|
||||
|
||||
_spawn_entries.push_back(e);
|
||||
|
||||
_spawn_entries_dirty = true;
|
||||
}
|
||||
void ESSEntityWorldSpawner3DArea::remove_spawn_entry(const int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, _spawn_entries.size());
|
||||
|
||||
_spawn_entries.remove(p_index);
|
||||
|
||||
_spawn_entries_dirty = true;
|
||||
}
|
||||
|
||||
void ESSEntityWorldSpawner3DArea::_spawn() {
|
||||
// force spawns in all empty slots
|
||||
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -98,83 +165,218 @@ void ESSEntityWorldSpawner3DArea::_spawn() {
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<EntityCreateInfo> info;
|
||||
info.instance();
|
||||
|
||||
if (!_entity_name.empty()) {
|
||||
info->set_entity_name(_entity_name);
|
||||
} else {
|
||||
info->set_entity_name(get_name());
|
||||
if (_spawn_entries_dirty) {
|
||||
_recalculate_valid_spawn_entries();
|
||||
}
|
||||
|
||||
info->set_entity_controller(EntityEnums::ENITIY_CONTROLLER_AI);
|
||||
info->set_level(_level);
|
||||
info->set_transform(get_global_transform());
|
||||
info->set_entity_data(_entity_data);
|
||||
info->set_species_instance(_entity_data->get_species_instance());
|
||||
ESS::get_singleton()->request_entity_spawn(info);
|
||||
|
||||
Entity *created_entity = info->get_created_entity();
|
||||
|
||||
if (created_entity != NULL) {
|
||||
created_entity->sets_spawner_object_id(get_instance_id());
|
||||
_entity = created_entity->get_instance_id();
|
||||
created_entity->connect("tree_exited", this, "_on_entity_tree_exited");
|
||||
if (_spawn_slots_dirty) {
|
||||
_recalculate_slots();
|
||||
}
|
||||
|
||||
emit_on_entity_spawned(info);
|
||||
for (int i = 0; i < _spawn_slots.size(); ++i) {
|
||||
const SpawnSlot &e = _spawn_slots.write[i];
|
||||
|
||||
if (e.entity == ObjectID()) {
|
||||
_spawn_slot(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ESSEntityWorldSpawner3DArea::ESSEntityWorldSpawner3DArea() {
|
||||
_level = 1;
|
||||
_entity = ObjectID();
|
||||
_spawn_slot_count = 0;
|
||||
_respawn_time_min = 0;
|
||||
_respawn_time_max = 0;
|
||||
_respawn_timer = 0;
|
||||
_spawn_area_extents = Vector3(2, 2, 2);
|
||||
_spawn_slots_dirty = true;
|
||||
_spawn_entries_dirty = true;
|
||||
_spawn_entries_max_chance = 0;
|
||||
}
|
||||
|
||||
ESSEntityWorldSpawner3DArea::~ESSEntityWorldSpawner3DArea() {
|
||||
}
|
||||
|
||||
void ESSEntityWorldSpawner3DArea::_on_entity_tree_exited() {
|
||||
_entity = ObjectID();
|
||||
Vector<Vector2> ESSEntityWorldSpawner3DArea::get_spawn_positions() const {
|
||||
Vector<Vector2> pos;
|
||||
|
||||
if (_respawn_time_min > CMP_EPSILON) {
|
||||
if (_respawn_time_max > CMP_EPSILON) {
|
||||
_respawn_timer = Math::random(_respawn_time_min, _respawn_time_max);
|
||||
} else {
|
||||
_respawn_timer = _respawn_time_min;
|
||||
}
|
||||
for (int i = 0; i < _spawn_slots.size(); ++i) {
|
||||
const SpawnSlot &e = _spawn_slots[i];
|
||||
|
||||
set_process_internal(true);
|
||||
pos.push_back(e.position);
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void ESSEntityWorldSpawner3DArea::_on_entity_tree_exited(const ObjectID p_entity_object_id) {
|
||||
for (int i = 0; i < _spawn_slots.size(); ++i) {
|
||||
SpawnSlot &e = _spawn_slots.write[i];
|
||||
|
||||
if (e.entity == p_entity_object_id) {
|
||||
e.entity = ObjectID();
|
||||
|
||||
if (_respawn_time_min > CMP_EPSILON) {
|
||||
if (_respawn_time_max > CMP_EPSILON) {
|
||||
e.respawn_timer = Math::random(_respawn_time_min, _respawn_time_max);
|
||||
} else {
|
||||
e.respawn_timer = _respawn_time_min;
|
||||
}
|
||||
|
||||
set_process_internal(true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ESSEntityWorldSpawner3DArea::_recalculate_slots() {
|
||||
_spawn_slots.resize(_spawn_slot_count);
|
||||
|
||||
for (int i = 0; i < _spawn_slots.size(); ++i) {
|
||||
SpawnSlot &e = _spawn_slots.write[i];
|
||||
|
||||
e.position = Vector2(Math::random(-_spawn_area_extents.x, _spawn_area_extents.x), Math::random(-_spawn_area_extents.z, _spawn_area_extents.z));
|
||||
}
|
||||
|
||||
_spawn_slots_dirty = false;
|
||||
}
|
||||
|
||||
void ESSEntityWorldSpawner3DArea::_recalculate_valid_spawn_entries() {
|
||||
_spawn_entries_max_chance = 0;
|
||||
_valid_spawn_entries.clear();
|
||||
|
||||
for (int i = 0; i < _spawn_entries.size(); ++i) {
|
||||
const SpawnEntry &e = _spawn_entries[i];
|
||||
|
||||
if (e.entity_data.is_valid() && e.spawn_chance > CMP_EPSILON) {
|
||||
_valid_spawn_entries.push_back(e);
|
||||
_spawn_entries_max_chance += e.spawn_chance;
|
||||
}
|
||||
}
|
||||
|
||||
_spawn_entries_dirty = false;
|
||||
}
|
||||
|
||||
void ESSEntityWorldSpawner3DArea::_spawn_slot(const int p_index) {
|
||||
int spawn_index = generate_spawn_index();
|
||||
|
||||
if (spawn_index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const SpawnEntry &e = _spawn_entries[spawn_index];
|
||||
|
||||
SpawnSlot &s = _spawn_slots.write[p_index];
|
||||
|
||||
Ref<EntityCreateInfo> info;
|
||||
info.instance();
|
||||
|
||||
if (!e.entity_name.empty()) {
|
||||
info->set_entity_name(e.entity_name);
|
||||
} else {
|
||||
info->set_entity_name(get_name());
|
||||
}
|
||||
|
||||
info->set_entity_controller(EntityEnums::ENITIY_CONTROLLER_AI);
|
||||
|
||||
int level;
|
||||
|
||||
if (e.level_range.y > 0) {
|
||||
level = Math::randomi(e.level_range.x, e.level_range.y);
|
||||
} else {
|
||||
level = e.level_range.x;
|
||||
}
|
||||
|
||||
info->set_level(level);
|
||||
|
||||
Transform offset;
|
||||
offset.translate_local(Vector3(s.position.x, 0, s.position.y));
|
||||
|
||||
info->set_transform(get_global_transform() * offset);
|
||||
|
||||
info->set_entity_data(e.entity_data);
|
||||
info->set_species_instance(e.entity_data->get_species_instance());
|
||||
ESS::get_singleton()->request_entity_spawn(info);
|
||||
|
||||
s.respawn_timer = 0;
|
||||
|
||||
Entity *created_entity = info->get_created_entity();
|
||||
|
||||
if (created_entity != NULL) {
|
||||
created_entity->sets_spawner_object_id(get_instance_id());
|
||||
s.entity = created_entity->get_instance_id();
|
||||
created_entity->connect("tree_exited", this, "_on_entity_tree_exited", varray(s.entity));
|
||||
}
|
||||
|
||||
emit_on_entity_spawned(info);
|
||||
}
|
||||
|
||||
int ESSEntityWorldSpawner3DArea::generate_spawn_index() {
|
||||
if (_spawn_entries_dirty) {
|
||||
_recalculate_valid_spawn_entries();
|
||||
}
|
||||
|
||||
float rnd = Math::random(0.0f, _spawn_entries_max_chance);
|
||||
float current_spawn_chance = 0;
|
||||
|
||||
for (int i = 0; i < _spawn_entries.size(); ++i) {
|
||||
const SpawnEntry &e = _spawn_entries[i];
|
||||
|
||||
current_spawn_chance += e.spawn_chance;
|
||||
|
||||
if (rnd < current_spawn_chance) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return _spawn_entries.size() - 1;
|
||||
}
|
||||
|
||||
void ESSEntityWorldSpawner3DArea::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
call_deferred("spawn");
|
||||
break;
|
||||
case NOTIFICATION_EXIT_TREE:
|
||||
if (_entity != ObjectID()) {
|
||||
Entity *ent = ObjectDB::get_instance<Entity>(_entity);
|
||||
} break;
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
for (int i = 0; i < _spawn_slots.size(); ++i) {
|
||||
SpawnSlot &s = _spawn_slots.write[i];
|
||||
|
||||
if (ent) {
|
||||
ent->sets_spawner_object_id(ObjectID());
|
||||
if (s.entity != ObjectID()) {
|
||||
Entity *ent = ObjectDB::get_instance<Entity>(s.entity);
|
||||
|
||||
if (ent) {
|
||||
ent->sets_spawner_object_id(ObjectID());
|
||||
}
|
||||
|
||||
s.entity = ObjectID();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NOTIFICATION_INTERNAL_PROCESS:
|
||||
_respawn_timer -= get_tree()->get_idle_process_time();
|
||||
} break;
|
||||
case NOTIFICATION_INTERNAL_PROCESS: {
|
||||
float delta = get_tree()->get_idle_process_time();
|
||||
|
||||
if (_respawn_timer <= 0) {
|
||||
_respawn_timer = 0;
|
||||
set_process_internal(false);
|
||||
call_deferred("spawn");
|
||||
bool has_active_timer = false;
|
||||
|
||||
for (int i = 0; i < _spawn_slots.size(); ++i) {
|
||||
SpawnSlot &s = _spawn_slots.write[i];
|
||||
|
||||
if (s.respawn_timer > CMP_EPSILON2) {
|
||||
s.respawn_timer -= delta;
|
||||
|
||||
if (s.respawn_timer <= 0) {
|
||||
s.respawn_timer = 0;
|
||||
|
||||
call_deferred("_spawn_slot", i);
|
||||
} else {
|
||||
has_active_timer = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
if (!has_active_timer) {
|
||||
set_process_internal(false);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -185,25 +387,41 @@ void ESSEntityWorldSpawner3DArea::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_spawn_area_extents", "value"), &ESSEntityWorldSpawner3DArea::set_spawn_area_extents);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "spawn_area_extents"), "set_spawn_area_extents", "get_spawn_area_extents");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_entity_name"), &ESSEntityWorldSpawner3DArea::get_entity_name);
|
||||
ClassDB::bind_method(D_METHOD("set_entity_name", "value"), &ESSEntityWorldSpawner3DArea::set_entity_name);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "entity_name"), "set_entity_name", "get_entity_name");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_entity_data"), &ESSEntityWorldSpawner3DArea::get_entity_data);
|
||||
ClassDB::bind_method(D_METHOD("set_entity_data", "value"), &ESSEntityWorldSpawner3DArea::set_entity_data);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "entity_data", PROPERTY_HINT_RESOURCE_TYPE, "EntityData"), "set_entity_data", "get_entity_data");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_level"), &ESSEntityWorldSpawner3DArea::get_level);
|
||||
ClassDB::bind_method(D_METHOD("set_level", "value"), &ESSEntityWorldSpawner3DArea::set_level);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "level"), "set_level", "get_level");
|
||||
ClassDB::bind_method(D_METHOD("get_spawn_slot_count"), &ESSEntityWorldSpawner3DArea::get_spawn_slot_count);
|
||||
ClassDB::bind_method(D_METHOD("set_spawn_slot_count", "respawn_time"), &ESSEntityWorldSpawner3DArea::set_spawn_slot_count);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "spawn_slot_count"), "set_spawn_slot_count", "get_spawn_slot_count");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_respawn_time_min"), &ESSEntityWorldSpawner3DArea::get_respawn_time_min);
|
||||
ClassDB::bind_method(D_METHOD("set_respawn_time_min", "respawn_time"), &ESSEntityWorldSpawner3DArea::set_respawn_time_min);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "respawn_time_min"), "set_respawn_time_min", "get_respawn_time_min");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "respawn_time_min"), "set_respawn_time_min", "get_respawn_time_min");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_respawn_time_max"), &ESSEntityWorldSpawner3DArea::get_respawn_time_max);
|
||||
ClassDB::bind_method(D_METHOD("set_respawn_time_max", "respawn_time"), &ESSEntityWorldSpawner3DArea::set_respawn_time_max);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "respawn_time_max"), "set_respawn_time_max", "get_respawn_time_max");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "respawn_time_max"), "set_respawn_time_max", "get_respawn_time_max");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_entity_name", "index"), &ESSEntityWorldSpawner3DArea::get_entity_name);
|
||||
ClassDB::bind_method(D_METHOD("set_entity_name", "index", "name"), &ESSEntityWorldSpawner3DArea::set_entity_name);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_entity_data", "index"), &ESSEntityWorldSpawner3DArea::get_entity_data);
|
||||
ClassDB::bind_method(D_METHOD("set_entity_data", "index", "data"), &ESSEntityWorldSpawner3DArea::set_entity_data);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_entity_level_range", "index"), &ESSEntityWorldSpawner3DArea::get_entity_level_range);
|
||||
ClassDB::bind_method(D_METHOD("set_entity_level_range", "index", "level_range"), &ESSEntityWorldSpawner3DArea::set_entity_level_range);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_entity_spawn_chance", "index"), &ESSEntityWorldSpawner3DArea::get_entity_spawn_chance);
|
||||
ClassDB::bind_method(D_METHOD("set_entity_spawn_chance", "index", "spawn_chance"), &ESSEntityWorldSpawner3DArea::set_entity_spawn_chance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_spawn_entry_count"), &ESSEntityWorldSpawner3DArea::get_spawn_entry_count);
|
||||
ClassDB::bind_method(D_METHOD("clear_spawn_entries"), &ESSEntityWorldSpawner3DArea::clear_spawn_entries);
|
||||
ClassDB::bind_method(D_METHOD("add_spawn_entry", "name", "data", "level_range", "spawn_chance"), &ESSEntityWorldSpawner3DArea::add_spawn_entry);
|
||||
ClassDB::bind_method(D_METHOD("remove_spawn_entry", "index"), &ESSEntityWorldSpawner3DArea::remove_spawn_entry);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_on_entity_tree_exited"), &ESSEntityWorldSpawner3DArea::_on_entity_tree_exited);
|
||||
ClassDB::bind_method(D_METHOD("_spawn_slot"), &ESSEntityWorldSpawner3DArea::_spawn_slot);
|
||||
}
|
||||
|
||||
ESSEntityWorldSpawner3DArea::SpawnEntry::SpawnEntry() {
|
||||
spawn_chance = 1;
|
||||
}
|
||||
ESSEntityWorldSpawner3DArea::SpawnEntry::~SpawnEntry() {
|
||||
}
|
||||
|
@ -43,14 +43,8 @@ public:
|
||||
Vector3 get_spawn_area_extents() const;
|
||||
void set_spawn_area_extents(const Vector3 &p_extents);
|
||||
|
||||
String get_entity_name() const;
|
||||
void set_entity_name(const String &p_name);
|
||||
|
||||
Ref<EntityData> get_entity_data() const;
|
||||
void set_entity_data(const Ref<EntityData> &p_data);
|
||||
|
||||
int get_level() const;
|
||||
void set_level(const int p_level);
|
||||
int get_spawn_slot_count() const;
|
||||
void set_spawn_slot_count(const int p_spawn_slot_count);
|
||||
|
||||
float get_respawn_time_min() const;
|
||||
void set_respawn_time_min(const float p_respawn_time);
|
||||
@ -58,27 +52,76 @@ public:
|
||||
float get_respawn_time_max() const;
|
||||
void set_respawn_time_max(const float p_respawn_time);
|
||||
|
||||
String get_entity_name(const int p_index) const;
|
||||
void set_entity_name(const int p_index, const String &p_name);
|
||||
|
||||
Ref<EntityData> get_entity_data(const int p_index) const;
|
||||
void set_entity_data(const int p_index, const Ref<EntityData> &p_data);
|
||||
|
||||
Vector2i get_entity_level_range(const int p_index) const;
|
||||
void set_entity_level_range(const int p_index, const Vector2i &p_level_range);
|
||||
|
||||
float get_entity_spawn_chance(const int p_index) const;
|
||||
void set_entity_spawn_chance(const int p_index, const float p_spawn_chance);
|
||||
|
||||
int get_spawn_entry_count() const;
|
||||
void clear_spawn_entries();
|
||||
void add_spawn_entry(const String &p_name, const Ref<EntityData> &p_data, const Vector2i &p_level_range, const float p_spawn_chance);
|
||||
void remove_spawn_entry(const int p_index);
|
||||
|
||||
virtual void _spawn();
|
||||
|
||||
ESSEntityWorldSpawner3DArea();
|
||||
~ESSEntityWorldSpawner3DArea();
|
||||
|
||||
// For the gizmo
|
||||
Vector<Vector2> get_spawn_positions() const;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
void _on_entity_tree_exited();
|
||||
void _on_entity_tree_exited(const ObjectID p_entity_object_id);
|
||||
void _recalculate_slots();
|
||||
void _recalculate_valid_spawn_entries();
|
||||
void _spawn_slot(const int p_index);
|
||||
int generate_spawn_index();
|
||||
|
||||
Vector3 _spawn_area_extents;
|
||||
int _spawn_slot_count;
|
||||
|
||||
bool _spawn_slots_dirty;
|
||||
|
||||
String _entity_name;
|
||||
Ref<EntityData> _entity_data;
|
||||
int _level;
|
||||
float _respawn_time_min;
|
||||
float _respawn_time_max;
|
||||
real_t _respawn_timer;
|
||||
|
||||
ObjectID _entity;
|
||||
struct SpawnEntry {
|
||||
String entity_name;
|
||||
Ref<EntityData> entity_data;
|
||||
Vector2i level_range;
|
||||
float spawn_chance;
|
||||
|
||||
SpawnEntry();
|
||||
~SpawnEntry();
|
||||
};
|
||||
|
||||
Vector<SpawnEntry> _spawn_entries;
|
||||
Vector<SpawnEntry> _valid_spawn_entries;
|
||||
float _spawn_entries_max_chance;
|
||||
bool _spawn_entries_dirty;
|
||||
|
||||
struct SpawnSlot {
|
||||
Vector2 position;
|
||||
float respawn_timer;
|
||||
ObjectID entity;
|
||||
|
||||
SpawnSlot() {
|
||||
respawn_timer = 0;
|
||||
entity = ObjectID();
|
||||
}
|
||||
};
|
||||
|
||||
Vector<SpawnSlot> _spawn_slots;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user