diff options
Diffstat (limited to 'src/map/map.hpp')
-rw-r--r-- | src/map/map.hpp | 260 |
1 files changed, 199 insertions, 61 deletions
diff --git a/src/map/map.hpp b/src/map/map.hpp index c3b4593..cb2513a 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -35,15 +35,35 @@ constexpr int MAX_DROP_PER_MAP = 48; constexpr interval_t DEFAULT_AUTOSAVE_INTERVAL = std::chrono::minutes(1); +struct map_session_data; +struct npc_data; +struct mob_data; +struct flooritem_data; +struct invocation; + struct block_list { - struct block_list *bl_next, *bl_prev; + dumb_ptr<block_list> bl_next, bl_prev; int bl_id; short bl_m, bl_x, bl_y; BL bl_type; -#warning "This is important!" - // virtual ~block_list() {} + // This deletes the copy-ctor also + // TODO give proper ctors. + block_list& operator = (block_list&&) = delete; + virtual ~block_list() {} + + dumb_ptr<map_session_data> as_player(); + dumb_ptr<npc_data> as_npc(); + dumb_ptr<mob_data> as_mob(); + dumb_ptr<flooritem_data> as_item(); + dumb_ptr<invocation> as_spell(); + + dumb_ptr<map_session_data> is_player(); + dumb_ptr<npc_data> is_npc(); + dumb_ptr<mob_data> is_mob(); + dumb_ptr<flooritem_data> is_item(); + dumb_ptr<invocation> is_spell(); }; struct walkpath_data @@ -155,7 +175,7 @@ struct map_session_data : block_list, SessionData int followtarget; tick_t cast_tick; // [Fate] Next tick at which spellcasting is allowed - struct invocation *active_spells; // [Fate] Singly-linked list of active spells linked to this PC + dumb_ptr<invocation> active_spells; // [Fate] Singly-linked list of active spells linked to this PC int attack_spell_override; // [Fate] When an attack spell is active for this player, they trigger it // like a weapon. Check pc_attack_timer() for details. // Weapon equipment slot (slot 4) item override @@ -279,6 +299,11 @@ struct npc_item_list { int nameid, value; }; + +class npc_data_script; +class npc_data_shop; +class npc_data_warp; +class npc_data_message; struct npc_data : block_list { NpcSubtype npc_subtype; @@ -288,41 +313,66 @@ struct npc_data : block_list interval_t speed; char name[24]; char exname[24]; - int chat_id; Opt1 opt1; Opt2 opt2; Opt3 opt3; Option option; short flag; - union - { - struct - { - const ScriptCode *script; - short xs, ys; - interval_t timer; - Timer timerid; - int timeramount, nexttimer; - tick_t timertick; - struct npc_timerevent_list *timer_event; - int label_list_num; - struct npc_label_list *label_list; - int src_id; - } scr; - struct npc_item_list shop_item[1]; - struct - { - short xs, ys; - short x, y; - char name[16]; - } warp; - char *message; // for NpcSubtype::MESSAGE: only send this message - } u; - // ここにメンバを追加してはならない(shop_itemが可変長の為) char eventqueue[MAX_EVENTQUEUE][50]; Timer eventtimer[MAX_EVENTTIMER]; short arenaflag; + + dumb_ptr<npc_data_script> as_script(); + dumb_ptr<npc_data_shop> as_shop(); + dumb_ptr<npc_data_warp> as_warp(); + dumb_ptr<npc_data_message> as_message(); + + dumb_ptr<npc_data_script> is_script(); + dumb_ptr<npc_data_shop> is_shop(); + dumb_ptr<npc_data_warp> is_warp(); + dumb_ptr<npc_data_message> is_message(); +}; + +class npc_data_script : public npc_data +{ +public: + struct + { + const ScriptCode *script; + short xs, ys; + interval_t timer; + Timer timerid; + int timeramount, nexttimer; + tick_t timertick; + struct npc_timerevent_list *timer_event; + int label_list_num; + struct npc_label_list *label_list; + int src_id; + } scr; +}; + +class npc_data_shop : public npc_data +{ +public: + std::vector<npc_item_list> shop_items; +}; + +class npc_data_warp : public npc_data +{ +public: + struct + { + short xs, ys; + short x, y; + char name[16]; + } warp; +}; + +class npc_data_message : public npc_data +{ +public: + char *message; }; constexpr int MOB_XP_BONUS_BASE = 1024; @@ -400,8 +450,8 @@ struct map_data char alias[24]; // [MouseJstr] // if NULL, actually a map_data_other_server std::unique_ptr<MapCell[]> gat; - struct block_list **block; - struct block_list **block_mob; + dumb_ptr<block_list> *block; + dumb_ptr<block_list> *block_mob; int *block_count, *block_mob_count; int m; short xs, ys; @@ -436,7 +486,7 @@ struct map_data unsigned town:1; // [remoitnane] } flag; struct point save; - struct npc_data *npc[MAX_NPC_PER_MAP]; + dumb_ptr<npc_data> npc[MAX_NPC_PER_MAP]; struct { int drop_id; @@ -496,21 +546,21 @@ public: ~MapBlockLock(); static - void freeblock(struct block_list *); + void freeblock(dumb_ptr<block_list>); }; -int map_addblock(struct block_list *); -int map_delblock(struct block_list *); -void map_foreachinarea(std::function<void(struct block_list *)>, +int map_addblock(dumb_ptr<block_list>); +int map_delblock(dumb_ptr<block_list>); +void map_foreachinarea(std::function<void(dumb_ptr<block_list>)>, int, int, int, int, int, BL); // -- moonsoul (added map_foreachincell) -void map_foreachincell(std::function<void(struct block_list *)>, +void map_foreachincell(std::function<void(dumb_ptr<block_list>)>, int, int, int, BL); -void map_foreachinmovearea(std::function<void(struct block_list *)>, +void map_foreachinmovearea(std::function<void(dumb_ptr<block_list>)>, int, int, int, int, int, int, int, @@ -518,15 +568,15 @@ void map_foreachinmovearea(std::function<void(struct block_list *)>, //block関連に追加 int map_count_oncell(int m, int x, int y); // 一時的object関連 -int map_addobject(struct block_list *); +int map_addobject(dumb_ptr<block_list>); int map_delobject(int, BL type); int map_delobjectnofree(int id, BL type); -void map_foreachobject(std::function<void(struct block_list *)>, +void map_foreachobject(std::function<void(dumb_ptr<block_list>)>, BL); // -void map_quit(struct map_session_data *); +void map_quit(dumb_ptr<map_session_data>); // npc -int map_addnpc(int, struct npc_data *); +int map_addnpc(int, dumb_ptr<npc_data>); void map_log(const_string line); #define MAP_LOG(format, ...) \ @@ -544,36 +594,100 @@ void map_clearflooritem(int id) map_clearflooritem_timer(nullptr, tick_t(), id); } int map_addflooritem_any(struct item *, int amount, int m, int x, int y, - struct map_session_data **owners, interval_t *owner_protection, + dumb_ptr<map_session_data> *owners, interval_t *owner_protection, interval_t lifetime, int dispersal); int map_addflooritem(struct item *, int, int, int, int, - struct map_session_data *, struct map_session_data *, - struct map_session_data *); + dumb_ptr<map_session_data>, dumb_ptr<map_session_data>, + dumb_ptr<map_session_data>); // キャラid=>キャラ名 変換関連 extern -DMap<int, struct block_list *> id_db; +DMap<int, dumb_ptr<block_list>> id_db; void map_addchariddb(int charid, const char *name); char *map_charid2nick(int); -struct map_session_data *map_id2sd(int); -struct block_list *map_id2bl(int); +dumb_ptr<map_session_data> map_id2sd(int); +dumb_ptr<block_list> map_id2bl(int); + +inline +dumb_ptr<map_session_data> map_id_as_player(int id) +{ + dumb_ptr<block_list> bl = map_id2bl(id); + return bl ? bl->as_player() : nullptr; +} +inline +dumb_ptr<npc_data> map_id_as_npc(int id) +{ + dumb_ptr<block_list> bl = map_id2bl(id); + return bl ? bl->as_npc() : nullptr; +} +inline +dumb_ptr<mob_data> map_id_as_mob(int id) +{ + dumb_ptr<block_list> bl = map_id2bl(id); + return bl ? bl->as_mob() : nullptr; +} +inline +dumb_ptr<flooritem_data> map_id_as_item(int id) +{ + dumb_ptr<block_list> bl = map_id2bl(id); + return bl ? bl->as_item() : nullptr; +} +inline +dumb_ptr<invocation> map_id_as_spell(int id) +{ + dumb_ptr<block_list> bl = map_id2bl(id); + return bl ? bl->as_spell() : nullptr; +} + +inline +dumb_ptr<map_session_data> map_id_is_player(int id) +{ + dumb_ptr<block_list> bl = map_id2bl(id); + return bl ? bl->is_player() : nullptr; +} +inline +dumb_ptr<npc_data> map_id_is_npc(int id) +{ + dumb_ptr<block_list> bl = map_id2bl(id); + return bl ? bl->is_npc() : nullptr; +} +inline +dumb_ptr<mob_data> map_id_is_mob(int id) +{ + dumb_ptr<block_list> bl = map_id2bl(id); + return bl ? bl->is_mob() : nullptr; +} +inline +dumb_ptr<flooritem_data> map_id_is_item(int id) +{ + dumb_ptr<block_list> bl = map_id2bl(id); + return bl ? bl->is_item() : nullptr; +} +inline +dumb_ptr<invocation> map_id_is_spell(int id) +{ + dumb_ptr<block_list> bl = map_id2bl(id); + return bl ? bl->is_spell() : nullptr; +} + + int map_mapname2mapid(const char *); int map_mapname2ipport(const char *, struct in_addr *, int *); int map_setipport(const char *name, struct in_addr ip, int port); -void map_addiddb(struct block_list *); -void map_deliddb(struct block_list *bl); -void map_addnickdb(struct map_session_data *); -int map_scriptcont(struct map_session_data *sd, int id); /* Continues a script either on a spell or on an NPC */ -struct map_session_data *map_nick2sd(const char *); +void map_addiddb(dumb_ptr<block_list>); +void map_deliddb(dumb_ptr<block_list> bl); +void map_addnickdb(dumb_ptr<map_session_data>); +int map_scriptcont(dumb_ptr<map_session_data> sd, int id); /* Continues a script either on a spell or on an NPC */ +dumb_ptr<map_session_data> map_nick2sd(const char *); int compare_item(struct item *a, struct item *b); -struct map_session_data *map_get_first_session(void); -struct map_session_data *map_get_last_session(void); -struct map_session_data *map_get_next_session( - struct map_session_data *current); -struct map_session_data *map_get_prev_session( - struct map_session_data *current); +dumb_ptr<map_session_data> map_get_first_session(void); +dumb_ptr<map_session_data> map_get_last_session(void); +dumb_ptr<map_session_data> map_get_next_session( + dumb_ptr<map_session_data> current); +dumb_ptr<map_session_data> map_get_prev_session( + dumb_ptr<map_session_data> current); // gat関連 MapCell map_getcell(int, int, int); @@ -581,11 +695,35 @@ void map_setcell(int, int, int, MapCell); // その他 bool map_check_dir(DIR s_dir, DIR t_dir); -DIR map_calc_dir(struct block_list *src, int x, int y); +DIR map_calc_dir(dumb_ptr<block_list> src, int x, int y); // path.cより int path_search(struct walkpath_data *, int, int, int, int, int, int); std::pair<uint16_t, uint16_t> map_randfreecell(int m, uint16_t x, uint16_t y, uint16_t w, uint16_t h); +inline dumb_ptr<map_session_data> block_list::as_player() { return dumb_ptr<map_session_data>(static_cast<map_session_data *>(this)) ; } +inline dumb_ptr<npc_data> block_list::as_npc() { return dumb_ptr<npc_data>(static_cast<npc_data *>(this)) ; } +inline dumb_ptr<mob_data> block_list::as_mob() { return dumb_ptr<mob_data>(static_cast<mob_data *>(this)) ; } +inline dumb_ptr<flooritem_data> block_list::as_item() { return dumb_ptr<flooritem_data>(static_cast<flooritem_data *>(this)) ; } +//inline dumb_ptr<invocation> block_list::as_spell() { return dumb_ptr<invocation>(static_cast<invocation *>(this)) ; } + +inline dumb_ptr<map_session_data> block_list::is_player() { return bl_type == BL::PC ? as_player() : nullptr; } +inline dumb_ptr<npc_data> block_list::is_npc() { return bl_type == BL::NPC ? as_npc() : nullptr; } +inline dumb_ptr<mob_data> block_list::is_mob() { return bl_type == BL::MOB ? as_mob() : nullptr; } +inline dumb_ptr<flooritem_data> block_list::is_item() { return bl_type == BL::ITEM ? as_item() : nullptr; } +//inline dumb_ptr<invocation> block_list::is_spell() { return bl_type == BL::SPELL ? as_spell() : nullptr; } + +// struct invocation is defined in another header + +inline dumb_ptr<npc_data_script> npc_data::as_script() { return dumb_ptr<npc_data_script>(static_cast<npc_data_script *>(this)) ; } +inline dumb_ptr<npc_data_shop> npc_data::as_shop() { return dumb_ptr<npc_data_shop>(static_cast<npc_data_shop *>(this)) ; } +inline dumb_ptr<npc_data_warp> npc_data::as_warp() { return dumb_ptr<npc_data_warp>(static_cast<npc_data_warp *>(this)) ; } +inline dumb_ptr<npc_data_message> npc_data::as_message() { return dumb_ptr<npc_data_message>(static_cast<npc_data_message *>(this)) ; } + +inline dumb_ptr<npc_data_script> npc_data::is_script() { return npc_subtype == NpcSubtype::SCRIPT ? as_script() : nullptr ; } +inline dumb_ptr<npc_data_shop> npc_data::is_shop() { return npc_subtype == NpcSubtype::SHOP ? as_shop() : nullptr ; } +inline dumb_ptr<npc_data_warp> npc_data::is_warp() { return npc_subtype == NpcSubtype::WARP ? as_warp() : nullptr ; } +inline dumb_ptr<npc_data_message> npc_data::is_message() { return npc_subtype == NpcSubtype::MESSAGE ? as_message() : nullptr ; } + #endif // MAP_HPP |