diff options
-rw-r--r-- | src/map/atcommand.cpp | 93 | ||||
-rw-r--r-- | src/map/magic-stmt.cpp | 4 | ||||
-rw-r--r-- | src/map/map.hpp | 3 | ||||
-rw-r--r-- | src/map/pc.cpp | 43 | ||||
-rw-r--r-- | src/map/pc.hpp | 2 | ||||
-rw-r--r-- | src/map/script-fun.cpp | 32 | ||||
-rwxr-xr-x | tools/config.py | 1 |
7 files changed, 83 insertions, 95 deletions
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index cd51b70..2a5791e 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -4030,81 +4030,19 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd, } static -ATCE atcommand_killer(Session *s, dumb_ptr<map_session_data> sd, +ATCE atcommand_pvp(Session *s, dumb_ptr<map_session_data> sd, ZString) { - sd->special_state.killer = !sd->special_state.killer; - - if (sd->special_state.killer) - clif_displaymessage(s, "You be a killa..."_s); - else - clif_displaymessage(s, "You gonna be own3d..."_s); - - return ATCE::OKAY; -} - -static -ATCE atcommand_charkiller(Session *s, dumb_ptr<map_session_data>, - ZString message) -{ - CharName character; - - if (!asplit(message, &character)) - return ATCE::USAGE; - - dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd == nullptr) - return ATCE::EXIST; - - pl_sd->special_state.killer = !pl_sd->special_state.killer; - - if (pl_sd->special_state.killer) - { - clif_displaymessage(s, "The player is now a killer"_s); - clif_displaymessage(pl_sd->sess, "You are now a killer"_s); - } - else - { - clif_displaymessage(s, "The player is no longer a killer"_s); - clif_displaymessage(pl_sd->sess, "You are no longer a killer"_s); - } - - return ATCE::OKAY; -} - -static -ATCE atcommand_killable(Session *s, dumb_ptr<map_session_data> sd, - ZString) -{ - sd->special_state.killable = !sd->special_state.killable; - - if (sd->special_state.killable) - clif_displaymessage(s, "You gonna be own3d..."_s); - else - clif_displaymessage(s, "You be a killa..."_s); - - return ATCE::OKAY; -} - -static -ATCE atcommand_charkillable(Session *s, dumb_ptr<map_session_data>, - ZString message) -{ - CharName character; - - if (!asplit(message, &character)) - return ATCE::USAGE; - - dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd == nullptr) - return ATCE::EXIST; + if (sd->pvp_timer) + return ATCE::OKAY; - pl_sd->special_state.killable = !pl_sd->special_state.killable; + sd->state.pvpon = !sd->state.pvpon; + pc_setpvptimer(sd, battle_config.player_pvp_time); - if (pl_sd->special_state.killable) - clif_displaymessage(s, "The player is now killable"_s); + if (sd->state.pvpon) + clif_displaymessage(s, "##3PvP : ##BOn"_s); else - clif_displaymessage(s, "The player is no longer killable"_s); + clif_displaymessage(s, "##3PvP : ##BOff"_s); return ATCE::OKAY; } @@ -5236,21 +5174,12 @@ Map<XString, AtCommandInfo> atcommand_info = {"addwarp"_s, {"<mapname> <x> <y>"_s, 80, atcommand_addwarp, "Create a new permanent warp"_s}}, - {"killer"_s, {""_s, - 60, atcommand_killer, - "Toggle whether you are a killer"_s}}, - {"charkiller"_s, {"<charname>"_s, - 60, atcommand_charkiller, - "Toggle whether a player is a killer"_s}}, + {"pvp"_s, {""_s, + 0, atcommand_pvp, + "Toggle your pvp flag"_s}}, {"npcmove"_s, {"<x> <y> <npc-name>"_s, 80, atcommand_npcmove, "Force an NPC to move on the map"_s}}, - {"killable"_s, {""_s, - 60, atcommand_killable, - "Toggle whether you are killable"_s}}, - {"charkillable"_s, {"<charname>"_s, - 60, atcommand_charkillable, - "Toggle whether a player is killable"_s}}, {"chareffect"_s, {"<type> <target>"_s, 40, atcommand_chareffect, "Apply effect type with arg 0 to a player"_s}}, diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp index c69dafa..544b290 100644 --- a/src/map/magic-stmt.cpp +++ b/src/map/magic-stmt.cpp @@ -773,8 +773,8 @@ int op_injure(dumb_ptr<env_t> env, Slice<val_t> args) if (target->bl_type == BL::PC && !target->bl_m->flag.get(MapFlag::PVP) - && !target->is_player()->special_state.killable - && (caster->bl_type != BL::PC || !caster->is_player()->special_state.killer)) + && (caster->bl_type != BL::PC) + && (!target->is_player()->state.pvpon && !caster->is_player()->state.pvpon)) return 0; /* Cannot damage other players outside of pvp */ if (target != caster) diff --git a/src/map/map.hpp b/src/map/map.hpp index 3dd03e7..9e15851 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -142,11 +142,10 @@ struct map_session_data : block_list, SessionData unsigned shroud_disappears_on_pickup:1; unsigned shroud_disappears_on_talk:1; unsigned seen_motd:1; + unsigned pvpon:1; } state; struct { - unsigned killer:1; - unsigned killable:1; unsigned unbreakable_weapon:1; unsigned unbreakable_armor:1; unsigned deaf:1; diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 7d04785..6a94f31 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -288,16 +288,10 @@ int pc_iskiller(dumb_ptr<map_session_data> src, { nullpo_retz(src); - if (src->bl_type != BL::PC) + if (src->bl_type != BL::PC || target->bl_type != BL::PC) return 0; - if (src->special_state.killer) + if (src->state.pvpon && target->state.pvpon && !src->bl_m->flag.get(MapFlag::NOPVP)) return 1; - - if (target->bl_type != BL::PC) - return 0; - if (target->special_state.killable) - return 1; - return 0; } @@ -320,6 +314,33 @@ int distance(int x0, int y0, int x1, int y1) } static +void pc_pvp_timer(TimerData *, tick_t, BlockId id) +{ + dumb_ptr<map_session_data> sd = map_id2sd(id); + + assert (sd != nullptr); + assert (sd->bl_type == BL::PC); +} + +int pc_setpvptimer(dumb_ptr<map_session_data> sd, interval_t val) +{ + nullpo_retz(sd); + + sd->pvp_timer = Timer(gettick() + val, + std::bind(pc_pvp_timer, ph::_1, ph::_2, + sd->bl_id)); + return 0; +} + +int pc_delpvptimer(dumb_ptr<map_session_data> sd) +{ + nullpo_retz(sd); + + sd->pvp_timer.cancel(); + return 0; +} + +static void pc_invincible_timer(TimerData *, tick_t, BlockId id) { dumb_ptr<map_session_data> sd = map_id2sd(id); @@ -378,7 +399,6 @@ int pc_setrestartvalue(dumb_ptr<map_session_data> sd, int type) clif_updatestatus(sd, SP::SP); sd->heal_xp = 0; // [Fate] Set gainable xp for healing this player to 0 - return 0; } @@ -899,6 +919,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) int bl; int aspd_rate, refinedef = 0; int str, dstr, dex; + int b_pvpon = 0; nullpo_retz(sd); @@ -927,6 +948,8 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) b_mdef = sd->mdef; b_mdef2 = sd->mdef2; b_base_atk = sd->base_atk; + if (!pc_isdead(sd) && sd->state.pvpchannel == 1) + b_pvpchannel = sd->state.pvpchannel; sd->max_weight = max_weight_base_0 + sd->status.attrs[ATTR::STR] * 300; @@ -1399,6 +1422,8 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) clif_updatestatus(sd, SP::HP); if (b_sp != sd->status.sp) clif_updatestatus(sd, SP::SP); + if (b_pvpon != sd->state.pvpon) + sd->state.pvpon = b_pvpon; return 0; } diff --git a/src/map/pc.hpp b/src/map/pc.hpp index ba0a46f..56f0491 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -170,6 +170,8 @@ void pc_setstand(dumb_ptr<map_session_data> sd); void pc_cleanup(dumb_ptr<map_session_data> sd); // [Fate] Clean up after a logged-out PC int pc_read_gm_account(Session *, const std::vector<Packet_Repeat<0x2b15>>&); +int pc_setpvptimer(dumb_ptr<map_session_data> sd, interval_t); +int pc_delpvptimer(dumb_ptr<map_session_data> sd); int pc_setinvincibletimer(dumb_ptr<map_session_data> sd, interval_t); int pc_delinvincibletimer(dumb_ptr<map_session_data> sd); int pc_logout(dumb_ptr<map_session_data> sd); // [fate] Player logs out diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 8c25266..bde1458 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -2175,6 +2175,36 @@ void builtin_pvpoff(ScriptState *st) } } +static +void builtin_pvp(ScriptState *st) +{ + dumb_ptr<map_session_data> sd = script_rid2sd(st); + int flag; + flag = conv_num(st, &AARG(0)); + if (flag > 1) + flag = 1; + + sd->state.pvpon = flag; +} + +static +void builtin_getpvpflag(ScriptState *st) +{ + dumb_ptr<map_session_data> sd = script_rid2sd(st); + int num = conv_num(st, &AARG(0)); + + switch (num){ + case 0: + num = sd->state.pvpon; + break; + case 1: + flag = bool(sd->status.option & Opt0::HIDE); + break; + } + + push_int<ScriptDataInt>(st->stack, num); +} + /*========================================== * NPCエモーション *------------------------------------------ @@ -3078,6 +3108,8 @@ BuiltinFunction builtin_functions[] = BUILTIN(getmapflag, "Mi"_s, 'i'), BUILTIN(pvpon, "M"_s, '\0'), BUILTIN(pvpoff, "M"_s, '\0'), + BUILTIN(pvp, "i"_s, '\0'), + BUILTIN(getpvpflag, "i"_s, 'i'), BUILTIN(emotion, "i"_s, '\0'), BUILTIN(mapwarp, "MMxy"_s, '\0'), BUILTIN(cmdothernpc, "ss"_s, '\0'), diff --git a/tools/config.py b/tools/config.py index 8d1423b..aa44669 100755 --- a/tools/config.py +++ b/tools/config.py @@ -614,6 +614,7 @@ def build_config(): battle_conf.opt('mob_count_rate', percent, '100') battle_conf.opt('basic_skill_check', bool, 'true') battle_conf.opt('player_invincible_time', milliseconds, '5_s') + battle_conf.opt('player_pvp_time', milliseconds, '5_s') battle_conf.opt('skill_min_damage', bool, 'false') battle_conf.opt('natural_healhp_interval', milliseconds, '6_s', {map_h}, min='NATURAL_HEAL_INTERVAL') battle_conf.opt('natural_healsp_interval', milliseconds, '8_s', {map_h}, min='NATURAL_HEAL_INTERVAL') |