Jump to content
  • 0
ZodiacoHCK

PvP cell Problem

Question

Hello people!

I wanted to tell you that I have a problem trying to implement NAPSTER's PvP cell in my emulator. I have my emulator running stable in the latest master version available about 4 months ago.

the problem is that there are certain differences between my rathena codes and the diff code of the patch.

I have successfully implemented the BGex manually and I had no problems. but this pvp_cell has not succeeded.

I leave the patch that I am trying to put!

 

 conf/battle/misc.conf      | 39 +++++++++++++++++++++
 conf/msg_conf/map_msg.conf |  4 +++
 db/const.txt               |  3 ++
 src/map/atcommand.c        |  8 ++---
 src/map/battle.c           | 30 ++++++++++++----
 src/map/battle.h           | 10 +++++-
 src/map/clif.c             |  8 ++++-
 src/map/map.cpp            | 46 +++++++++++++++++++++++--
 src/map/map.h              | 12 +++++--
 src/map/pc.c               | 86 ++++++++++++++++++++++++++++++++++++++++++----
 src/map/pc.h               |  2 ++
 src/map/script_constants.h |  4 ++-
 src/map/skill.c            |  3 +-
 src/map/unit.c             | 47 ++++++++++++++++++++++++-
 14 files changed, 274 insertions(+), 28 deletions(-)

diff --git a/conf/battle/misc.conf b/conf/battle/misc.conf
index 7c085fd41..37759b659 100644
--- a/conf/battle/misc.conf
+++ b/conf/battle/misc.conf
@@ -176,3 +176,42 @@ mail_delay: 1000
 
 // Hides items from the player's favorite tab from being sold to a NPC. (Note 1)
 hide_fav_sell: no
+
+// Addon Cell PVP [Napster]
+// Enable Deathmatch for cell pvp
+// Default: 0
+// 0 = No
+// 1 = Yes
+cellpvp_deathmatch: 1
+
+// Delay player alive deathmatch for cell pvp
+// Default: 1000 (1 secand)
+cellpvp_deathmatch_delay: 1000
+
+// When player is dead recovery HP/SP Rate for cell pvp
+// Default: 100 (recovery 100%)
+deathmatch_hp_rate: 100
+deathmatch_sp_rate: 100
+
+// Enable buff when player is dead for cell pvp
+// Default: 1
+// 0 = No
+// 1 = Yes
+// Request core npc files use name "deathmatch_core"
+cellpvp_autobuff: yes
+
+// Can atk player in party
+// Default: 1
+// 0 = No
+// 1 = Yes
+cellpvp_party_enable: no
+
+// Can atk player in guild
+// Default: 1
+// 0 = No
+// 1 = Yes
+cellpvp_guild_enable: no
+
+// When player move to cell pvp is delay walk out cooldown
+// Default: 5000 (5 secand)
+cellpvp_walkout_delay: 5000
\ No newline at end of file
diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf
index 50306ef97..d3afebbc8 100644
--- a/conf/msg_conf/map_msg.conf
+++ b/conf/msg_conf/map_msg.conf
@@ -1664,3 +1664,7 @@
 
 //Custom translations
 //import: conf/msg_conf/import/map_msg_eng_conf.txt
+
+// Addon Cell PVP [Napster]
+1599: Walking failed. [%s] is cooling down. Wait %.1f minutes.
+1600: Walking failed. [%s] is cooling down. Wait %d seconds.
\ No newline at end of file
diff --git a/db/const.txt b/db/const.txt
index a10cc018b..46bf071f9 100644
--- a/db/const.txt
+++ b/db/const.txt
@@ -2313,3 +2313,6 @@ ARCWANDCLAN	2
 GOLDENMACECLAN	3
 CROSSBOWCLAN	4
 JUMPINGCLAN	5
+
+CELL_PVP		10
+CELL_CHKPVP	16
\ No newline at end of file
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index d8d52b9cc..c6bd4ce11 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -482,7 +482,7 @@ ACMD_FUNC(mapmove)
 		clif_displaymessage(fd, msg_txt(sd,247)); // You are not authorized to warp to this map.
 		return -1;
 	}
-	if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+	if (sd->state.pvp || sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
 		clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map.
 		return -1;
 	}
@@ -830,11 +830,11 @@ ACMD_FUNC(load)
 	nullpo_retr(-1, sd);
 
 	m = map_mapindex2mapid(sd->status.save_point.map);
-	if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+	if (sd->state.pvp && (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) {
 		clif_displaymessage(fd, msg_txt(sd,249));	// You are not authorized to warp to your save map.
 		return -1;
 	}
-	if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+	if (sd->state.pvp && (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) {
 		clif_displaymessage(fd, msg_txt(sd,248));	// You are not authorized to warp from your current map.
 		return -1;
 	}
@@ -2054,7 +2054,7 @@ ACMD_FUNC(go)
 			clif_displaymessage(fd, msg_txt(sd,247)); // You are not authorized to warp to this map.
 			return -1;
 		}
-		if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+		if (sd->state.pvp || sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
 			clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map.
 			return -1;
 		}
diff --git a/src/map/battle.c b/src/map/battle.c
index e2d616bd9..ef7b5e9cd 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -7767,6 +7767,10 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
 					else
 						return 0; // You can't target anything out of your duel
 				}
+				else if( map_getcell( s_bl->m, s_bl->x, s_bl->y, CELL_CHKPVP ) && map_getcell( t_bl->m, t_bl->x, t_bl->y, CELL_CHKPVP ) )		// Addon Cell PVP [Napster]
+				{
+					 state |= BCT_ENEMY;
+				}
 			}
 			if( map_flag_gvg(m) && !sd->status.guild_id && t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->mob_id == MOBID_EMPERIUM )
 				return 0; //If you don't belong to a guild, can't target emperium.
@@ -7868,15 +7872,19 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
 		if( flag&BCT_PARTY || state&BCT_ENEMY )
 		{
 			int s_party = status_get_party_id(s_bl);
-			if(s_party && s_party == status_get_party_id(t_bl))
-				state |= BCT_PARTY;
+			if(s_party && s_party == status_get_party_id(t_bl) && !(battle_config.cellpvp_party_enable && map_getcell( t_bl->m, t_bl->x, t_bl->y, CELL_CHKPVP )) )		// Addon Cell PVP [Napster]
+ 				state |= BCT_PARTY;
+			else
+				state |= BCT_ENEMY;
 		}
 		if( flag&BCT_GUILD || state&BCT_ENEMY )
 		{
 			int s_guild = status_get_guild_id(s_bl);
 			int t_guild = status_get_guild_id(t_bl);
-			if(s_guild && t_guild && (s_guild == t_guild || (!(flag&BCT_SAMEGUILD) && guild_isallied(s_guild, t_guild))))
-				state |= BCT_GUILD;
+			if(s_guild && t_guild && (s_guild == t_guild || (!(flag&BCT_SAMEGUILD) && guild_isallied(s_guild, t_guild))) && !(battle_config.cellpvp_guild_enable && map_getcell( t_bl->m, t_bl->x, t_bl->y, CELL_CHKPVP )) )		// Addon Cell PVP [Napster]
+ 				state |= BCT_GUILD;
+			else
+				state |= BCT_ENEMY;
 		}
 	} //end non pvp/gvg chk rivality
 
@@ -8419,7 +8427,7 @@ static const struct _battle_data {
 	{ "change_party_leader_samemap",        &battle_config.change_party_leader_samemap,     1,      0,      1,              },
 	{ "dispel_song",                        &battle_config.dispel_song,                     0,      0,      1,              },
 	{ "guild_maprespawn_clones",			&battle_config.guild_maprespawn_clones,			0,		0,		1,				},
-	{ "hide_fav_sell", 			&battle_config.hide_fav_sell,			0,      0,      1,              },
+	{ "hide_fav_sell", 						&battle_config.hide_fav_sell,			0,      0,      1,              },
 	{ "mail_daily_count",					&battle_config.mail_daily_count,				100,	0,		INT32_MAX,		},
 	{ "mail_zeny_fee",						&battle_config.mail_zeny_fee,					2,		0,		100,			},
 	{ "mail_attachment_price",				&battle_config.mail_attachment_price,			2500,	0,		INT32_MAX,		},
@@ -8427,10 +8435,20 @@ static const struct _battle_data {
 	{ "banana_bomb_duration",				&battle_config.banana_bomb_duration,			0,		0,		UINT16_MAX,		},
 	{ "guild_leaderchange_delay",			&battle_config.guild_leaderchange_delay,		1440,	0,		INT32_MAX,		},
 	{ "guild_leaderchange_woe",				&battle_config.guild_leaderchange_woe,			0,		0,		1,				},
-	{ "guild_alliance_onlygm",              &battle_config.guild_alliance_onlygm,           0,      0,      1, },
+	{ "guild_alliance_onlygm",              &battle_config.guild_alliance_onlygm,           0,      0,      1, 				},
 	{ "feature.achievement",                &battle_config.feature_achievement,             1,      0,      1,              },
 	{ "allow_bound_sell",                   &battle_config.allow_bound_sell,                1,      0,      1,              },
 
+	// Addon Cell PVP [Napster]
+	{ "cellpvp_deathmatch",               	&battle_config.cellpvp_deathmatch,              1,      0,      1,              },
+	{ "cellpvp_deathmatch_delay",           &battle_config.cellpvp_deathmatch_delay,     1000,      0,INT_MAX,        		},
+	{ "deathmatch_hp_rate",           		&battle_config.deathmatch_hp_rate,         		0,		0,	  100,				},
+	{ "deathmatch_sp_rate",           		&battle_config.deathmatch_sp_rate,         		0,		0,	  100,				},
+	{ "cellpvp_autobuff",               	&battle_config.cellpvp_autobuff,                1,      0,	 	1,              },
+	{ "cellpvp_party_enable",               &battle_config.cellpvp_party_enable,            1,      0,      1,              },
+	{ "cellpvp_guild_enable",               &battle_config.cellpvp_guild_enable,            1,      0,      1,              },
+	{ "cellpvp_walkout_delay",              &battle_config.cellpvp_walkout_delay,        5000,     	0,INT_MAX,    		    },
+
 #include "../custom/battle_config_init.inc"
 };
 
diff --git a/src/map/battle.h b/src/map/battle.h
index 37c86dfbb..abcb2b4a7 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -632,7 +632,15 @@ extern struct Battle_Config
 	int guild_alliance_onlygm;
 	int feature_achievement;
 	int allow_bound_sell;
-
+	// Addon Cell PVP [Napster]
+	int cellpvp_deathmatch;
+	int cellpvp_deathmatch_delay;
+	int deathmatch_hp_rate;
+	int deathmatch_sp_rate;
+	int cellpvp_autobuff;
+	int cellpvp_party_enable;
+	int cellpvp_guild_enable;
+	int cellpvp_walkout_delay;
 #include "../custom/battle_config_struct.inc"
 } battle_config;
 
diff --git a/src/map/clif.c b/src/map/clif.c
index e3d4a5abf..8bf9f93dc 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -10446,7 +10446,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 
 
 	mail_clear(sd);
-
+	
+	// Addon Cell PVP [Napster]
+	if( !sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+		map_pvp_area(sd, 1);
+	else if( sd->state.pvp && !map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+		map_pvp_area(sd, 0);
+	
 	/* Guild Aura Init */
 	if( sd->state.gmaster_flag ) {
 		guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->guild,GD_LEADERSHIP));
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 57486ac58..02013af02 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -115,7 +115,7 @@ static int block_free_count = 0, block_free_lock = 0;
 static struct block_list *bl_list[BL_LIST_MAX];
 static int bl_list_count = 0;
 
-#define MAP_MAX_MSG 1550
+#define MAP_MAX_MSG 1601
 
 struct map_data map[MAX_MAP_PER_SERVER];
 int map_num = 0;
@@ -2092,7 +2092,10 @@ int map_quit(struct map_session_data *sd) {
 
 	if (sd->state.buyingstore)
 		idb_remove(buyingstore_getdb(), sd->status.char_id);
-
+	// Addon Cell PVP [Napster]
+	if( sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) )
+		map_pvp_area(sd, 0);
+	
 	pc_damage_log_clear(sd,0);
 	party_booking_delete(sd); // Party Booking [Spiria]
 	pc_makesavestatus(sd);
@@ -3068,7 +3071,8 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk)
 			return (cell.maelstrom);
 		case CELL_CHKICEWALL:
 			return (cell.icewall);
-
+		case CELL_CHKPVP:	// Addon Cell PVP [Napster]
+			return (cell.pvp);
 		// special checks
 		case CELL_CHKPASS:
 #ifdef CELL_NOSTACK
@@ -3122,6 +3126,7 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag)
 		case CELL_NOCHAT:        map[m].cell[j].nochat = flag;        break;
 		case CELL_MAELSTROM:	 map[m].cell[j].maelstrom = flag;	  break;
 		case CELL_ICEWALL:		 map[m].cell[j].icewall = flag;		  break;
+		case CELL_PVP:        	 map[m].cell[j].pvp = flag;        	  break;		// Addon Cell PVP [Napster]
 		default:
 			ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
 			break;
@@ -4054,6 +4059,41 @@ int inter_config_read(const char *cfgName)
 	return 0;
 }
 
+// Addon Cell PVP [Napster]
+int map_pvp_area(struct map_session_data* sd, bool flag)
+{
+	switch(flag) 
+	{
+		case 1:
+			clif_map_property(&sd->bl, MAPPROPERTY_FREEPVPZONE, SELF);
+			if (sd->pvp_timer == INVALID_TIMER) {
+				map[sd->bl.m].cell_pvpuser++;
+ 
+				sd->pvp_timer  = add_timer(gettick()+200, pc_calc_pvprank_timer, sd->bl.id, 0);
+				sd->pvp_rank  = 0;
+				sd->pvp_lastusers = 0;
+				sd->pvp_point  = 5;
+				sd->pvp_won   = 0;
+				sd->pvp_lost  = 0;
+				sd->state.pvp  = 1;
+				sd->pvpcan_walkout_tick = gettick();
+			}
+			break;
+		default:
+			clif_pvpset(sd, 0, 0, 2);
+			map[sd->bl.m].cell_pvpuser--;
+
+			if( sd->pvp_timer != INVALID_TIMER )
+				delete_timer(sd->pvp_timer, pc_calc_pvprank_timer);
+
+			sd->pvp_timer  = INVALID_TIMER;
+			sd->state.pvp  = 0;
+			break;
+	}
+
+	return 0;
+}
+
 /*=======================================
  *  MySQL Init
  *---------------------------------------*/
diff --git a/src/map/map.h b/src/map/map.h
index fd5a6b046..e6687c1fa 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -521,7 +521,7 @@ typedef enum {
 	CELL_NOCHAT,
 	CELL_MAELSTROM,
 	CELL_ICEWALL,
-
+	CELL_PVP,
 } cell_t;
 
 // used by map_getcell()
@@ -545,7 +545,7 @@ typedef enum {
 	CELL_CHKNOCHAT,			// Whether the cell denies Player Chat Window
 	CELL_CHKMAELSTROM,		// Whether the cell has Maelstrom
 	CELL_CHKICEWALL,		// Whether the cell has Ice Wall
-
+	CELL_CHKPVP,			// Addon Cell PVP [Napster]
 } cell_chk;
 
 struct mapcell
@@ -564,7 +564,8 @@ struct mapcell
 		novending : 1,
 		nochat : 1,
 		maelstrom : 1,
-		icewall : 1;
+		icewall : 1,
+		pvp : 1;		// Addon Cell PVP [Napster]
 
 #ifdef CELL_NOSTACK
 	unsigned char cell_bl; //Holds amount of bls in this cell.
@@ -624,6 +625,7 @@ struct map_data {
 	int npc_num;
 	int users;
 	int users_pvp;
+	int cell_pvpuser;		// Addon Cell PVP [Napster]
 	int iwall_num; // Total of invisible walls in this map
 	struct map_flag {
 		unsigned town : 1; // [Suggestion to protect Mail System]
@@ -684,6 +686,7 @@ struct map_data {
 		unsigned gvg_te : 1; // GVG WOE:TE. This was added as purpose to change 'gvg' for GVG TE, so item_noequp, skill_nocast exlude GVG TE maps from 'gvg' (flag &4)
 		unsigned gvg_te_castle : 1; // GVG WOE:TE Castle
 		unsigned hidemobhpbar : 1;
+		
 #ifdef ADJUST_SKILL_DAMAGE
 		unsigned skill_damage : 1;
 #endif
@@ -1006,6 +1009,9 @@ extern char roulette_table[32];
 
 void do_shutdown(void);
 
+// Addon Cell PVP [Napster]
+int map_pvp_area(struct map_session_data* sd, bool flag);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/map/pc.c b/src/map/pc.c
index 4682102bb..3342c74ce 100755
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -672,8 +672,9 @@ void pc_makesavestatus(struct map_session_data *sd) {
 		sd->status.last_point.x = sd->bl.x;
 		sd->status.last_point.y = sd->bl.y;
 	}
-
-	if(map[sd->bl.m].flag.nosave) {
+	
+	// Addon Cell PVP [Napster]
+	if(map[sd->bl.m].flag.nosave || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) ) {
 		struct map_data *m=&map[sd->bl.m];
 		if(m->save.map)
 			memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point));
@@ -4826,7 +4827,7 @@ bool pc_isUseitem(struct map_session_data *sd,int n)
 		case ITEMID_WING_OF_FLY:
 		case ITEMID_GIANT_FLY_WING:
 		case ITEMID_N_FLY_WING:
-			if( map[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m) ) {
+			if( map[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m) || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP )) {
 				clif_skill_teleportmessage(sd,0);
 				return false;
 			}
@@ -4867,7 +4868,7 @@ bool pc_isUseitem(struct map_session_data *sd,int n)
 				clif_displaymessage(sd->fd, msg_txt(sd,663));
 				return false;
 			}
-			if( map[sd->bl.m].flag.noreturn && nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && nameid != ITEMID_N_FLY_WING )
+			if( map[sd->bl.m].flag.noreturn && nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && nameid != ITEMID_N_FLY_WING || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ))
 				return false;
 			break;
 		case ITEMID_MERCENARY_RED_POTION:
@@ -5478,6 +5479,10 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
 		}
 
 		channel_pcquit(sd,4); //quit map chan
+
+		// Addon Cell PVP [Napster]
+		if(sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP))
+			map[sd->state.pmap].cell_pvpuser--;
 	}
 
 	if( m < 0 )
@@ -5634,7 +5639,7 @@ bool pc_memo(struct map_session_data* sd, int pos)
 	nullpo_ret(sd);
 
 	// check mapflags
-	if( sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) {
+	if( sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) ) {
 		clif_skill_teleportmessage(sd, 1); // "Saved point cannot be memorized."
 		return false;
 	}
@@ -7528,6 +7533,12 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype)
 	pc_setrestartvalue(sd,3);
 	if( pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, clrtype) != SETPOS_OK )
 		clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
+
+	// Addon Cell PVP [Napster]
+	if (sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+		map_pvp_area(sd, 1);
+	else
+		map_pvp_area(sd, 0);
 }
 
 static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data)
@@ -7542,6 +7553,55 @@ static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data)
 	return 0;
 }
 
+// Addon Cell PVP [Napster]
+void pc_deathmatch(struct map_session_data* sd, clr_type clrtype)
+{
+	struct npc_data *nd;
+	short x = 0, y = 0;
+
+	if( !pc_isdead(sd) )
+		return; // not applicable
+
+	if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) && battle_config.cellpvp_deathmatch ) 
+	{
+		do {
+			x = rand() % (map[sd->bl.m].xs - 2) + 1;
+			y = rand() % (map[sd->bl.m].ys - 2) + 1;
+		} while( !map_getcell(sd->bl.m, x, y, CELL_CHKPVP) );
+
+		pc_setstand(sd, true);
+		pc_setrestartvalue(sd,3);
+		status_percent_heal(&sd->bl, battle_config.deathmatch_hp_rate, battle_config.deathmatch_sp_rate);
+
+		if( pc_setpos(sd, sd->mapindex, x, y, clrtype) )
+			clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
+
+		status_change_clear(&sd->bl, 3);
+
+		if(sd && battle_config.cellpvp_autobuff)
+		{
+			nd = npc_name2id("deathmatch_core");
+			if (nd && nd->subtype == NPCTYPE_SCRIPT)
+				run_script(nd->u.scr.script, 0, sd->bl.id, nd->bl.id);
+		}
+	}
+}
+
+static int pc_deathmatch_timer(int tid, unsigned int tick, int id, intptr_t data)
+{
+	struct map_session_data *sd = map_id2sd(id);
+	if( sd != NULL )
+	{
+		pc_deathmatch(sd, CLR_OUTSIGHT);
+		if (sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) )
+		{
+			map_pvp_area(sd, 1);
+			map[sd->bl.m].cell_pvpuser--;
+		}
+	}
+	return 0;
+}
+
 /*==========================================
  * Invoked when a player has received damage
  *------------------------------------------*/
@@ -7779,7 +7839,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 	}
 
 	if(battle_config.bone_drop==2
-		|| (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp))
+		|| (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp) || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) && sd->state.pvp)
 	{
 		struct item item_tmp;
 		memset(&item_tmp,0,sizeof(item_tmp));
@@ -7852,6 +7912,12 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 				pc_payzeny(sd, zeny_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL);
 		}
 	}
+	// Addon Cell PVP [Napster]
+	if (map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) && battle_config.cellpvp_deathmatch && sd->state.pvp)
+	{
+		add_timer(tick+battle_config.cellpvp_deathmatch_delay, pc_deathmatch_timer, sd->bl.id, 0);
+		return 1|8;
+	}
 
 	if(map[sd->bl.m].flag.pvp_nightmaredrop) { // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker]
 		int j;
@@ -10152,6 +10218,14 @@ int pc_calc_pvprank(struct map_session_data *sd)
 
 	sd->pvp_rank=1;
 	map_foreachinmap(pc_calc_pvprank_sub,sd->bl.m,BL_PC,sd);
+
+	// Addon Cell PVP [Napster]
+	if( (old!=sd->pvp_rank || sd->pvp_lastusers!=m->cell_pvpuser) || sd->state.pvp ) 
+	{
+		clif_pvpset( sd, sd->pvp_rank, sd->pvp_lastusers = m->cell_pvpuser, 0);
+		return sd->pvp_rank;
+	}
+
 	if(old!=sd->pvp_rank || sd->pvp_lastusers!=m->users_pvp)
 		clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=m->users_pvp,0);
 	return sd->pvp_rank;
diff --git a/src/map/pc.h b/src/map/pc.h
index c8be94592..f6ecdeb60 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -268,6 +268,7 @@ struct map_session_data {
 		bool keepshop; // Whether shop data should be removed when the player disconnects
 		bool mail_writing; // Whether the player is currently writing a mail in RODEX or not
 		bool cashshop_open;
+		unsigned int pvp : 1;		// Addon Cell PVP [Napster]
 	} state;
 	struct {
 		unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
@@ -347,6 +348,7 @@ struct map_session_data {
 	unsigned int canskill_tick; // used to prevent abuse from no-delay ACT files
 	unsigned int cansendmail_tick; // [Mail System Flood Protection]
 	unsigned int ks_floodprotect_tick; // [Kill Steal Protection]
+	unsigned int pvpcan_walkout_tick;		// Addon Cell PVP [Napster]
 
 	struct s_item_delay {
 		unsigned short nameid;
diff --git a/src/map/script_constants.h b/src/map/script_constants.h
index 408f3ff64..6ddb844be 100644
--- a/src/map/script_constants.h
+++ b/src/map/script_constants.h
@@ -448,6 +448,7 @@
 	export_constant(CELL_NOCHAT);
 	export_constant(CELL_MAELSTROM);
 	export_constant(CELL_ICEWALL);
+	export_constant(CELL_PVP);
 
 	/* getcell types */
 	export_constant(CELL_CHKWALL);
@@ -466,7 +467,8 @@
 	export_constant(CELL_CHKNOCHAT);
 	export_constant(CELL_CHKMAELSTROM);
 	export_constant(CELL_CHKICEWALL);
-
+	export_constant(CELL_CHKPVP);
+	
 	/* parameters */
 	export_parameter("StatusPoint",SP_STATUSPOINT);
 	export_parameter("BaseLevel",SP_BASELEVEL);
diff --git a/src/map/skill.c b/src/map/skill.c
index 42d19eef9..789d8745f 100755
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -6976,8 +6976,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 
 	case MO_ABSORBSPIRITS:
 		i = 0;
-		if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m) || (sd && sd->duel_group && sd->duel_group == dstsd->duel_group)) &&
-			((dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK) != MAPID_REBELLION)) { // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen]
+		if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m) || (map_getcell(src->m,src->x,src->y,CELL_CHKPVP) && map_getcell(bl->m,bl->x,bl->y,CELL_CHKPVP)) || (sd && sd->duel_group && sd->duel_group == dstsd->duel_group)) && ((dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK) != MAPID_REBELLION)) { // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen]
 			if (dstsd->spiritball > 0) {
 				i = dstsd->spiritball * 7;
 				pc_delspiritball(dstsd,dstsd->spiritball,0);
diff --git a/src/map/unit.c b/src/map/unit.c
index ef713e1ed..879aef341 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -428,6 +428,12 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data
 			} else
 				sd->areanpc_id=0;
 			pc_cell_basilica(sd);
+
+			// Addon Cell PVP [Napster]
+			if( !sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+				map_pvp_area(sd, 1);
+			else if( sd->state.pvp && !map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+				map_pvp_area(sd, 0);
 			break;
 		case BL_MOB:
 			//Movement was successful, reset walktoxy_fail_count
@@ -648,6 +654,28 @@ int unit_walktoxy( struct block_list *bl, short x, short y, unsigned char flag)
 	if(!(flag&2) && (!status_bl_has_mode(bl,MD_CANMOVE) || !unit_can_move(bl)))
 		return 0;
 
+	// Addon Cell PVP [Napster]
+	if (bl->type == BL_PC)
+	{
+		struct map_session_data* sd = (TBL_PC*)bl;
+		unsigned int tick = gettick();
+
+		if (sd && sd->pvpcan_walkout_tick && !map_getcell( sd->bl.m, x, y, CELL_CHKPVP ) ) {
+			if ( DIFF_TICK(tick, sd->pvpcan_walkout_tick) < battle_config.cellpvp_walkout_delay )
+			{
+				int e_tick = (battle_config.cellpvp_walkout_delay - DIFF_TICK( tick, sd->pvpcan_walkout_tick))/1000;
+				char e_msg[150];
+				if( e_tick > 99 )
+						sprintf(e_msg, msg_txt(sd, 1599), sd->status.name, (double)e_tick / 60); 
+				else
+						sprintf(e_msg, msg_txt(sd, 1600), sd->status.name, e_tick+1);
+
+				clif_messagecolor(sd,color_table[COLOR_YELLOW], e_msg, false, SELF);
+				return 0;
+			}
+		}
+	}
+	
 	ud->state.walk_easy = flag&1;
 	ud->to_x = x;
 	ud->to_y = y;
@@ -959,7 +987,13 @@ bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, boo
 				return false;
 		} else
 			sd->areanpc_id=0;
-
+		
+		// Addon Cell PVP [Ize]
+		if( !sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+			map_pvp_area(sd, 1);
+		else if( sd->state.pvp && !map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+			map_pvp_area(sd, 0);
+		
 		if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 ) {
 			// Check if pet needs to be teleported. [Skotlex]
 			int flag = 0;
@@ -1302,6 +1336,17 @@ int unit_stop_walking(struct block_list *bl,int type)
  */
 int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv)
 {
+	// Addon Cell PVP [Napster]
+	struct block_list *bl = map_id2bl(target_id);	
+
+	if( bl && src->type == BL_PC && bl->type == BL_PC && src->id != target_id)
+	{
+		struct map_session_data *dstsd = (TBL_PC*)bl;
+
+		 if( dstsd && dstsd->state.pvp != ((TBL_PC*)src)->state.pvp )
+			 return 0;
+	}
+	
 	return unit_skilluse_id2(
 		src, target_id, skill_id, skill_lv,
 		skill_castfix(src, skill_id, skill_lv),

 

if necessary I can put my emulator on a github

 

Link to comment
Share on other sites

1 answer to this question

Recommended Posts

  • 0
On 8/26/2021 at 2:57 AM, ZodiacoHCK said:

Hello people!

I wanted to tell you that I have a problem trying to implement NAPSTER's PvP cell in my emulator. I have my emulator running stable in the latest master version available about 4 months ago.

the problem is that there are certain differences between my rathena codes and the diff code of the patch.

I have successfully implemented the BGex manually and I had no problems. but this pvp_cell has not succeeded.

I leave the patch that I am trying to put!

 

 conf/battle/misc.conf      | 39 +++++++++++++++++++++
 conf/msg_conf/map_msg.conf |  4 +++
 db/const.txt               |  3 ++
 src/map/atcommand.c        |  8 ++---
 src/map/battle.c           | 30 ++++++++++++----
 src/map/battle.h           | 10 +++++-
 src/map/clif.c             |  8 ++++-
 src/map/map.cpp            | 46 +++++++++++++++++++++++--
 src/map/map.h              | 12 +++++--
 src/map/pc.c               | 86 ++++++++++++++++++++++++++++++++++++++++++----
 src/map/pc.h               |  2 ++
 src/map/script_constants.h |  4 ++-
 src/map/skill.c            |  3 +-
 src/map/unit.c             | 47 ++++++++++++++++++++++++-
 14 files changed, 274 insertions(+), 28 deletions(-)

diff --git a/conf/battle/misc.conf b/conf/battle/misc.conf
index 7c085fd41..37759b659 100644
--- a/conf/battle/misc.conf
+++ b/conf/battle/misc.conf
@@ -176,3 +176,42 @@ mail_delay: 1000
 
 // Hides items from the player's favorite tab from being sold to a NPC. (Note 1)
 hide_fav_sell: no
+
+// Addon Cell PVP [Napster]
+// Enable Deathmatch for cell pvp
+// Default: 0
+// 0 = No
+// 1 = Yes
+cellpvp_deathmatch: 1
+
+// Delay player alive deathmatch for cell pvp
+// Default: 1000 (1 secand)
+cellpvp_deathmatch_delay: 1000
+
+// When player is dead recovery HP/SP Rate for cell pvp
+// Default: 100 (recovery 100%)
+deathmatch_hp_rate: 100
+deathmatch_sp_rate: 100
+
+// Enable buff when player is dead for cell pvp
+// Default: 1
+// 0 = No
+// 1 = Yes
+// Request core npc files use name "deathmatch_core"
+cellpvp_autobuff: yes
+
+// Can atk player in party
+// Default: 1
+// 0 = No
+// 1 = Yes
+cellpvp_party_enable: no
+
+// Can atk player in guild
+// Default: 1
+// 0 = No
+// 1 = Yes
+cellpvp_guild_enable: no
+
+// When player move to cell pvp is delay walk out cooldown
+// Default: 5000 (5 secand)
+cellpvp_walkout_delay: 5000
\ No newline at end of file
diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf
index 50306ef97..d3afebbc8 100644
--- a/conf/msg_conf/map_msg.conf
+++ b/conf/msg_conf/map_msg.conf
@@ -1664,3 +1664,7 @@
 
 //Custom translations
 //import: conf/msg_conf/import/map_msg_eng_conf.txt
+
+// Addon Cell PVP [Napster]
+1599: Walking failed. [%s] is cooling down. Wait %.1f minutes.
+1600: Walking failed. [%s] is cooling down. Wait %d seconds.
\ No newline at end of file
diff --git a/db/const.txt b/db/const.txt
index a10cc018b..46bf071f9 100644
--- a/db/const.txt
+++ b/db/const.txt
@@ -2313,3 +2313,6 @@ ARCWANDCLAN	2
 GOLDENMACECLAN	3
 CROSSBOWCLAN	4
 JUMPINGCLAN	5
+
+CELL_PVP		10
+CELL_CHKPVP	16
\ No newline at end of file
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index d8d52b9cc..c6bd4ce11 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -482,7 +482,7 @@ ACMD_FUNC(mapmove)
 		clif_displaymessage(fd, msg_txt(sd,247)); // You are not authorized to warp to this map.
 		return -1;
 	}
-	if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+	if (sd->state.pvp || sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
 		clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map.
 		return -1;
 	}
@@ -830,11 +830,11 @@ ACMD_FUNC(load)
 	nullpo_retr(-1, sd);
 
 	m = map_mapindex2mapid(sd->status.save_point.map);
-	if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+	if (sd->state.pvp && (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) {
 		clif_displaymessage(fd, msg_txt(sd,249));	// You are not authorized to warp to your save map.
 		return -1;
 	}
-	if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+	if (sd->state.pvp && (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))) {
 		clif_displaymessage(fd, msg_txt(sd,248));	// You are not authorized to warp from your current map.
 		return -1;
 	}
@@ -2054,7 +2054,7 @@ ACMD_FUNC(go)
 			clif_displaymessage(fd, msg_txt(sd,247)); // You are not authorized to warp to this map.
 			return -1;
 		}
-		if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+		if (sd->state.pvp || sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
 			clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map.
 			return -1;
 		}
diff --git a/src/map/battle.c b/src/map/battle.c
index e2d616bd9..ef7b5e9cd 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -7767,6 +7767,10 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
 					else
 						return 0; // You can't target anything out of your duel
 				}
+				else if( map_getcell( s_bl->m, s_bl->x, s_bl->y, CELL_CHKPVP ) && map_getcell( t_bl->m, t_bl->x, t_bl->y, CELL_CHKPVP ) )		// Addon Cell PVP [Napster]
+				{
+					 state |= BCT_ENEMY;
+				}
 			}
 			if( map_flag_gvg(m) && !sd->status.guild_id && t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->mob_id == MOBID_EMPERIUM )
 				return 0; //If you don't belong to a guild, can't target emperium.
@@ -7868,15 +7872,19 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
 		if( flag&BCT_PARTY || state&BCT_ENEMY )
 		{
 			int s_party = status_get_party_id(s_bl);
-			if(s_party && s_party == status_get_party_id(t_bl))
-				state |= BCT_PARTY;
+			if(s_party && s_party == status_get_party_id(t_bl) && !(battle_config.cellpvp_party_enable && map_getcell( t_bl->m, t_bl->x, t_bl->y, CELL_CHKPVP )) )		// Addon Cell PVP [Napster]
+ 				state |= BCT_PARTY;
+			else
+				state |= BCT_ENEMY;
 		}
 		if( flag&BCT_GUILD || state&BCT_ENEMY )
 		{
 			int s_guild = status_get_guild_id(s_bl);
 			int t_guild = status_get_guild_id(t_bl);
-			if(s_guild && t_guild && (s_guild == t_guild || (!(flag&BCT_SAMEGUILD) && guild_isallied(s_guild, t_guild))))
-				state |= BCT_GUILD;
+			if(s_guild && t_guild && (s_guild == t_guild || (!(flag&BCT_SAMEGUILD) && guild_isallied(s_guild, t_guild))) && !(battle_config.cellpvp_guild_enable && map_getcell( t_bl->m, t_bl->x, t_bl->y, CELL_CHKPVP )) )		// Addon Cell PVP [Napster]
+ 				state |= BCT_GUILD;
+			else
+				state |= BCT_ENEMY;
 		}
 	} //end non pvp/gvg chk rivality
 
@@ -8419,7 +8427,7 @@ static const struct _battle_data {
 	{ "change_party_leader_samemap",        &battle_config.change_party_leader_samemap,     1,      0,      1,              },
 	{ "dispel_song",                        &battle_config.dispel_song,                     0,      0,      1,              },
 	{ "guild_maprespawn_clones",			&battle_config.guild_maprespawn_clones,			0,		0,		1,				},
-	{ "hide_fav_sell", 			&battle_config.hide_fav_sell,			0,      0,      1,              },
+	{ "hide_fav_sell", 						&battle_config.hide_fav_sell,			0,      0,      1,              },
 	{ "mail_daily_count",					&battle_config.mail_daily_count,				100,	0,		INT32_MAX,		},
 	{ "mail_zeny_fee",						&battle_config.mail_zeny_fee,					2,		0,		100,			},
 	{ "mail_attachment_price",				&battle_config.mail_attachment_price,			2500,	0,		INT32_MAX,		},
@@ -8427,10 +8435,20 @@ static const struct _battle_data {
 	{ "banana_bomb_duration",				&battle_config.banana_bomb_duration,			0,		0,		UINT16_MAX,		},
 	{ "guild_leaderchange_delay",			&battle_config.guild_leaderchange_delay,		1440,	0,		INT32_MAX,		},
 	{ "guild_leaderchange_woe",				&battle_config.guild_leaderchange_woe,			0,		0,		1,				},
-	{ "guild_alliance_onlygm",              &battle_config.guild_alliance_onlygm,           0,      0,      1, },
+	{ "guild_alliance_onlygm",              &battle_config.guild_alliance_onlygm,           0,      0,      1, 				},
 	{ "feature.achievement",                &battle_config.feature_achievement,             1,      0,      1,              },
 	{ "allow_bound_sell",                   &battle_config.allow_bound_sell,                1,      0,      1,              },
 
+	// Addon Cell PVP [Napster]
+	{ "cellpvp_deathmatch",               	&battle_config.cellpvp_deathmatch,              1,      0,      1,              },
+	{ "cellpvp_deathmatch_delay",           &battle_config.cellpvp_deathmatch_delay,     1000,      0,INT_MAX,        		},
+	{ "deathmatch_hp_rate",           		&battle_config.deathmatch_hp_rate,         		0,		0,	  100,				},
+	{ "deathmatch_sp_rate",           		&battle_config.deathmatch_sp_rate,         		0,		0,	  100,				},
+	{ "cellpvp_autobuff",               	&battle_config.cellpvp_autobuff,                1,      0,	 	1,              },
+	{ "cellpvp_party_enable",               &battle_config.cellpvp_party_enable,            1,      0,      1,              },
+	{ "cellpvp_guild_enable",               &battle_config.cellpvp_guild_enable,            1,      0,      1,              },
+	{ "cellpvp_walkout_delay",              &battle_config.cellpvp_walkout_delay,        5000,     	0,INT_MAX,    		    },
+
 #include "../custom/battle_config_init.inc"
 };
 
diff --git a/src/map/battle.h b/src/map/battle.h
index 37c86dfbb..abcb2b4a7 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -632,7 +632,15 @@ extern struct Battle_Config
 	int guild_alliance_onlygm;
 	int feature_achievement;
 	int allow_bound_sell;
-
+	// Addon Cell PVP [Napster]
+	int cellpvp_deathmatch;
+	int cellpvp_deathmatch_delay;
+	int deathmatch_hp_rate;
+	int deathmatch_sp_rate;
+	int cellpvp_autobuff;
+	int cellpvp_party_enable;
+	int cellpvp_guild_enable;
+	int cellpvp_walkout_delay;
 #include "../custom/battle_config_struct.inc"
 } battle_config;
 
diff --git a/src/map/clif.c b/src/map/clif.c
index e3d4a5abf..8bf9f93dc 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -10446,7 +10446,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 
 
 	mail_clear(sd);
-
+	
+	// Addon Cell PVP [Napster]
+	if( !sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+		map_pvp_area(sd, 1);
+	else if( sd->state.pvp && !map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+		map_pvp_area(sd, 0);
+	
 	/* Guild Aura Init */
 	if( sd->state.gmaster_flag ) {
 		guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->guild,GD_LEADERSHIP));
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 57486ac58..02013af02 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -115,7 +115,7 @@ static int block_free_count = 0, block_free_lock = 0;
 static struct block_list *bl_list[BL_LIST_MAX];
 static int bl_list_count = 0;
 
-#define MAP_MAX_MSG 1550
+#define MAP_MAX_MSG 1601
 
 struct map_data map[MAX_MAP_PER_SERVER];
 int map_num = 0;
@@ -2092,7 +2092,10 @@ int map_quit(struct map_session_data *sd) {
 
 	if (sd->state.buyingstore)
 		idb_remove(buyingstore_getdb(), sd->status.char_id);
-
+	// Addon Cell PVP [Napster]
+	if( sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) )
+		map_pvp_area(sd, 0);
+	
 	pc_damage_log_clear(sd,0);
 	party_booking_delete(sd); // Party Booking [Spiria]
 	pc_makesavestatus(sd);
@@ -3068,7 +3071,8 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk)
 			return (cell.maelstrom);
 		case CELL_CHKICEWALL:
 			return (cell.icewall);
-
+		case CELL_CHKPVP:	// Addon Cell PVP [Napster]
+			return (cell.pvp);
 		// special checks
 		case CELL_CHKPASS:
 #ifdef CELL_NOSTACK
@@ -3122,6 +3126,7 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag)
 		case CELL_NOCHAT:        map[m].cell[j].nochat = flag;        break;
 		case CELL_MAELSTROM:	 map[m].cell[j].maelstrom = flag;	  break;
 		case CELL_ICEWALL:		 map[m].cell[j].icewall = flag;		  break;
+		case CELL_PVP:        	 map[m].cell[j].pvp = flag;        	  break;		// Addon Cell PVP [Napster]
 		default:
 			ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
 			break;
@@ -4054,6 +4059,41 @@ int inter_config_read(const char *cfgName)
 	return 0;
 }
 
+// Addon Cell PVP [Napster]
+int map_pvp_area(struct map_session_data* sd, bool flag)
+{
+	switch(flag) 
+	{
+		case 1:
+			clif_map_property(&sd->bl, MAPPROPERTY_FREEPVPZONE, SELF);
+			if (sd->pvp_timer == INVALID_TIMER) {
+				map[sd->bl.m].cell_pvpuser++;
+ 
+				sd->pvp_timer  = add_timer(gettick()+200, pc_calc_pvprank_timer, sd->bl.id, 0);
+				sd->pvp_rank  = 0;
+				sd->pvp_lastusers = 0;
+				sd->pvp_point  = 5;
+				sd->pvp_won   = 0;
+				sd->pvp_lost  = 0;
+				sd->state.pvp  = 1;
+				sd->pvpcan_walkout_tick = gettick();
+			}
+			break;
+		default:
+			clif_pvpset(sd, 0, 0, 2);
+			map[sd->bl.m].cell_pvpuser--;
+
+			if( sd->pvp_timer != INVALID_TIMER )
+				delete_timer(sd->pvp_timer, pc_calc_pvprank_timer);
+
+			sd->pvp_timer  = INVALID_TIMER;
+			sd->state.pvp  = 0;
+			break;
+	}
+
+	return 0;
+}
+
 /*=======================================
  *  MySQL Init
  *---------------------------------------*/
diff --git a/src/map/map.h b/src/map/map.h
index fd5a6b046..e6687c1fa 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -521,7 +521,7 @@ typedef enum {
 	CELL_NOCHAT,
 	CELL_MAELSTROM,
 	CELL_ICEWALL,
-
+	CELL_PVP,
 } cell_t;
 
 // used by map_getcell()
@@ -545,7 +545,7 @@ typedef enum {
 	CELL_CHKNOCHAT,			// Whether the cell denies Player Chat Window
 	CELL_CHKMAELSTROM,		// Whether the cell has Maelstrom
 	CELL_CHKICEWALL,		// Whether the cell has Ice Wall
-
+	CELL_CHKPVP,			// Addon Cell PVP [Napster]
 } cell_chk;
 
 struct mapcell
@@ -564,7 +564,8 @@ struct mapcell
 		novending : 1,
 		nochat : 1,
 		maelstrom : 1,
-		icewall : 1;
+		icewall : 1,
+		pvp : 1;		// Addon Cell PVP [Napster]
 
 #ifdef CELL_NOSTACK
 	unsigned char cell_bl; //Holds amount of bls in this cell.
@@ -624,6 +625,7 @@ struct map_data {
 	int npc_num;
 	int users;
 	int users_pvp;
+	int cell_pvpuser;		// Addon Cell PVP [Napster]
 	int iwall_num; // Total of invisible walls in this map
 	struct map_flag {
 		unsigned town : 1; // [Suggestion to protect Mail System]
@@ -684,6 +686,7 @@ struct map_data {
 		unsigned gvg_te : 1; // GVG WOE:TE. This was added as purpose to change 'gvg' for GVG TE, so item_noequp, skill_nocast exlude GVG TE maps from 'gvg' (flag &4)
 		unsigned gvg_te_castle : 1; // GVG WOE:TE Castle
 		unsigned hidemobhpbar : 1;
+		
 #ifdef ADJUST_SKILL_DAMAGE
 		unsigned skill_damage : 1;
 #endif
@@ -1006,6 +1009,9 @@ extern char roulette_table[32];
 
 void do_shutdown(void);
 
+// Addon Cell PVP [Napster]
+int map_pvp_area(struct map_session_data* sd, bool flag);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/map/pc.c b/src/map/pc.c
index 4682102bb..3342c74ce 100755
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -672,8 +672,9 @@ void pc_makesavestatus(struct map_session_data *sd) {
 		sd->status.last_point.x = sd->bl.x;
 		sd->status.last_point.y = sd->bl.y;
 	}
-
-	if(map[sd->bl.m].flag.nosave) {
+	
+	// Addon Cell PVP [Napster]
+	if(map[sd->bl.m].flag.nosave || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) ) {
 		struct map_data *m=&map[sd->bl.m];
 		if(m->save.map)
 			memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point));
@@ -4826,7 +4827,7 @@ bool pc_isUseitem(struct map_session_data *sd,int n)
 		case ITEMID_WING_OF_FLY:
 		case ITEMID_GIANT_FLY_WING:
 		case ITEMID_N_FLY_WING:
-			if( map[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m) ) {
+			if( map[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m) || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP )) {
 				clif_skill_teleportmessage(sd,0);
 				return false;
 			}
@@ -4867,7 +4868,7 @@ bool pc_isUseitem(struct map_session_data *sd,int n)
 				clif_displaymessage(sd->fd, msg_txt(sd,663));
 				return false;
 			}
-			if( map[sd->bl.m].flag.noreturn && nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && nameid != ITEMID_N_FLY_WING )
+			if( map[sd->bl.m].flag.noreturn && nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && nameid != ITEMID_N_FLY_WING || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ))
 				return false;
 			break;
 		case ITEMID_MERCENARY_RED_POTION:
@@ -5478,6 +5479,10 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
 		}
 
 		channel_pcquit(sd,4); //quit map chan
+
+		// Addon Cell PVP [Napster]
+		if(sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP))
+			map[sd->state.pmap].cell_pvpuser--;
 	}
 
 	if( m < 0 )
@@ -5634,7 +5639,7 @@ bool pc_memo(struct map_session_data* sd, int pos)
 	nullpo_ret(sd);
 
 	// check mapflags
-	if( sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) {
+	if( sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) ) {
 		clif_skill_teleportmessage(sd, 1); // "Saved point cannot be memorized."
 		return false;
 	}
@@ -7528,6 +7533,12 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype)
 	pc_setrestartvalue(sd,3);
 	if( pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, clrtype) != SETPOS_OK )
 		clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
+
+	// Addon Cell PVP [Napster]
+	if (sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+		map_pvp_area(sd, 1);
+	else
+		map_pvp_area(sd, 0);
 }
 
 static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data)
@@ -7542,6 +7553,55 @@ static int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data)
 	return 0;
 }
 
+// Addon Cell PVP [Napster]
+void pc_deathmatch(struct map_session_data* sd, clr_type clrtype)
+{
+	struct npc_data *nd;
+	short x = 0, y = 0;
+
+	if( !pc_isdead(sd) )
+		return; // not applicable
+
+	if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) && battle_config.cellpvp_deathmatch ) 
+	{
+		do {
+			x = rand() % (map[sd->bl.m].xs - 2) + 1;
+			y = rand() % (map[sd->bl.m].ys - 2) + 1;
+		} while( !map_getcell(sd->bl.m, x, y, CELL_CHKPVP) );
+
+		pc_setstand(sd, true);
+		pc_setrestartvalue(sd,3);
+		status_percent_heal(&sd->bl, battle_config.deathmatch_hp_rate, battle_config.deathmatch_sp_rate);
+
+		if( pc_setpos(sd, sd->mapindex, x, y, clrtype) )
+			clif_resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
+
+		status_change_clear(&sd->bl, 3);
+
+		if(sd && battle_config.cellpvp_autobuff)
+		{
+			nd = npc_name2id("deathmatch_core");
+			if (nd && nd->subtype == NPCTYPE_SCRIPT)
+				run_script(nd->u.scr.script, 0, sd->bl.id, nd->bl.id);
+		}
+	}
+}
+
+static int pc_deathmatch_timer(int tid, unsigned int tick, int id, intptr_t data)
+{
+	struct map_session_data *sd = map_id2sd(id);
+	if( sd != NULL )
+	{
+		pc_deathmatch(sd, CLR_OUTSIGHT);
+		if (sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) )
+		{
+			map_pvp_area(sd, 1);
+			map[sd->bl.m].cell_pvpuser--;
+		}
+	}
+	return 0;
+}
+
 /*==========================================
  * Invoked when a player has received damage
  *------------------------------------------*/
@@ -7779,7 +7839,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 	}
 
 	if(battle_config.bone_drop==2
-		|| (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp))
+		|| (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp) || map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) && sd->state.pvp)
 	{
 		struct item item_tmp;
 		memset(&item_tmp,0,sizeof(item_tmp));
@@ -7852,6 +7912,12 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 				pc_payzeny(sd, zeny_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL);
 		}
 	}
+	// Addon Cell PVP [Napster]
+	if (map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP ) && battle_config.cellpvp_deathmatch && sd->state.pvp)
+	{
+		add_timer(tick+battle_config.cellpvp_deathmatch_delay, pc_deathmatch_timer, sd->bl.id, 0);
+		return 1|8;
+	}
 
 	if(map[sd->bl.m].flag.pvp_nightmaredrop) { // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker]
 		int j;
@@ -10152,6 +10218,14 @@ int pc_calc_pvprank(struct map_session_data *sd)
 
 	sd->pvp_rank=1;
 	map_foreachinmap(pc_calc_pvprank_sub,sd->bl.m,BL_PC,sd);
+
+	// Addon Cell PVP [Napster]
+	if( (old!=sd->pvp_rank || sd->pvp_lastusers!=m->cell_pvpuser) || sd->state.pvp ) 
+	{
+		clif_pvpset( sd, sd->pvp_rank, sd->pvp_lastusers = m->cell_pvpuser, 0);
+		return sd->pvp_rank;
+	}
+
 	if(old!=sd->pvp_rank || sd->pvp_lastusers!=m->users_pvp)
 		clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=m->users_pvp,0);
 	return sd->pvp_rank;
diff --git a/src/map/pc.h b/src/map/pc.h
index c8be94592..f6ecdeb60 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -268,6 +268,7 @@ struct map_session_data {
 		bool keepshop; // Whether shop data should be removed when the player disconnects
 		bool mail_writing; // Whether the player is currently writing a mail in RODEX or not
 		bool cashshop_open;
+		unsigned int pvp : 1;		// Addon Cell PVP [Napster]
 	} state;
 	struct {
 		unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
@@ -347,6 +348,7 @@ struct map_session_data {
 	unsigned int canskill_tick; // used to prevent abuse from no-delay ACT files
 	unsigned int cansendmail_tick; // [Mail System Flood Protection]
 	unsigned int ks_floodprotect_tick; // [Kill Steal Protection]
+	unsigned int pvpcan_walkout_tick;		// Addon Cell PVP [Napster]
 
 	struct s_item_delay {
 		unsigned short nameid;
diff --git a/src/map/script_constants.h b/src/map/script_constants.h
index 408f3ff64..6ddb844be 100644
--- a/src/map/script_constants.h
+++ b/src/map/script_constants.h
@@ -448,6 +448,7 @@
 	export_constant(CELL_NOCHAT);
 	export_constant(CELL_MAELSTROM);
 	export_constant(CELL_ICEWALL);
+	export_constant(CELL_PVP);
 
 	/* getcell types */
 	export_constant(CELL_CHKWALL);
@@ -466,7 +467,8 @@
 	export_constant(CELL_CHKNOCHAT);
 	export_constant(CELL_CHKMAELSTROM);
 	export_constant(CELL_CHKICEWALL);
-
+	export_constant(CELL_CHKPVP);
+	
 	/* parameters */
 	export_parameter("StatusPoint",SP_STATUSPOINT);
 	export_parameter("BaseLevel",SP_BASELEVEL);
diff --git a/src/map/skill.c b/src/map/skill.c
index 42d19eef9..789d8745f 100755
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -6976,8 +6976,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 
 	case MO_ABSORBSPIRITS:
 		i = 0;
-		if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m) || (sd && sd->duel_group && sd->duel_group == dstsd->duel_group)) &&
-			((dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK) != MAPID_REBELLION)) { // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen]
+		if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m) || (map_getcell(src->m,src->x,src->y,CELL_CHKPVP) && map_getcell(bl->m,bl->x,bl->y,CELL_CHKPVP)) || (sd && sd->duel_group && sd->duel_group == dstsd->duel_group)) && ((dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK) != MAPID_REBELLION)) { // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen]
 			if (dstsd->spiritball > 0) {
 				i = dstsd->spiritball * 7;
 				pc_delspiritball(dstsd,dstsd->spiritball,0);
diff --git a/src/map/unit.c b/src/map/unit.c
index ef713e1ed..879aef341 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -428,6 +428,12 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data
 			} else
 				sd->areanpc_id=0;
 			pc_cell_basilica(sd);
+
+			// Addon Cell PVP [Napster]
+			if( !sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+				map_pvp_area(sd, 1);
+			else if( sd->state.pvp && !map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+				map_pvp_area(sd, 0);
 			break;
 		case BL_MOB:
 			//Movement was successful, reset walktoxy_fail_count
@@ -648,6 +654,28 @@ int unit_walktoxy( struct block_list *bl, short x, short y, unsigned char flag)
 	if(!(flag&2) && (!status_bl_has_mode(bl,MD_CANMOVE) || !unit_can_move(bl)))
 		return 0;
 
+	// Addon Cell PVP [Napster]
+	if (bl->type == BL_PC)
+	{
+		struct map_session_data* sd = (TBL_PC*)bl;
+		unsigned int tick = gettick();
+
+		if (sd && sd->pvpcan_walkout_tick && !map_getcell( sd->bl.m, x, y, CELL_CHKPVP ) ) {
+			if ( DIFF_TICK(tick, sd->pvpcan_walkout_tick) < battle_config.cellpvp_walkout_delay )
+			{
+				int e_tick = (battle_config.cellpvp_walkout_delay - DIFF_TICK( tick, sd->pvpcan_walkout_tick))/1000;
+				char e_msg[150];
+				if( e_tick > 99 )
+						sprintf(e_msg, msg_txt(sd, 1599), sd->status.name, (double)e_tick / 60); 
+				else
+						sprintf(e_msg, msg_txt(sd, 1600), sd->status.name, e_tick+1);
+
+				clif_messagecolor(sd,color_table[COLOR_YELLOW], e_msg, false, SELF);
+				return 0;
+			}
+		}
+	}
+	
 	ud->state.walk_easy = flag&1;
 	ud->to_x = x;
 	ud->to_y = y;
@@ -959,7 +987,13 @@ bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, boo
 				return false;
 		} else
 			sd->areanpc_id=0;
-
+		
+		// Addon Cell PVP [Ize]
+		if( !sd->state.pvp && map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+			map_pvp_area(sd, 1);
+		else if( sd->state.pvp && !map_getcell( sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKPVP) )
+			map_pvp_area(sd, 0);
+		
 		if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 ) {
 			// Check if pet needs to be teleported. [Skotlex]
 			int flag = 0;
@@ -1302,6 +1336,17 @@ int unit_stop_walking(struct block_list *bl,int type)
  */
 int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv)
 {
+	// Addon Cell PVP [Napster]
+	struct block_list *bl = map_id2bl(target_id);	
+
+	if( bl && src->type == BL_PC && bl->type == BL_PC && src->id != target_id)
+	{
+		struct map_session_data *dstsd = (TBL_PC*)bl;
+
+		 if( dstsd && dstsd->state.pvp != ((TBL_PC*)src)->state.pvp )
+			 return 0;
+	}
+	
 	return unit_skilluse_id2(
 		src, target_id, skill_id, skill_lv,
 		skill_castfix(src, skill_id, skill_lv),

 

if necessary I can put my emulator on a github

 

this is a paid service and if you wish someone to update it for you personally, you had to negotiate with them or with the author of this mod.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.