summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map/atcommand.cpp93
-rw-r--r--src/map/magic-stmt.cpp4
-rw-r--r--src/map/map.hpp3
-rw-r--r--src/map/pc.cpp43
-rw-r--r--src/map/pc.hpp2
-rw-r--r--src/map/script-fun.cpp32
-rwxr-xr-xtools/config.py1
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')