summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWushin <pasekei@gmail.com>2015-04-13 21:13:52 -0500
committerWushin <pasekei@gmail.com>2015-04-13 21:13:52 -0500
commitbf54afff27cd03ed535859009baa0b4c4fa663e9 (patch)
tree92b3e0ab2e6e668da98cc023b27858e7c5fef419
parentc776b7a5d8075ede4a364bfdd0c6fb3cb6f6c5fa (diff)
parent8e8876474eddefe474528c73851b3af2c6d9327f (diff)
downloadtmwa-bf54afff27cd03ed535859009baa0b4c4fa663e9.tar.gz
tmwa-bf54afff27cd03ed535859009baa0b4c4fa663e9.tar.bz2
tmwa-bf54afff27cd03ed535859009baa0b4c4fa663e9.tar.xz
tmwa-bf54afff27cd03ed535859009baa0b4c4fa663e9.zip
Merge pull request #41 from wushin/pvp-script-persistance
Make killer & killable script builtins
-rw-r--r--src/map/atcommand.cpp89
-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.cpp33
-rwxr-xr-xtools/config.py1
7 files changed, 95 insertions, 80 deletions
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index cd51b70..f226706 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -4030,81 +4030,40 @@ 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;
+ int chan = sd->state.pvpchannel;
+ if (sd->pvp_timer || (chan > 1))
+ return ATCE::OKAY;
- 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);
+ if (chan < 1) {
+ sd->state.pvpchannel = 1;
+ clif_displaymessage(s, "##3PvP : ##BOn"_s);
+ } else {
+ sd->state.pvpchannel = 0;
+ clif_displaymessage(s, "##3PvP : ##BOff"_s);
}
+ pc_setpvptimer(sd, battle_config.player_pvp_time);
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>,
+ATCE atcommand_charpvp(Session *, dumb_ptr<map_session_data>,
ZString message)
{
CharName character;
+ int channel;
- if (!asplit(message, &character))
+ if (!extract(message, record<' '>(&character, &channel)))
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd == nullptr)
return ATCE::EXIST;
- pl_sd->special_state.killable = !pl_sd->special_state.killable;
-
- if (pl_sd->special_state.killable)
- clif_displaymessage(s, "The player is now killable"_s);
- else
- clif_displaymessage(s, "The player is no longer killable"_s);
+ pl_sd->state.pvpchannel = channel;
return ATCE::OKAY;
}
@@ -5236,21 +5195,15 @@ 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}},
+ {"charpvp"_s, {"<charname> <channel>"_s,
+ 40, atcommand_charpvp,
+ "Set the pvp channel of another player"_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..fdeac3a 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)
+ && ((caster->is_player()->state.pvpchannel > 1) && (target->is_player()->state.pvpchannel != caster->is_player()->state.pvpchannel)))
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..f57dcee 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 pvpchannel;
} 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..8b0391b 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -288,16 +288,12 @@ 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.pvpchannel == 1) && (target->state.pvpchannel == 1) && !src->bl_m->flag.get(MapFlag::NOPVP))
return 1;
-
- if (target->bl_type != BL::PC)
- return 0;
- if (target->special_state.killable)
+ if ((src->state.pvpchannel > 1) && (target->state.pvpchannel == src->state.pvpchannel)) // this one does not respect NOPVP
return 1;
-
return 0;
}
@@ -320,6 +316,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 +401,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 +921,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_pvpchannel = 0;
nullpo_retz(sd);
@@ -927,6 +950,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 +1424,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_pvpchannel != sd->state.pvpchannel)
+ sd->state.pvpchannel = b_pvpchannel;
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 da26e2b..8300d38 100644
--- a/src/map/script-fun.cpp
+++ b/src/map/script-fun.cpp
@@ -2156,6 +2156,37 @@ void builtin_pvpoff(ScriptState *st)
}
}
+static
+void builtin_setpvpchannel(ScriptState *st)
+{
+ dumb_ptr<map_session_data> sd = script_rid2sd(st);
+ int flag;
+ flag = conv_num(st, &AARG(0));
+ if (flag < 1)
+ flag = 0;
+
+ sd->state.pvpchannel = flag;
+}
+
+static
+void builtin_getpvpflag(ScriptState *st)
+{
+ dumb_ptr<map_session_data> sd = script_rid2sd(st);
+ int num = conv_num(st, &AARG(0));
+ int flag = 0;
+
+ switch (num){
+ case 0:
+ flag = sd->state.pvpchannel;
+ break;
+ case 1:
+ flag = bool(sd->status.option & Opt0::HIDE);
+ break;
+ }
+
+ push_int<ScriptDataInt>(st->stack, flag);
+}
+
/*==========================================
* NPCエモーション
*------------------------------------------
@@ -3163,6 +3194,8 @@ BuiltinFunction builtin_functions[] =
BUILTIN(getmapflag, "Mi"_s, 'i'),
BUILTIN(pvpon, "M"_s, '\0'),
BUILTIN(pvpoff, "M"_s, '\0'),
+ BUILTIN(setpvpchannel, "i"_s, '\0'),
+ BUILTIN(getpvpflag, "i"_s, 'i'),
BUILTIN(emotion, "i"_s, '\0'),
BUILTIN(mapwarp, "MMxy"_s, '\0'),
BUILTIN(mobcount, "ME"_s, 'i'),
diff --git a/tools/config.py b/tools/config.py
index 88b7644..a32e8ca 100755
--- a/tools/config.py
+++ b/tools/config.py
@@ -613,6 +613,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')