Explorar o código

Small edits to battleground code (bugreport:2816)
- removed bg_idle_announce setting (could be considered later)
- moved crystal protection code to battle_calc_bg_damage
- removed mob state 'inmunity' in favor of a script-based solution
- removed unneeded 'setmobdata' (fixes collision with mob controller)
- added svn:eol-style native for battleground code

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13565 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage %!s(int64=16) %!d(string=hai) anos
pai
achega
9c6c292775
Modificáronse 11 ficheiros con 427 adicións e 493 borrados
  1. 0 3
      conf/battle/battleground.conf
  2. 13 20
      src/map/battle.c
  3. 0 1
      src/map/battle.h
  4. 354 362
      src/map/battleground.c
  5. 50 50
      src/map/battleground.h
  6. 8 6
      src/map/clif.c
  7. 0 1
      src/map/mob.h
  8. 0 22
      src/map/pc.c
  9. 0 2
      src/map/pc.h
  10. 0 23
      src/map/script.c
  11. 2 3
      src/map/skill.c

+ 0 - 3
conf/battle/battleground.conf

@@ -56,6 +56,3 @@ bg_guild_id2: 999
 // bgemblem_2.ebm (used for Prince Croix Marollo)
 // You can set your own emblems for battleground, using files from the _tmpEmblem folder
 // in your client files, just remember to keep the names.
-
-// If player is idle for N seconds it will be announced to all battle members in the same team.
-bg_idle_announce: 30

+ 13 - 20
src/map/battle.c

@@ -283,13 +283,6 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
 	if( mob_ksprotected(src, bl) )
 		return 0;
 
-	if( bl->type == BL_MOB )
-	{ // Event Emperiums works like GvG Emperiums
-		struct mob_data *md = BL_CAST(BL_MOB, bl);
-		if( map[bl->m].flag.battleground && (md->class_ == 1914 || md->class_ == 1915) && flag&BF_SKILL )
-			return 0; // Crystal Cannot receive magic damage on battlegrounds
-	}
-
 	if (bl->type == BL_PC) {
 		sd=(struct map_session_data *)bl;
 		//Special no damage states
@@ -536,7 +529,16 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
  *------------------------------------------*/
 int battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int damage, int div_, int skill_num, int skill_lv, int flag)
 {
-	if( !damage ) return 0;
+	if( !damage )
+		return 0;
+
+	if( bl->type == BL_MOB )
+	{
+		struct mob_data* md = BL_CAST(BL_MOB, bl);
+		if( map[bl->m].flag.battleground && (md->class_ == 1914 || md->class_ == 1915) && flag&BF_SKILL )
+			return 0; // Crystal cannot receive skill damage on battlegrounds
+	}
+
 	switch( skill_num )
 	{
 		case PA_PRESSURE:
@@ -572,17 +574,12 @@ int battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int dam
  *------------------------------------------*/
 int battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag)
 {
-	struct mob_data *md = NULL;
-	int class_;
+	struct mob_data* md = BL_CAST(BL_MOB, bl);
+	int class_ = status_get_class(bl);
 
 	if (!damage) //No reductions to make.
 		return 0;
 	
-	class_ = status_get_class(bl);
-
-	if (bl->type == BL_MOB)
-		md=(struct mob_data *)bl;
-
 	if(md && md->guardian_data) {
 		if(class_ == MOBID_EMPERIUM && flag&BF_SKILL)
 		//Skill immunity.
@@ -598,8 +595,7 @@ int battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int dama
 			if (!g) return 0;
 			if (class_ == MOBID_EMPERIUM && guild_checkskill(g,GD_APPROVAL) <= 0)
 				return 0;
-			if (battle_config.guild_max_castles &&
-				guild_checkcastles(g)>=battle_config.guild_max_castles)
+			if (battle_config.guild_max_castles && guild_checkcastles(g)>=battle_config.guild_max_castles)
 				return 0; // [MouseJstr]
 		}
 	}
@@ -3263,8 +3259,6 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
 
 			if( !((agit_flag || agit2_flag) && map[m].flag.gvg_castle) && md->guardian_data && md->guardian_data->guild_id )
 				return 0; // Disable guardians/emperiums owned by Guilds on non-woe times.
-			if( md->state.inmunity && flag&BCT_ENEMY )
-				return 0;
 			break;
 		}
 	}
@@ -3842,7 +3836,6 @@ static const struct _battle_data {
 	{ "bg_magic_attack_damage_rate",        &battle_config.bg_magic_damage_rate,            60,     0,      INT_MAX,        },
 	{ "bg_misc_attack_damage_rate",         &battle_config.bg_misc_damage_rate,             60,     0,      INT_MAX,        },
 	{ "bg_flee_penalty",                    &battle_config.bg_flee_penalty,                 20,     0,      INT_MAX,        },
-	{ "bg_idle_announce",                   &battle_config.bg_idle_announce,                0,      0,      INT_MAX,        },
 };
 
 

+ 0 - 1
src/map/battle.h

@@ -471,7 +471,6 @@ extern struct Battle_Config
 	int bg_magic_damage_rate;
 	int bg_misc_damage_rate;
 	int bg_flee_penalty;
-	int bg_idle_announce;
 } battle_config;
 
 void do_init_battle(void);

+ 354 - 362
src/map/battleground.c

@@ -1,362 +1,354 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#include "../common/cbasetypes.h"
-#include "../common/timer.h"
-#include "../common/malloc.h"
-#include "../common/nullpo.h"
-#include "../common/showmsg.h"
-#include "../common/socket.h"
-#include "../common/strlib.h"
-
-#include "battleground.h"
-#include "battle.h"
-#include "clif.h"
-#include "map.h"
-#include "npc.h"
-#include "pc.h"
-#include "pet.h"
-#include "homunculus.h"
-#include "mercenary.h"
-
-#include <string.h>
-#include <stdio.h>
-
-static DBMap* bg_team_db; // int bg_id -> struct battleground_data*
-static unsigned int bg_team_counter = 0; // Next bg_id
-struct guild bg_guild[2]; // Temporal fake guild information
-
-struct battleground_data* bg_team_search(int bg_id)
-{ // Search a BG Team using bg_id
-	if( !bg_id ) return NULL;
-	return (struct battleground_data *)idb_get(bg_team_db, bg_id);
-}
-
-struct map_session_data* bg_getavailablesd(struct battleground_data *bg)
-{
-	int i;
-	nullpo_retr(NULL, bg);
-	ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd != NULL);
-	return( i < MAX_BG_MEMBERS ) ? bg->members[i].sd : NULL;
-}
-
-int bg_team_delete(int bg_id)
-{ // Deletes BG Team from db
-	int i;
-	struct map_session_data *sd;
-	struct battleground_data *bg = bg_team_search(bg_id);
-	struct guild *g;
-
-	if( bg == NULL ) return 0;
-	for( i = 0; i < MAX_BG_MEMBERS; i++ )
-	{
-		if( (sd = bg->members[i].sd) == NULL )
-			continue;
-
-		bg_send_dot_remove(sd);
-		sd->state.bg_id = 0;
-		if( sd->status.guild_id && (g = guild_search(sd->status.guild_id)) != NULL )
-		{
-			clif_guild_belonginfo(sd,g);
-			clif_guild_basicinfo(sd);
-			clif_guild_allianceinfo(sd);
-			clif_guild_memberlist(sd);
-			clif_guild_skillinfo(sd);
-		}
-		else
-			clif_bg_leave_single(sd, sd->status.name, "Leaving Battleground...");
-
-		clif_charnameupdate(sd);
-		clif_guild_emblem_area(&sd->bl);
-	}
-	idb_remove(bg_team_db, bg_id);
-	return 1;
-}
-
-int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y)
-{ // Warps a Team
-	int i;
-	struct battleground_data *bg = bg_team_search(bg_id);
-	if( bg == NULL ) return 0;
-	for( i = 0; i < MAX_BG_MEMBERS; i++ )
-		if( bg->members[i].sd != NULL ) pc_setpos(bg->members[i].sd, mapindex, x, y, 3);
-	return 1;
-}
-
-int bg_send_dot_remove(struct map_session_data *sd)
-{
-	if( sd && sd->state.bg_id )
-		clif_bg_xy_remove(sd);
-	return 0;
-}
-
-int bg_team_join(int bg_id, struct map_session_data *sd)
-{ // Player joins team
-	int i;
-	struct battleground_data *bg = bg_team_search(bg_id);
-	struct map_session_data *pl_sd;
-
-	if( bg == NULL || sd == NULL || sd->state.bg_id ) return 0;
-
-	ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == NULL);
-	if( i == MAX_BG_MEMBERS ) return 0; // No free slots
-
-	sd->state.bg_id = bg_id;
-	bg->members[i].sd = sd;
-	bg->members[i].x = sd->bl.x;
-	bg->members[i].y = sd->bl.y;
-	bg->count++;
-
-	guild_send_dot_remove(sd);
-	clif_bg_belonginfo(sd);
-	// clif_bg_emblem(sd, bg->g);
-	clif_charnameupdate(sd);
-
-	for( i = 0; i < MAX_BG_MEMBERS; i++ )
-	{
-		if( (pl_sd = bg->members[i].sd) == NULL )
-			continue;
-		clif_guild_basicinfo(pl_sd);
-		clif_bg_emblem(pl_sd, bg->g);
-		clif_bg_memberlist(pl_sd);
-		if( pl_sd != sd )
-			clif_hpmeter_single(sd->fd, pl_sd->bl.id, pl_sd->battle_status.hp, pl_sd->battle_status.max_hp);
-	}
-
-	clif_guild_emblem_area(&sd->bl);
-	clif_bg_hp(sd);
-	clif_bg_xy(sd);
-
-	return 1;
-}
-
-int bg_team_leave(struct map_session_data *sd, int flag)
-{ // Single Player leaves team
-	int i, bg_id;
-	struct battleground_data *bg;
-	struct map_session_data *pl_sd;
-	struct guild *g;
-
-	if( sd == NULL || !sd->state.bg_id )
-		return 0;
-
-	// Packets
-	clif_bg_leave_single(sd, sd->status.name, "Leaving Battle...");
-	bg_send_dot_remove(sd);
-	bg_id = sd->state.bg_id;
-	sd->state.bg_id = 0;
-
-	if( sd->status.guild_id && (g = guild_search(sd->status.guild_id)) != NULL )
-	{ // Refresh Guild Information
-		clif_guild_belonginfo(sd, g);
-		clif_guild_basicinfo(sd);
-		clif_guild_allianceinfo(sd);
-		clif_guild_memberlist(sd);
-		clif_guild_skillinfo(sd);
-		clif_guild_emblem(sd, g);
-	}
-
-	clif_charnameupdate(sd);
-	clif_guild_emblem_area(&sd->bl);
-
-	if( (bg = bg_team_search(bg_id)) == NULL )
-		return 0;
-
-	ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == sd);
-	if( i < MAX_BG_MEMBERS ) // Removes member from BG
-		memset(&bg->members[i], 0, sizeof(bg->members[0]));
-
-	bg->count--;
-	for( i = 0; i < MAX_BG_MEMBERS; i++ )
-	{ // Update other BG members
-		if( (pl_sd = bg->members[i].sd) == NULL )
-			continue;
-		if( flag )
-			clif_bg_expulsion_single(pl_sd, sd->status.name, "User has quit the game...");
-		else
-			clif_bg_leave_single(pl_sd, sd->status.name, "Leaving Battle...");
-
-		clif_guild_basicinfo(pl_sd);
-		clif_bg_emblem(pl_sd, bg->g);
-		clif_bg_memberlist(pl_sd);
-	}
-
-	if( bg->logout_event[0] && flag )
-		npc_event(sd, bg->logout_event, 0);
-
-	return bg->count;
-}
-
-int bg_member_respawn(struct map_session_data *sd)
-{ // Respawn after killed
-	struct battleground_data *bg;
-	if( sd == NULL || !pc_isdead(sd) || !sd->state.bg_id || (bg = bg_team_search(sd->state.bg_id)) == NULL )
-		return 0;
-	if( bg->mapindex == 0 )
-		return 0; // Respawn not handled by Core
-	pc_setpos(sd, bg->mapindex, bg->x, bg->y, 0);
-	status_revive(&sd->bl, 1, 100);
-
-	return 1; // Warped
-}
-
-struct guild* bg_guild_get(int bg_id)
-{ // Return Fake Guild for BG Members
-	struct battleground_data *bg = bg_team_search(bg_id);
-	if( bg == NULL ) return NULL;
-	return bg->g;
-}
-
-int bg_create(unsigned short mapindex, short rx, short ry, int guild_index, const char *ev, const char *dev)
-{
-	struct battleground_data *bg;
-	bg_team_counter++;
-
-	CREATE(bg, struct battleground_data, 1);
-	bg->bg_id = bg_team_counter;
-	bg->count = 0;
-	bg->g = &bg_guild[guild_index];
-	bg->mapindex = mapindex;
-	bg->x = rx;
-	bg->y = ry;
-	safestrncpy(bg->logout_event, ev, sizeof(bg->logout_event));
-	safestrncpy(bg->die_event, dev, sizeof(bg->die_event));
-
-	memset(&bg->members, 0, sizeof(bg->members));
-	idb_put(bg_team_db, bg_team_counter, bg);
-
-	return bg->bg_id;
-}
-
-int bg_team_get_id(struct block_list *bl)
-{
-	nullpo_retr(0, bl);
-	switch( bl->type )
-	{
-		case BL_PC:
-			return ((TBL_PC*)bl)->state.bg_id;
-		case BL_PET:
-			if( ((TBL_PET*)bl)->msd )
-				return ((TBL_PET*)bl)->msd->state.bg_id;
-			break;
-		case BL_MOB:
-		{
-			struct map_session_data *msd;
-			struct mob_data *md = (TBL_MOB*)bl;
-			if( md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL )
-				return msd->state.bg_id;
-			return md->state.bg_id;
-		}
-		case BL_HOM:
-			if( ((TBL_HOM*)bl)->master )
-				return ((TBL_HOM*)bl)->master->state.bg_id;
-			break;
-		case BL_MER:
-			if( ((TBL_MER*)bl)->master )
-				return ((TBL_MER*)bl)->master->state.bg_id;
-			break;
-		case BL_SKILL:
-			return ((TBL_SKILL*)bl)->group->bg_id;
-	}
-
-	return 0;
-}
-
-int bg_send_message(struct map_session_data *sd, const char *mes, int len)
-{
-	struct battleground_data *bg;
-
-	nullpo_retr(0, sd);
-	if( sd->state.bg_id == 0 || (bg = bg_team_search(sd->state.bg_id)) == NULL )
-		return 0;
-	clif_bg_message(bg, sd->status.account_id, mes, len);
-	return 0;
-}
-
-int bg_send_xy_timer_sub(DBKey key, void *data, va_list ap)
-{
-	struct battleground_data *bg = (struct battleground_data *)data;
-	struct map_session_data *sd;
-	int i;
-	nullpo_retr(0, bg);
-	for( i = 0; i < MAX_BG_MEMBERS; i++ )
-	{
-		if( (sd = bg->members[i].sd) == NULL )
-			continue;
-		if( sd->bl.x != bg->members[i].x || sd->bl.y != bg->members[i].y )
-		{ // xy update
-			bg->members[i].x = sd->bl.x;
-			bg->members[i].y = sd->bl.y;
-			clif_bg_xy(sd);
-		}
-		if( battle_config.bg_idle_announce && !bg->members[i].afk && DIFF_TICK(last_tick, sd->idletime) >= battle_config.bg_idle_announce && bg->g )
-		{ // Idle announces
-			char output[128];
-			bg->members[i].afk = 1;
-			sprintf(output, "%s : %s seens to be away...", bg->g->name, sd->status.name);
-
-			clif_bg_message(bg, 0, output, strlen(output));
-		}
-	}
-	return 0;
-}
-
-int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr data)
-{
-	bg_team_db->foreach(bg_team_db, bg_send_xy_timer_sub, tick);
-	return 0;
-}
-
-void bg_guild_build_data(void)
-{
-	int i, j;
-	memset(&bg_guild, 0, sizeof(bg_guild));
-	for( i = 1; i <= 2; i++ )
-	{ // Emblem Data
-		FILE* fp = NULL;
-		char path[256];
-
-		j = i - 1;
-		sprintf(path, "%s/bgemblem_%d.ebm", db_path, i);
-		if( (fp = fopen(path, "rb")) == NULL )
-			continue;
-
-		bg_guild[j].emblem_id = 1;
-		fseek(fp, 0, SEEK_END);
-		bg_guild[j].emblem_len = ftell(fp);
-		fseek(fp, 0, SEEK_SET);
-		fread(&bg_guild[j].emblem_data, 1, bg_guild[j].emblem_len, fp);
-		fclose(fp);
-
-		ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"' emblem data file.\n", path);
-	}
-
-	// Guild Data - Guillaume
-	strncpy(bg_guild[0].name, "Blue Team", NAME_LENGTH);
-	strncpy(bg_guild[0].master, "General Guillaume Marollo", NAME_LENGTH);
-	bg_guild[0].guild_id = battle_config.bg_guild_id1;
-	bg_guild[0].guild_lv = 1;
-	strncpy(bg_guild[0].position[0].name, "Blue Team", NAME_LENGTH);
-	bg_guild[0].max_member = MAX_BG_MEMBERS;
-
-	// Guild Data - Croix
-	strncpy(bg_guild[1].name, "Red Team", NAME_LENGTH);
-	strncpy(bg_guild[1].master, "Prince Croix Marollo", NAME_LENGTH);
-	bg_guild[1].guild_id = battle_config.bg_guild_id2;
-	bg_guild[1].guild_lv = 1;
-	strncpy(bg_guild[1].position[0].name, "Red Team", NAME_LENGTH);
-	bg_guild[1].max_member = MAX_BG_MEMBERS;
-}
-
-void do_init_battleground(void)
-{
-	bg_team_db = idb_alloc(DB_OPT_RELEASE_DATA);
-	add_timer_func_list(bg_send_xy_timer, "bg_send_xy_timer");
-	add_timer_interval(gettick() + battle_config.bg_update_interval, bg_send_xy_timer, 0, 0, battle_config.bg_update_interval);
-	bg_guild_build_data();
-}
-
-void do_final_battleground(void)
-{
-	bg_team_db->destroy(bg_team_db, NULL);
-}
+// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#include "../common/cbasetypes.h"
+#include "../common/timer.h"
+#include "../common/malloc.h"
+#include "../common/nullpo.h"
+#include "../common/showmsg.h"
+#include "../common/socket.h"
+#include "../common/strlib.h"
+
+#include "battleground.h"
+#include "battle.h"
+#include "clif.h"
+#include "map.h"
+#include "npc.h"
+#include "pc.h"
+#include "pet.h"
+#include "homunculus.h"
+#include "mercenary.h"
+
+#include <string.h>
+#include <stdio.h>
+
+static DBMap* bg_team_db; // int bg_id -> struct battleground_data*
+static unsigned int bg_team_counter = 0; // Next bg_id
+struct guild bg_guild[2]; // Temporal fake guild information
+
+struct battleground_data* bg_team_search(int bg_id)
+{ // Search a BG Team using bg_id
+	if( !bg_id ) return NULL;
+	return (struct battleground_data *)idb_get(bg_team_db, bg_id);
+}
+
+struct map_session_data* bg_getavailablesd(struct battleground_data *bg)
+{
+	int i;
+	nullpo_retr(NULL, bg);
+	ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd != NULL);
+	return( i < MAX_BG_MEMBERS ) ? bg->members[i].sd : NULL;
+}
+
+int bg_team_delete(int bg_id)
+{ // Deletes BG Team from db
+	int i;
+	struct map_session_data *sd;
+	struct battleground_data *bg = bg_team_search(bg_id);
+	struct guild *g;
+
+	if( bg == NULL ) return 0;
+	for( i = 0; i < MAX_BG_MEMBERS; i++ )
+	{
+		if( (sd = bg->members[i].sd) == NULL )
+			continue;
+
+		bg_send_dot_remove(sd);
+		sd->state.bg_id = 0;
+		if( sd->status.guild_id && (g = guild_search(sd->status.guild_id)) != NULL )
+		{
+			clif_guild_belonginfo(sd,g);
+			clif_guild_basicinfo(sd);
+			clif_guild_allianceinfo(sd);
+			clif_guild_memberlist(sd);
+			clif_guild_skillinfo(sd);
+		}
+		else
+			clif_bg_leave_single(sd, sd->status.name, "Leaving Battleground...");
+
+		clif_charnameupdate(sd);
+		clif_guild_emblem_area(&sd->bl);
+	}
+	idb_remove(bg_team_db, bg_id);
+	return 1;
+}
+
+int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y)
+{ // Warps a Team
+	int i;
+	struct battleground_data *bg = bg_team_search(bg_id);
+	if( bg == NULL ) return 0;
+	for( i = 0; i < MAX_BG_MEMBERS; i++ )
+		if( bg->members[i].sd != NULL ) pc_setpos(bg->members[i].sd, mapindex, x, y, 3);
+	return 1;
+}
+
+int bg_send_dot_remove(struct map_session_data *sd)
+{
+	if( sd && sd->state.bg_id )
+		clif_bg_xy_remove(sd);
+	return 0;
+}
+
+int bg_team_join(int bg_id, struct map_session_data *sd)
+{ // Player joins team
+	int i;
+	struct battleground_data *bg = bg_team_search(bg_id);
+	struct map_session_data *pl_sd;
+
+	if( bg == NULL || sd == NULL || sd->state.bg_id ) return 0;
+
+	ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == NULL);
+	if( i == MAX_BG_MEMBERS ) return 0; // No free slots
+
+	sd->state.bg_id = bg_id;
+	bg->members[i].sd = sd;
+	bg->members[i].x = sd->bl.x;
+	bg->members[i].y = sd->bl.y;
+	bg->count++;
+
+	guild_send_dot_remove(sd);
+	clif_bg_belonginfo(sd);
+	// clif_bg_emblem(sd, bg->g);
+	clif_charnameupdate(sd);
+
+	for( i = 0; i < MAX_BG_MEMBERS; i++ )
+	{
+		if( (pl_sd = bg->members[i].sd) == NULL )
+			continue;
+		clif_guild_basicinfo(pl_sd);
+		clif_bg_emblem(pl_sd, bg->g);
+		clif_bg_memberlist(pl_sd);
+		if( pl_sd != sd )
+			clif_hpmeter_single(sd->fd, pl_sd->bl.id, pl_sd->battle_status.hp, pl_sd->battle_status.max_hp);
+	}
+
+	clif_guild_emblem_area(&sd->bl);
+	clif_bg_hp(sd);
+	clif_bg_xy(sd);
+
+	return 1;
+}
+
+int bg_team_leave(struct map_session_data *sd, int flag)
+{ // Single Player leaves team
+	int i, bg_id;
+	struct battleground_data *bg;
+	struct map_session_data *pl_sd;
+	struct guild *g;
+
+	if( sd == NULL || !sd->state.bg_id )
+		return 0;
+
+	// Packets
+	clif_bg_leave_single(sd, sd->status.name, "Leaving Battle...");
+	bg_send_dot_remove(sd);
+	bg_id = sd->state.bg_id;
+	sd->state.bg_id = 0;
+
+	if( sd->status.guild_id && (g = guild_search(sd->status.guild_id)) != NULL )
+	{ // Refresh Guild Information
+		clif_guild_belonginfo(sd, g);
+		clif_guild_basicinfo(sd);
+		clif_guild_allianceinfo(sd);
+		clif_guild_memberlist(sd);
+		clif_guild_skillinfo(sd);
+		clif_guild_emblem(sd, g);
+	}
+
+	clif_charnameupdate(sd);
+	clif_guild_emblem_area(&sd->bl);
+
+	if( (bg = bg_team_search(bg_id)) == NULL )
+		return 0;
+
+	ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == sd);
+	if( i < MAX_BG_MEMBERS ) // Removes member from BG
+		memset(&bg->members[i], 0, sizeof(bg->members[0]));
+
+	bg->count--;
+	for( i = 0; i < MAX_BG_MEMBERS; i++ )
+	{ // Update other BG members
+		if( (pl_sd = bg->members[i].sd) == NULL )
+			continue;
+		if( flag )
+			clif_bg_expulsion_single(pl_sd, sd->status.name, "User has quit the game...");
+		else
+			clif_bg_leave_single(pl_sd, sd->status.name, "Leaving Battle...");
+
+		clif_guild_basicinfo(pl_sd);
+		clif_bg_emblem(pl_sd, bg->g);
+		clif_bg_memberlist(pl_sd);
+	}
+
+	if( bg->logout_event[0] && flag )
+		npc_event(sd, bg->logout_event, 0);
+
+	return bg->count;
+}
+
+int bg_member_respawn(struct map_session_data *sd)
+{ // Respawn after killed
+	struct battleground_data *bg;
+	if( sd == NULL || !pc_isdead(sd) || !sd->state.bg_id || (bg = bg_team_search(sd->state.bg_id)) == NULL )
+		return 0;
+	if( bg->mapindex == 0 )
+		return 0; // Respawn not handled by Core
+	pc_setpos(sd, bg->mapindex, bg->x, bg->y, 0);
+	status_revive(&sd->bl, 1, 100);
+
+	return 1; // Warped
+}
+
+struct guild* bg_guild_get(int bg_id)
+{ // Return Fake Guild for BG Members
+	struct battleground_data *bg = bg_team_search(bg_id);
+	if( bg == NULL ) return NULL;
+	return bg->g;
+}
+
+int bg_create(unsigned short mapindex, short rx, short ry, int guild_index, const char *ev, const char *dev)
+{
+	struct battleground_data *bg;
+	bg_team_counter++;
+
+	CREATE(bg, struct battleground_data, 1);
+	bg->bg_id = bg_team_counter;
+	bg->count = 0;
+	bg->g = &bg_guild[guild_index];
+	bg->mapindex = mapindex;
+	bg->x = rx;
+	bg->y = ry;
+	safestrncpy(bg->logout_event, ev, sizeof(bg->logout_event));
+	safestrncpy(bg->die_event, dev, sizeof(bg->die_event));
+
+	memset(&bg->members, 0, sizeof(bg->members));
+	idb_put(bg_team_db, bg_team_counter, bg);
+
+	return bg->bg_id;
+}
+
+int bg_team_get_id(struct block_list *bl)
+{
+	nullpo_retr(0, bl);
+	switch( bl->type )
+	{
+		case BL_PC:
+			return ((TBL_PC*)bl)->state.bg_id;
+		case BL_PET:
+			if( ((TBL_PET*)bl)->msd )
+				return ((TBL_PET*)bl)->msd->state.bg_id;
+			break;
+		case BL_MOB:
+		{
+			struct map_session_data *msd;
+			struct mob_data *md = (TBL_MOB*)bl;
+			if( md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL )
+				return msd->state.bg_id;
+			return md->state.bg_id;
+		}
+		case BL_HOM:
+			if( ((TBL_HOM*)bl)->master )
+				return ((TBL_HOM*)bl)->master->state.bg_id;
+			break;
+		case BL_MER:
+			if( ((TBL_MER*)bl)->master )
+				return ((TBL_MER*)bl)->master->state.bg_id;
+			break;
+		case BL_SKILL:
+			return ((TBL_SKILL*)bl)->group->bg_id;
+	}
+
+	return 0;
+}
+
+int bg_send_message(struct map_session_data *sd, const char *mes, int len)
+{
+	struct battleground_data *bg;
+
+	nullpo_retr(0, sd);
+	if( sd->state.bg_id == 0 || (bg = bg_team_search(sd->state.bg_id)) == NULL )
+		return 0;
+	clif_bg_message(bg, sd->status.account_id, mes, len);
+	return 0;
+}
+
+int bg_send_xy_timer_sub(DBKey key, void *data, va_list ap)
+{
+	struct battleground_data *bg = (struct battleground_data *)data;
+	struct map_session_data *sd;
+	int i;
+	nullpo_retr(0, bg);
+	for( i = 0; i < MAX_BG_MEMBERS; i++ )
+	{
+		if( (sd = bg->members[i].sd) == NULL )
+			continue;
+		if( sd->bl.x != bg->members[i].x || sd->bl.y != bg->members[i].y )
+		{ // xy update
+			bg->members[i].x = sd->bl.x;
+			bg->members[i].y = sd->bl.y;
+			clif_bg_xy(sd);
+		}
+	}
+	return 0;
+}
+
+int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr data)
+{
+	bg_team_db->foreach(bg_team_db, bg_send_xy_timer_sub, tick);
+	return 0;
+}
+
+void bg_guild_build_data(void)
+{
+	int i, j;
+	memset(&bg_guild, 0, sizeof(bg_guild));
+	for( i = 1; i <= 2; i++ )
+	{ // Emblem Data
+		FILE* fp = NULL;
+		char path[256];
+
+		j = i - 1;
+		sprintf(path, "%s/bgemblem_%d.ebm", db_path, i);
+		if( (fp = fopen(path, "rb")) == NULL )
+			continue;
+
+		bg_guild[j].emblem_id = 1;
+		fseek(fp, 0, SEEK_END);
+		bg_guild[j].emblem_len = ftell(fp);
+		fseek(fp, 0, SEEK_SET);
+		fread(&bg_guild[j].emblem_data, 1, bg_guild[j].emblem_len, fp);
+		fclose(fp);
+
+		ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"' emblem data file.\n", path);
+	}
+
+	// Guild Data - Guillaume
+	strncpy(bg_guild[0].name, "Blue Team", NAME_LENGTH);
+	strncpy(bg_guild[0].master, "General Guillaume Marollo", NAME_LENGTH);
+	bg_guild[0].guild_id = battle_config.bg_guild_id1;
+	bg_guild[0].guild_lv = 1;
+	strncpy(bg_guild[0].position[0].name, "Blue Team", NAME_LENGTH);
+	bg_guild[0].max_member = MAX_BG_MEMBERS;
+
+	// Guild Data - Croix
+	strncpy(bg_guild[1].name, "Red Team", NAME_LENGTH);
+	strncpy(bg_guild[1].master, "Prince Croix Marollo", NAME_LENGTH);
+	bg_guild[1].guild_id = battle_config.bg_guild_id2;
+	bg_guild[1].guild_lv = 1;
+	strncpy(bg_guild[1].position[0].name, "Red Team", NAME_LENGTH);
+	bg_guild[1].max_member = MAX_BG_MEMBERS;
+}
+
+void do_init_battleground(void)
+{
+	bg_team_db = idb_alloc(DB_OPT_RELEASE_DATA);
+	add_timer_func_list(bg_send_xy_timer, "bg_send_xy_timer");
+	add_timer_interval(gettick() + battle_config.bg_update_interval, bg_send_xy_timer, 0, 0, battle_config.bg_update_interval);
+	bg_guild_build_data();
+}
+
+void do_final_battleground(void)
+{
+	bg_team_db->destroy(bg_team_db, NULL);
+}

+ 50 - 50
src/map/battleground.h

@@ -1,50 +1,50 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
-
-#ifndef _BATTLEGROUND_H_
-#define _BATTLEGROUND_H_
-
-#include "../common/mmo.h" // struct party
-#include "guild.h"
-
-#define MAX_BG_MEMBERS 30
-
-struct battleground_member_data {
-	unsigned short x, y;
-	struct map_session_data *sd;
-	unsigned afk : 1;
-};
-
-struct battleground_data {
-	unsigned int bg_id;
-	unsigned char count;
-	struct battleground_member_data members[MAX_BG_MEMBERS];
-	// Fake Guild Link
-	struct guild *g;
-	// BG Cementery
-	unsigned short mapindex, x, y;
-	// Logout Event
-	char logout_event[50];
-	char die_event[50];
-};
-
-extern struct guild bg_guild[];
-
-void do_init_battleground(void);
-void do_final_battleground(void);
-
-struct battleground_data* bg_team_search(int bg_id);
-struct guild* bg_guild_get(int bg_id);
-int bg_send_dot_remove(struct map_session_data *sd);
-int bg_team_get_id(struct block_list *bl);
-struct map_session_data* bg_getavailablesd(struct battleground_data *bg);
-
-int bg_create(unsigned short mapindex, short rx, short ry, int guild_index, const char *ev, const char *dev);
-int bg_team_join(int bg_id, struct map_session_data *sd);
-int bg_team_delete(int bg_id);
-int bg_team_leave(struct map_session_data *sd, int flag);
-int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y);
-int bg_member_respawn(struct map_session_data *sd);
-int bg_send_message(struct map_session_data *sd, const char *mes, int len);
-
-#endif /* _BATTLEGROUND_H_ */
+// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#ifndef _BATTLEGROUND_H_
+#define _BATTLEGROUND_H_
+
+#include "../common/mmo.h" // struct party
+#include "guild.h"
+
+#define MAX_BG_MEMBERS 30
+
+struct battleground_member_data {
+	unsigned short x, y;
+	struct map_session_data *sd;
+	unsigned afk : 1;
+};
+
+struct battleground_data {
+	unsigned int bg_id;
+	unsigned char count;
+	struct battleground_member_data members[MAX_BG_MEMBERS];
+	// Fake Guild Link
+	struct guild *g;
+	// BG Cementery
+	unsigned short mapindex, x, y;
+	// Logout Event
+	char logout_event[50];
+	char die_event[50];
+};
+
+extern struct guild bg_guild[];
+
+void do_init_battleground(void);
+void do_final_battleground(void);
+
+struct battleground_data* bg_team_search(int bg_id);
+struct guild* bg_guild_get(int bg_id);
+int bg_send_dot_remove(struct map_session_data *sd);
+int bg_team_get_id(struct block_list *bl);
+struct map_session_data* bg_getavailablesd(struct battleground_data *bg);
+
+int bg_create(unsigned short mapindex, short rx, short ry, int guild_index, const char *ev, const char *dev);
+int bg_team_join(int bg_id, struct map_session_data *sd);
+int bg_team_delete(int bg_id);
+int bg_team_leave(struct map_session_data *sd, int flag);
+int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y);
+int bg_member_respawn(struct map_session_data *sd);
+int bg_send_message(struct map_session_data *sd, const char *mes, int len);
+
+#endif /* _BATTLEGROUND_H_ */

+ 8 - 6
src/map/clif.c

@@ -5639,6 +5639,7 @@ int clif_hpmeter(struct map_session_data *sd)
 		WBUFW(buf,8) = sd->battle_status.max_hp;
 	}
 
+	//TODO: replace with map_foreachinarea?
 	for( i = 0; i < fd_max; i++ )
 	{
 		if( session[i] && session[i]->func_parse == clif_parse && (sd2 = (struct map_session_data*)session[i]->session_data) && sd != sd2 && sd2->state.active )
@@ -7918,7 +7919,8 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 		clif_party_hp(sd); // Show hp after displacement [LuzZza]
 	}
 
-	if( sd->state.bg_id ) clif_bg_hp(sd); // BattleGround System
+	if( sd->state.bg_id )
+		clif_bg_hp(sd); // BattleGround System
 
 	if(map[sd->bl.m].flag.pvp) {
 		if(!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris]
@@ -8202,7 +8204,7 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
 	y = ((RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]+1) & 0x3f) << 4) +
 		(RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0] + 2) >> 4);
 	//Set last idle time... [Skotlex]
-	pc_update_last_action(sd);
+	sd->idletime = last_tick;
 	
 	unit_walktoxy(&sd->bl, x, y, 4);
 }
@@ -8494,7 +8496,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
 		}
 
 		pc_delinvincibletimer(sd);
-		pc_update_last_action(sd);
+		sd->idletime = last_tick;
 		unit_attack(&sd->bl, target_id, action_type != 0);
 	break;
 	case 0x02: // sitdown
@@ -8854,7 +8856,7 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd)
 	pc_delinvincibletimer(sd);
 
 	//Whether the item is used or not is irrelevant, the char ain't idle. [Skotlex]
-	pc_update_last_action(sd);
+	sd->idletime = last_tick;
 	n = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
 	
 	if(n <0 || n >= MAX_INVENTORY)
@@ -9367,7 +9369,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
 	}
 
 	// Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
-	pc_update_last_action(sd);
+	sd->idletime = last_tick;
 
 	if( pc_cant_act(sd) )
 		return;
@@ -9493,7 +9495,7 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, short skil
 	}
 
 	//Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
-	pc_update_last_action(sd);
+	sd->idletime = last_tick;
 
 	if( skillnotok(skillnum, sd) )
 		return;

+ 0 - 1
src/map/mob.h

@@ -112,7 +112,6 @@ struct mob_data {
 		int provoke_flag; // Celest
 		unsigned npc_killmonster: 1; //for new killmonster behavior
 		unsigned rebirth: 1; // NPC_Rebirth used
-		unsigned inmunity: 1; // Monster Cannot be attacked
 		unsigned int bg_id; // BattleGround System
 	} state;
 	struct guardian_data* guardian_data; 

+ 0 - 22
src/map/pc.c

@@ -82,28 +82,6 @@ int pc_class2idx(int class_) {
 	return class_;
 }
 
-void pc_update_last_action(struct map_session_data *sd)
-{
-	struct battleground_data *bg;
-	int i;
-
-	sd->idletime = last_tick;
-	if( sd->state.bg_id && (bg = bg_team_search(sd->state.bg_id)) != NULL )
-	{ // Update Battleground Idle Timer
-		ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == sd);
-		if( i == MAX_BG_MEMBERS)
-			return;
-
-		if( bg->members[i].afk && bg->g )
-		{
-			char output[128];
-			sprintf(output, "%s : %s is no longer away...", bg->g->name, sd->status.name);
-			clif_bg_message(bg, 0, output, strlen(output));
-			bg->members[i].afk = 0;
-		}
-	}
-}
-
 int pc_isGM(struct map_session_data* sd)
 {
 	return sd->gmlevel;

+ 0 - 2
src/map/pc.h

@@ -716,8 +716,6 @@ extern int night_timer_tid;
 int map_day_timer(int tid, unsigned int tick, int id, intptr data); // by [yor]
 int map_night_timer(int tid, unsigned int tick, int id, intptr data); // by [yor]
 
-void pc_update_last_action(struct map_session_data *sd);
-
 // Rental System
 void pc_inventory_rentals(struct map_session_data *sd);
 int pc_inventory_rental_clear(struct map_session_data *sd);

+ 0 - 23
src/map/script.c

@@ -13437,28 +13437,6 @@ BUILDIN_FUNC(bg_monster)
 	return 0;
 }
 
-BUILDIN_FUNC(setmobdata)
-{
-	struct mob_data *md;
-	struct block_list *mbl;
-	int id = script_getnum(st,2),
-		type = script_getnum(st,3),
-		value = script_getnum(st,4);
-
-	if( (mbl = map_id2bl(id)) == NULL || mbl->type != BL_MOB )
-		return 0;
-	md = (TBL_MOB *)mbl;
-	switch( type )
-	{
-		case 0: md->state.inmunity = value > 0 ? 1 : 0; break;
-		default:
-			ShowError("script:setmobdata: unknown data identifier %d\n", type);
-			return 1;
-	}
-
-	return 0;
-}
-
 BUILDIN_FUNC(bg_leave)
 {
 	struct map_session_data *sd = script_rid2sd(st);
@@ -13901,7 +13879,6 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(bg_leave,""),
 	BUILDIN_DEF(bg_destroy,"i"),
 	BUILDIN_DEF(areapercentheal,"siiiiii"),
-	BUILDIN_DEF(setmobdata,"iii"),
 	BUILDIN_DEF(bg_get_data,"ii"),
 	BUILDIN_DEF(bg_getareausers,"isiiii"),
 	{NULL,NULL,NULL},

+ 2 - 3
src/map/skill.c

@@ -2983,10 +2983,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			int heal = skill_calc_heal(src, bl, skilllv);
 			int heal_get_jobexp;
 	
-			if( status_isimmune(bl) )
+			if( status_isimmune(bl) || (dstmd && (dstmd->class_ == MOBID_EMPERIUM || mob_is_battleground(dstmd))) )
 				heal=0;
-			if( dstmd && (dstmd->class_ == MOBID_EMPERIUM || mob_is_battleground(dstmd)) )
-				heal=0; // Emperium - BattleGround Mobs cannot be Healed
+
 			if( sd )
 			{
 				if( (i = pc_skillheal_bonus(sd, skillid)) )