From cf4007f34bf5feee7903506e1a569f60aec5b795 Mon Sep 17 00:00:00 2001 From: mekolat <mekolat@users.noreply.github.com> Date: Thu, 21 Apr 2016 10:46:15 -0400 Subject: make `get` return -1 when getting a param fails --- src/map/script-fun.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index beabef3..13a635d 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -3813,7 +3813,10 @@ void builtin_get(ScriptState *st) } if (bl == nullptr) + { + push_int<ScriptDataInt>(st->stack, -1); return; + } int var = pc_readparam(bl, reg.sp()); push_int<ScriptDataInt>(st->stack, var); return; @@ -3869,9 +3872,8 @@ void builtin_get(ScriptState *st) if (!bl) { - PRINTF("builtin_get: no block list attached %s!\n"_fmt, conv_str(st, &AARG(1))); if (postfix == '$') - push_str<ScriptDataStr>(st->stack, conv_str(st, &AARG(1))); + push_str<ScriptDataStr>(st->stack, ""_s); else push_int<ScriptDataInt>(st->stack, 0); return; -- cgit v1.2.3-70-g09d2 From 48b9900248f74b8dc5179e34e851047e05c862b3 Mon Sep 17 00:00:00 2001 From: mekolat <mekolat@users.noreply.github.com> Date: Thu, 21 Apr 2016 12:32:12 -0400 Subject: allow to set params on npcs and mobs --- src/map/pc.cpp | 293 ++++++++++++++++++++++++++++++--------------------------- src/map/pc.hpp | 2 +- 2 files changed, 155 insertions(+), 140 deletions(-) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index d65297b..2954ca8 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -3544,155 +3544,170 @@ int pc_readparam(dumb_ptr<block_list> bl, SP type) * script用PCステータス設定 *------------------------------------------ */ -int pc_setparam(dumb_ptr<map_session_data> sd, SP type, int val) +int pc_setparam(dumb_ptr<block_list> bl, SP type, int val) { - int i = 0, up_level = 50; + nullpo_retz(bl); + dumb_ptr<map_session_data> sd; + dumb_ptr<npc_data> nd; + dumb_ptr<mob_data> md; - nullpo_retz(sd); + if (bl->bl_type == BL::PC) + sd = bl->is_player(); + else if (bl->bl_type == BL::MOB) + md = bl->is_mob(); + else if (bl->bl_type == BL::NPC) + nd = bl->is_npc(); + else + return 0; - switch (type) + int i = 0, up_level = 50; + + if (sd) { - case SP::BASELEVEL: - if (val > sd->status.base_level) - { - for (i = 1; i <= (val - sd->status.base_level); i++) - sd->status.status_point += - (sd->status.base_level + i + 14) / 4; - } - sd->status.base_level = val; - sd->status.base_exp = 0; - clif_updatestatus(sd, SP::BASELEVEL); - clif_updatestatus(sd, SP::NEXTBASEEXP); - clif_updatestatus(sd, SP::STATUSPOINT); - clif_updatestatus(sd, SP::BASEEXP); - pc_calcstatus(sd, 0); - pc_heal(sd, sd->status.max_hp, sd->status.max_sp); - break; - case SP::JOBLEVEL: - up_level -= 40; - if (val >= sd->status.job_level) - { - if (val > up_level) - val = up_level; - sd->status.skill_point += (val - sd->status.job_level); - sd->status.job_level = val; - sd->status.job_exp = 0; - clif_updatestatus(sd, SP::JOBLEVEL); - clif_updatestatus(sd, SP::NEXTJOBEXP); - clif_updatestatus(sd, SP::JOBEXP); - clif_updatestatus(sd, SP::SKILLPOINT); - pc_calcstatus(sd, 0); - clif_misceffect(sd, 1); - } - else - { - sd->status.job_level = val; - sd->status.job_exp = 0; - clif_updatestatus(sd, SP::JOBLEVEL); - clif_updatestatus(sd, SP::NEXTJOBEXP); - clif_updatestatus(sd, SP::JOBEXP); + switch (type) + { + case SP::BASELEVEL: + if (val > sd->status.base_level) + { + for (i = 1; i <= (val - sd->status.base_level); i++) + sd->status.status_point += + (sd->status.base_level + i + 14) / 4; + } + sd->status.base_level = val; + sd->status.base_exp = 0; + clif_updatestatus(sd, SP::BASELEVEL); + clif_updatestatus(sd, SP::NEXTBASEEXP); + clif_updatestatus(sd, SP::STATUSPOINT); + clif_updatestatus(sd, SP::BASEEXP); pc_calcstatus(sd, 0); - } - clif_updatestatus(sd, type); - break; - case SP::CLASS: - sd->status.species = wrap<Species>(val); - clif_changelook(sd, LOOK::BASE, val); - return 0; - case SP::SKILLPOINT: - sd->status.skill_point = val; - break; - case SP::STATUSPOINT: - sd->status.status_point = val; - break; - case SP::ZENY: - sd->status.zeny = val; - break; - case SP::BASEEXP: - if (pc_nextbaseexp(sd) > 0) - { - sd->status.base_exp = val; - if (sd->status.base_exp < 0) - sd->status.base_exp = 0; - pc_checkbaselevelup(sd); - } - break; - case SP::JOBEXP: - if (pc_nextjobexp(sd) > 0) - { - sd->status.job_exp = val; - if (sd->status.job_exp < 0) + pc_heal(sd, sd->status.max_hp, sd->status.max_sp); + break; + case SP::JOBLEVEL: + up_level -= 40; + if (val >= sd->status.job_level) + { + if (val > up_level) + val = up_level; + sd->status.skill_point += (val - sd->status.job_level); + sd->status.job_level = val; sd->status.job_exp = 0; - pc_checkjoblevelup(sd); - } - break; - case SP::SEX: - switch (val) - { - case 0: - sd->sex = sd->status.sex = SEX::FEMALE; + clif_updatestatus(sd, SP::JOBLEVEL); + clif_updatestatus(sd, SP::NEXTJOBEXP); + clif_updatestatus(sd, SP::JOBEXP); + clif_updatestatus(sd, SP::SKILLPOINT); + pc_calcstatus(sd, 0); + clif_misceffect(sd, 1); + } + else + { + sd->status.job_level = val; + sd->status.job_exp = 0; + clif_updatestatus(sd, SP::JOBLEVEL); + clif_updatestatus(sd, SP::NEXTJOBEXP); + clif_updatestatus(sd, SP::JOBEXP); + pc_calcstatus(sd, 0); + } + clif_updatestatus(sd, type); break; - case 1: - sd->sex = sd->status.sex = SEX::MALE; + case SP::CLASS: + sd->status.species = wrap<Species>(val); + clif_changelook(sd, LOOK::BASE, val); + return 0; + case SP::SKILLPOINT: + sd->status.skill_point = val; break; - default: - sd->sex = sd->status.sex = SEX::NEUTRAL; + case SP::STATUSPOINT: + sd->status.status_point = val; break; - } - for (IOff0 j : IOff0::iter()) - { - if (sd->status.inventory[j].nameid - && bool(sd->status.inventory[j].equip) - && !pc_isequip(sd, j)) - pc_unequipitem(sd, j, CalcStatus::LATER); - } - pc_calcstatus(sd, 0); - chrif_save(sd); - clif_fixpcpos(sd); - break; - case SP::WEIGHT: - sd->weight = val; - break; - case SP::MAXWEIGHT: - sd->max_weight = val; - break; - case SP::HP: - sd->status.hp = val; - break; - case SP::MAXHP: - sd->status.max_hp = val; - break; - case SP::SP: - sd->status.sp = val; - break; - case SP::MAXSP: - sd->status.max_sp = val; - break; - case SP::STR: - case SP::AGI: - case SP::VIT: - case SP::INT: - case SP::DEX: - case SP::LUK: - pc_statusup2(sd, type, (val - sd->status.attrs[sp_to_attr(type)])); - break; - case SP::PARTNER: - dumb_ptr<block_list> p_bl; - if (val < 2000000 && val >= 150000) - { - dumb_ptr<map_session_data> p_sd = nullptr; - if ((p_sd = map_nick2sd(map_charid2nick(wrap<CharId>(val)))) != nullptr) - p_bl = map_id2bl(p_sd->bl_id); - } - else - p_bl = map_id2bl(wrap<BlockId>(val)); - if (val < 1) - pc_divorce(sd); - else - p_bl ? pc_marriage(sd, p_bl->is_player()) : 0; - break; + case SP::ZENY: + sd->status.zeny = val; + break; + case SP::BASEEXP: + if (pc_nextbaseexp(sd) > 0) + { + sd->status.base_exp = val; + if (sd->status.base_exp < 0) + sd->status.base_exp = 0; + pc_checkbaselevelup(sd); + } + break; + case SP::JOBEXP: + if (pc_nextjobexp(sd) > 0) + { + sd->status.job_exp = val; + if (sd->status.job_exp < 0) + sd->status.job_exp = 0; + pc_checkjoblevelup(sd); + } + break; + case SP::SEX: + switch (val) + { + case 0: + sd->sex = sd->status.sex = SEX::FEMALE; + break; + case 1: + sd->sex = sd->status.sex = SEX::MALE; + break; + default: + sd->sex = sd->status.sex = SEX::NEUTRAL; + break; + } + for (IOff0 j : IOff0::iter()) + { + if (sd->status.inventory[j].nameid + && bool(sd->status.inventory[j].equip) + && !pc_isequip(sd, j)) + pc_unequipitem(sd, j, CalcStatus::LATER); + } + pc_calcstatus(sd, 0); + chrif_save(sd); + clif_fixpcpos(sd); + break; + case SP::WEIGHT: + sd->weight = val; + break; + case SP::MAXWEIGHT: + sd->max_weight = val; + break; + case SP::HP: + sd->status.hp = val; + break; + case SP::MAXHP: + sd->status.max_hp = val; + break; + case SP::SP: + sd->status.sp = val; + break; + case SP::MAXSP: + sd->status.max_sp = val; + break; + case SP::STR: + case SP::AGI: + case SP::VIT: + case SP::INT: + case SP::DEX: + case SP::LUK: + pc_statusup2(sd, type, (val - sd->status.attrs[sp_to_attr(type)])); + break; + case SP::PARTNER: + dumb_ptr<block_list> p_bl; + if (val < 2000000 && val >= 150000) + { + dumb_ptr<map_session_data> p_sd = nullptr; + if ((p_sd = map_nick2sd(map_charid2nick(wrap<CharId>(val)))) != nullptr) + p_bl = map_id2bl(p_sd->bl_id); + } + else + p_bl = map_id2bl(wrap<BlockId>(val)); + if (val < 1) + pc_divorce(sd); + else + p_bl ? pc_marriage(sd, p_bl->is_player()) : 0; + break; + } + clif_updatestatus(sd, type); } - clif_updatestatus(sd, type); return 0; } diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 0f04698..2e63c26 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -143,7 +143,7 @@ int pc_itemheal(dumb_ptr<map_session_data> sd, int hp, int sp); int pc_changelook(dumb_ptr<map_session_data>, LOOK, int); int pc_readparam(dumb_ptr<block_list>, SP); -int pc_setparam(dumb_ptr<map_session_data>, SP, int); +int pc_setparam(dumb_ptr<block_list>, SP, int); int pc_readreg(dumb_ptr<block_list>, SIR); void pc_setreg(dumb_ptr<block_list>, SIR, int); ZString pc_readregstr(dumb_ptr<block_list> sd, SIR reg); -- cgit v1.2.3-70-g09d2 From becc8312ff9a373ba22760ba89cdff6fe5e4895a Mon Sep 17 00:00:00 2001 From: mekolat <mekolat@users.noreply.github.com> Date: Sat, 23 Apr 2016 14:42:18 -0400 Subject: forbid puppet creation if name already exists --- src/map/script-fun.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 13a635d..b39a763 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -1121,6 +1121,13 @@ void builtin_puppet(ScriptState *st) { int x, y; + NpcName npc = stringish<NpcName>(ZString(conv_str(st, &AARG(3)))); + if (npc_name2id(npc) != nullptr) + { + push_int<ScriptDataInt>(st->stack, 0); + return; + } + dumb_ptr<block_list> bl = map_id2bl(st->oid); dumb_ptr<npc_data_script> parent_nd = bl->is_npc()->is_script(); dumb_ptr<npc_data_script> nd; @@ -1137,7 +1144,6 @@ void builtin_puppet(ScriptState *st) nd->scr.event_needs_map = false; // PlayerName::SpellName - NpcName npc = stringish<NpcName>(ZString(conv_str(st, &AARG(3)))); nd->name = npc; // Dynamically set location -- cgit v1.2.3-70-g09d2 From 5a92a6817378f69785b77bb9993c9c950d6e0eb9 Mon Sep 17 00:00:00 2001 From: mekolat <mekolat@users.noreply.github.com> Date: Sat, 23 Apr 2016 14:59:48 -0400 Subject: dispose orphan puppet if the parent is gone --- src/map/npc.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 47bf820..3eb13b3 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -366,6 +366,12 @@ void npc_eventtimer(TimerData *, tick_t, BlockId id, NpcEvent data) return; } + if (nd->scr.parent && map_id2bl(nd->scr.parent) == nullptr) + { + npc_free(nd); + return; + } + if (nd->scr.event_needs_map) { int xs = nd->scr.xs; @@ -436,6 +442,12 @@ void npc_timerevent(TimerData *, tick_t tick, BlockId id, interval_t data) assert (nd->npc_subtype == NpcSubtype::SCRIPT); assert (nd->scr.next_event != nd->scr.timer_eventv.end()); + if (nd->scr.parent && map_id2bl(nd->scr.parent) == nullptr) + { + npc_free(nd); + return; + } + nd->scr.timertick = tick; const auto te = nd->scr.next_event; // nd->scr.timerid = nullptr; @@ -606,6 +618,13 @@ int npc_event(dumb_ptr<map_session_data> sd, NpcEvent eventname, eventname); return 0; } + + if (nd->scr.parent && map_id2bl(nd->scr.parent) == nullptr) + { + npc_free(nd); + return 0; + } + if (sd) { if (nd->scr.event_needs_map) @@ -774,7 +793,13 @@ int npc_click(dumb_ptr<map_session_data> sd, BlockId id) npc_event_dequeue(sd); break; case NpcSubtype::SCRIPT: - sd->npc_pos = run_script(ScriptPointer(script_or_parent(nd->is_script()), 0), sd->bl_id, id); + dumb_ptr<npc_data_script> nds = nd->is_script(); + if (nds->scr.parent && map_id2bl(nds->scr.parent) == nullptr) + { + npc_free(nds); + return 1; + } + sd->npc_pos = run_script(ScriptPointer(script_or_parent(nds), 0), sd->bl_id, id); break; } @@ -808,6 +833,13 @@ int npc_scriptcont(dumb_ptr<map_session_data> sd, BlockId id) return 0; } + if (nd->is_script()->scr.parent && + map_id2bl(nd->is_script()->scr.parent) == nullptr) + { + npc_free(nd); + return 0; + } + sd->npc_pos = run_script(ScriptPointer(script_or_parent(nd->is_script()), sd->npc_pos), sd->bl_id, id); return 0; -- cgit v1.2.3-70-g09d2 From 881e3c06581f566f626f0c7d4da7724ff7a6d6a4 Mon Sep 17 00:00:00 2001 From: mekolat <mekolat@users.noreply.github.com> Date: Sun, 24 Apr 2016 12:24:17 -0400 Subject: add INVISIBLE param --- src/map/pc.cpp | 298 ++++++++++++++++++++++++++++-------------------- src/map/script-call.cpp | 2 +- src/mmo/clif.t.hpp | 1 + 3 files changed, 176 insertions(+), 125 deletions(-) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 2954ca8..8c2bc01 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -3535,6 +3535,12 @@ int pc_readparam(dumb_ptr<block_list> bl, SP type) case SP::ELTTYPE: val = static_cast<int>(battle_get_element(bl).element); break; + case SP::INVISIBLE: + if (sd) + val = bool(sd->status.option & Opt0::INVISIBILITY); + if (nd) + val = bool(nd->flag & 1); + break; } return val; @@ -3560,137 +3566,176 @@ int pc_setparam(dumb_ptr<block_list> bl, SP type, int val) else return 0; - int i = 0, up_level = 50; + int i = 0; - if (sd) + switch (type) { - switch (type) - { - case SP::BASELEVEL: - if (val > sd->status.base_level) - { - for (i = 1; i <= (val - sd->status.base_level); i++) - sd->status.status_point += - (sd->status.base_level + i + 14) / 4; - } - sd->status.base_level = val; - sd->status.base_exp = 0; - clif_updatestatus(sd, SP::BASELEVEL); - clif_updatestatus(sd, SP::NEXTBASEEXP); - clif_updatestatus(sd, SP::STATUSPOINT); - clif_updatestatus(sd, SP::BASEEXP); - pc_calcstatus(sd, 0); - pc_heal(sd, sd->status.max_hp, sd->status.max_sp); - break; - case SP::JOBLEVEL: - up_level -= 40; - if (val >= sd->status.job_level) - { - if (val > up_level) - val = up_level; - sd->status.skill_point += (val - sd->status.job_level); - sd->status.job_level = val; - sd->status.job_exp = 0; - clif_updatestatus(sd, SP::JOBLEVEL); - clif_updatestatus(sd, SP::NEXTJOBEXP); - clif_updatestatus(sd, SP::JOBEXP); - clif_updatestatus(sd, SP::SKILLPOINT); - pc_calcstatus(sd, 0); - clif_misceffect(sd, 1); - } - else - { - sd->status.job_level = val; - sd->status.job_exp = 0; - clif_updatestatus(sd, SP::JOBLEVEL); - clif_updatestatus(sd, SP::NEXTJOBEXP); - clif_updatestatus(sd, SP::JOBEXP); - pc_calcstatus(sd, 0); - } - clif_updatestatus(sd, type); - break; - case SP::CLASS: + case SP::BASELEVEL: + nullpo_retz(sd); + // TODO: mob mutation + if (val > sd->status.base_level) + { + if (val > MAX_LEVEL) + val = MAX_LEVEL; + for (i = 1; i <= (val - sd->status.base_level); i++) + sd->status.status_point += + (sd->status.base_level + i + 14) / 4; + } + sd->status.base_level = val; + sd->status.base_exp = 0; + clif_updatestatus(sd, SP::BASELEVEL); + clif_updatestatus(sd, SP::NEXTBASEEXP); + clif_updatestatus(sd, SP::STATUSPOINT); + clif_updatestatus(sd, SP::BASEEXP); + pc_calcstatus(sd, 0); + pc_heal(sd, sd->status.max_hp, sd->status.max_sp); + break; + case SP::JOBLEVEL: + nullpo_retz(sd); + if (val > sd->status.job_level) + { + if (val > MAX_LEVEL) + val = MAX_LEVEL; + sd->status.skill_point += (val - sd->status.job_level); + clif_updatestatus(sd, SP::SKILLPOINT); + clif_misceffect(sd, 1); + } + sd->status.job_level = val; + sd->status.job_exp = 0; + clif_updatestatus(sd, SP::JOBLEVEL); + clif_updatestatus(sd, SP::NEXTJOBEXP); + clif_updatestatus(sd, SP::JOBEXP); + pc_calcstatus(sd, 0); + break; + case SP::CLASS: + // TODO: mob class change + if (sd) + { sd->status.species = wrap<Species>(val); clif_changelook(sd, LOOK::BASE, val); - return 0; - case SP::SKILLPOINT: - sd->status.skill_point = val; - break; - case SP::STATUSPOINT: - sd->status.status_point = val; - break; - case SP::ZENY: - sd->status.zeny = val; - break; - case SP::BASEEXP: - if (pc_nextbaseexp(sd) > 0) - { - sd->status.base_exp = val; - if (sd->status.base_exp < 0) - sd->status.base_exp = 0; - pc_checkbaselevelup(sd); - } - break; - case SP::JOBEXP: - if (pc_nextjobexp(sd) > 0) + } + else if (nd) + { + if (unwrap<Species>(nd->npc_class) != val) { - sd->status.job_exp = val; - if (sd->status.job_exp < 0) - sd->status.job_exp = 0; - pc_checkjoblevelup(sd); + nd->npc_class = wrap<Species>(val); + npc_enable(nd->name, 0); + npc_enable(nd->name, 1); } - break; - case SP::SEX: - switch (val) + } + return 0; + case SP::SKILLPOINT: + nullpo_retz(sd); + sd->status.skill_point = val; + clif_updatestatus(sd, type); + break; + case SP::STATUSPOINT: + nullpo_retz(sd); + sd->status.status_point = val; + clif_updatestatus(sd, type); + break; + case SP::ZENY: + nullpo_retz(sd); + sd->status.zeny = val; + clif_updatestatus(sd, type); + break; + case SP::BASEEXP: + nullpo_retz(sd); + if (pc_nextbaseexp(sd) > 0) + { + sd->status.base_exp = val; + if (sd->status.base_exp < 0) + sd->status.base_exp = 0; + pc_checkbaselevelup(sd); + } + clif_updatestatus(sd, type); + break; + case SP::JOBEXP: + nullpo_retz(sd); + if (pc_nextjobexp(sd) > 0) + { + sd->status.job_exp = val; + if (sd->status.job_exp < 0) + sd->status.job_exp = 0; + pc_checkjoblevelup(sd); + } + clif_updatestatus(sd, type); + break; + case SP::SEX: + { + SEX sex = SEX::NEUTRAL; + if (val == 0) + sex = SEX::FEMALE; + if (val == 1) + sex = SEX::MALE; + + if (nd) { - case 0: - sd->sex = sd->status.sex = SEX::FEMALE; - break; - case 1: - sd->sex = sd->status.sex = SEX::MALE; - break; - default: - sd->sex = sd->status.sex = SEX::NEUTRAL; - break; + nd->sex = sex; + npc_enable(nd->name, 0); + npc_enable(nd->name, 1); } - for (IOff0 j : IOff0::iter()) + else if (sd) { - if (sd->status.inventory[j].nameid - && bool(sd->status.inventory[j].equip) - && !pc_isequip(sd, j)) - pc_unequipitem(sd, j, CalcStatus::LATER); + sd->sex = sd->status.sex = sex; + for (IOff0 j : IOff0::iter()) + { + if (sd->status.inventory[j].nameid + && bool(sd->status.inventory[j].equip) + && !pc_isequip(sd, j)) + pc_unequipitem(sd, j, CalcStatus::LATER); + } + pc_calcstatus(sd, 0); + chrif_save(sd); + clif_fixpcpos(sd); } - pc_calcstatus(sd, 0); - chrif_save(sd); - clif_fixpcpos(sd); - break; - case SP::WEIGHT: - sd->weight = val; - break; - case SP::MAXWEIGHT: - sd->max_weight = val; - break; - case SP::HP: - sd->status.hp = val; - break; - case SP::MAXHP: - sd->status.max_hp = val; - break; - case SP::SP: - sd->status.sp = val; - break; - case SP::MAXSP: - sd->status.max_sp = val; - break; - case SP::STR: - case SP::AGI: - case SP::VIT: - case SP::INT: - case SP::DEX: - case SP::LUK: - pc_statusup2(sd, type, (val - sd->status.attrs[sp_to_attr(type)])); - break; - case SP::PARTNER: + } + break; + case SP::WEIGHT: + nullpo_retz(sd); + sd->weight = val; + clif_updatestatus(sd, type); + break; + case SP::MAXWEIGHT: + nullpo_retz(sd); + sd->max_weight = val; + clif_updatestatus(sd, type); + break; + case SP::HP: + nullpo_retz(sd); + // TODO: mob mutation + sd->status.hp = val; + clif_updatestatus(sd, type); + break; + case SP::MAXHP: + nullpo_retz(sd); + // TODO: mob mutation + sd->status.max_hp = val; + clif_updatestatus(sd, type); + break; + case SP::SP: + nullpo_retz(sd); + sd->status.sp = val; + clif_updatestatus(sd, type); + break; + case SP::MAXSP: + nullpo_retz(sd); + sd->status.max_sp = val; + clif_updatestatus(sd, type); + break; + case SP::STR: + case SP::AGI: + case SP::VIT: + case SP::INT: + case SP::DEX: + case SP::LUK: + nullpo_retz(sd); + // TODO: mob mutation + pc_statusup2(sd, type, (val - sd->status.attrs[sp_to_attr(type)])); + break; + case SP::PARTNER: + if (sd) + { dumb_ptr<block_list> p_bl; if (val < 2000000 && val >= 150000) { @@ -3704,9 +3749,14 @@ int pc_setparam(dumb_ptr<block_list> bl, SP type, int val) pc_divorce(sd); else p_bl ? pc_marriage(sd, p_bl->is_player()) : 0; - break; - } - clif_updatestatus(sd, type); + } + break; + case SP::INVISIBLE: + if (sd) + pc_invisibility(sd, (val > 0) ? 1 : 0); + else if (nd) + npc_enable(nd->name, (val > 0) ? false : true); + break; } return 0; diff --git a/src/map/script-call.cpp b/src/map/script-call.cpp index 085d90a..2e90432 100644 --- a/src/map/script-call.cpp +++ b/src/map/script-call.cpp @@ -219,7 +219,7 @@ void set_reg(dumb_ptr<block_list> sd, VariableCode type, SIR reg, struct script_ if (type == VariableCode::PARAM) { int val = vd.get_if<ScriptDataInt>()->numi; - pc_setparam(sd->is_player(), reg.sp(), val); + pc_setparam(sd, reg.sp(), val); return; } assert (type == VariableCode::VARIABLE); diff --git a/src/mmo/clif.t.hpp b/src/mmo/clif.t.hpp index c1b222f..1dfbd67 100644 --- a/src/mmo/clif.t.hpp +++ b/src/mmo/clif.t.hpp @@ -474,6 +474,7 @@ enum class SP : uint16_t BL_ID = 1077, BL_TYPE = 1078, CHAR_ID = 1079, + INVISIBLE = 1080, }; constexpr -- cgit v1.2.3-70-g09d2 From d007bb6c7b519137585c53373ec085b57528b17d Mon Sep 17 00:00:00 2001 From: mekolat <mekolat@users.noreply.github.com> Date: Sun, 24 Apr 2016 13:06:34 -0400 Subject: fix npc gender for ManaPlus --- src/map/clif.cpp | 10 +++++++++- src/map/npc-parse.cpp | 5 ++++- src/map/script-fun.cpp | 1 + src/mmo/enums.hpp | 1 + 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 31ecaf8..81ae02f 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -913,7 +913,15 @@ void clif_npc0078(dumb_ptr<npc_data> nd, Buffer& buf) fixed_78.pos.x = nd->bl_x; fixed_78.pos.y = nd->bl_y; fixed_78.pos.dir = nd->dir; - fixed_78.sex = nd->sex; + + // ManaPlus uses a different sex enum for npcs... + if (nd->sex == SEX::FEMALE) + fixed_78.sex = SEX::UNSPECIFIED; + else if (nd->sex == SEX::MALE) + fixed_78.sex = SEX::NEUTRAL; + else if (nd->sex == SEX::NEUTRAL) + fixed_78.sex = SEX::__OTHER; + buf = create_fpacket<0x0078, 54>(fixed_78); } diff --git a/src/map/npc-parse.cpp b/src/map/npc-parse.cpp index 164d793..99e6267 100644 --- a/src/map/npc-parse.cpp +++ b/src/map/npc-parse.cpp @@ -142,6 +142,7 @@ bool npc_load_warp(ast::npc::Warp& warp) nd->bl_id = npc_get_new_npc_id(); nd->n = map_addnpc(m, nd); + nd->sex = SEX::UNSPECIFIED; nd->bl_prev = nd->bl_next = nullptr; nd->bl_m = m; nd->bl_x = x; @@ -208,6 +209,7 @@ bool npc_load_shop(ast::npc::Shop& shop) } } + nd->sex = SEX::UNSPECIFIED; nd->bl_prev = nd->bl_next = nullptr; nd->bl_m = m; nd->bl_x = x; @@ -435,6 +437,7 @@ bool npc_load_script_none(ast::script::ScriptBody& body, ast::npc::ScriptNone& s nd->name = script_none.name.data; + nd->sex = SEX::UNSPECIFIED; nd->bl_prev = nd->bl_next = nullptr; nd->bl_m = borrow(undefined_gat); nd->bl_x = 0; @@ -542,7 +545,7 @@ bool npc_load_script_map(ast::script::ScriptBody& body, ast::npc::ScriptMap& scr } nd->name = script_map.name.data; - + nd->sex = SEX::UNSPECIFIED; nd->bl_prev = nd->bl_next = nullptr; nd->bl_m = m; nd->bl_x = x; diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index b39a763..fc555ad 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -1145,6 +1145,7 @@ void builtin_puppet(ScriptState *st) // PlayerName::SpellName nd->name = npc; + nd->sex = SEX::UNSPECIFIED; // Dynamically set location nd->bl_m = m; diff --git a/src/mmo/enums.hpp b/src/mmo/enums.hpp index 9a8f8ea..2564ec9 100644 --- a/src/mmo/enums.hpp +++ b/src/mmo/enums.hpp @@ -115,6 +115,7 @@ enum class SEX : uint8_t // TODO switch to Option<SEX> where appropriate. UNSPECIFIED = 2, NEUTRAL = 3, + __OTHER = 4, // used in ManaPlus only }; inline char sex_to_char(SEX sex) -- cgit v1.2.3-70-g09d2 From 543bdef8acecf4456d42c73fb712e570b01dc741 Mon Sep 17 00:00:00 2001 From: mekolat <mekolat@users.noreply.github.com> Date: Sun, 24 Apr 2016 13:21:31 -0400 Subject: add HIDDEN param --- src/map/pc.cpp | 12 ++++++++++++ src/mmo/clif.t.hpp | 1 + 2 files changed, 13 insertions(+) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 8c2bc01..63b1497 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -3541,6 +3541,10 @@ int pc_readparam(dumb_ptr<block_list> bl, SP type) if (nd) val = bool(nd->flag & 1); break; + case SP::HIDDEN: + if (sd) + val = bool(sd->status.option & Opt0::HIDE); + break; } return val; @@ -3757,6 +3761,14 @@ int pc_setparam(dumb_ptr<block_list> bl, SP type, int val) else if (nd) npc_enable(nd->name, (val > 0) ? false : true); break; + case SP::HIDDEN: + nullpo_retz(sd); + if (val == 1) + sd->status.option |= Opt0::HIDE; + else + sd->status.option &= ~Opt0::HIDE; + clif_changeoption(sd); + break; } return 0; diff --git a/src/mmo/clif.t.hpp b/src/mmo/clif.t.hpp index 1dfbd67..c23842e 100644 --- a/src/mmo/clif.t.hpp +++ b/src/mmo/clif.t.hpp @@ -475,6 +475,7 @@ enum class SP : uint16_t BL_TYPE = 1078, CHAR_ID = 1079, INVISIBLE = 1080, + HIDDEN = 1081, }; constexpr -- cgit v1.2.3-70-g09d2 From 6fac3210f0de07ab1ff483875ac517a3eea7367a Mon Sep 17 00:00:00 2001 From: mekolat <mekolat@users.noreply.github.com> Date: Sun, 24 Apr 2016 13:46:11 -0400 Subject: check for null pointer where npc_dialog_mes is used --- src/map/script-fun.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index fc555ad..b73a8fc 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -90,6 +90,8 @@ static void builtin_mes(ScriptState *st) { dumb_ptr<map_session_data> sd = script_rid2sd(st); + if (sd == nullptr) + return; sd->state.npc_dialog_mes = 1; RString mes = HARG(0) ? conv_str(st, &AARG(0)) : ""_s; clif_scriptmes(sd, st->oid, mes); @@ -327,6 +329,8 @@ void builtin_close(ScriptState *st) } st->state = ScriptEndState::END; dumb_ptr<map_session_data> sd = script_rid2sd(st); + if (sd == nullptr) + return; if (sd->state.npc_dialog_mes) clif_scriptclose(sd, st->oid); else @@ -338,6 +342,8 @@ void builtin_close2(ScriptState *st) { st->state = ScriptEndState::STOP; dumb_ptr<map_session_data> sd = script_rid2sd(st); + if (sd == nullptr) + return; if (sd->state.npc_dialog_mes) clif_scriptclose(sd, st->oid); else -- cgit v1.2.3-70-g09d2