diff options
Diffstat (limited to 'src/map/npc.cpp')
-rw-r--r-- | src/map/npc.cpp | 388 |
1 files changed, 189 insertions, 199 deletions
diff --git a/src/map/npc.cpp b/src/map/npc.cpp index f0ea12e..43766e9 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -43,13 +43,13 @@ int npc_get_new_npc_id(void) struct event_data { - struct npc_data *nd; + dumb_ptr<npc_data_script> nd; int pos; }; static Map<std::string, struct event_data> ev_db; static -DMap<std::string, struct npc_data *> npcname_db; +DMap<std::string, dumb_ptr<npc_data>> npcname_db; static struct tm ev_tm_b; // 時計イベント用 @@ -61,22 +61,26 @@ struct tm ev_tm_b; // 時計イベント用 *------------------------------------------ */ static -void npc_enable_sub(struct block_list *bl, struct npc_data *nd) +void npc_enable_sub(dumb_ptr<block_list> bl, dumb_ptr<npc_data> nd) { - struct map_session_data *sd; + dumb_ptr<map_session_data> sd; char *name = (char *) calloc(50, sizeof(char)); nullpo_retv(bl); - if (bl->bl_type == BL::PC && (sd = (struct map_session_data *) bl)) + if (bl->bl_type == BL::PC) { + sd = bl->as_player(); if (nd->flag & 1) // 無効化されている return; memcpy(name, nd->name, sizeof(nd->name)); if (sd->areanpc_id == nd->bl_id) - return; // TODO fix leak of 'name' + { + free(name); + return; + } sd->areanpc_id = nd->bl_id; npc_event(sd, strcat(name, "::OnTouch"), 0); } @@ -85,7 +89,7 @@ void npc_enable_sub(struct block_list *bl, struct npc_data *nd) int npc_enable(const char *name, bool flag) { - struct npc_data *nd = npcname_db.get(name); + dumb_ptr<npc_data> nd = npcname_db.get(name); if (nd == NULL) return 0; @@ -99,10 +103,18 @@ int npc_enable(const char *name, bool flag) nd->flag |= 1; clif_clearchar(nd, BeingRemoveWhy::GONE); } - if (flag && (nd->u.scr.xs > 0 || nd->u.scr.ys > 0)) + + int xs = 0, ys = 0; + if (dumb_ptr<npc_data_script> nd_ = nd->is_script()) + { + xs = nd_->scr.xs; + ys = nd_->scr.ys; + } + + if (flag && (xs > 0 || ys > 0)) map_foreachinarea(std::bind(npc_enable_sub, ph::_1, nd), - nd->bl_m, nd->bl_x - nd->u.scr.xs, nd->bl_y - nd->u.scr.ys, - nd->bl_x + nd->u.scr.xs, nd->bl_y + nd->u.scr.ys, BL::PC); + nd->bl_m, nd->bl_x - xs, nd->bl_y - ys, + nd->bl_x + xs, nd->bl_y + ys, BL::PC); return 0; } @@ -111,7 +123,7 @@ int npc_enable(const char *name, bool flag) * NPCを名前で探す *------------------------------------------ */ -struct npc_data *npc_name2id(const char *name) +dumb_ptr<npc_data> npc_name2id(const char *name) { return npcname_db.get(name); } @@ -120,7 +132,7 @@ struct npc_data *npc_name2id(const char *name) * イベントキューのイベント処理 *------------------------------------------ */ -int npc_event_dequeue(struct map_session_data *sd) +int npc_event_dequeue(dumb_ptr<map_session_data> sd) { nullpo_ret(sd); @@ -144,7 +156,7 @@ int npc_event_dequeue(struct map_session_data *sd) return 0; } -int npc_delete(struct npc_data *nd) +int npc_delete(dumb_ptr<npc_data> nd) { nullpo_retr(1, nd); @@ -159,7 +171,7 @@ int npc_delete(struct npc_data *nd) int npc_timer_event(const char *eventname) // Added by RoVeRT { struct event_data *ev = ev_db.search(eventname); - struct npc_data *nd; + dumb_ptr<npc_data_script> nd; // int xs,ys; if ((ev == NULL || (nd = ev->nd) == NULL)) @@ -168,7 +180,7 @@ int npc_timer_event(const char *eventname) // Added by RoVeRT return 0; } - run_script(nd->u.scr.script, ev->pos, nd->bl_id, nd->bl_id); + run_script(nd->scr.script, ev->pos, nd->bl_id, nd->bl_id); return 0; } @@ -187,7 +199,7 @@ void npc_event_doall_sub(const std::string& key, struct event_data *ev, if ((p = strchr(p, ':')) && p && strcasecmp(name, p) == 0) { - run_script_l(ev->nd->u.scr.script, ev->pos, rid, ev->nd->bl_id, argc, + run_script_l(ev->nd->scr.script, ev->pos, rid, ev->nd->bl_id, argc, argv); (*c)++; } @@ -215,7 +227,7 @@ void npc_event_do_sub(const std::string& key, struct event_data *ev, if (p && strcasecmp(name, p) == 0) { - run_script_l(ev->nd->u.scr.script, ev->pos, rid, ev->nd->bl_id, argc, + run_script_l(ev->nd->scr.script, ev->pos, rid, ev->nd->bl_id, argc, argv); (*c)++; } @@ -291,55 +303,56 @@ int npc_event_do_oninit(void) static void npc_timerevent(TimerData *, tick_t tick, int id, interval_t data) { - struct npc_data *nd = (struct npc_data *) map_id2bl(id); + dumb_ptr<npc_data_script> nd = map_id2bl(id)->as_npc()->as_script(); struct npc_timerevent_list *te; assert (nd != NULL); - assert (nd->u.scr.nexttimer >= 0); + assert (nd->npc_subtype == NpcSubtype::SCRIPT); + assert (nd->scr.nexttimer >= 0); - nd->u.scr.timertick = tick; - te = nd->u.scr.timer_event + nd->u.scr.nexttimer; - // nd->u.scr.timerid = nullptr; + nd->scr.timertick = tick; + te = nd->scr.timer_event + nd->scr.nexttimer; + // nd->scr.timerid = nullptr; - interval_t t = nd->u.scr.timer += data; - nd->u.scr.nexttimer++; - if (nd->u.scr.timeramount > nd->u.scr.nexttimer) + interval_t t = nd->scr.timer += data; + nd->scr.nexttimer++; + if (nd->scr.timeramount > nd->scr.nexttimer) { - interval_t next = nd->u.scr.timer_event[nd->u.scr.nexttimer].timer - t; - nd->u.scr.timerid = Timer(tick + next, + interval_t next = nd->scr.timer_event[nd->scr.nexttimer].timer - t; + nd->scr.timerid = Timer(tick + next, std::bind(npc_timerevent, ph::_1, ph::_2, id, next)); } - run_script(nd->u.scr.script, te->pos, 0, nd->bl_id); + run_script(nd->scr.script, te->pos, 0, nd->bl_id); } /*========================================== * タイマーイベント開始 *------------------------------------------ */ -int npc_timerevent_start(struct npc_data *nd) +int npc_timerevent_start(dumb_ptr<npc_data_script> nd) { int j, n; nullpo_ret(nd); - n = nd->u.scr.timeramount; - if (nd->u.scr.nexttimer >= 0 || n == 0) + n = nd->scr.timeramount; + if (nd->scr.nexttimer >= 0 || n == 0) return 0; for (j = 0; j < n; j++) { - if (nd->u.scr.timer_event[j].timer > nd->u.scr.timer) + if (nd->scr.timer_event[j].timer > nd->scr.timer) break; } - nd->u.scr.nexttimer = j; - nd->u.scr.timertick = gettick(); + nd->scr.nexttimer = j; + nd->scr.timertick = gettick(); if (j >= n) return 0; - interval_t next = nd->u.scr.timer_event[j].timer - nd->u.scr.timer; - nd->u.scr.timerid = Timer(gettick() + next, + interval_t next = nd->scr.timer_event[j].timer - nd->scr.timer; + nd->scr.timerid = Timer(gettick() + next, std::bind(npc_timerevent, ph::_1, ph::_2, nd->bl_id, next)); return 0; @@ -349,15 +362,15 @@ int npc_timerevent_start(struct npc_data *nd) * タイマーイベント終了 *------------------------------------------ */ -int npc_timerevent_stop(struct npc_data *nd) +int npc_timerevent_stop(dumb_ptr<npc_data_script> nd) { nullpo_ret(nd); - if (nd->u.scr.nexttimer >= 0) + if (nd->scr.nexttimer >= 0) { - nd->u.scr.nexttimer = -1; - nd->u.scr.timer += gettick() - nd->u.scr.timertick; - nd->u.scr.timerid.cancel(); + nd->scr.nexttimer = -1; + nd->scr.timer += gettick() - nd->scr.timertick; + nd->scr.timerid.cancel(); } return 0; } @@ -366,14 +379,14 @@ int npc_timerevent_stop(struct npc_data *nd) * タイマー値の所得 *------------------------------------------ */ -interval_t npc_gettimerevent_tick(struct npc_data *nd) +interval_t npc_gettimerevent_tick(dumb_ptr<npc_data_script> nd) { nullpo_retr(interval_t::zero(), nd); - interval_t tick = nd->u.scr.timer; + interval_t tick = nd->scr.timer; - if (nd->u.scr.nexttimer >= 0) - tick += gettick() - nd->u.scr.timertick; + if (nd->scr.nexttimer >= 0) + tick += gettick() - nd->scr.timertick; return tick; } @@ -381,16 +394,16 @@ interval_t npc_gettimerevent_tick(struct npc_data *nd) * タイマー値の設定 *------------------------------------------ */ -int npc_settimerevent_tick(struct npc_data *nd, interval_t newtimer) +int npc_settimerevent_tick(dumb_ptr<npc_data_script> nd, interval_t newtimer) { int flag; nullpo_ret(nd); - flag = nd->u.scr.nexttimer; + flag = nd->scr.nexttimer; npc_timerevent_stop(nd); - nd->u.scr.timer = newtimer; + nd->scr.timer = newtimer; if (flag >= 0) npc_timerevent_start(nd); return 0; @@ -400,11 +413,11 @@ int npc_settimerevent_tick(struct npc_data *nd, interval_t newtimer) * イベント型のNPC処理 *------------------------------------------ */ -int npc_event(struct map_session_data *sd, const char *eventname, +int npc_event(dumb_ptr<map_session_data> sd, const char *eventname, int mob_kill) { struct event_data *ev = ev_db.search(eventname); - struct npc_data *nd; + dumb_ptr<npc_data_script> nd; int xs, ys; char mobevent[100]; @@ -439,8 +452,8 @@ int npc_event(struct map_session_data *sd, const char *eventname, } } - xs = nd->u.scr.xs; - ys = nd->u.scr.ys; + xs = nd->scr.xs; + ys = nd->scr.ys; if (xs >= 0 && ys >= 0) { if (nd->bl_m != sd->bl_m) @@ -483,7 +496,7 @@ int npc_event(struct map_session_data *sd, const char *eventname, sd->npc_id = nd->bl_id; sd->npc_pos = - run_script(nd->u.scr.script, ev->pos, sd->bl_id, nd->bl_id); + run_script(nd->scr.script, ev->pos, sd->bl_id, nd->bl_id); return 0; } @@ -499,11 +512,11 @@ void npc_command_sub(const std::string& key, struct event_data *ev, const char * sscanf(&p[11], "%s", temp); if (strcmp(command, temp) == 0) - run_script(ev->nd->u.scr.script, ev->pos, 0, ev->nd->bl_id); + run_script(ev->nd->scr.script, ev->pos, 0, ev->nd->bl_id); } } -int npc_command(struct map_session_data *, const char *npcname, const char *command) +int npc_command(dumb_ptr<map_session_data>, const char *npcname, const char *command) { for (auto& pair : ev_db) npc_command_sub(pair.first, &pair.second, npcname, command); @@ -515,7 +528,7 @@ int npc_command(struct map_session_data *, const char *npcname, const char *comm * 接触型のNPC処理 *------------------------------------------ */ -int npc_touch_areanpc(struct map_session_data *sd, int m, int x, int y) +int npc_touch_areanpc(dumb_ptr<map_session_data> sd, int m, int x, int y) { int i, f = 1; int xs, ys; @@ -536,13 +549,17 @@ int npc_touch_areanpc(struct map_session_data *sd, int m, int x, int y) switch (map[m].npc[i]->npc_subtype) { case NpcSubtype::WARP: - xs = map[m].npc[i]->u.warp.xs; - ys = map[m].npc[i]->u.warp.ys; + xs = map[m].npc[i]->as_warp()->warp.xs; + ys = map[m].npc[i]->as_warp()->warp.ys; break; case NpcSubtype::MESSAGE: + assert (0 && "I'm pretty sure these are never put on a map"); + xs = 0; + ys = 0; + break; case NpcSubtype::SCRIPT: - xs = map[m].npc[i]->u.scr.xs; - ys = map[m].npc[i]->u.scr.ys; + xs = map[m].npc[i]->as_script()->scr.xs; + ys = map[m].npc[i]->as_script()->scr.ys; break; default: continue; @@ -566,10 +583,12 @@ int npc_touch_areanpc(struct map_session_data *sd, int m, int x, int y) { case NpcSubtype::WARP: skill_stop_dancing(sd, 0); - pc_setpos(sd, map[m].npc[i]->u.warp.name, - map[m].npc[i]->u.warp.x, map[m].npc[i]->u.warp.y, BeingRemoveWhy::GONE); + pc_setpos(sd, map[m].npc[i]->as_warp()->warp.name, + map[m].npc[i]->as_warp()->warp.x, map[m].npc[i]->as_warp()->warp.y, BeingRemoveWhy::GONE); break; case NpcSubtype::MESSAGE: + assert (0 && "I'm pretty sure these NPCs are never put on a map."); + break; case NpcSubtype::SCRIPT: { char *name = (char *)malloc(50); @@ -592,19 +611,15 @@ int npc_touch_areanpc(struct map_session_data *sd, int m, int x, int y) *------------------------------------------ */ static -int npc_checknear(struct map_session_data *sd, int id) +int npc_checknear(dumb_ptr<map_session_data> sd, int id) { - struct npc_data *nd; + dumb_ptr<npc_data> nd; nullpo_ret(sd); - nd = (struct npc_data *) map_id2bl(id); - if (nd == NULL || nd->bl_type != BL::NPC) - { - if (battle_config.error_log) - PRINTF("no such npc : %d\n", id); - return 1; - } + nd = map_id_as_npc(id); + assert (nd != NULL); + assert (nd->bl_type == BL::NPC); if (nd->npc_class < 0) // イベント系は常にOK return 0; @@ -624,9 +639,9 @@ int npc_checknear(struct map_session_data *sd, int id) * クリック時のNPC処理 *------------------------------------------ */ -int npc_click(struct map_session_data *sd, int id) +int npc_click(dumb_ptr<map_session_data> sd, int id) { - struct npc_data *nd; + dumb_ptr<npc_data> nd; nullpo_retr(1, sd); @@ -642,7 +657,7 @@ int npc_click(struct map_session_data *sd, int id) return 1; } - nd = (struct npc_data *) map_id2bl(id); + nd = map_id_as_npc(id); if (nd->flag & 1) // 無効化されている return 1; @@ -655,12 +670,12 @@ int npc_click(struct map_session_data *sd, int id) npc_event_dequeue(sd); break; case NpcSubtype::SCRIPT: - sd->npc_pos = run_script(nd->u.scr.script, 0, sd->bl_id, id); + sd->npc_pos = run_script(nd->as_script()->scr.script, 0, sd->bl_id, id); break; case NpcSubtype::MESSAGE: - if (nd->u.message) + if (nd->as_message()->message) { - clif_scriptmes(sd, id, nd->u.message); + clif_scriptmes(sd, id, nd->as_message()->message); clif_scriptclose(sd, id); } break; @@ -673,20 +688,21 @@ int npc_click(struct map_session_data *sd, int id) * *------------------------------------------ */ -int npc_scriptcont(struct map_session_data *sd, int id) +int npc_scriptcont(dumb_ptr<map_session_data> sd, int id) { - struct npc_data *nd; + dumb_ptr<npc_data> nd; nullpo_retr(1, sd); if (id != sd->npc_id) return 1; - if (npc_checknear(sd, id)) { + if (npc_checknear(sd, id)) + { clif_scriptclose(sd, id); return 1; } - nd = (struct npc_data *) map_id2bl(id); + nd = map_id_as_npc(id); if (!nd /* NPC was disposed? */ || nd->npc_subtype == NpcSubtype::MESSAGE) { @@ -695,7 +711,7 @@ int npc_scriptcont(struct map_session_data *sd, int id) return 0; } - sd->npc_pos = run_script(nd->u.scr.script, sd->npc_pos, sd->bl_id, id); + sd->npc_pos = run_script(nd->as_script()->scr.script, sd->npc_pos, sd->bl_id, id); return 0; } @@ -704,16 +720,16 @@ int npc_scriptcont(struct map_session_data *sd, int id) * *------------------------------------------ */ -int npc_buysellsel(struct map_session_data *sd, int id, int type) +int npc_buysellsel(dumb_ptr<map_session_data> sd, int id, int type) { - struct npc_data *nd; + dumb_ptr<npc_data> nd; nullpo_retr(1, sd); if (npc_checknear(sd, id)) return 1; - nd = (struct npc_data *) map_id2bl(id); + nd = map_id_as_npc(id); if (nd->npc_subtype != NpcSubtype::SHOP) { if (battle_config.error_log) @@ -727,7 +743,7 @@ int npc_buysellsel(struct map_session_data *sd, int id, int type) sd->npc_shopid = id; if (type == 0) { - clif_buylist(sd, nd); + clif_buylist(sd, nd->as_shop()); } else { @@ -741,10 +757,10 @@ int npc_buysellsel(struct map_session_data *sd, int id, int type) *------------------------------------------ */ // TODO enumify return type -int npc_buylist(struct map_session_data *sd, int n, +int npc_buylist(dumb_ptr<map_session_data> sd, int n, const uint16_t *item_list) { - struct npc_data *nd; + dumb_ptr<npc_data> nd; double z; int i, j, w, itemamount = 0, new_stacks = 0; @@ -754,21 +770,21 @@ int npc_buylist(struct map_session_data *sd, int n, if (npc_checknear(sd, sd->npc_shopid)) return 3; - nd = (struct npc_data *) map_id2bl(sd->npc_shopid); + nd = map_id_as_npc(sd->npc_shopid); if (nd->npc_subtype != NpcSubtype::SHOP) return 3; for (i = 0, w = 0, z = 0; i < n; i++) { - for (j = 0; nd->u.shop_item[j].nameid; j++) + for (j = 0; j < nd->as_shop()->shop_items.size(); j++) { - if (nd->u.shop_item[j].nameid == item_list[i * 2 + 1]) + if (nd->as_shop()->shop_items[j].nameid == item_list[i * 2 + 1]) break; } - if (nd->u.shop_item[j].nameid == 0) + if (j == nd->as_shop()->shop_items.size()) return 3; - z += (double) nd->u.shop_item[j].value * item_list[i * 2]; + z += (double) nd->as_shop()->shop_items[j].value * item_list[i * 2]; itemamount += item_list[i * 2]; switch (pc_checkadditem(sd, item_list[i * 2 + 1], item_list[i * 2])) @@ -836,7 +852,7 @@ int npc_buylist(struct map_session_data *sd, int n, * *------------------------------------------ */ -int npc_selllist(struct map_session_data *sd, int n, +int npc_selllist(dumb_ptr<map_session_data> sd, int n, const uint16_t *item_list) { double z; @@ -961,7 +977,7 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4) int x, y, xs, ys, to_x, to_y, m; int i, j; char mapname[24], to_mapname[24]; - struct npc_data *nd; + dumb_ptr<npc_data_warp> nd; // 引数の個数チェック if (sscanf(w1, "%[^,],%d,%d", mapname, &x, &y) != 3 || @@ -974,7 +990,7 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4) m = map_mapname2mapid(mapname); - nd = (struct npc_data *) calloc(1, sizeof(struct npc_data)); + nd.new_(); nd->bl_id = npc_get_new_npc_id(); nd->n = map_addnpc(m, nd); @@ -987,7 +1003,6 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4) memcpy(nd->name, w3, 24); memcpy(nd->exname, w3, 24); - nd->chat_id = 0; if (!battle_config.warp_point_debug) nd->npc_class = WARP_CLASS; else @@ -997,13 +1012,13 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4) nd->opt1 = Opt1::ZERO; nd->opt2 = Opt2::ZERO; nd->opt3 = Opt3::ZERO; - memcpy(nd->u.warp.name, to_mapname, 16); + memcpy(nd->warp.name, to_mapname, 16); xs += 2; ys += 2; - nd->u.warp.x = to_x; - nd->u.warp.y = to_y; - nd->u.warp.xs = xs; - nd->u.warp.ys = ys; + nd->warp.x = to_x; + nd->warp.y = to_y; + nd->warp.xs = xs; + nd->warp.ys = ys; for (i = 0; i < ys; i++) { @@ -1042,9 +1057,8 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) int x, y; DIR dir; int m; - int max = 100, pos = 0; char mapname[24]; - struct npc_data *nd; + dumb_ptr<npc_data_shop> nd; // 引数の個数チェック int dir_; // TODO use SSCANF or extract @@ -1058,12 +1072,10 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) dir = static_cast<DIR>(dir_); m = map_mapname2mapid(mapname); - nd = (struct npc_data *) calloc(1, sizeof(struct npc_data) + - sizeof(nd->u.shop_item[0]) * (max + - 1)); + nd.new_(); p = strchr(w4, ','); - while (p && pos < max) + while (p) { int nameid, value; char name[24]; @@ -1085,7 +1097,8 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) if (nameid > 0) { - nd->u.shop_item[pos].nameid = nameid; + npc_item_list sh_it; + sh_it.nameid = nameid; if (value < 0) { if (id == NULL) @@ -1093,17 +1106,16 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) value = id->value_buy * abs(value); } - nd->u.shop_item[pos].value = value; - pos++; + sh_it.value = value; + nd->shop_items.push_back(sh_it); } p = strchr(p, ','); } - if (pos == 0) + if (nd->shop_items.empty()) { - free(nd); + nd.delete_(); return 1; } - nd->u.shop_item[pos++].nameid = 0; nd->bl_prev = nd->bl_next = NULL; nd->bl_m = m; @@ -1115,15 +1127,11 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) memcpy(nd->name, w3, 24); nd->npc_class = atoi(w4); nd->speed = std::chrono::milliseconds(200); - nd->chat_id = 0; nd->option = Option::ZERO; nd->opt1 = Opt1::ZERO; nd->opt2 = Opt2::ZERO; nd->opt3 = Opt3::ZERO; - nd = (struct npc_data *) - realloc(nd, sizeof(struct npc_data) + sizeof(nd->u.shop_item[0]) * pos); - //PRINTF("shop npc %s %d read done\n",mapname,nd->bl_id); npc_shop++; nd->bl_type = BL::NPC; @@ -1141,15 +1149,15 @@ int npc_parse_shop(char *w1, char *, char *w3, char *w4) *------------------------------------------ */ static -void npc_convertlabel_db(const std::string& lname, int pos, struct npc_data *nd) +void npc_convertlabel_db(const std::string& lname, int pos, dumb_ptr<npc_data_script> nd) { struct npc_label_list *lst; int num; nullpo_retv(nd); - lst = nd->u.scr.label_list; - num = nd->u.scr.label_list_num; + lst = nd->scr.label_list; + num = nd->scr.label_list_num; if (!lst) { lst = (struct npc_label_list *) @@ -1162,8 +1170,8 @@ void npc_convertlabel_db(const std::string& lname, int pos, struct npc_data *nd) strzcpy(lst[num].name, lname.c_str(), sizeof(lst[num].name)); lst[num].pos = pos; - nd->u.scr.label_list = lst; - nd->u.scr.label_list_num = num + 1; + nd->scr.label_list = lst; + nd->scr.label_list_num = num + 1; } /*========================================== @@ -1183,7 +1191,7 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, int srcsize = 65536; int startline = 0; char line[1024]; - struct npc_data *nd; + dumb_ptr<npc_data_script> nd; int evflag = 0; char *p; struct npc_label_list *label_dup = NULL; @@ -1261,33 +1269,15 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, } else { - // duplicateする - - char srcname[128]; - struct npc_data *nd2; - if (sscanf(w2, "duplicate (%[^)])", srcname) != 1) - { - PRINTF("bad duplicate name! : %s", w2); - return 0; - } - if ((nd2 = npc_name2id(srcname)) == NULL) - { - PRINTF("bad duplicate name! (not exist) : %s\n", srcname); - return 0; - } - script = nd2->u.scr.script; - label_dup = nd2->u.scr.label_list; - label_dupnum = nd2->u.scr.label_list_num; - src_id = nd2->bl_id; - + PRINTF("duplicate() is no longer supported!\n"); + return 0; } // end of スクリプト解析 - nd = (struct npc_data *) calloc(1, sizeof(struct npc_data)); + nd.new_(); if (m == -1) { // スクリプトコピー用のダミーNPC - } else if (sscanf(w4, "%d,%d,%d", &npc_class, &xs, &ys) == 3) { @@ -1318,14 +1308,14 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, } } - nd->u.scr.xs = xs; - nd->u.scr.ys = ys; + nd->scr.xs = xs; + nd->scr.ys = ys; } else { // クリック型NPC npc_class = atoi(w4); - nd->u.scr.xs = 0; - nd->u.scr.ys = 0; + nd->scr.xs = 0; + nd->scr.ys = 0; } if (npc_class < 0 && m >= 0) @@ -1359,9 +1349,8 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, nd->flag = 0; nd->npc_class = npc_class; nd->speed = std::chrono::milliseconds(200); - nd->u.scr.script = script; - nd->u.scr.src_id = src_id; - nd->chat_id = 0; + nd->scr.script = script; + nd->scr.src_id = src_id; nd->option = Option::ZERO; nd->opt1 = Opt1::ZERO; nd->opt2 = Opt2::ZERO; @@ -1406,19 +1395,19 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, { // duplicate -// nd->u.scr.label_list=malloc(sizeof(struct npc_label_list)*label_dupnum); -// memcpy(nd->u.scr.label_list,label_dup,sizeof(struct npc_label_list)*label_dupnum); +// nd->scr.label_list=malloc(sizeof(struct npc_label_list)*label_dupnum); +// memcpy(nd->scr.label_list,label_dup,sizeof(struct npc_label_list)*label_dupnum); - nd->u.scr.label_list = label_dup; // ラベルデータ共有 - nd->u.scr.label_list_num = label_dupnum; + nd->scr.label_list = label_dup; // ラベルデータ共有 + nd->scr.label_list_num = label_dupnum; } //----------------------------------------- // イベント用ラベルデータのエクスポート - for (int i = 0; i < nd->u.scr.label_list_num; i++) + for (int i = 0; i < nd->scr.label_list_num; i++) { - char *lname = nd->u.scr.label_list[i].name; - int pos = nd->u.scr.label_list[i].pos; + char *lname = nd->scr.label_list[i].name; + int pos = nd->scr.label_list[i].pos; if ((lname[0] == 'O' || lname[0] == 'o') && (lname[1] == 'N' || lname[1] == 'n')) @@ -1438,17 +1427,17 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, //----------------------------------------- // ラベルデータからタイマーイベント取り込み - for (int i = 0; i < nd->u.scr.label_list_num; i++) + for (int i = 0; i < nd->scr.label_list_num; i++) { int t_ = 0, n = 0; - char *lname = nd->u.scr.label_list[i].name; - int pos = nd->u.scr.label_list[i].pos; + char *lname = nd->scr.label_list[i].name; + int pos = nd->scr.label_list[i].pos; if (sscanf(lname, "OnTimer%d%n", &t_, &n) == 1 && lname[n] == '\0') { interval_t t = static_cast<interval_t>(t_); // タイマーイベント - struct npc_timerevent_list *te = nd->u.scr.timer_event; - int j, k = nd->u.scr.timeramount; + struct npc_timerevent_list *te = nd->scr.timer_event; + int j, k = nd->scr.timeramount; if (te == NULL) te = (struct npc_timerevent_list *) calloc(1, sizeof(struct @@ -1469,12 +1458,12 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4, } te[j].timer = t; te[j].pos = pos; - nd->u.scr.timer_event = te; - nd->u.scr.timeramount = k + 1; + nd->scr.timer_event = te; + nd->scr.timeramount = k + 1; } } - nd->u.scr.nexttimer = -1; - // nd->u.scr.timerid = nullptr; + nd->scr.nexttimer = -1; + // nd->scr.timerid = nullptr; return 0; } @@ -1558,7 +1547,7 @@ int npc_parse_mob(const char *w1, const char *, const char *w3, const char *w4) int i; char mapname[24]; char eventname[24] = ""; - struct mob_data *md; + dumb_ptr<mob_data> md; xs = ys = 0; int delay1_ = 0, delay2_ = 0; @@ -1583,7 +1572,7 @@ int npc_parse_mob(const char *w1, const char *, const char *w3, const char *w4) for (i = 0; i < num; i++) { - md = (struct mob_data *) calloc(1, sizeof(struct mob_data)); + md.new_(); md->bl_prev = NULL; md->bl_next = NULL; @@ -1767,11 +1756,11 @@ int npc_parse_mapflag(char *w1, char *, char *w3, char *w4) return 0; } -struct npc_data *npc_spawn_text(int m, int x, int y, +dumb_ptr<npc_data> npc_spawn_text(int m, int x, int y, int npc_class, const char *name, const char *message) { - struct npc_data *retval = - (struct npc_data *) calloc(1, sizeof(struct npc_data)); + dumb_ptr<npc_data_message> retval; + retval.new_(); retval->bl_id = npc_get_new_npc_id(); retval->bl_x = x; retval->bl_y = y; @@ -1783,7 +1772,7 @@ struct npc_data *npc_spawn_text(int m, int x, int y, strncpy(retval->exname, name, 23); retval->name[15] = 0; retval->exname[15] = 0; - retval->u.message = message ? strdup(message) : NULL; + retval->message = message ? strdup(message) : NULL; retval->npc_class = npc_class; retval->speed = std::chrono::milliseconds(200); @@ -1798,49 +1787,50 @@ struct npc_data *npc_spawn_text(int m, int x, int y, } static -void npc_free_internal(struct npc_data *nd) +void npc_free_internal(dumb_ptr<npc_data> nd_) { - struct chat_data *cd; - - if (nd->chat_id && (cd = (struct chat_data *) map_id2bl(nd->chat_id))) + if (nd_->npc_subtype == NpcSubtype::SCRIPT) { - free(cd); - cd = NULL; - } - if (nd->npc_subtype == NpcSubtype::SCRIPT) - { - if (nd->u.scr.timer_event) - free(nd->u.scr.timer_event); - if (nd->u.scr.src_id == 0) + dumb_ptr<npc_data_script> nd = nd_->as_script(); + if (nd->scr.timer_event) + free(nd->scr.timer_event); + if (nd->scr.src_id == 0) { - if (nd->u.scr.script) + if (nd->scr.script) { - free(const_cast<ScriptCode *>(nd->u.scr.script)); - nd->u.scr.script = NULL; + free(const_cast<ScriptCode *>(nd->scr.script)); + nd->scr.script = NULL; } - if (nd->u.scr.label_list) + if (nd->scr.label_list) { - free(nd->u.scr.label_list); - nd->u.scr.label_list = NULL; + free(nd->scr.label_list); + nd->scr.label_list = NULL; } } } - else if (nd->npc_subtype == NpcSubtype::MESSAGE && nd->u.message) + else if (nd_->npc_subtype == NpcSubtype::MESSAGE) { - free(nd->u.message); + dumb_ptr<npc_data_message> nd = nd_->as_message(); + free(nd->message); } - free(nd); + nd_.delete_(); } static -void npc_propagate_update(struct npc_data *nd) +void npc_propagate_update(dumb_ptr<npc_data> nd) { + int xs = 0, ys = 0; + if (dumb_ptr<npc_data_script> nd_ = nd->is_script()) + { + xs = nd_->scr.xs; + ys = nd_->scr.ys; + } map_foreachinarea(std::bind(npc_enable_sub, ph::_1, nd), - nd->bl_m, nd->bl_x - nd->u.scr.xs, nd->bl_y - nd->u.scr.ys, - nd->bl_x + nd->u.scr.xs, nd->bl_y + nd->u.scr.ys, BL::PC); + nd->bl_m, nd->bl_x - xs, nd->bl_y - ys, + nd->bl_x + xs, nd->bl_y + ys, BL::PC); } -void npc_free(struct npc_data *nd) +void npc_free(dumb_ptr<npc_data> nd) { clif_clearchar(nd, BeingRemoveWhy::GONE); npc_propagate_update(nd); |