Horizon Official Technical Documentation
Horizon::Zone::GameLogicProcess::MonsterSpawnAgent Class Reference
+ Collaboration diagram for Horizon::Zone::GameLogicProcess::MonsterSpawnAgent:

Public Member Functions

 ~MonsterSpawnAgent ()
 
void initialize (std::shared_ptr< GameLogicProcess > game_logic_process)
 
void finalize ()
 
std::shared_ptr< GameLogicProcessget_container ()
 
void spawn_monsters (std::string map_name)
 
void reschedule_single_monster_spawn (std::shared_ptr< Horizon::Zone::Units::Monster > monster)
 
void spawn_monster_internal (std::shared_ptr< Map > map, int spawn_dataset_id, int monster_id, int16_t amount, int16_t x, int16_t y, int16_t x_area, int16_t y_area)
 
void despawn_monsters (std::string map_name)
 
void register_monster_spawn_info (uint32_t id, std::shared_ptr< monster_spawn_data > data)
 
std::shared_ptr< monster_spawn_dataget_monster_spawn_info (uint32_t id)
 
void clear_monster_spawn_info ()
 

Public Attributes

int32_t _last_monster_spawn_id {0}
 

Private Attributes

std::weak_ptr< GameLogicProcess_game_logic_process
 
LockedLookupTable< uint32_t, std::shared_ptr< monster_spawn_data > > _monster_spawn_db
 

Constructor & Destructor Documentation

◆ ~MonsterSpawnAgent()

GameLogicProcess::MonsterSpawnAgent::~MonsterSpawnAgent ( )
221{
222
223}

Member Function Documentation

◆ clear_monster_spawn_info()

void Horizon::Zone::GameLogicProcess::MonsterSpawnAgent::clear_monster_spawn_info ( )
inline
LockedLookupTable< uint32_t, std::shared_ptr< monster_spawn_data > > _monster_spawn_db
Definition: GameLogicProcess.hpp:78
void clear()
Definition: LockedLookupTable.hpp:112

References _monster_spawn_db, and LockedLookupTable< Key, Value, Hash >::clear().

Referenced by Horizon::Zone::GameLogicProcess::finalize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ despawn_monsters()

void GameLogicProcess::MonsterSpawnAgent::despawn_monsters ( std::string  map_name)
329{
330 int segment_number = sZone->get_segment_number_for_resource<Horizon::Zone::GameLogicProcess, RESOURCE_PRIORITY_PRIMARY, std::string, std::shared_ptr<Map>>(Horizon::System::RUNTIME_GAMELOGIC, map_name, nullptr);
331
332 if (segment_number == 0)
333 return;
334
335 std::shared_ptr<Horizon::Zone::GameLogicProcess> container = sZone->get_component_of_type<Horizon::Zone::GameLogicProcess>(Horizon::System::RUNTIME_GAMELOGIC, segment_number);
336
337 if (container == nullptr)
338 return;
339
340 auto monster_spawned_map = container->get_resource_manager().get_medium<RESOURCE_PRIORITY_TERTIARY>().get_map();
341
342 for (auto i = monster_spawned_map.begin(); i != monster_spawned_map.end();)
343 if ((*i).second->map()->get_name() == map_name && (*i).second->type() == UNIT_MONSTER) {
344 (*i).second->finalize();
345 container->get_resource_manager().remove<RESOURCE_PRIORITY_TERTIARY>((*i).second->uuid());
346 i = monster_spawned_map.erase(i);
347 } else {
348 i++;
349 }
350}
@ RESOURCE_PRIORITY_PRIMARY
Definition: Server.hpp:79
@ RESOURCE_PRIORITY_TERTIARY
Definition: Server.hpp:81
@ UNIT_MONSTER
Definition: UnitDefinitions.hpp:50
#define sZone
Definition: Zone.hpp:247
Definition: GameLogicProcess.hpp:48
ResourceManager & get_resource_manager()
Definition: GameLogicProcess.hpp:113
auto & get_medium()
Definition: Server.hpp:152
@ RUNTIME_GAMELOGIC
Definition: System.hpp:86

References SharedPriorityResourceManager< SharedPriorityResourceMediums >::get_medium(), Horizon::Zone::GameLogicProcess::get_resource_manager(), RESOURCE_PRIORITY_PRIMARY, RESOURCE_PRIORITY_TERTIARY, Horizon::System::RUNTIME_GAMELOGIC, sZone, and UNIT_MONSTER.

+ Here is the call graph for this function:

◆ finalize()

void Horizon::Zone::GameLogicProcess::MonsterSpawnAgent::finalize ( )

◆ get_container()

std::shared_ptr< GameLogicProcess > Horizon::Zone::GameLogicProcess::MonsterSpawnAgent::get_container ( )
inline
62{ return _game_logic_process.lock(); }
std::weak_ptr< GameLogicProcess > _game_logic_process
Definition: GameLogicProcess.hpp:77

References _game_logic_process.

◆ get_monster_spawn_info()

std::shared_ptr< monster_spawn_data > Horizon::Zone::GameLogicProcess::MonsterSpawnAgent::get_monster_spawn_info ( uint32_t  id)
inline
72{ return _monster_spawn_db.at(id); }
Value at(Key const &key, Value const &default_value=Value()) const
Definition: LockedLookupTable.hpp:63

References _monster_spawn_db, and LockedLookupTable< Key, Value, Hash >::at().

+ Here is the call graph for this function:

◆ initialize()

void Horizon::Zone::GameLogicProcess::MonsterSpawnAgent::initialize ( std::shared_ptr< GameLogicProcess game_logic_process)
inline
56 {
57 _game_logic_process = game_logic_process;
58 }

References _game_logic_process.

Referenced by Horizon::Zone::GameLogicProcess::initialize().

+ Here is the caller graph for this function:

◆ register_monster_spawn_info()

void Horizon::Zone::GameLogicProcess::MonsterSpawnAgent::register_monster_spawn_info ( uint32_t  id,
std::shared_ptr< monster_spawn_data data 
)
inline
71{ _monster_spawn_db.insert(id, data); }
void insert(const Key &key, const Value &value)
Definition: LockedLookupTable.hpp:68

References _monster_spawn_db, and LockedLookupTable< Key, Value, Hash >::insert().

+ Here is the call graph for this function:

◆ reschedule_single_monster_spawn()

void GameLogicProcess::MonsterSpawnAgent::reschedule_single_monster_spawn ( std::shared_ptr< Horizon::Zone::Units::Monster monster)
226{
227 uint8_t type = 0;
228 uint32_t guid = 0;
229 uint16_t spawn_dataset_id = 0;
230 uint8_t spawn_id = 0;
231
232 sZone->from_uuid(monster->uuid(), type, guid, spawn_dataset_id, spawn_id);
233
234 std::shared_ptr<monster_spawn_data> msd = get_monster_spawn_info(spawn_dataset_id);
235
236 if (msd == nullptr) {
237 HLog(error) << "Couldn't find monster spawn data for monster " << monster->uuid() << ", spawn_dataset_id " << spawn_dataset_id << ", monster_id " << monster->job_id() << " and spawn_id " << spawn_id << ".";
238 return;
239 }
240
241 std::shared_ptr<Map> map = monster->map();
242
243 msd->dead_amount++;
244 // Set the spawn time cache. This is used to calculate the time to spawn the monster.
246 spawn_time_cache.dead_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
247
248 spawn_time_cache.spawn_time = msd->spawn_delay_base + std::rand() % (msd->spawn_delay_variance + 1);
249 msd->dead_spawn_time_list.emplace(monster->uuid(), spawn_time_cache);
250
251 get_container()->getScheduler().Schedule(
252 Milliseconds(spawn_time_cache.spawn_time),
253 monster->get_scheduler_task_id(UNIT_SCHEDULE_MONSTER_RESPAWN),
254 [this, monster, map, msd](TaskContext /*&context*/) {
255 if (map->get_user_count() == 0)
256 return;
257
258 this->spawn_monster_internal(map, msd->spawn_dataset_id, msd->monster_id, 1, msd->x, msd->y, msd->x_area, msd->y_area);
259 msd->dead_spawn_time_list.erase(monster->uuid());
260 msd->dead_amount--;
261 });
262}
#define HLog(type)
Definition: Logger.hpp:122
std::chrono::milliseconds Milliseconds
Definition: TaskScheduler.hpp:31
@ UNIT_SCHEDULE_MONSTER_RESPAWN
Definition: Unit.hpp:61
std::shared_ptr< GameLogicProcess > get_container()
Definition: GameLogicProcess.hpp:62
std::shared_ptr< monster_spawn_data > get_monster_spawn_info(uint32_t id)
Definition: GameLogicProcess.hpp:72
Definition: TaskScheduler.hpp:487
Definition: MonsterDefinitions.hpp:179
int64_t spawn_time
Definition: MonsterDefinitions.hpp:181
int64_t dead_time
Definition: MonsterDefinitions.hpp:180

References monster_spawn_data::s_monster_spawn_time_cache::dead_time, HLog, monster_spawn_data::s_monster_spawn_time_cache::spawn_time, sZone, and UNIT_SCHEDULE_MONSTER_RESPAWN.

◆ spawn_monster_internal()

void GameLogicProcess::MonsterSpawnAgent::spawn_monster_internal ( std::shared_ptr< Map map,
int  spawn_dataset_id,
int  monster_id,
int16_t  amount,
int16_t  x,
int16_t  y,
int16_t  x_area,
int16_t  y_area 
)
353{
354 std::shared_ptr<const monster_config_data> md = MonsterDB->get_monster_by_id(monster_id);
355
356 if (md == nullptr) {
357 HLog(warning) << "Monster " << monster_id << " set for spawn in " << map->get_name() << " does not exist in the database.";
358 return;
359 }
360
361 std::shared_ptr<std::vector<std::shared_ptr<const monster_skill_config_data>>> mskd = MonsterDB->get_monster_skill_by_id(monster_id);
362
363 for (int i = 0; i < amount; i++) {
364 MapCoords mcoords = MapCoords(x, y);
365 if (mcoords == MapCoords(0, 0))
366 mcoords = map->get_random_accessible_coordinates();
367 else if (x_area && y_area) {
368 if ((mcoords = map->get_random_coordinates_in_walkable_area(x, y, x_area, y_area)) == MapCoords(0, 0)) {
369 HLog(warning) << "Couldn't spawn monster " << md->name << " in area, spawning it on random co-ordinates.";
370 mcoords = map->get_random_accessible_coordinates();
371 }
372 }
373 std::shared_ptr<Horizon::Zone::Units::Monster> monster = std::make_shared<Horizon::Zone::Units::Monster>(spawn_dataset_id, i, map, mcoords, md, mskd);
374
375 monster->initialize();
376 map->container()->get_resource_manager().add<RESOURCE_PRIORITY_TERTIARY>(monster->guid(), monster);
377 }
378
379 return;
380}
Coordinates< MAX_CELLS_PER_MAP > MapCoords
Definition: GridDefinitions.hpp:83
#define MonsterDB
Definition: MonsterDB.hpp:101

References HLog, MonsterDB, and RESOURCE_PRIORITY_TERTIARY.

◆ spawn_monsters()

void GameLogicProcess::MonsterSpawnAgent::spawn_monsters ( std::string  map_name)
265{
266 auto monster_spawn_map = _monster_spawn_db.get_map();
267
268 for (auto i = monster_spawn_map.begin(); i != monster_spawn_map.end(); i++) {
269 std::shared_ptr<monster_spawn_data> msd = (*i).second;
270 if (map_name.compare(msd->map_name) == 0) {
271 if (msd->dead_amount > 0) {
272 for (auto dead_it = msd->dead_spawn_time_list.begin(); dead_it != msd->dead_spawn_time_list.end();) {
273 int64_t dead_monster_spawn_uuid = dead_it->first;
274 monster_spawn_data::s_monster_spawn_time_cache dead_stc = dead_it->second;
275
276 uint8_t type = 0;
277 uint32_t guid = 0;
278 uint16_t spawn_dataset_id = 0;
279 uint8_t spawn_id = 0;
280
281 sZone->from_uuid(dead_monster_spawn_uuid, type, guid, spawn_dataset_id, spawn_id);
282
283 int64_t since_death_ms = (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - dead_stc.dead_time);
284
285 int64_t time_to_spawn_ms = dead_stc.spawn_time - since_death_ms;
286
287 if (time_to_spawn_ms < 0)
288 time_to_spawn_ms = 0;
289
290 this->get_container()->getScheduler().Schedule(
291 Milliseconds(time_to_spawn_ms),
292 ((uint64_t) guid << 32) + (int) UNIT_SCHEDULE_MONSTER_RESPAWN,
293 [this, map_name, msd](TaskContext /*&context*/) {
294 int segment_number = sZone->get_segment_number_for_resource<Horizon::Zone::GameLogicProcess, RESOURCE_PRIORITY_PRIMARY, std::string, std::shared_ptr<Map>>(Horizon::System::RUNTIME_GAMELOGIC, map_name, nullptr);
295
296 if (segment_number == 0)
297 return;
298
299 std::shared_ptr<Horizon::Zone::GameLogicProcess> container = sZone->get_component_of_type<Horizon::Zone::GameLogicProcess>(Horizon::System::RUNTIME_GAMELOGIC, segment_number);
300
301 std::shared_ptr<Map> map = container->get_resource_manager().template get_resource<RESOURCE_PRIORITY_PRIMARY, std::string, std::shared_ptr<Map>>(map_name, nullptr);
302
303 if (map->get_user_count() == 0)
304 return;
305
306 this->spawn_monster_internal(map, msd->spawn_dataset_id, msd->monster_id, 1, msd->x, msd->y, msd->x_area, msd->y_area);
307 });
308
309 dead_it = msd->dead_spawn_time_list.erase(dead_it);
310 msd->dead_amount--;
311 }
312 }
313
314 int segment_number = sZone->get_segment_number_for_resource<Horizon::Zone::GameLogicProcess, RESOURCE_PRIORITY_PRIMARY, std::string, std::shared_ptr<Map>>(Horizon::System::RUNTIME_GAMELOGIC, map_name, nullptr);
315
316 if (segment_number == 0)
317 return;
318
319 std::shared_ptr<Horizon::Zone::GameLogicProcess> container = sZone->get_component_of_type<Horizon::Zone::GameLogicProcess>(Horizon::System::RUNTIME_GAMELOGIC, segment_number);
320
321 std::shared_ptr<Map> map = container->get_resource_manager().template get_resource<RESOURCE_PRIORITY_PRIMARY, std::string, std::shared_ptr<Map>>(map_name, nullptr);
322
323 this->spawn_monster_internal(map, msd->spawn_dataset_id, msd->monster_id, msd->amount - msd->dead_amount, msd->x, msd->y, msd->x_area, msd->y_area);
324 }
325 }
326}
void spawn_monster_internal(std::shared_ptr< Map > map, int spawn_dataset_id, int monster_id, int16_t amount, int16_t x, int16_t y, int16_t x_area, int16_t y_area)
Definition: GameLogicProcess.cpp:352
std::map< Key, Value > get_map() const
Definition: LockedLookupTable.hpp:78

References monster_spawn_data::s_monster_spawn_time_cache::dead_time, Horizon::Zone::GameLogicProcess::get_resource_manager(), RESOURCE_PRIORITY_PRIMARY, Horizon::System::RUNTIME_GAMELOGIC, monster_spawn_data::s_monster_spawn_time_cache::spawn_time, sZone, and UNIT_SCHEDULE_MONSTER_RESPAWN.

+ Here is the call graph for this function:

Member Data Documentation

◆ _game_logic_process

std::weak_ptr<GameLogicProcess> Horizon::Zone::GameLogicProcess::MonsterSpawnAgent::_game_logic_process
private

Referenced by get_container(), and initialize().

◆ _last_monster_spawn_id

int32_t Horizon::Zone::GameLogicProcess::MonsterSpawnAgent::_last_monster_spawn_id {0}

◆ _monster_spawn_db

LockedLookupTable<uint32_t, std::shared_ptr<monster_spawn_data> > Horizon::Zone::GameLogicProcess::MonsterSpawnAgent::_monster_spawn_db
private

The documentation for this class was generated from the following files: