Jump to content

MikZ

Members
  • Content Count

    461
  • Joined

  • Last visited

Posts posted by MikZ


  1. On 6/25/2018 at 1:38 AM, Rebel said:

    Do you mind posting the script?

    I'm using the same script in Hercules trunk.
    Here:

    //===== Hercules Script ======================================
    //= Warper
    //===== By: ==================================================
    //= Euphy
    //===== Current Version: =====================================
    //= 1.4b
    //===== Description: =========================================
    //= A complete - but very condensed - warper script.
    //= Some coordinates written by Tekno-Kanix and ToastOfDoom.
    //===== Additional Comments: =================================
    //= 1.0 Initial script.
    //= 1.1 Added missing duplicates and fixed coordinates.
    //= 1.2 Added new episodes and simplified functions.
    //= 1.3 Added Renewal checks and Instances menu.
    //=     Aligned coordinates with @go.
    //= 1.4 Added new Guild Dungeons.
    //= 1.4a Slight edits.
    //= 1.4b Added Wolfchev's Laboratory warp.
    //============================================================
    
    -	script	Warper	FAKE_NPC,{
    function Go; function Disp; function Pick; function Restrict;
    
    // --------------------------------------------------
    //	Main Menu:
    // --------------------------------------------------
    
    menu	"Last Warp ^777777["+lastwarp$+"]^000000",-,
    		" ~ Towns",Towns,
    		" ~ Fields",Fields,
    		" ~ Dungeons",Dungeons,
    		" ~ Guild Castles",Castles,
    		" ~ Guild Dungeons",Guild_Dungeons,
    		" ~ Instances",Instances,
    		" ~ Special Areas",Special;
    
    	if (lastwarp$ == "")
    		message strcharinfo(PC_NAME),"You haven't warped anywhere yet.";
    	else
    		warp lastwarp$,lastwarpx,lastwarpy;
    	end;
    
    // ------------------- Functions -------------------
    // * Go("<map>",<x>,<y>);
    //	~ Warps directly to a map.
    //
    // * Disp("<Menu Option>",<first option>,<last option>);
    // * Pick("<map_prefix>"{,<index offset>});
    //	~ Dynamic menu and map selection (auto-numbered).
    //
    // * Disp("<Option 1>:<Option 2>:<etc.>");
    // * Pick("","<map1>","<map2>","<etc.>");
    //	~ Manual menu and map selection (listed).
    //
    // * Restrict("<RE | Pre-RE>"{,<menu option numbers>});
    //	~ Only allows map for Renewal or Pre-Renewal modes.
    //     If menu option numbers are given, only those maps
    //     will be restricted (i.e. not for "Go").
    //
    // Other notes:
    //   ~ Array @c[] holds all (x,y) coordinates.
    //   ~ Use @c[2] EXCEPT when maps begin dynamically
    //	  at 0: use @c[0] and Pick() offset 1.
    // --------------------------------------------------
    
    function Go {
    	lastwarp$ = getarg(0);
    	lastwarpx = getarg(1,0);
    	lastwarpy = getarg(2,0);
    	warp getarg(0),getarg(1,0),getarg(2,0);
    	end;
    }
    function Disp {
    	if (getargcount() < 3)
    		@menu$ = getarg(0);
    	else {
    		@menu$ = "";
    		for (.@i = getarg(1); .@i <= getarg(2); .@i++)
    			@menu$ = @menu$+getarg(0)+" "+.@i+":";
    	}
    	return;
    }
    function Pick {
    	.@warp_block = @warp_block;
    	@warp_block = 0;
    	.@select = select(@menu$);
    	if (getarg(0) == "") {
    		.@i = .@select;
    		.@map$ = getarg(.@i);
    	} else {
    		.@i = .@select-getarg(1,0);
    		.@map$ = getarg(0)+((.@i<10)?"0":"")+.@i;
    	}
    	if (.@warp_block & (1<<.@select)) {
    		message strcharinfo(PC_NAME),"This map is not enabled in "+(RENEWAL?"":"Pre-")+"Renewal.";
    		end;
    	}
    	.@x = @c[.@i*2];
    	.@y = @c[.@i*2+1];
    	deletearray @c[0],getarraysize(@c);
    	Go(.@map$,.@x,.@y);
    }
    function Restrict {
    	if ((getarg(0) == "RE" && !RENEWAL) || (getarg(0) == "Pre-RE" && RENEWAL)) {
    		if (getarg(1,0)) {
    			@warp_block = 0;
    			for (.@i = 1; .@i < getargcount(); .@i++)
    				@warp_block = @warp_block | (1<<getarg(.@i));
    		} else {
    			message strcharinfo(PC_NAME),"This map is not enabled in "+(RENEWAL?"":"Pre-")+"Renewal.";
    			end;
    		}
    	}
    	return;
    }
    
    // --------------------------------------------------
    	Towns:
    // --------------------------------------------------
    menu	"Prontera",T1, "Alberta",T2, "Aldebaran",T3, "Amatsu",T4, "Ayothaya",T5,
    		"Brasilis",T6, "Comodo",T7, "Dewata",T8, "Eclage",T9, "Einbech",T10,
    		"Einbroch",T11, "El Dicastes",T12, "Geffen",T13, "Gonryun",T14, "Hugel",T15,
    		"Izlude",T16, "Jawaii",T17, "Lighthalzen",T18, "Louyang",T19, "Lutie",T20,
    		"Malangdo",T21, "Malaya",T22, "Manuk",T23, "Midgarts Expedition Camp",T24,
    		"Mora",T25, "Morroc",T26, "Moscovia",T27, "Nameless Island",T28,
    		"Niflheim",T29, "Payon",T30, "Rachel",T31, "Splendide",T32, "Thor Camp",T33,
    		"Umbala",T34, "Veins",T35, "Yuno",T36;
    
    T1: Go("prontera",155,183);
    T2: Go("alberta",28,234);
    T3: Go("aldebaran",140,131);
    T4: Go("amatsu",198,84);
    T5: Go("ayothaya",208,166);
    T6: Restrict("RE");
    	Go("brasilis",196,217);
    T7: Go("comodo",209,143);
    T8: Restrict("RE");
    	Go("dewata",200,180);
    T9: Restrict("RE");
    	Go("ecl_in01",48,53);
    T10: Go("einbech",63,35);
    T11: Go("einbroch",64,200);
    T12: Restrict("RE");
    	 Go("dicastes01",198,187);
    T13: Go("geffen",119,59);
    T14: Go("gonryun",160,120);
    T15: Go("hugel",96,145);
    T16: Go("izlude",128,(RENEWAL?146:114));
    T17: Go("jawaii",251,132);
    T18: Go("lighthalzen",158,92);
    T19: Go("louyang",217,100);
    T20: Go("xmas",147,134);
    T21: Restrict("RE");
    	 Go("malangdo",140,114);
    T22: Restrict("RE");
    	 Go("malaya",231,200);
    T23: Go("manuk",282,138);
    T24: Go("mid_camp",210,288);
    T25: Restrict("RE");
    	 Go("mora",55,146);
    T26: Go("morocc",156,93);
    T27: Go("moscovia",223,184);
    T28: Go("nameless_n",256,215);
    T29: Go("niflheim",202,174);
    T30: Go("payon",179,100);
    T31: Go("rachel",130,110);
    T32: Go("splendide",201,147);
    T33: Go("thor_camp",246,68);
    T34: Go("umbala",97,153);
    T35: Go("veins",216,123);
    T36: Go("yuno",157,51);
    
    // --------------------------------------------------
    	Fields:
    // --------------------------------------------------
    menu	"Amatsu Fields",F1, "Ayothaya Fields",F2, "Bifrost Fields", F3,
    		"Brasilis Fields",F4, "Comodo Fields",F5, "Dewata Fields",F6,
    		"Eclage Fields",F7, "Einbroch Fields",F8, "El Dicastes Fields",F9,
    		"Geffen Fields",F10, "Gonryun Fields",F11, "Hugel Fields",F12,
    		"Lighthalzen Fields",F13, "Louyang Field",F14, "Lutie Field",F15,
    		"Malaya Fields",F16, "Manuk Fields",F17, "Mjolnir Fields",F18,
    		"Moscovia Fields",F19, "Niflheim Fields",F20, "Payon Forests",F21,
    		"Prontera Fields",F22, "Rachel Fields",F23, "Sograt Deserts",F24,
    		"Splendide Fields",F25, "Umbala Fields",F26, "Veins Fields",F27,
    		"Yuno Fields",F28;
    
    F1: setarray @c[2],190,197;
    	Disp("Amatsu Field",1,1); Pick("ama_fild");
    F2: setarray @c[2],173,134,212,150;
    	Disp("Ayothaya Field",1,2); Pick("ayo_fild");
    F3: Restrict("RE");
    	setarray @c[2],193,220,220,187;
    	Disp("Bifrost Field",1,2); Pick("bif_fild");
    F4: Restrict("RE");
    	setarray @c[2],74,32;
    	Disp("Brasilis Field",1,1); Pick("bra_fild");
    F5: Restrict("Pre-RE",5);
    	setarray @c[2],180,178,231,160,191,172,228,194,224,203,190,223,234,177,194,175,172,172;
    	Disp("Comodo Field",1,9); Pick("cmd_fild");
    F6: Restrict("RE");
    	setarray @c[2],371,212;
    	Disp("Dewata Field",1,1); Pick("dew_fild");
    F7: Restrict("RE");
    	setarray @c[2],97,314;
    	Disp("Eclage Field",1,1); Pick("ecl_fild");
    F8: Restrict("Pre-RE",2,10);
    	setarray @c[2],142,225,182,141,187,228,185,173,216,173,195,148,272,220,173,214,207,174,196,200;
    	Disp("Einbroch Field",1,10); Pick("ein_fild");
    F9: Restrict("RE");
    	setarray @c[2],143,132,143,217;
    	Disp("El Dicastes Field",1,2); Pick("dic_fild");
    F10: Restrict("Pre-RE",13,15);
    	 setarray @c[0],46,199,213,204,195,212,257,192,188,171,166,263,248,158,195,191,186,183,221,117,178,218,136,328,240,181,235,235,211,185;
    	 Disp("Geffen Field",0,14); Pick("gef_fild",1);
    F11: setarray @c[2],220,227;
    	 Disp("Gonryun Field",1,1); Pick("gon_fild");
    F12: Restrict("Pre-RE",3,7);
    	 setarray @c[2],268,101,222,193,232,185,252,189,196,106,216,220,227,197;
    	 Disp("Hugel Field",1,7); Pick("hu_fild");
    F13: setarray @c[2],240,179,185,235,240,226;
    	 Disp("Lighthalzen Field",1,3); Pick("lhz_fild");
    F14: setarray @c[2],229,187;
    	 Disp("Louyang Field",1,1); Pick("lou_fild");
    F15: setarray @c[2],115,145;
    	 Disp("Lutie Field",1,1); Pick("xmas_fild");
    F16: Restrict("RE");
    	 setarray @c[2],40,272,207,180;
    	 Disp("Malaya Field",1,2); Pick("ma_fild");
    F17: setarray @c[2],35,236,35,262,84,365;
    	 Disp("Manuk Field",1,3); Pick("man_fild");
    F18: setarray @c[2],204,120,175,193,208,213,179,180,181,240,195,270,235,202,188,215,205,144,245,223,180,206,196,208;
    	 Disp("Mjolnir Field",1,12); Pick("mjolnir_");
    F19: setarray @c[2],82,104,131,147;
    	 Disp("Moscovia Field",1,2); Pick("mosk_fild");
    F20: setarray @c[2],215,229,167,234;
    	 Disp("Niflheim Field",1,2); Pick("nif_fild");
    F21: Restrict("Pre-RE",5,11);
    	 setarray @c[2],158,206,151,219,205,148,186,247,134,204,193,235,200,177,137,189,201,224,160,205,194,150;
    	 Disp("Payon Forest",1,11); Pick("pay_fild");
    F22: setarray @c[0],208,227,190,206,240,206,190,143,307,252,239,213,185,188,193,194,187,218,210,183,195,149,198,164;
    	 Disp("Prontera Field",0,11); Pick("prt_fild",1);
    F23: Restrict("Pre-RE",2,7,9,10,11,13);
    	 setarray @c[2],192,162,235,166,202,206,202,208,225,202,202,214,263,196,217,201,87,121,277,181,221,185,175,200,174,197;
    	 Disp("Rachel Field",1,13); Pick("ra_fild");
    F24: setarray @c[2],219,205,177,206,194,182,224,170,198,216,156,187,185,263,206,228,208,238,209,223,85,97,207,202,31,195,38,195;
    	 Disp("Sograt Desert 1:Sograt Desert 2:Sograt Desert 3:Sograt Desert 7:Sograt Desert 11:Sograt Desert 12:Sograt Desert 13:Sograt Desert 16:Sograt Desert 17:Sograt Desert 18:Sograt Desert 19:Sograt Desert 20:Sograt Desert 21:Sograt Desert 22");
    	 Pick("","moc_fild01","moc_fild02","moc_fild03","moc_fild07","moc_fild11","moc_fild12","moc_fild13","moc_fild16","moc_fild17","moc_fild18","moc_fild19","moc_fild20","moc_fild21","moc_fild22");
    F25: setarray @c[2],175,186,236,184,188,204;
    	 Disp("Splendide Field",1,3); Pick("spl_fild");
    F26: setarray @c[2],217,206,223,221,237,215,202,197;
    	 Disp("Umbala Field",1,4); Pick("um_fild");
    F27: Restrict("Pre-RE",5);
    	 setarray @c[2],186,175,196,370,222,45,51,250,202,324,150,223,149,307;
    	 Disp("Veins Field",1,7); Pick("ve_fild");
    F28: Restrict("Pre-RE",5,10);
    	 setarray @c[2],189,224,192,207,221,157,226,199,223,177,187,232,231,174,196,203,183,214,200,124,195,226,210,304;
    	 Disp("Yuno Field",1,12); Pick("yuno_fild");
    
    // --------------------------------------------------
    	Dungeons:
    // --------------------------------------------------
    menu	"Abyss Lakes",D1, "Amatsu Dungeon",D2, "Anthell",D3,
    		"Ayothaya Dungeon",D4, "Beach Dungeon",D5, "Bifrost Tower",D41,
    		"Bio Labs",D6, "Brasilis Dungeon",D7, "Byalan Dungeon",D8, "Clock Tower",D9,
    		"Coal Mines",D10, "Culvert",D11, "Cursed Abbey",D12, "Dewata Dungeon",D13,
    		"Einbroch Dungeon",D14, "Gefenia",D15, "Geffen Dungeon",D16,
    		"Glast Heim",D17, "Gonryun Dungeon",D18, "Hidden Dungeon",D19,
    		"Ice Dungeon",D20, "Juperos",D21, "Kiel Dungeon",D22, "Louyang Dungeon",D23,
    		"Magma Dungeon",D24, "Malangdo Dungeon",D25, "Moscovia Dungeon",D26,
    		"Nidhogg's Dungeon",D27, "Odin Temple",D28, "Orc Dungeon",D29,
    		"Payon Dungeon",D30, "Pyramids",D31, "Rachel Sanctuary",D32,
    		"Scaraba Hole",D33, "Sphinx",D34, "Sunken Ship",D35, "Thanatos Tower",D36,
    		"Thor Volcano",D37, "Toy Factory",D38, "Turtle Dungeon",D39, "Umbala Dungeon",D40;
    
    D1: setarray @c[2],261,272,275,270,116,27;
    	Disp("Abyss Lakes",1,3); Pick("abyss_");
    D2: setarray @c[2],228,11,34,41,119,14;
    	Disp("Amatsu Dungeon",1,3); Pick("ama_dun");
    D3: setarray @c[2],35,262,168,170;
    	Disp("Anthell",1,2); Pick("anthell");
    D4: setarray @c[2],275,19,24,26;
    	Disp("Ancient Shrine Maze:Inside Ancient Shrine"); Pick("ayo_dun");
    D5: setarray @c[2],266,67,255,244,23,260;
    	Disp("Beach Dungeon",1,3); Pick("","beach_dun","beach_dun2","beach_dun3");
    D6: Restrict("RE",4);
    	setarray @c[2],150,288,150,18,140,134,244,52;
    	Disp("Bio Lab",1,4); Pick("lhz_dun");
    D7: Restrict("RE");
    	setarray @c[2],87,47,262,262;
    	Disp("Brasilis Dungeon",1,2); Pick("bra_dun");
    D8: Restrict("RE",6);
    	setarray @c[0],168,168,253,252,236,204,32,63,26,27,141,187;
    	Disp("Byalan Dungeon",1,6); Pick("iz_dun",1);
    D9: setarray @c[2],199,159,148,283,65,147,56,155,297,25,127,169,277,178,268,74;
    	Disp("Clock Tower 1:Clock Tower 2:Clock Tower 3:Clock Tower 4:Basement 1:Basement 2:Basement 3:Basement 4");
    	Pick("","c_tower1","c_tower2","c_tower3","c_tower4","alde_dun01","alde_dun02","alde_dun03","alde_dun04");
    D10: setarray @c[2],52,17,381,343,302,262;
    	 Disp("Coal Mines",1,3); Pick("mjo_dun");
    D11: setarray @c[2],131,247,19,19,180,169,100,92;
    	 Disp("Culvert",1,4); Pick("","prt_sewb1","prt_sewb2","prt_sewb3","prt_sewb4");
    D12: setarray @c[2],51,14,150,11,120,10;
    	 Disp("Cursed Abbey",1,3); Pick("abbey");
    D13: Restrict("RE");
    	 setarray @c[2],285,160,299,29;
    	 Disp("Dewata Dungeon",1,2); Pick("dew_dun");
    D14: setarray @c[2],22,14,292,290;
    	 Disp("Einbroch Dungeon",1,2); Pick("ein_dun");
    D15: setarray @c[2],40,103,203,34,266,168,130,272;
    	 Disp("Gefenia",1,4); Pick("gefenia",0);
    D16: setarray @c[0],104,99,115,236,106,132,203,200;
    	 Disp("Geffen Dungeon",1,4); Pick("gef_dun",1);
    D17: setarray @c[2],370,304,199,29,104,25,150,15,157,287,147,15,258,255,108,291,171,283,68,277,156,7,12,7,133,271,224,274,14,70,150,14;
    	 Disp("Entrance:Castle 1:Castle 2:Chivalry 1:Chivalry 2:Churchyard:Culvert 1:Culvert 2:Culvert 3:Culvert 4:St. Abbey:Staircase Dungeon:Underground Cave 1:Underground Cave 2:Underground Prison 1:Underground Prison 2");
    	 Pick("","glast_01","gl_cas01","gl_cas02","gl_knt01","gl_knt02","gl_chyard","gl_sew01","gl_sew02","gl_sew03","gl_sew04","gl_church","gl_step","gl_dun01","gl_dun02","gl_prison","gl_prison1");
    D18: setarray @c[2],153,53,28,113,68,16;
    	 Disp("Gonryun Dungeon",1,3); Pick("gon_dun");
    D19: setarray @c[2],176,7,93,20,23,8;
    	 Disp("Hidden Dungeon",1,3); Pick("prt_maze");
    D20: setarray @c[2],157,14,151,155,149,22,33,158;
    	 Disp("Ice Dungeon",1,4); Pick("ice_dun");
    D21: setarray @c[2],140,51,53,247,37,63,150,285;
    	 Disp("Entrance:Juperos 1:Juperos 2:Core");
    	 Pick("","jupe_cave","juperos_01","juperos_02","jupe_core");
    D22: setarray @c[2],28,226,41,198;
    	 Disp("Kiel Dungeon",1,2); Pick("kh_dun");
    D23: setarray @c[2],218,196,282,20,165,38;
    	 Disp("The Royal Tomb:Inside the Royal Tomb:Suei Long Gon"); Pick("lou_dun");
    D24: setarray @c[2],126,68,47,30;
    	 Disp("Magma Dungeon",1,2); Pick("mag_dun");
    D25: Restrict("RE");
    	 setarray @c[2],33,230;
    	 Disp("Malangdo Dungeon",1,1); Pick("mal_dun");
    D26: setarray @c[2],189,48,165,30,32,135;
    	 Disp("Moscovia Dungeon",1,3); Pick("mosk_dun");
    D27: setarray @c[2],61,239,60,271;
    	 Disp("Nidhogg's Dungeon",1,2); Pick("nyd_dun");
    D28: setarray @c[2],298,167,224,149,266,280;
    	 Disp("Odin Temple",1,3); Pick("odin_tem");
    D29: setarray @c[2],32,170,21,185;
    	 Disp("Orc Dungeon",1,2); Pick("orcsdun");
    D30: setarray @c[0],21,183,19,33,19,63,155,159,201,204;
    	 Disp("Payon Dungeon",1,5); Pick("pay_dun",1);
    D31: Restrict("RE",7,8);
    	 setarray @c[2],192,9,10,192,100,92,181,11,94,96,192,8,94,96,192,8;
    	 Disp("Pyramids 1:Pyramids 2:Pyramids 3:Pyramids 4:Basement 1:Basement 2:Basement 1 - Nightmare Mode:Basement 2 - Nightmare Mode");
    	 Pick("","moc_pryd01","moc_pryd02","moc_pryd03","moc_pryd04","moc_pryd05","moc_pryd06","moc_prydn1","moc_prydn2");
    D32: setarray @c[2],140,11,32,21,8,149,204,218,150,9;
    	 Disp("Rachel Sanctuary",1,5); Pick("ra_san");
    D33: Restrict("RE");
    	 setarray @c[2],364,44,101,141;
    	 Disp("Scaraba Hole",1,2); Pick("dic_dun");
    D34: setarray @c[2],288,9,149,81,210,54,10,222,100,99;
    	 Disp("Sphinx",1,5); Pick("","in_sphinx1","in_sphinx2","in_sphinx3","in_sphinx4","in_sphinx5");
    D35: setarray @c[2],69,24,102,27;
    	 Disp("Sunken Ship",1,2); Pick("treasure");
    D36: setarray @c[2],150,39,150,136,220,158,59,143,62,11,89,221,35,166,93,148,29,107,159,138,19,20,130,52;
    	 Disp("Thanatos Tower",1,12); Pick("tha_t");
    D37: setarray @c[2],21,228,75,205,34,272;
    	 Disp("Thor Volcano",1,3); Pick("thor_v");
    D38: setarray @c[2],205,15,129,133;
    	 Disp("Toy Factory",1,2); Pick("xmas_dun");
    D39: setarray @c[2],154,49,148,261,132,189,100,192;
    	 Disp("Entrance:Turtle Dungeon 1:Turtle Dungeon 2:Turtle Dungeon 3"); Pick("tur_dun");
    D40: Restrict("Pre-RE",1,2);
    	 setarray @c[2],42,31,48,30,204,78;
    	 Disp("Carpenter's Shop in the Tree:Passage to a Foreign World:Hvergermil's Fountain");
    	 Pick("","um_dun01","um_dun02","yggdrasil01");
    D41: Restrict("RE");
    	 setarray @c[2],57,13,64,88,45,14,26,23;
    	 Disp("Bifrost Tower",1,4); Pick("ecl_tdun");
    
    // --------------------------------------------------
    	Castles:
    // --------------------------------------------------
    menu	"Aldebaran Castles",C1, "Geffen Castles",C2, "Payon Castles",C3,
    		"Prontera Castles",C4, "Arunafeltz Castles",C5, "Schwaltzvalt Castles",C6;
    
    C1: setarray @c[2],48,83,95,249,142,85,239,242,264,90;
    	Disp("Neuschwanstein:Hohenschwangau:Nuenberg:Wuerzburg:Rothenburg");
    	Pick("","alde_gld","alde_gld","alde_gld","alde_gld","alde_gld");
    C2: setarray @c[2],214,75,308,240,143,240,193,278,305,87;
    	Disp("Repherion:Eeyolbriggar:Yesnelph:Bergel:Mersetzdeitz");
    	Pick("","gef_fild13","gef_fild13","gef_fild13","gef_fild13","gef_fild13");
    C3: setarray @c[2],121,233,295,116,317,293,140,160,204,266;
    	Disp("Bright Arbor:Scarlet Palace:Holy Shadow:Sacred Altar:Bamboo Grove Hill");
    	Pick("","pay_gld","pay_gld","pay_gld","pay_gld","pay_gld");
    C4: setarray @c[2],134,65,240,128,153,137,111,240,208,240;
    	Disp("Kriemhild:Swanhild:Fadhgridh:Skoegul:Gondul");
    	Pick("","prt_gld","prt_gld","prt_gld","prt_gld","prt_gld");
    C5: setarray @c[2],158,272,83,47,68,155,299,345,292,107;
    	Disp("Mardol:Cyr:Horn:Gefn:Banadis");
    	Pick("","aru_gld","aru_gld","aru_gld","aru_gld","aru_gld");
    C6: setarray @c[2],293,100,288,252,97,196,137,90,71,315;
    	Disp("Himinn:Andlangr:Viblainn:Hljod:Skidbladnir");
    	Pick("","sch_gld","sch_gld","sch_gld","sch_gld","sch_gld");
    
    // --------------------------------------------------
    	Guild_Dungeons:
    // --------------------------------------------------
    menu	"Baldur",G1, "Luina",G2, "Valkyrie",G3, "Britoniah",G4,
    		"Arunafeltz",G5, "Schwaltzvalt",G6;
    
    G1: Restrict("RE",2,3);
    	setarray @c[2],119,93,119,93,120,130;
    	Disp("Baldur F1:Baldur F2:Hall of Abyss");
    	Pick("","gld_dun01","gld_dun01_2","gld2_pay");
    G2: Restrict("RE",2,3);
    	setarray @c[2],39,161,39,161,147,155;
    	Disp("Luina F1:Luina F2:Hall of Abyss");
    	Pick("","gld_dun02","gld_dun02_2","gld2_ald");
    G3: Restrict("RE",2,3);
    	setarray @c[2],50,44,50,44,140,132;
    	Disp("Valkyrie F1:Valkyrie F2:Hall of Abyss");
    	Pick("","gld_dun03","gld_dun03_2","gld2_prt");
    G4: Restrict("RE",2,3);
    	setarray @c[2],116,45,116,45,152,118;
    	Disp("Britoniah F1:Britoniah F2:Hall of Abyss");
    	Pick("","gld_dun04","gld_dun04_2","gld2_gef");
    G5: Go("arug_dun01",199,195);
    G6: Go("schg_dun01",200,124);
    
    // --------------------------------------------------
    	Instances:
    // --------------------------------------------------
    menu	"Bakonawa Lake",I1, "Bangungot Hospital 2F",I2, "Buwaya Cave",I3,
    		"Endless Tower",I4, "Hazy Forest",I5, "Malangdo Culvert",I6, "Nidhoggur's Nest",I7,
    		"Octopus Cave",I8, "Old Glast Heim",I9, "Orc's Memory",I10, "Sealed Shrine",I11,
    		"Wolfchev's Laboratory",I12;
    
    I1: Restrict("RE");
    	Go("ma_scene01",172,175);
    I2: Restrict("RE");
    	Go("ma_dun01",151,8);
    I3: Restrict("RE");
    	Go("ma_fild02",316,317);
    I4: Go("e_tower",72,112);
    I5: Restrict("RE");
    	Go("bif_fild01",161,334);
    I6: Restrict("RE");
    	Go("mal_in01",164,21);
    I7: Go("nyd_dun02",95,193);
    I8: Restrict("RE");
    	Go("mal_dun01",152,230);
    I9: Restrict("RE");
    	Go("glast_01",204,268);
    I10: Go("gef_fild10",240,198);
    I11: Go("monk_test",306,143);
    I12: Restrict("RE");
    	Go("lhz_dun04",148,269);
    
    // --------------------------------------------------
    	Special:
    // --------------------------------------------------
    menu	"Auction Hall",S1, "Battlegrounds",S2, "Casino",S3, "Eden Group Headquarters",S4,
    		"Gonryun Arena",S5, "Izlude Arena",S6, "Monster Race Arena",S7, "Turbo Track",S8;
    
    S1: Go("auction_01",22,68);
    S2: Go("bat_room",154,150);
    S3: Go("cmd_in02",179,129);
    S4: Restrict("RE");
    	Go("moc_para01",31,14);
    S5: Go("gon_test",48,10);
    S6: Go("arena_room",100,88);
    S7: Go("p_track01",62,41);
    S8: Go("turbo_room",99,114);
    }
    
    // --------------------------------------------------
    //	Duplicates:
    // --------------------------------------------------
    alb2trea,57,70,6	duplicate(Warper)	Warper#tre	4_F_VALKYRIE
    alberta,28,240,4	duplicate(Warper)	Warper#alb	4_F_VALKYRIE
    aldebaran,145,118,4	duplicate(Warper)	Warper#alde	4_F_VALKYRIE
    amatsu,203,87,4	duplicate(Warper)	Warper#ama	4_F_VALKYRIE
    ayothaya,209,169,6	duplicate(Warper)	Warper#ayo	4_F_VALKYRIE
    comodo,194,158,4	duplicate(Warper)	Warper#com	4_F_VALKYRIE
    einbech,59,38,6	duplicate(Warper)	Warper#einbe	4_F_VALKYRIE
    einbroch,69,202,4	duplicate(Warper)	Warper#einbr	4_F_VALKYRIE
    gef_fild10,71,339,4	duplicate(Warper)	Warper#orc	4_F_VALKYRIE
    geffen,124,72,4	duplicate(Warper)	Warper#gef	4_F_VALKYRIE
    glast_01,372,308,4	duplicate(Warper)	Warper#glh	4_F_VALKYRIE
    gonryun,162,122,4	duplicate(Warper)	Warper#gon	4_F_VALKYRIE
    hugel,101,151,4	duplicate(Warper)	Warper#hug	4_F_VALKYRIE
    izlu2dun,110,92,4	duplicate(Warper)	Warper#izd	4_F_VALKYRIE
    izlude,134,150,4	duplicate(Warper)	Warper#izl	4_F_VALKYRIE	//Pre-RE: (132,120)
    jawaii,253,138,4	duplicate(Warper)	Warper#jaw	4_F_VALKYRIE
    lighthalzen,162,102,4	duplicate(Warper)	Warper#lhz	4_F_VALKYRIE
    louyang,208,103,6	duplicate(Warper)	Warper#lou	4_F_VALKYRIE
    manuk,274,146,6	duplicate(Warper)	Warper#man	4_F_VALKYRIE
    mid_camp,216,288,4	duplicate(Warper)	Warper#mid	4_F_VALKYRIE
    mjolnir_02,85,364,4	duplicate(Warper)	Warper#mjo	4_F_VALKYRIE
    moc_ruins,64,164,4	duplicate(Warper)	Warper#moc	4_F_VALKYRIE
    morocc,159,97,4	duplicate(Warper)	Warper#mor	4_F_VALKYRIE
    moscovia,229,191,4	duplicate(Warper)	Warper#mos	4_F_VALKYRIE
    nameless_n,259,213,4	duplicate(Warper)	Warper#nam	4_F_VALKYRIE
    niflheim,205,179,4	duplicate(Warper)	Warper#nif	4_F_VALKYRIE
    pay_arche,42,134,4	duplicate(Warper)	Warper#arc	4_F_VALKYRIE
    payon,182,108,4	duplicate(Warper)	Warper#pay	4_F_VALKYRIE
    prontera,159,192,4	duplicate(Warper)	Warper#prt	4_F_VALKYRIE
    prt_fild05,279,223,6	duplicate(Warper)	Warper#cul	4_F_VALKYRIE
    rachel,135,116,4	duplicate(Warper)	Warper#rac	4_F_VALKYRIE
    splendide,205,153,4	duplicate(Warper)	Warper#spl	4_F_VALKYRIE
    thor_camp,249,76,4	duplicate(Warper)	Warper#thor	4_F_VALKYRIE
    umbala,106,150,3	duplicate(Warper)	Warper#umb	4_F_VALKYRIE
    veins,214,123,4	duplicate(Warper)	Warper#ve	4_F_VALKYRIE
    xmas,150,136,6	duplicate(Warper)	Warper#xmas	4_F_VALKYRIE
    yuno,162,47,4	duplicate(Warper)	Warper#yuno	4_F_VALKYRIE
    
    // --------------------------------------------------
    //	Duplicates (Renewal):
    // --------------------------------------------------
    brasilis,201,222,4	duplicate(Warper)	Warper#bra	4_F_VALKYRIE
    dewata,204,186,6	duplicate(Warper)	Warper#dew	4_F_VALKYRIE
    dicastes01,194,194,6	duplicate(Warper)	Warper#dic	4_F_VALKYRIE
    ecl_in01,51,60,4	duplicate(Warper)	Warper#ecl	4_F_VALKYRIE
    malangdo,134,117,6	duplicate(Warper)	Warper#mal	4_F_VALKYRIE
    malaya,231,204,4	duplicate(Warper)	Warper#ma	4_F_VALKYRIE
    mora,57,152,4	duplicate(Warper)	Warper#mora	4_F_VALKYRIE

     


  2. 2 hours ago, meko said:

    change end; to return; on lines 96 and 111

    Hi @meko i did change as advised. Yet, it allows me to warp to renewal map instead of restricting for Pre-Re

    function Pick {
    	.@warp_block = @warp_block;
    	@warp_block = 0;
    	.@select = select(@menu$);
    	if (getarg(0) == "") {
    		.@i = .@select;
    		.@map$ = getarg(.@i);
    	} else {
    		.@i = .@select-getarg(1,0);
    		.@map$ = getarg(0)+((.@i<10)?"0":"")+.@i;
    	}
    	if (.@warp_block & (1<<.@select)) {
    		message strcharinfo(PC_NAME),"This map is not enabled in "+(RENEWAL?"":"Pre-")+"Renewal.";
    		return;
    	}
    	.@x = @c[.@i*2];
    	.@y = @c[.@i*2+1];
    	deletearray @c[0],getarraysize(@c);
    	Go(.@map$,.@x,.@y);
    }
    function Restrict {
    	if ((getarg(0) == "RE" && !RENEWAL) || (getarg(0) == "Pre-RE" && RENEWAL)) {
    		if (getarg(1,0)) {
    			@warp_block = 0;
    			for (.@i = 1; .@i < getargcount(); .@i++)
    				@warp_block = @warp_block | (1<<getarg(.@i));
    		} else {
    			message strcharinfo(PC_NAME),"This map is not enabled in "+(RENEWAL?"":"Pre-")+"Renewal.";
    			return;
    		}
    	}
    	return;
    }

     


  3. Good day!

    I don't know if this has been address or what, but if you happen to choose the Renewal Maps in the NPC warper a message will appear:

    "        message strcharinfo(0),"This map is not enabled in "+((RENEWAL)?"":"Pre-")+"Renewal.";"

    However, after the receiving the message you won't be able to move nor to click on NPCs, you need to @refresh or relog. 
    How to fix this? thanks!

     


  4. Good day Master Scripters,

    Requesting a script for race to 99/70 event for all trans job:
    NPC Features:

    • NPC will let players know who won the race to 99/70 or was it still availble per job.
      • Switch ("FIRST 99ners")
        • LORD KNIGHT : PLAYER NAME 1
        • HIGH WIZARD : PLAYER NAME 2
        • HUNTER : <NONE> (Meaning slot is still available)
        • HIGH PRIEST: <NONE>
    • Once reach 99/70 World Announce :
      • Lord Knight Player Name 1 has reached the maximum level(For lord knight Job)
      • High Wizard Player Name 2 so on and so fort.
    • Guess that's all i need will just give the prize manual trade for picture taking purposes.

  5. Good day!

    Requesting for guide how to update fluxcp.

    I tried the theme uploaded by Plug and Play but seems it not compatible to the current emulator anymore .
    Or was this being address? thanks!
     

    Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; Markdown_Parser has a deprecated constructor in /homepages/19/d739599868/htdocs/LibRO/lib/markdown/markdown.php on line 215
    
    Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; MarkdownExtra_Parser has a deprecated constructor in /homepages/19/d739599868/htdocs/LibRO/lib/markdown/markdown.php on line 1677
    
    Strict Standards: date(): We selected 'America/New_York' for 'EDT/-4.0/DST' instead in /homepages/19/d739599868/htdocs/LibRO/lib/Flux/Connection/Statement.php on line 14
    
    Strict Standards: date(): We selected 'America/New_York' for 'EDT/-4.0/DST' instead in /homepages/19/d739599868/htdocs/LibRO/lib/Flux/LogFile.php on line 74

     


  6. 21 hours ago, AnnieRuru said:

    the script you posted made by me ...
    sorry as I don't own Gepard, I don't know how it works so I couldn't make this system for you

    and what meko said was spot on,
    just reminded the IP address detection method on this script can just bypass by restarting the modem

    the mac address system though ...
    sry maybe I was out from RO scene too long ?
    2 years ago I heard that mac address is something that is only possible by adding a 3rd party program running in the background ...

    and this makes me assume that Gepard is also something 3rd party program ... stuffs

    @AnnieRuru its okay. 

    I somehow just edit it with the common query command and change the ip to unique_id. Somehow it worked fine for daily login.
    Wonder if you have any suggestion or tips to improve this. I don't kinda understand the script cuz im noob. but that this mean every 00:00 server time you will be able to get coin or 24hr from last talked to the npc?

    prontera,164,173,5	script	Daily Login	4_F_FAIRYKID4,{
    //	$ip_reward_daytime = 0;
    	query_sql("SELECT `last_unique_id` from `login` WHERE `account_id` = "+getcharid(3),@lui$);
    
    	mes "["+ strnpcinfo(NPC_NAME) +"]";
    	if ( $ip_reward_daytime != atoi( gettimestr("%Y%m%d", 20 ) ) ) {
    		$ip_reward_daytime = atoi( gettimestr("%Y%m%d", 20 ) );
    		deletearray $ip_reward$;
    	}
    	.@size = getarraysize( $ip_reward$ );
    	while ( @lui$ != $ip_reward$[.@i] && .@i < .@size ) { ++.@i; }
    	if ( .@i < .@size ) {
    		mes "You have claimed the reward.";
    		close;
    	}
    	if ( @ip_reward && @ip_reward + .countdown <= gettimetick(2) ) {
    		mes "Here is the surprise reward";
    		getitem 25045, 1;
    		$ip_reward$[ getarraysize( $ip_reward$ ) ] = @lui$;
    		close;
    	}
    	if ( @ip_reward ) {
    		mes "Countdown timer...";
    		.@timeleft = @ip_reward + .countdown - gettimetick(2);
    		mes .@timeleft /3600 +" hour "+ .@timeleft %3600/60 +" min "+ .@timeleft %60 +" sec left";
    		close;
    	}
    	mes "Hello "+ strcharinfo(PC_NAME) +", I am here to give you a daily Surprise Reward. Do you want to have it?";
    	next;
    	select "Yes, sure !!";
    	mes "["+ strnpcinfo(NPC_NAME) +"]";
    	mes "You can claim the reward after an hour.";
    	close2;
    	addtimer .countdown *1000, strnpcinfo(NPC_NAME) +"::OnClaimReward";
    	@ip_reward = gettimetick(2);
    	end;
    OnClaimReward:
    	dispbottom "You can claim Daily Login Reward now.";
    	end;
    OnInit:
    	.countdown = 1*60*60; // 5 hours
    //	.countdown = 5;
    }

     


  7. 2 hours ago, meko said:

    IP addresses and mac addresses do not uniquely identify people. Most home internet users have dynamic IP addresses assigned by their ISP, so it changes over time, and some ISPs even assign a different one every single time the router is rebooted (ie: Orange). Even with a static IP, nothing prevents anyone from using a VPN, tor, or any other anonymity tool. IP addresses may also be shared: some schools, dormitories, and organizations have a single address for every single computer on its network, so you could end up mistaking hundreds of people as the same person. Some computers themselves are also shared (ie: with coworkers, family members, friends, …). As for mac addresses, they can very easily be spoofed, and one could even make a script to change their mac address every minute if they wanted to... so yeah, that's a bad idea too.

    If this still does not discourage you from using mac addresses, feel free to add this "feature" to Hercules: https://github.com/HerculesWS/Hercules/issues/1734

     

    There's really no silver bullet to really be sure of the identity of someone, but one of the approaches that kinda works is to make abuse costly on abusers, while not imposing a huge burden on non-abusers. What works best is doing a physical verification instead of a digital one when someone creates an account. For example, most social media platforms now ask you to provide and validate a phone number. This means if someone were to bypass this verification they would have to have more than one phone. Some sites, such as Paypal, go even further ask you for your credit card number (or bank account number) and then do a transaction on it (usually $1), to see if the card is valid. This means you would have to have more than one credit card if you want to bypass this verification, which implies physically going to your bank, making an appointment, and opening a new account. Some (such as Google) prefer to snail mail you an envelope containing a code, which you then have to enter on their website. To abuse this you would need more than one street address. Keep in mind that this only makes it harder on would-be abusers and that nothing can 100% fingerprint someone. Even DNA profiling isn't perfect.

    Thank you for this @meko. I am planning to buy gepard. How about gepard last_unique_id is it changeable?
    May I know how to change the script from last_ip to last_unique_id? thanks!


  8. On 5/24/2018 at 10:55 PM, AnnieRuru said:

    @Begin

    
    prontera,155,180,5	script	Reward NPC	4_F_FAIRYKID4,{
    //	$ip_reward_daytime = 0;
    	mes "["+ strnpcinfo(NPC_NAME) +"]";
    	if ( $ip_reward_daytime != atoi( gettimestr("%Y%m%d", 20 ) ) ) {
    		$ip_reward_daytime = atoi( gettimestr("%Y%m%d", 20 ) );
    		deletearray $ip_reward$;
    	}
    	.@size = getarraysize( $ip_reward$ );
    	while ( getcharip() != $ip_reward$[.@i] && .@i < .@size ) { ++.@i; }
    	if ( .@i < .@size ) {
    		mes "You have claimed the reward with this IP address.";
    		close;
    	}
    	if ( @ip_reward && @ip_reward + .countdown <= gettimetick(2) ) {
    		mes "Here is the surprise reward";
    		getitem Poring_Coin, 1;
    		$ip_reward$[ getarraysize( $ip_reward$ ) ] = getcharip();
    		close;
    	}
    	if ( @ip_reward ) {
    		mes "Countdown timer...";
    		.@timeleft = @ip_reward + .countdown - gettimetick(2);
    		mes .@timeleft /3600 +" hour "+ .@timeleft %3600/60 +" min "+ .@timeleft %60 +" sec left";
    		close;
    	}
    	mes "Hello "+ strcharinfo(PC_NAME) +", I am here to give you a daily Surprise Reward. Do you want to have it?";
    	next;
    	select "Yes, sure !!";
    	mes "["+ strnpcinfo(NPC_NAME) +"]";
    	mes "You can claim the reward in 5 hours time.";
    	close2;
    	addtimer .countdown *1000, strnpcinfo(NPC_NAME) +"::OnClaimReward";
    	@ip_reward = gettimetick(2);
    	end;
    OnClaimReward:
    	dispbottom "You can claim Daily Login Reward now.";
    	end;
    OnInit:
    	.countdown = 5*60*60; // 5 hours
    //	.countdown = 5;
    }

    @AnnieRuru how can i change getcharip() to last_mac or last_unique_id?


  9. I already post this request when I found out someone someone already requested with same script.
    Wanted to know how to change to last_mac.

    prontera,155,180,5	script	Reward NPC	4_F_FAIRYKID4,{
    //	$ip_reward_daytime = 0;
    	mes "["+ strnpcinfo(NPC_NAME) +"]";
    	if ( $ip_reward_daytime != atoi( gettimestr("%Y%m%d", 20 ) ) ) {
    		$ip_reward_daytime = atoi( gettimestr("%Y%m%d", 20 ) );
    		deletearray $ip_reward$;
    	}
    	.@size = getarraysize( $ip_reward$ );
    	while ( getcharip() != $ip_reward$[.@i] && .@i < .@size ) { ++.@i; }
    	if ( .@i < .@size ) {
    		mes "You have claimed the reward with this IP address.";
    		close;
    	}
    	if ( @ip_reward && @ip_reward + .countdown <= gettimetick(2) ) {
    		mes "Here is the surprise reward";
    		getitem Poring_Coin, 1;
    		$ip_reward$[ getarraysize( $ip_reward$ ) ] = getcharip();
    		close;
    	}
    	if ( @ip_reward ) {
    		mes "Countdown timer...";
    		.@timeleft = @ip_reward + .countdown - gettimetick(2);
    		mes .@timeleft /3600 +" hour "+ .@timeleft %3600/60 +" min "+ .@timeleft %60 +" sec left";
    		close;
    	}
    	mes "Hello "+ strcharinfo(PC_NAME) +", I am here to give you a daily Surprise Reward. Do you want to have it?";
    	next;
    	select "Yes, sure !!";
    	mes "["+ strnpcinfo(NPC_NAME) +"]";
    	mes "You can claim the reward in 5 hours time.";
    	close2;
    	addtimer .countdown *1000, strnpcinfo(NPC_NAME) +"::OnClaimReward";
    	@ip_reward = gettimetick(2);
    	end;
    OnClaimReward:
    	dispbottom "You can claim Daily Login Reward now.";
    	end;
    OnInit:
    	.countdown = 5*60*60; // 5 hours
    //	.countdown = 5;
    }

     


  10. Hi Ms. @AnnieRuru I really like the idea. i know this is just a sample but mind if i ask if possible or is it possible; how

    • to make this DAILY chain quest.
    • to make this every 00:00 server time this quest reset back to zero 0. Player should finish the quest before 00:00
    • and if player finishes the quest before 00:00 then player took a quest again will remind that need to wait for --:-- hours until quest reset at 00:00.
    • Regardless if player only reach mission 2, quest will reset back to 0 once 00:00.
    • to Place item reward or exp reward per npc mission accomplish (guess this can added in after "dispbottom "mission 1 pass";")
    • quest depend per base level "1-20","21-40","41-60","61-80","81-99".

      Thanks!

  11. 2 hours ago, AnnieRuru said:

    assuming you have this https://github.com/HerculesWS/Hercules/blob/stable/npc/mapflag/town.txt

    
    prontera,150,185,5	script	test	1_F_MARIA,{
    	input .@map$;
    	if ( getmapusers( .@map$ ) == -1 )
    		dispbottom "no such map";
    	else if ( !getmapflag( .@map$, mf_town ) )
    		dispbottom "not a town";
    	else
    		atcommand "@go "+ .@map$; // yeah lazy to note down the coordinate, so use atcommand
    	end;
    }

     

    Thank you so much Ms. AnnieRuru!!!


  12. Good day!

    May I request a script in consumable items to allow players to warp to a town.
    wanted to have it like @go not @warp to player can just input town number or name. no dungeon or field. strictly for town warp.
    Thanks!

    	Script: <"	input .@map$;
    			if ( getmapusers( .@map$ ) != -1 ) warp .@map$,0,0; end; ">
    },

     


  13. On 4/5/2017 at 6:43 PM, tedexx said:

     

     

    map_index.txt

    
    // Haunt
    haunt_e
    haunt_h
    1@haunt
    2@haunt
    

    conf/map/maps.conf

    
    // Haunt
    "haunt_e",
    "haunt_h",
    "1@haunt",
    "2@haunt",
    

     

    resnametable

    
    1@haunt.gnd#haunt_e.gnd#
    1@haunt.gat#haunt_e.gat#
    1@haunt.rsw#haunt_e.rsw#
    유저인터페이스\map\1@haunt.bmp#유저인터페이스\map\blank.bmp#
    
    2@haunt.gnd#haunt_h.gnd#
    2@haunt.gat#haunt_h.gat#
    2@haunt.rsw#haunt_h.rsw#
    유저인터페이스\map\1@haunt.bmp#유저인터페이스\map\blank.bmp#

     

    All files added to map_cache.dat and yet I'm still having problems. I had this problem before trying to use one map as same as another and wasn't able to make it work. Just don't get how it works.

    qPWxCzL.png

    Le05t0O.png

     

     

    Ignoring the map problem, this occurs when starting the solo option (only one tested)

    4XziUN9.png

    Got the same ERROR.
    Any update?

    Tried to ignore error and i got this. /sob

    [Debug]: script debug : 2000000 110137260 : Attempting to create Instance.
    [Debug]: script debug : 2000000 110137260 : Attempt successful on Instance attach!
    [Debug]: script debug : 0 110139933 : [Floor] # 1 :: [Total mobs] : 5
    [Debug]: script debug : 0 110139933 : [Floor] # 2 :: [Total mobs] : 7
    [Debug]: script debug : 0 110139933 : [Floor] # 3 :: [Total mobs] : 6
    [Debug]: script debug : 0 110139933 : [Floor] # 4 :: [Total mobs] : 5
    [Debug]: script debug : 0 110139933 : [Floor] # 5 :: [Total mobs] : 7
    [Debug]: script debug : 0 110139933 : [Floor] # 6 :: [Total mobs] : 7
    [Debug]: script debug : 0 110139933 : [Floor] # 7 :: [Total mobs] : 7
    [Debug]: script debug : 0 110139933 : [Floor] # 8 :: [Total mobs] : 7
    [Debug]: script debug : 0 110139933 : [Floor] # 9 :: [Total mobs] : 6
    [Debug]: script debug : 0 110139933 : [Floor] # 10 :: [Total mobs] : 7
    [Debug]: script debug : 0 110139933 : 64 Total mobs.
    [Error]: script:instance_npcname: invalid instance NPC (instance_id: 0, NPC name: "Hidden Key#1".)
    [Debug]: Source (NPC): InstanceBegin#Ins at 000#1@haunt (1,4)
    [Info]: Saved char 150001 - DarK: status skills.

     


  14. Good day!

    Help me how to correct these warnings please.

    Spoiler
    
    /*
    * This file is part of a Hercules Plugin library.
    * http://herc.ws - http://github.com/HerculesWS/Hercules
    *  __                 _
    * / _\_ __ ___   ___ | | _______  ___   _ ____
    * \ \| '_ ` _ \ / _ \| |/ / _ \ \/ / | | |_  /
    * _\ \ | | | | | (_) |   <  __/>  <| |_| |/ /
    * \__/_| |_| |_|\___/|_|\_\___/_/\_\\__, /___|
    *                                   |___/
    *
    * Copyright (c) 2017 Smokexyz ([email protected])
    * 
    * Hercules is free software: you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation, either version 3 of the License, or
    * (at your option) any later version.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    * GNU General Public License <http://www.gnu.org/licenses/> for
    * more details.
    * * * * * * * * * * * * * * * * * * * * * * * * *
    * Hercules Battlegrounds Plugin by [Smokexyz]
    * * * * * * * * * * * * * * * * * * * * * * * * */
    
    #include "common/hercules.h" /* Should always be the first Hercules file included! */
    
    #include "common/memmgr.h"
    #include "common/mmo.h"
    #include "common/socket.h"
    #include "common/strlib.h"
    #include "common/nullpo.h"
    #include "common/timer.h"
    #include "common/utils.h"
    #include "common/sql.h"
    
    #include "map/chrif.h"
    #include "map/atcommand.h"
    #include "map/clif.h"
    #include "map/pc.h"
    #include "map/script.h"
    #include "map/npc.h"
    #include "map/party.h"
    #include "map/mapreg.h"
    #include "map/guild.h"
    #include "map/chat.h"
    #include "map/quest.h"
    #include "map/mob.h"
    #include "map/map.h"
    #include "map/pet.h"
    #include "map/homunculus.h"
    #include "map/mercenary.h"
    #include "map/elemental.h"
    #include "map/skill.h"
    #include "map/battleground.h"
    
    #include "char/mapif.h"
    #include "char/inter.h"
    
    #include "plugins/HPMHooking.h" /* Hooking Macros */
    #include "common/HPMDataCheck.h" /* should always be the last Hercules file included! */
    
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                    Utility Functions
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    #define add2limit(a, b, max) \
    	do { \
    		if ((max - a) < b) { \
    			a = max; \
    		} else { \
    			a += b; \
    		} \
    	} while(0)
    
    #define sub2limit(a, b, min) \
    	do { \
    		if ((b + min) > a) { \
    			a = min; \
    		} else { \
    			a -= b; \
    		} \
    	} while(0)
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                    HPM Structure Definition
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    HPExport struct hplugin_info pinfo = {
    	"Hercules Battlegrounds",    // Plugin name
    	SERVER_TYPE_MAP | SERVER_TYPE_CHAR, // Server Type
    	"1.0a",       // Plugin version
    	HPM_VERSION, // HPM Version (automatically updated)
    };
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                    Global Variables
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    #define MAX_BATTLEGROUND_TEAMS 13
    #define BLUE_SKULL 8965
    #define RED_SKULL 8966
    #define GREEN_SKULL 8967
    
    /* Queue Database */
    static struct DBMap* hBG_queue_db;
    /* Battleground Guild Storage */
    struct guild bg_guild[MAX_BATTLEGROUND_TEAMS];
    /* Battleground Guild Colors */
    const unsigned int bg_colors[MAX_BATTLEGROUND_TEAMS] = {
    	0x0000FF, // Blue
    	0xFF0000, // Red
    	0x00FF00, // Green
    	0xFFFFFF,
    	0xFFFFFF,
    	0xFFFFFF,
    	0xFFFFFF,
    	0xFFFFFF,
    	0xFFFFFF,
    	0xFFFFFF,
    	0xFFFFFF,
    	0xFFFFFF,
    	0xFFFFFF
    };
    
    /* Counter to check the next battleground ID */
    static unsigned int bg_team_counter = 0;
    /* hBG Queue Counter */
    static unsigned int hBG_queue_counter = 0;
    
    /**
     * Battle Configuration Variables
     */
    int hBG_idle_announce,
    	hBG_idle_autokick,
    	hBG_reward_rates,
    	hBG_ranked_mode,
    	hBG_reportafk_leaderonly,
    	hBG_balanced_queue,
    	hBG_ip_check,
    	hBG_from_town_only,
    	hBG_enabled,
    	hBG_xy_interval,
    	hBG_leader_change;
    
    /**
     * BG Fame list types
     */
    enum bg_fame_list_types
    {
    	BG_NORMAL,
    	BG_RANKED
    };
    
    /**
     * Inter-server communication packet IDs.
     */
    enum inter_packet_types {
    	PACKET_INTER_BG_STATS_SAVE =  0x9000,
    	PACKET_INTER_BG_STATS_REQ,
    	PACKET_MAP_BG_STATS_GET,
    };
    
    enum bg_mob_types {
    	BARRICADE_        = 1906,
    	OBJ_NEUTRAL       = 1911,
    	E_BAPHOMET2       = 2100,
    	E_LORD_OF_DEATH2,
    	E_DARK_LORD,
    	E_KTULLANUX,
    	E_DARK_SNAKE_LORD,
    	E_TURTLE_GENERAL,
    	E_APOCALIPS_H,
    	E_FALLINGBISHOP,
    };
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                    Structure Definitions
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    
    /**
     * BGD Structure Appendant
     */
    struct hBG_data
    {
    	time_t created_at; // Creation of this Team
    	int leader_char_id;
    	unsigned int color;
    	// BG Guild Link
    	struct guild *g;
    	bool reveal_pos, reveal_pos2, reveal_flag;
    	// Score Board
    	int team_score;
    };
    
    /**
     * hBG Queue Member Linked List
     */
    struct hBG_queue_member
    {
    	int position;
    	struct map_session_data *sd;
    	struct hBG_queue_member *next;
    };
    
    struct hBG_stats
    {
    	unsigned int
    	best_damage,
    	boss_damage,
    	total_damage_done,
    	total_damage_received;
    	
    	unsigned short
    	// Triple Inferno
    	ti_wins,
    	ti_lost,
    	ti_tie,
    	// Tierra EoS
    	eos_flags,
    	eos_bases,
    	eos_wins,
    	eos_lost,
    	eos_tie,
    	// Tierra Bossnia
    	boss_killed,
    	boss_flags,
    	boss_wins,
    	boss_lost,
    	boss_tie,
    	// Tierra Domination
    	dom_bases,
    	dom_off_kills,
    	dom_def_kills,
    	dom_wins,
    	dom_lost,
    	dom_tie,
    	// Flavius TD
    	td_kills,
    	td_deaths,
    	td_wins,
    	td_lost,
    	td_tie,
    	// Flavius SC
    	sc_stolen,
    	sc_captured,
    	sc_dropped,
    	sc_wins,
    	sc_lost,
    	sc_tie,
    	// Flavius CTF
    	ctf_taken,
    	ctf_captured,
    	ctf_dropped,
    	ctf_wins,
    	ctf_lost,
    	ctf_tie,
    	// Conquest
    	emperium_kills,
    	barricade_kills,
    	guardian_stone_kills,
    	conquest_wins,
    	conquest_losses,
    	// Rush
    	ru_captures,
    	ru_wins,
    	ru_lost,
    	ru_skulls;
    	
    	unsigned int // Ammo
    	sp_heal_potions,
    	hp_heal_potions,
    	yellow_gemstones,
    	red_gemstones,
    	blue_gemstones,
    	poison_bottles,
    	acid_demostration,
    	acid_demostration_fail,
    	support_skills_used,
    	healing_done,
    	wrong_support_skills_used,
    	wrong_healing_done,
    	sp_used,
    	zeny_used,
    	spiritb_used,
    	ammo_used;
    	
    	unsigned short
    	kill_count,
    	death_count,
    	wins, losses, ties,
    	wins_as_leader,
    	losses_as_leader,
    	ties_as_leader,
    	total_deserted,
    	ranked_games;
    	
    	int score,
    	points,
    	ranked_points;
    };
    
    /**
     * MSD Structure Appendant (class 0)
     */
    struct hBG_queue_data
    {
    	unsigned int q_id, users, min_level;
    	struct hBG_queue_member *first, *last;
    	char queue_name[50], join_event[EVENT_NAME_LENGTH];
    };
    
    /**
     * MSD Structure Appendant (class 1)
     */
    struct hBG_map_session_data
    {
    	unsigned int bg_kills;
    	struct {
    		unsigned afk : 1;
    	} state;
    	
    	struct hBG_stats stats;
    };
    
    /**
     * MOBD Structure Appendant
     */
    struct hBG_mob_data
    {
    	struct {
    		unsigned immunity: 1;
    	} state;
    };
    
    /**
     * MAPD Structure Appendant
     */
    struct hBG_mapflag
    {
    	unsigned hBG_topscore : 1; // No Detect NoMapFlag
    };
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                    Function Forward Declarations
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    int hBG_countlogin(struct map_session_data *sd, bool check_bat_room);
    int hBG_config_get(const char *key);
    struct guild* hBG_get_guild(int bg_id);
    struct map_session_data* hBG_getavailablesd(struct battleground_data *bgd);
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                    Packet Sending Functions
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    /**
     * Updates HP bar of a camp member.
     * Packet Ver < 20140613: 02e0 <account id>.L <name>.24B <hp>.W <max hp>.W (ZC_BATTLEFIELD_NOTIFY_HP).
     * Packet Ver >= 20140613: 0a0e <account id>.L <hp>.L <max hp>.L (ZC_BATTLEFIELD_NOTIFY_HP2)
     *
     * @param sd map_session_data to send the packet to.
     * @return void.
     */
    void hBG_send_hp_area(struct map_session_data *sd)
    {
    	unsigned char buf[34];
    	
    	// packet version can be wrong,
    	// due to inconsistend data on other servers.
    #if PACKETVER < 20140613
    	const int cmd = 0x2e0;
    	const struct s_packet_db *packet = clif->packet(cmd);
    	
    	nullpo_retv(sd);
    	
    	if (packet == NULL)
    		return;
    
    	WBUFW(buf, 0) = cmd;
    	WBUFL(buf, 2) = sd->status.account_id;
    	memcpy(WBUFP(buf, 6), sd->status.name, NAME_LENGTH);
    
    	if (sd->battle_status.max_hp > INT16_MAX) { // To correctly display the %hp bar. [Skotlex]
    		WBUFW(buf, 30) = sd->battle_status.hp / (sd->battle_status.max_hp / 100);
    		WBUFW(buf, 32) = 100;
    	}
    	else {
    		WBUFW(buf, 30) = sd->battle_status.hp;
    		WBUFW(buf, 32) = sd->battle_status.max_hp;
    	}
    	
    	clif->send(buf, packet->len, &sd->bl, BG_AREA_WOS);
    #else
    	const int cmd = 0xa0e;
    	const struct s_packet_db *packet = clif->packet(cmd);
    	
    	nullpo_retv(sd);
    	
    	if (packet == NULL)
    		return;
    
    	WBUFW(buf, 0) = cmd;
    	WBUFL(buf, 2) = sd->status.account_id;
    	if (sd->battle_status.max_hp > INT32_MAX) {
    		WBUFL(buf, 6) = sd->battle_status.hp / (sd->battle_status.max_hp / 100);
    		WBUFL(buf, 10) = 100;
    	} else {
    		WBUFL(buf, 6) = sd->battle_status.hp;
    		WBUFL(buf, 10) = sd->battle_status.max_hp;
    	}
    	
    	clif->send(buf, packet->len, &sd->bl, BG_AREA_WOS);
    #endif
    }
    
    /**
     * Notify a singly client of HP change.
     *
     * @param fd  socket fd to write
     * @param sd  map_session_data containing information to be sent.
     */
    void hBG_send_hp_single(int fd, struct map_session_data* sd)
    {
    	const int cmd = 0x2e0;
    	const struct s_packet_db *packet = clif->packet(cmd);
    	
    	nullpo_retv(sd);
    	
    	if (packet == NULL)
    		return;
    
    	WFIFOHEAD(fd, packet->len);
    	WFIFOW(fd, 0) = cmd;
    	WFIFOL(fd, 2) = sd->bl.id;
    	memcpy(WFIFOP(fd,6),sd->status.name, NAME_LENGTH);
    	if (sd->battle_status.max_hp > INT16_MAX) {
    		WFIFOW(fd, 30) = sd->battle_status.hp/(sd->battle_status.max_hp/100);
    		WFIFOW(fd, 32) = 100;
    	} else {
    		WFIFOW(fd, 30) = sd->battle_status.hp;
    		WFIFOW(fd, 32) = sd->battle_status.max_hp;
    	}
    
    	WFIFOSET(fd, packet->len);
    }
    
    /**
     * Character Guild Name Information Packet
     *
     * @param sd map_session_data to send the packet to.
     * @return void
     */
    void hBG_send_guild_info(struct map_session_data *sd)
    {
    	int fd;
    	int cmd = 0x16c;
    	struct guild *g;
    	const struct s_packet_db *packet = clif->packet(cmd);
    	
    	nullpo_retv(sd);
    
    	if (!sd->bg_id || (g = hBG_get_guild(sd->bg_id)) == NULL || packet == NULL)
    		return;
    
    	fd = sd->fd;
    	WFIFOHEAD(fd, packet->len);
    	WFIFOW(fd,0) = 0x16c;
    	WFIFOL(fd,2) = g->guild_id;
    	WFIFOL(fd,6) = g->emblem_id;
    	WFIFOL(fd,10) = 0;
    	WFIFOB(fd,14) = 0;
    	WFIFOL(fd,15) = 0;
    	memcpy(WFIFOP(fd,19), g->name, NAME_LENGTH);
    
    	WFIFOSET(fd,  packet->len);
    }
    
    /** 
     * Sends guild skills (ZC_GUILD_SKILLINFO).
     * 0162 <packet len>.W <skill points>.W { <skill id>.W <type>.L <level>.W <sp cost>.W <atk range>.W <skill name>.24B <upgradeable>.B }*
     */
    void hBG_send_guild_skillinfo(struct map_session_data* sd)
    {
    	int fd;
    	struct guild* g;
    	int i,c;
    	
    	nullpo_retv(sd);
    	
    	if (!sd->bg_id || (g = hBG_get_guild(sd->bg_id)) == NULL)
    		return;
    	
    	fd = sd->fd;
    	WFIFOHEAD(fd, 6 + MAX_GUILDSKILL*37);
    	WFIFOW(fd,0) = 0x0162;
    	WFIFOW(fd,4) = g->skill_point;
    	for (i = 0, c = 0; i < MAX_GUILDSKILL; i++) {
    		if(g->skill[i].id > 0 && guild->check_skill_require(g, g->skill[i].id)) {
    			int id = g->skill[i].id;
    			int p = 6 + c*37;
    			WFIFOW(fd,p+0) = id;
    			WFIFOL(fd,p+2) = skill->get_inf(id);
    			WFIFOW(fd,p+6) = g->skill[i].lv;
    			if ( g->skill[i].lv) {
    				WFIFOW(fd, p + 8) = skill->get_sp(id, g->skill[i].lv);
    				WFIFOW(fd, p + 10) = skill->get_range(id, g->skill[i].lv);
    			} else {
    				WFIFOW(fd, p + 8) = 0;
    				WFIFOW(fd, p + 10) = 0;
    			}
    			safestrncpy(WFIFOP(fd,p+12), skill->get_name(id), NAME_LENGTH);
    			WFIFOB(fd,p+36)= (g->skill[i].lv < guild->skill_get_max(id) && sd == g->member[0].sd) ? 1 : 0;
    			c++;
    		}
    	}
    	WFIFOW(fd,2) = 6 + c*37;
    	WFIFOSET(fd,WFIFOW(fd,2));
    }
    
    /**
     * Sends Guild Window Information
     * 01b6 <guild id>.L <level>.L <member num>.L <member max>.L <exp>.L <max exp>.L <points>.L <honor>.L <virtue>.L <emblem id>.L <name>.24B <master name>.24B <manage land>.16B <zeny>.L (ZC_GUILD_INFO2)
     * @param sd map_session_data to send the packet to.
     * @return void
     */
    void hBG_guild_window_info(struct map_session_data *sd)
    {
    	int fd;
    	int cmd = 0x1b6;
    	struct guild *g;
    	const struct s_packet_db *packet = clif->packet(cmd);
    	
    	nullpo_retv(sd);
    	
    	fd = sd->fd;
    	
    	if ((g = hBG_get_guild(sd->bg_id)) == NULL || packet == NULL)
    		return;
    	
    	WFIFOHEAD(fd, packet->len); // Hardcoded Length
    	WFIFOW(fd, 0)= cmd;
    	WFIFOL(fd, 2)= g->guild_id;
    	WFIFOL(fd, 6)= g->guild_lv;
    	WFIFOL(fd,10)= g->connect_member;
    	WFIFOL(fd,14)= g->max_member;
    	WFIFOL(fd,18)= g->average_lv;
    	WFIFOL(fd,22)= (uint32)cap_value(g->exp,0,INT32_MAX);
    	WFIFOL(fd,26)= g->next_exp;
    	WFIFOL(fd,30)= 0; // Tax Points
    	WFIFOL(fd,34)= 0; // Honor: (left) Vulgar [-100,100] Famed (right)
    	WFIFOL(fd,38)= 0; // Virtue: (down) Wicked [-100,100] Righteous (up)
    	WFIFOL(fd,42)= g->emblem_id;
    	memcpy(WFIFOP(fd,46), g->name, NAME_LENGTH);
    	memcpy(WFIFOP(fd,70), g->master, NAME_LENGTH);
    	
    	//safestrncpy(WFIFOP(fd,94), 0, 0); // "'N' castles"
    	WFIFOL(fd, 110) = 0;  // zeny
    	
    	WFIFOSET(fd, packet->len);
    }
    
    /**
     * Sends Guild Emblem to a player
     * @param sd   map_session_data to send the packet to
     * @param g    guild data
     * @return void
     */
    void hBG_send_emblem(struct map_session_data *sd, struct guild *g)
    {
    	int fd;
    
    	nullpo_retv(sd);
    	nullpo_retv(g);
    
    	if (g->emblem_len <= 0)
    		return;
    
    	fd = sd->fd;
    	WFIFOHEAD(fd, g->emblem_len+12);
    	WFIFOW(fd,0) = 0x152;
    	WFIFOW(fd,2) = g->emblem_len+12;
    	WFIFOL(fd,4) = g->guild_id;
    	WFIFOL(fd,8) = g->emblem_id;
    	memcpy(WFIFOP(fd,12),g->emblem_data,g->emblem_len);
    
    	WFIFOSET(fd, WFIFOW(fd,2));
    }
    
    /**
     * Sends guild member list 
     * @param sd  map_session_data to send the packet to
     * @return void
     */
    void hBG_send_guild_member_list(struct map_session_data *sd)
    {
    	int fd, i, c;
    	struct battleground_data *bgd;
    	struct map_session_data *psd;
    	struct hBG_data *hBGd;
    	
    	nullpo_retv(sd);
    
    	if ((fd = sd->fd) == 0)
    		return;
    	if (!sd->bg_id || (bgd = bg->team_search(sd->bg_id)) == NULL)
    		return;
    	else if ((hBGd = getFromBGDATA(bgd, 0)) == NULL)
    		return;
    
    	WFIFOHEAD(fd, bgd->count * 104 + 4);
    	WFIFOW(fd, 0) = 0x154;
    
    	for (i = 0, c = 0; i < bgd->count; i++) {
    		struct hBG_map_session_data *hBGsd;
    
    		if ((psd = bgd->members[i].sd) == NULL)
    			continue;
    
    		if ((hBGsd = getFromMSD(psd, 1)) == NULL)
    			continue;
    
    		WFIFOL(fd,c*104+ 4) = psd->status.account_id;
    		WFIFOL(fd,c*104+ 8) = psd->status.char_id;
    		WFIFOW(fd,c*104+12) = psd->status.hair;
    		WFIFOW(fd,c*104+14) = psd->status.hair_color;
    		WFIFOW(fd,c*104+16) = psd->status.sex;
    		WFIFOW(fd,c*104+18) = psd->status.class;
    		WFIFOW(fd,c*104+20) = psd->status.base_level;
    		WFIFOL(fd,c*104+22) = hBGsd->bg_kills; // Exp slot used to show kills
    		WFIFOL(fd,c*104+26) = 1; // Online
    		WFIFOL(fd,c*104+30) = hBGd->leader_char_id == psd->status.char_id ? 0 : 1; // Position
    		memset(WFIFOP(fd,c*104+34),0,50); // Position Name
    		memcpy(WFIFOP(fd,c*104+84),psd->status.name,NAME_LENGTH); // Player Name
    		c++;
    	}
    
    	WFIFOW(fd, 2)=c*104+4;
    
    	WFIFOSET(fd,WFIFOW(fd,2));
    }
    
    /**
     * Send guild leave packet
     * @param sd map_session_data to send the packet to
     * @param *name contains name of the character.
     * @param *mes  contains leave message from player.
     * @return void
     */
    void hBG_send_leave_single(struct map_session_data *sd, const char *name, const char *mes)
    {
    	unsigned char buf[128];
    	int cmd = 0x15a;
    	const struct s_packet_db *packet = clif->packet(cmd);
    	
    	nullpo_retv(sd);
    	
    	if (packet == NULL)
    		return;
    	
    	WBUFW(buf, 0) = cmd;
    	memcpy(WBUFP(buf, 2), name, NAME_LENGTH);
    	memcpy(WBUFP(buf,26), mes, 40);
    	
    	clif->send(buf, packet->len, &sd->bl, SELF);
    }
    
    /**
     * Notifies clients of a battleground message ZC_BATTLEFIELD_CHAT
     * 02dc <packet len>.W <account id>.L <name>.24B <message>.?B
     *
     * @param bgd battleground_data to send the message to
     * @param src_id id of the source of the message.
     * @param name contains the name of the character.
     * @param mes contains the message to be sent.
     * @param len contains the length of the message.
     * @return void.
     */
    void hBG_send_chat_message(struct battleground_data *bgd, int src_id, const char *name, const char *mes, int len)
    {
    	struct map_session_data *sd;
    	unsigned char *buf;
    
    	nullpo_retv(bgd);
    	nullpo_retv(name);
    	nullpo_retv(mes);
    
    	if ((sd = hBG_getavailablesd(bgd)) == NULL)
    		return;
    
    	len = (int)strlen(mes);
    	Assert_retv(len <= INT16_MAX - NAME_LENGTH - 8);
    	buf = (unsigned char*)aMalloc((len + NAME_LENGTH + 8)*sizeof(unsigned char));
    
    	WBUFW(buf, 0) = 0x2dc;
    
    	WBUFW(buf, 2) = len + NAME_LENGTH + 8;
    	WBUFL(buf, 4) = src_id;
    	memcpy(WBUFP(buf, 8), name, NAME_LENGTH);
    	memcpy(WBUFP(buf, 32), mes, len); // [!] no NULL terminator
    
    	clif->send(buf, WBUFW(buf, 2), &sd->bl, BG);
    
    	if (buf)
    		aFree(buf);
    }
    
    /**
     * Notifies the client of a guild expulsion.
     *
     * @param sd   map_session_data to send the packet to
     * @param *name  contains the name of the character.
     * @param *mes   contains the expulsion message.
     */
    void hBG_send_expulsion(struct map_session_data *sd, const char *name, const char *mes)
    {
    	int fd;
    	int cmd = 0x15c;
    	const struct s_packet_db *packet = clif->packet(cmd);
    	
    	nullpo_retv(sd);
    	
    	if (packet == NULL)
    		return;
    
    	fd = sd->fd;
    	WFIFOHEAD(fd, packet->len);
    	WFIFOW(fd,0) = cmd;
    	safestrncpy((char*)WFIFOP(fd,2), name, NAME_LENGTH);
    	safestrncpy((char*)WFIFOP(fd,26), mes, 40);
    	safestrncpy((char*)WFIFOP(fd,66), "", NAME_LENGTH);
    	WFIFOSET(fd, packet->len);
    }
    
    /**
     * Notifies a single client of BG score updates
     * 
     * @param sd map_session_data to send the packet to
     * @return void
     */
    void hBG_update_score_single(struct map_session_data *sd)
    {
    	int fd;
    	int cmd = 0x2de;
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    	struct hBG_mapflag *hBG_mf = getFromMAPD(&map->list[sd->bl.m], 0);
    	const struct s_packet_db *packet = clif->packet(cmd);
    	
    	nullpo_retv(sd);
    	
    	if (packet == NULL)
    		return;
    	
    	fd = sd->fd;
    
    	WFIFOHEAD(fd, packet->len);
    	WFIFOW(fd,0) = cmd;
    
    	if (map->list[sd->bl.m].flag.battleground == 2) { // Score Board on Map. Team vs Team
    		WFIFOW(fd,2) = map->list[sd->bl.m].bgscore_lion;
    		WFIFOW(fd,4) = map->list[sd->bl.m].bgscore_eagle;
    	} else if (map->list[sd->bl.m].flag.battleground == 3
    			&& (bgd = bg->team_search(sd->bg_id)) != NULL
    			&& (hBGd = getFromBGDATA(bgd, 0)) != NULL) { // Score Board Multiple. Team vs Best Score
    		WFIFOW(fd,2) = hBGd->team_score;
    		WFIFOL(fd,4) = hBG_mf->hBG_topscore;
    	}
    	WFIFOSET(fd, packet->len);
    }
    
    /**
     * Notifies all clients in a Battleground Team
     *
     * @param bgd battleground_data containing the map_session_datas to send the packet to
     * @return void
     */
    void hBG_update_score_team(struct battleground_data *bgd)
    {
    	unsigned char buf[6];
    	struct map_session_data *sd;
    	int i, m, cmd = 0x2de;
    	struct hBG_data *hBGd = getFromBGDATA(bgd, 0);
    	struct hBG_mapflag *hBG_mf;
    	const struct s_packet_db *packet = clif->packet(cmd);
    
    	nullpo_retv(bg);
    
    	if ((m = map->mapindex2mapid(bgd->mapindex)) < 0
    		|| hBGd == NULL
    		|| (hBG_mf = getFromMAPD(&map->list[m], 0)) == NULL
    		|| packet == NULL)
    		return;
    
    	WBUFW(buf,0) = cmd;
    	WBUFW(buf,2) = hBGd->team_score;
    	WBUFW(buf,4) = hBG_mf->hBG_topscore;
    
    	for (i = 0; i < MAX_BG_MEMBERS; i++) {
    		if ((sd = bgd->members[i].sd) == NULL || sd->bl.m != m)
    			continue;
    
    		clif->send(buf, packet->len, &sd->bl, SELF);
    	}
    }
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                    Queue System Functions
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    
    /**
     * Searches hBG_queue_db by q_id
     * @param q_id contains the id of the queue to be searched.
     * @return hBG_queue_data * pointer to the memory location or null if not found.
     */
    struct hBG_queue_data* hBG_queue_search(int q_id)
    { // Search a Queue using q_id
    	if (!q_id)
    		return NULL;
    	
    	return (struct hBG_queue_data *) idb_get(hBG_queue_db, q_id);
    }
    
    /**
     * Creates a Queue
     * @param queue_name contains the name of the queue.
     * @param join_event contains the event run on joining the queue.
     * @param min_level contains the minimum level to be able to join.
     * @return queue_id id of the queue created.
     */
    int hBG_queue_create(const char* queue_name, const char* join_event, int min_level)
    {
    	struct hBG_queue_data *hBGqd;
    	
    	if (++hBG_queue_counter <= 0)
    		hBG_queue_counter = 1;
    
    	CREATE(hBGqd, struct hBG_queue_data, 1);
    	hBGqd->q_id = hBG_queue_counter;
    	
    	safestrncpy(hBGqd->queue_name, queue_name, sizeof(hBGqd->queue_name));
    	safestrncpy(hBGqd->join_event, join_event, sizeof(hBGqd->join_event));
    	
    	hBGqd->first = hBGqd->last = NULL; // First and Last Queue Members
    	hBGqd->users = 0;
    	hBGqd->min_level = min_level;
    	
    	idb_put(hBG_queue_db, hBG_queue_counter, hBGqd);
    
    	return hBGqd->q_id;
    }
    
    /**
     * Remove all queue members from the queue and free the links.
     * @param hBGqd pointer to the queue data.
     * @return void.
     */
    void hBG_queue_members_finalize(struct hBG_queue_data *hBGqd)
    {
    	struct hBG_queue_member *head, *next;
    	
    	nullpo_retv(hBGqd);
    
    	head = hBGqd->first;
    	while (head) {
    		next = head->next;
    		
    		aFree(head);
    		
    		head = next;
    	}
    
    	hBGqd->first = hBGqd->last = NULL;
    	hBGqd->users = 0;
    }
    
    /**
     * Add a player to the queue.
     * @param hBGqd pointer to the queue data.
     * @param sd    player to be added to the queue.
     * @return postition of the player in queue.
     */
    int hBG_queue_member_add(struct hBG_queue_data *hBGqd, struct map_session_data *sd)
    {
    	struct hBG_queue_member *hBGqm;
    
    	nullpo_retr(0, hBGqd);
    	nullpo_retr(0, sd);
    
    	hBGqd->users++;
    	
    	CREATE(hBGqm, struct hBG_queue_member, 1);
    	
    	hBGqm->sd = sd;
    	hBGqm->position = hBGqd->users;
    	hBGqm->next = NULL;
    	
    	if (getFromMSD (sd, 0) == NULL)
    		addToMSD(sd, hBGqd, 0, false);
    	
    	if (hBGqd->last == NULL) {
    		hBGqd->first = hBGqd->last = hBGqm; // Attach to first position
    	} else { // Attach at the end of the queue
    		hBGqd->last->next = hBGqm;
    		hBGqd->last = hBGqm;
    	}
    	
    	return hBGqm->position;
    }
    
    /**
     * Get a member of the queue from position n.
     * @param hBGqd    pointer to the queue data
     * @param position position of the player in queue
     * @return queue_member data or NULL if not found.
     */
    struct hBG_queue_member* hBG_queue_member_get(struct hBG_queue_data *hBGqd, int position)
    {
    	struct hBG_queue_member *head;
    	if (!hBGqd) return NULL;
    
    	head = hBGqd->first;
    	while (head != NULL) {
    		if (head->sd && head->position == position)
    			return head;
    
    		head = head->next;
    	}
    
    	return NULL;
    }
    
    /**
     * Clear a queue and remove from memory.
     * @param hBGqd pointer to queue_data
     * return 1 on success, 0 on failure.
     */
    int hBG_queue_destroy(struct hBG_queue_data *hBGqd)
    {
    	nullpo_ret(hBGqd);
    	
    	hBG_queue_members_finalize(hBGqd);
    	
    	idb_remove(hBG_queue_db, hBGqd->q_id);
    	
    	return 1;
    }
    
    /**
     * Remove a member from a queue
     * @param hBGqd pointer to queue data.
     * @param id    block list ID of player in queue.
     * @return position of a player in the queue or 0 if not found.
     */
    int hBG_queue_member_remove(struct hBG_queue_data *hBGqd, int id)
    {
    	struct hBG_queue_member *head, *previous;
    	int i;
    	
    	nullpo_retr(0, hBGqd);
    
    	head = hBGqd->first;
    	previous = NULL;
    
    	while (head != NULL) {
    		if (head->sd && head->sd->bl.id == id) {
    			struct hBG_queue_member *next;
    			
    			next = head->next;
    			i = head->position;
    			
    			hBGqd->users--;
    			
    			// De-attach target from the main queue
    			if (previous) {
    				previous->next = head->next;
    			} else {
    				hBGqd->first = head->next; // Deleted is on first position
    			}
    			
    			if (head->next == NULL)
    				hBGqd->last = previous; // Deleted is on last position
    			
    			while (next != NULL) {
    				next->position--; // Decrement positions of the next in queue.
    				next = next->next;
    			}
    			
    			aFree(head);
    			
    			return i;
    		}
    
    		previous = head;
    		head = head->next;
    	}
    
    	return 0;
    }
    
    /**
     * Search a member in the queue by Block List ID.
     * @param hBGqd pointer to queue data.
     * @param id    block list ID of a player in queue.
     * @return position of a player in the queue or 0 if not found.
     */
    int hBG_queue_member_search(struct hBG_queue_data *hBGqd, int id)
    {
    	struct hBG_queue_member *head;
    	
    	nullpo_retr(0,hBGqd);
    
    	head = hBGqd->first;
    
    	while (head != NULL) {
    		if (head->sd && head->sd->bl.id == id)
    			return head->position;
    
    		head = head->next;
    	}
    
    	return 0; // Not Found
    }
    
    /**
     * Add a player to the queue.
     * @param sd pointer to player to be added in queue.
     * @param q_id ID of the queue to be appended.
     * @return 0 on failure, 1 on success.
     */
    int hBG_queue_join(struct map_session_data *sd, int q_id)
    {
    	char output[128];
    	struct hBG_queue_data *hBGqd;
    	int i = 0;
    	int login_ip_count = hBG_config_get("battle_configuration/hBG_ip_check");
    	
    	nullpo_ret(sd);
    	
    	if (hBG_config_get("battle_configuration/hBG_from_town_only") && map->list[sd->bl.m].flag.town == 0) {
    		clif->message(sd->fd,"You only can join BG queues from Towns or BG Waiting Room.");
    		return 0;
    	} else if (sd->bg_id) {
    		clif->message(sd->fd,"You cannot join queues when already playing Battlegrounds.");
    		return 0;
    	} else if (sd->sc.data[SC_JAILED]) {
    		clif->message(sd->fd,"You cannot join queues when jailed.");
    		return 0;
    	}
    	// Get Queue by ID
    	if ((hBGqd = hBG_queue_search(q_id)) == NULL) {
    		return 0; // Current Queue don't exists
    	} else if ((i = hBG_queue_member_search(hBGqd, sd->bl.id))) { // You cannot join a Queue if you are already in one.
    		sprintf(output, "You are already in %s queue at position %d.", hBGqd->queue_name, i);
    		clif->message(sd->fd, output);
    		return 0;
    	} else if (hBGqd && hBGqd->min_level && sd->status.base_level < hBGqd->min_level) {
    		sprintf(output,"You cannot join %s queue. Required min level is %ud.", hBGqd->queue_name, hBGqd->min_level);
    		clif->message(sd->fd,output);
    		return 0;
    	} else if (login_ip_count && hBG_countlogin(sd,false) > login_ip_count) {
    		sprintf(output,"You cannot join %s queue. A max of %d characters are using your IP address.", hBGqd->queue_name, login_ip_count);
    		clif->message(sd->fd,output);
    		return 0;
    	}
    
    	i = hBG_queue_member_add(hBGqd, sd);
    	
    	sprintf(output,"You have joined %s queue at position %d.", hBGqd->queue_name, i);
    	
    	clif->message(sd->fd,output);
    
    	if (hBGqd->join_event[0])
    		npc->event_do(hBGqd->join_event);
    
    	return i;
    }
    
    /**
     * Process player leaving a queue.
     * @param sd pointer to player leaving the queue.
     * @param q_id ID of the queue to be left.
     * @return 0 on failure, 1 on success.
     */
    int hBG_queue_leave(struct map_session_data *sd, int q_id)
    {
    	char output[128];
    	struct hBG_queue_data *qd;
    
    	if ((qd = hBG_queue_search(q_id)) == NULL)
    		return 0;
    
    	if (!hBG_queue_member_remove(qd,sd->bl.id)) {
    		sprintf(output,"You are not in the %s queue.", qd->queue_name);
    		clif->message(sd->fd,output);
    		return 0;
    	}
    	
    	sprintf(output, "You have been removed from the %s queue.", qd->queue_name);
    	clif->message(sd->fd, output);
    
    	return 1;
    }
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                     Battleground Functions
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    /**
     * Return any available player in a Battleground
     * @param bgd pointer to battleground queue.
     * @return map_session_data *sd pointer to player data or NULL if not found.
     */
    struct map_session_data* hBG_getavailablesd(struct battleground_data *bgd)
    {
    	int i;
    	nullpo_retr(NULL, bgd);
    	ARR_FIND(0, MAX_BG_MEMBERS, i, bgd->members[i].sd != NULL);
    	return(i < MAX_BG_MEMBERS) ? bgd->members[i].sd : NULL;
    }
    
    /**
     * Count the number of players with the same IP in battlegrounds.
     * @param sd pointer to map session data.
     * @param check_bat_room boolean to include checks in bat_room.
     * @return amount of accounts online.
     */
    int hBG_countlogin(struct map_session_data *sd, bool check_bat_room)
    {
    	int c = 0, m = map->mapname2mapid("bat_room");
    	struct map_session_data* pl_sd;
    	struct s_mapiterator* iter;
    	nullpo_ret(sd);
    
    	iter = mapit_getallusers();
    	for (pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter)) {
    		if (!(getFromMSD(sd, 0) || map->list[pl_sd->bl.m].flag.battleground || (check_bat_room && pl_sd->bl.m == m)))
    			continue;
    		if (sockt->session[sd->fd]->client_addr == sockt->session[pl_sd->fd]->client_addr)
    			c++;
    	}
    	mapit->free(iter);
    	return c;
    }
    
    /**
     * Performs initialization tasks on new battlegrounds.
     * @param m map Index
     * @param rx respawn X co-ordinate
     * @param ry respawn Y co-ordinate
     * @param guild_index Index of the BG guild to be used
     * @param *ev NPC Script event to be called when player logs out.
     * @param *dev NPC Script event to be called when player dies.
     * @return ID of the battleground.
     */
    int hBG_create(unsigned short m, short rx, short ry, int guild_index, const char *ev, const char *dev)
    {
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    
    	CREATE(bgd, struct battleground_data, 1);
    	CREATE(hBGd, struct hBG_data, 1);
    
    	if (++bg_team_counter <= 0)
    		bg_team_counter = 1;
    
    	bgd->bg_id = bg_team_counter;
    	bgd->count = 0;
    	bgd->mapindex = m;
    	bgd->x = rx;
    	bgd->y = ry;
    
    	safestrncpy(bgd->logout_event, ev, sizeof(bgd->logout_event));
    	safestrncpy(bgd->die_event, dev, sizeof(bgd->die_event));
    
    	memset(&bgd->members, 0, sizeof(bgd->members));
    
    	hBGd->color = bg_colors[guild_index];
    	hBGd->created_at = 0;
    	hBGd->g = &bg_guild[guild_index];
    
    	addToBGDATA(bgd, hBGd, 0, true);
    
    	idb_put(bg->team_db, bg_team_counter, bgd);
    
    	return bgd->bg_id;
    }
    
    /**
     * Add a player to the Battleground Team
     * @param bg_id Id of the battleground
     * @param sd pointer to the player's session data.
     * @return 0 on failure, 1 on success.
     */
    int hBG_team_join(int bg_id, struct map_session_data *sd)
    { // Player joins team
    	int i;
    	struct battleground_data *bgd = bg->team_search(bg_id);
    	struct map_session_data *pl_sd;
    	struct hBG_map_session_data *hBGsd;
    	struct hBG_data *hBGd;
    
    	if (bgd == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL || sd == NULL || sd->bg_id)
    		return 0;
    
    	ARR_FIND(0, MAX_BG_MEMBERS, i, bgd->members[i].sd == NULL);
    	
    	if (i == MAX_BG_MEMBERS)
    		return 0; // No free slots
    
    	// Handle Additional Map Session BG data
    	if ((hBGsd = getFromMSD(sd, 1)) == NULL) {
    		CREATE(hBGsd, struct hBG_map_session_data, 1);
    		addToMSD(sd, hBGsd, 1, false);
    	}
    	
    	hBGsd->bg_kills = 0;
    	hBGsd->state.afk = 0;
    
    	// Update player's idle item.
    	pc->update_idle_time(sd, BCIDLE_WALK);
    
    	sd->bg_id = bg_id;
    
    	// Battleground Member data
    	bgd->members[i].sd = sd;
    	bgd->members[i].x = sd->bl.x;
    	bgd->members[i].y = sd->bl.y;
    	bgd->count++;
    	
    	// Guild Member Data simulation
    	hBGd->g->member[i].sd = sd;
    
    	// Creation Tick = First member joined.
    	if (hBGd->created_at == 0)
    		hBGd->created_at = sockt->last_tick;
    
    	// First Join = Team Leader
    	if (hBGd->leader_char_id == 0)
    		hBGd->leader_char_id = sd->status.char_id;
    
    	guild->send_dot_remove(sd);
    
    	hBG_send_guild_info(sd); // Send Guild Name/Emblem under character
    	
    	clif->charnameupdate(sd); // Update character's nameplate
    	
    	for (i = 0; i < MAX_BG_MEMBERS; i++) {
    		if ((pl_sd = bgd->members[i].sd) == NULL)
    			continue;
    
    		// Simulate Guild Information
    		hBG_guild_window_info(pl_sd); // Main Guild window information.
    		hBG_send_emblem(pl_sd, hBGd->g); // Emblems
    		hBG_send_guild_member_list(pl_sd); // Member list
    		hBG_send_guild_skillinfo(sd); // Send Guild skill information.
    
    		if (pl_sd != sd)
    			hBG_send_hp_single(sd->fd,pl_sd);
    	}
    
    	clif->guild_emblem_area(&sd->bl);
    
    	clif->bg_hp(sd);
    	clif->bg_xy(sd);
    
    	return 1;
    }
    
    /**
     * Reveal a player's position to another player.
     * @param bl pointer to block list.
     * @param ap list of arguments
     * @return 0.
     */
    int hBG_reveal_pos(struct block_list *bl, va_list ap)
    {
    	struct map_session_data *pl_sd, *sd = NULL;
    	int flag, color;
    
    	pl_sd = (struct map_session_data *)bl;
    	sd = va_arg(ap,struct map_session_data *); // Source
    	flag = va_arg(ap,int);
    	color = va_arg(ap,int);
    
    	if (pl_sd->bg_id == sd->bg_id)
    		return 0; // Same Team
    
    	clif->viewpoint(pl_sd,sd->bl.id,flag,sd->bl.x,sd->bl.y,sd->bl.id,color);
    	return 0;
    }
    
    /**
     * Remove minimap indicator for player.
     * @param sd pointer to session data.
     * @return 0
     */
    int hBG_send_dot_remove(struct map_session_data *sd)
    {
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    	int m;
    
    	if (sd && sd->bg_id && (bgd = bg->team_search(sd->bg_id)) != NULL
    	   && (hBGd = getFromBGDATA(bgd, 0)) != NULL) {
    		clif->bg_xy_remove(sd);
    		if (hBGd->reveal_pos && (m = map->mapindex2mapid(bgd->mapindex)) == sd->bl.m)
    			map->foreachinmap(hBG_reveal_pos, m,BL_PC,sd,2,0xFFFFFF);
    	}
    	return 0;
    }
    
    /**
     * Searches and removes battleground game specific 
     * items from the player's inventory.
     * @param sd as struct map_session_data
     */
    void hBG_member_remove_bg_items(struct map_session_data *sd)
    {
    	int n;
    	
    	nullpo_retv(sd);
    	
    	if ((n = pc->search_inventory(sd,BLUE_SKULL)) >= 0)
    		pc->delitem(sd, n, sd->status.inventory[n].amount, 0, 2, LOG_TYPE_CONSUME);
    	
    	if ((n = pc->search_inventory(sd,RED_SKULL)) >= 0)
    		pc->delitem(sd, n, sd->status.inventory[n].amount, 0, 2,LOG_TYPE_CONSUME);
    	
    	if ((n = pc->search_inventory(sd,GREEN_SKULL)) >= 0)
    		pc->delitem(sd, n, sd->status.inventory[n].amount, 0, 2,LOG_TYPE_CONSUME);
    }
    
    /**
     * Get guild data of the Battleground
     * @param bg_id ID of the battleground
     * @return guild of the battleground or NULL.
     */
    struct guild* hBG_get_guild(int bg_id)
    {
    	struct battleground_data *bgd = bg->team_search(bg_id);
    	struct hBG_data *hBGd;
    
    	if (bgd == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL)
    		return NULL;
    
    	return hBGd->g;
    }
    
    /**
     * Remove all members from a BG Team.
     * @param bg_id ID of the battleground.
     * @param remove Boolean for removal of BG from team_db.
     * @return 0 on failure, 1 on success.
     */
    int hBG_team_finalize(int bg_id, bool remove)
    { // Deletes BG Team from db
    	int i;
    	struct map_session_data *sd;
    	struct battleground_data *bgd = bg->team_search(bg_id);
    	struct hBG_data *hBGd;
    	struct guild *g;
    
    	if (bgd == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL)
    		return 0;
    
    	for (i = 0; i < MAX_BG_MEMBERS; i++) {
    		if ((sd = bgd->members[i].sd) == NULL)
    			continue;
    
    		hBG_send_dot_remove(sd);
    		sd->bg_id = 0;
    
    		// Remove Guild Skill Buffs
    		status_change_end(&sd->bl, SC_GUILDAURA, INVALID_TIMER);
    		status_change_end(&sd->bl, SC_GDSKILL_BATTLEORDER, INVALID_TIMER);
    		status_change_end(&sd->bl, SC_GDSKILL_REGENERATION, INVALID_TIMER);
    
    		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 {
    			hBG_send_leave_single(sd, sd->status.name, "Leaving Battle...");
    		}
    
    		clif->charnameupdate(sd);
    		clif->guild_emblem_area(&sd->bl);
    	}
    
    	if (remove) {
    		idb_remove(bg->team_db, bg_id);
    	} else {
    		bgd->count = 0;
    		hBGd->leader_char_id = 0;
    		hBGd->team_score = 0;
    		hBGd->created_at = 0;
    		memset(&bgd->members, 0, sizeof(bgd->members));
    	}
    
    	return 1;
    }
    
    /**
     * Give items to the Battleground Team.
     * @param bg_id ID of the battleground.
     * @param nameid ID of the item.
     * @param amount Amount of the Item to be given.
     * @return void;
     */
    void hBG_team_getitem(int bg_id, int nameid, int amount)
    {
    	struct battleground_data *bgd;
    	struct map_session_data *sd;
    	struct item_data *id;
    	struct item it;
    	int reward_rate = hBG_config_get("battle_configuration/bg_reward_rates");
    	int get_amount, j, flag;
    
    	if (amount < 1 || (bgd = bg->team_search(bg_id)) == NULL || (id = itemdb->exists(nameid)) == NULL)
    		return;
    	if (nameid != 7828 && nameid != 7829 && nameid != 7773)
    		return;
    	if (reward_rate != 100)
    		amount = amount * reward_rate / 100;
    
    	memset(&it, 0, sizeof(it));
    	it.nameid = nameid;
    	it.identify = 1;
    
    	for (j = 0; j < MAX_BG_MEMBERS; j++) {
    		if ((sd = bgd->members[j].sd) == NULL)
    			continue;
    
    		get_amount = amount;
    
    		if ((flag = pc->additem(sd,&it,get_amount,LOG_TYPE_SCRIPT)))
    			clif->additem(sd,0,0,flag);
    	}
    }
    
    /**
     * Give kafra points to the team.
     * @param bg_id ID of the battleground.
     * @param amount Amount of kafra points to be given.
     */
    void hBG_team_get_kafrapoints(int bg_id, int amount)
    {
    	struct battleground_data *bgd;
    	struct map_session_data *sd;
    	int i, get_amount, reward_rate = hBG_config_get("battle_configuration/bg_reward_rates");
    
    	if ((bgd = bg->team_search(bg_id)) == NULL)
    		return;
    
    	if (reward_rate != 100)
    		amount = amount * reward_rate/ 100;
    
    	for (i = 0; i < MAX_BG_MEMBERS; i++) {
    		if ((sd = bgd->members[i].sd) == NULL)
    			continue;
    
    		get_amount = amount;
    		pc->getcash(sd,0,get_amount);
    	}
    }
    
    void hBG_add_rank_points(struct map_session_data *sd, int ranktype, int count)
    {
    	struct hBG_map_session_data *hBGsd;
    	char message[100];
    	
    	nullpo_retv(sd);
    	
    	if ((hBGsd = getFromMSD(sd, 1)) == NULL)
    		return;
    	
    	if (ranktype == BG_RANKED) {
    		add2limit(hBGsd->stats.ranked_points, count, MAX_FAME);
    		sprintf(message, "[Battlegrounds Ranked] Your ranking has increased by %d.", count);
    		clif->disp_message(&sd->bl, message, SELF);
    		hookStop();
    	} else if (ranktype == BG_NORMAL) {
    		add2limit(hBGsd->stats.points, count, MAX_FAME);
    		sprintf(message, "[Battlegrounds Normal] Your ranking has increased by %d.", count);
    		clif->disp_message(&sd->bl, message, SELF);
    		hookStop();
    	}
    }
    
    /* ==============================================================
     bg_arena (0 EoS | 1 Boss | 2 TI | 3 CTF | 4 TD | 5 SC | 6 CON | 7 RUSH | 8 DOM)
     bg_result (0 Won | 1 Tie | 2 Lost)
     ============================================================== */
    void hBG_team_rewards(int bg_id, int nameid, int amount, int kafrapoints, int quest_id, const char *var, int add_value, int bg_arena, int bg_result)
    {
    	struct battleground_data *bgd = NULL;
    	struct map_session_data *sd = NULL;
    	struct hBG_map_session_data *hBGsd = NULL;
    	struct hBG_data *hBGd = NULL;
    	struct item_data *id;
    	struct item it;
    	int j, flag, get_amount,
    	reward_rate = hBG_config_get("battle_configuration/hBG_reward_rates"), fame = 0, type = 0;
    	
    	if (amount < 1 || (bgd = bg->team_search(bg_id)) == NULL || (id = itemdb->exists(nameid)) == NULL)
    		return;
    
    	if (reward_rate != 100) { // BG Reward Rates
    		amount = amount * reward_rate / 100;
    		kafrapoints = kafrapoints * reward_rate / 100;
    	}
    	
    	memset(&it,0,sizeof(it));
    	
    	bg_result = cap_value(bg_result, 0, 2);
    	
    	if (nameid == 7828 || nameid == 7829 || nameid == 7773) {
    		it.nameid = nameid;
    		it.identify = 1;
    	} else {
    		nameid = 0;
    	}
    
    	for (j = 0; j < MAX_BG_MEMBERS; j++) {
    		if ((sd = bgd->members[j].sd) == NULL)
    			continue;
    		else if ((hBGsd = getFromMSD(sd, 1)) == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL)
    			continue;
    
    		if (quest_id)
    			quest->add(sd, quest_id, 0);
    		
    		pc_setglobalreg(sd, script->add_str(var), pc_readglobalreg(sd,script->add_str(var)) + add_value);
    
    		if (kafrapoints > 0) {
    			get_amount = kafrapoints;
    			pc->getcash(sd,0,get_amount);
    		}
    
    		if (nameid && amount > 0) {
    			get_amount = amount;
    
    			if ((flag = pc->additem(sd,&it,get_amount,LOG_TYPE_SCRIPT)))
    				clif->additem(sd,0,0,flag);
    		}
    		
    		type = hBG_config_get("battle_configuration/hBG_ranked_mode")?BG_RANKED:BG_NORMAL;
    		
    		switch (bg_result) {
    			case 0: // Won
    				add2limit(hBGsd->stats.wins,1,USHRT_MAX);
    				fame = 100;
    				if (sd->status.char_id == hBGd->leader_char_id) {
    					add2limit(hBGsd->stats.wins_as_leader,1,USHRT_MAX);
    					fame += 25;
    				}
    				
    				hBG_add_rank_points(sd, fame, type);
    				
    				switch (bg_arena) {
    					case 0:
    						add2limit(hBGsd->stats.eos_wins,1,USHRT_MAX);
    						break;
    					case 1:
    						add2limit(hBGsd->stats.boss_wins,1,USHRT_MAX);
    						break;
    					case 2:
    						add2limit(hBGsd->stats.ti_wins,1,USHRT_MAX);
    						break;
    					case 3:
    						add2limit(hBGsd->stats.ctf_wins,1,USHRT_MAX);
    						break;
    					case 4:
    						add2limit(hBGsd->stats.td_wins,1,USHRT_MAX);
    						break;
    					case 5:
    						add2limit(hBGsd->stats.sc_wins,1,USHRT_MAX);
    						break;
    					case 6:
    						add2limit(hBGsd->stats.conquest_wins,1,USHRT_MAX);
    						break;
    					case 7:
    						add2limit(hBGsd->stats.ru_wins,1,USHRT_MAX);
    						break;
    					case 8:
    						add2limit(hBGsd->stats.dom_wins,1,USHRT_MAX);
    						break;
    				}
    				break;
    			case 1: // Tie
    				add2limit(hBGsd->stats.ties,1,USHRT_MAX);
    				fame = 75;
    				if (sd->status.char_id == hBGd->leader_char_id) {
    					add2limit(hBGsd->stats.ties_as_leader,1,USHRT_MAX);
    					fame += 10;
    				}
    				hBG_add_rank_points(sd, fame, type);
    				switch (bg_arena) {
    					case 0: add2limit(hBGsd->stats.eos_tie,1,USHRT_MAX); break;
    					case 1: add2limit(hBGsd->stats.boss_tie,1,USHRT_MAX); break;
    					case 2: add2limit(hBGsd->stats.ti_tie,1,USHRT_MAX); break;
    					case 3: add2limit(hBGsd->stats.ctf_tie,1,USHRT_MAX); break;
    					case 4: add2limit(hBGsd->stats.td_tie,1,USHRT_MAX); break;
    					case 5: add2limit(hBGsd->stats.sc_tie,1,USHRT_MAX); break;
    						// No Tie for Conquest or Rush
    					case 8: add2limit(hBGsd->stats.dom_tie,1,USHRT_MAX); break;
    				}
    				break;
    			case 2: // Lost
    				add2limit(hBGsd->stats.losses,1,USHRT_MAX);
    				
    				fame = 50;
    				
    				if (sd->status.char_id == hBGd->leader_char_id)
    					add2limit(hBGsd->stats.losses_as_leader,1,USHRT_MAX);
    				
    				hBG_add_rank_points(sd, fame, type);
    				
    				switch (bg_arena) {
    					case 0: add2limit(hBGsd->stats.eos_lost,1,USHRT_MAX); break;
    					case 1: add2limit(hBGsd->stats.boss_lost,1,USHRT_MAX); break;
    					case 2: add2limit(hBGsd->stats.ti_lost,1,USHRT_MAX); break;
    					case 3: add2limit(hBGsd->stats.ctf_lost,1,USHRT_MAX); break;
    					case 4: add2limit(hBGsd->stats.td_lost,1,USHRT_MAX); break;
    					case 5: add2limit(hBGsd->stats.sc_lost,1,USHRT_MAX); break;
    					case 6: add2limit(hBGsd->stats.conquest_losses,1,USHRT_MAX); break;
    					case 7: add2limit(hBGsd->stats.ru_lost,1,USHRT_MAX); break;
    					case 8: add2limit(hBGsd->stats.dom_lost,1,USHRT_MAX); break;
    				}
    				break;
    		}
    	}
    }
    
    /**
     * Build BG Guild Emulation data.
     * @params (void)
     * @return void.
     */
    void hBG_build_guild_data(void)
    {
    	int i, j, k, gskill;
    	memset(&bg_guild, 0, sizeof(bg_guild));
    
    	for (i = 1; i <= MAX_BATTLEGROUND_TEAMS; i++) { // Emblem Data - Guild ID's
    		FILE* fp = NULL;
    		char gpath[256];
    
    		j = i - 1;
    		bg_guild[j].emblem_id = 1; // Emblem Index
    		bg_guild[j].guild_id = SHRT_MAX - j;
    		bg_guild[j].guild_lv = 1;
    		bg_guild[j].max_member = MAX_BG_MEMBERS;
    
    		// Skills
    		if (j < 3) { // Clan Skills
    			for (k = 0; k < MAX_GUILDSKILL; k++) {
    				gskill = k + GD_SKILLBASE;
    				bg_guild[j].skill[k].id = gskill;
    				switch (gskill) {
    					case GD_GLORYGUILD:
    						bg_guild[j].skill[k].lv = 0;
    						break;
    					case GD_APPROVAL:
    					case GD_KAFRACONTRACT:
    					case GD_GUARDRESEARCH:
    					case GD_BATTLEORDER:
    					case GD_RESTORE:
    					case GD_EMERGENCYCALL:
    					case GD_DEVELOPMENT:
    						bg_guild[j].skill[k].lv = 1;
    						break;
    					case GD_GUARDUP:
    					case GD_REGENERATION:
    						bg_guild[j].skill[k].lv = 3;
    						break;
    					case GD_LEADERSHIP:
    					case GD_GLORYWOUNDS:
    					case GD_SOULCOLD:
    					case GD_HAWKEYES:
    						bg_guild[j].skill[k].lv = 5;
    						break;
    					case GD_EXTENSION:
    						bg_guild[j].skill[k].lv = 10;
    						break;
    				}
    			}
    		} else { // Other Data
    			snprintf(bg_guild[j].name, NAME_LENGTH, "Team %d", i - 3); // Team 1, Team 2 ... Team 10
    			strncpy(bg_guild[j].master, bg_guild[j].name, NAME_LENGTH);
    			snprintf(bg_guild[j].position[0].name, NAME_LENGTH, "%s Leader", bg_guild[j].name);
    			strncpy(bg_guild[j].position[1].name, bg_guild[j].name, NAME_LENGTH);
    		}
    
    		sprintf(gpath, "%s/%s/bg_%d.ebm", "plugins","hBG", i);
    		if ((fp = fopen(gpath, "rb")) != NULL) {
    			fseek(fp, 0, SEEK_END);
    			bg_guild[j].emblem_len = (int)ftell(fp);
    			fseek(fp, 0, SEEK_SET);
    			fread(&bg_guild[j].emblem_data, 1, bg_guild[j].emblem_len, fp);
    			fclose(fp);
    		} else {
    			ShowWarning("Error reading '"CL_WHITE"%s"CL_RESET"' emblem data file.\n", gpath);
    		}
    	}
    	
    	ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"' v%s emblem data files. [By Smokexyz]\n", pinfo.name, pinfo.version);
    
    	// Guild Data - Guillaume
    	strncpy(bg_guild[0].name, "Blue Team", NAME_LENGTH);
    	strncpy(bg_guild[0].master, "General Guillaume", NAME_LENGTH);
    	strncpy(bg_guild[0].position[0].name, "Blue Team Leader", NAME_LENGTH);
    	strncpy(bg_guild[0].position[1].name, "Blue Team", NAME_LENGTH);
    
    	// Guild Data - Croix
    	strncpy(bg_guild[1].name, "Red Team", NAME_LENGTH);
    	strncpy(bg_guild[1].master, "Prince Croix", NAME_LENGTH);
    	strncpy(bg_guild[1].position[0].name, "Red Team Leader", NAME_LENGTH);
    	strncpy(bg_guild[1].position[1].name, "Red Team", NAME_LENGTH);
    
    	// Guild Data - Traitors
    	strncpy(bg_guild[2].name, "Green Team", NAME_LENGTH);
    	strncpy(bg_guild[2].master, "Mercenary", NAME_LENGTH);
    	strncpy(bg_guild[2].position[0].name, "Green Team Leader", NAME_LENGTH);
    	strncpy(bg_guild[2].position[1].name, "Green Team", NAME_LENGTH);
    }
    
    /**
     * Timer function for revealing/hiding mini map positions.
     * Also handles player AFK mechanic.
     * @see DBApply
     * @see hBG_send_xy_timer
     * @param data battleground data pointer.
     * @return int
     */
    int hBG_send_xy_timer_sub(union DBKey key, struct DBData *data, va_list ap)
    {
    	struct battleground_data *bgd = DB->data2ptr(data);
    	struct hBG_data *hBGd = getFromBGDATA(bgd, 0);
    	char output[128];
    	int i, m, idle_announce = hBG_config_get("battle_configuration/hBG_idle_announce"),
    		idle_autokick = hBG_config_get("battle_configuration/hBG_idle_autokick");
    
    	nullpo_ret(bgd);
    	nullpo_ret(hBGd);
    
    	m = map->mapindex2mapid(bgd->mapindex);
    	hBGd->reveal_flag = !hBGd->reveal_flag; // Switch
    
    	for (i = 0; i < MAX_BG_MEMBERS; i++) {
    		struct map_session_data *sd = bgd->members[i].sd;
    		struct hBG_map_session_data *hBGsd = NULL;
    
    		if (sd == NULL || (hBGsd = getFromMSD(sd, 1)) == NULL)
    			continue;
    
    		if (idle_autokick && DIFF_TICK(sockt->last_tick, sd->idletime) >= idle_autokick
    			&& hBGd->g && map->list[sd->bl.m].flag.battleground)
    		{
    			sprintf(output, "[Battlegrounds] %s has been kicked for being AFK.", sd->status.name);
    			clif->broadcast2(&sd->bl, output, (int)strlen(output)+1, hBGd->color, 0x190, 20, 0, 0, BG);
    
    			bg->team_leave(sd,3);
    
    			clif->message(sd->fd, "You have been kicked from the battleground because of your AFK status.");
    			pc->setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, 3);
    			continue;
    		} else if (sd->bl.x != bgd->members[i].x || sd->bl.y != bgd->members[i].y) { // xy update
    			bgd->members[i].x = sd->bl.x;
    			bgd->members[i].y = sd->bl.y;
    			clif->bg_xy(sd);
    		}
    		
    		if (hBGd->reveal_pos && hBGd->reveal_flag && sd->bl.m == m)
    			map->foreachinmap(hBG_reveal_pos, m, BL_PC, sd, 1, hBGd->color);
    		
    		// Message for AFK Idling
    		if (idle_announce && DIFF_TICK(sockt->last_tick, sd->idletime) >= idle_announce && !hBGsd->state.afk && hBGd->g)
    		{ // Set AFK status and announce to the team.
    			hBGsd->state.afk = 1;
    			sprintf(output, "%s : %s seems to be away. AFK Warning - Can be kicked out with @reportafk.", hBGd->g->name, sd->status.name);
    			hBG_send_chat_message(bgd, sd->bl.id, sd->status.name, output, (int)strlen(output) + 1);
    		}
    	}
    
    	return 0;
    }
    
    /**
     * Timer function for revealing/hiding mini map positions.
     * Also handles player AFK time.
     * @see hBG_send_xy_timer_sub
     */
    int hBG_send_xy_timer(int tid, int64 tick, int id, intptr_t data)
    {
    	bg->team_db->foreach(bg->team_db, hBG_send_xy_timer_sub, tick);
    	return 0;
    }
    
    /**
     * Add an item to the floor at m (x,y)
     * @param bl pointer to the block list.
     * @param m map index
     * @param x map x co-ordinate
     * @param y map y co-ordinate
     * @param nameid ID of the item to be dropped.
     * @param amount Amount of the item to be dropped.
     * @return count of the item dropped.
     */
    int hBG_addflooritem_area(struct block_list* bl, int16 m, int16 x, int16 y, int nameid, int amount)
    {
    	struct item item_tmp;
    	int count, range, i;
    	short mx, my;
    	
    	memset(&item_tmp, 0, sizeof(item_tmp));
    	item_tmp.nameid = nameid;
    	item_tmp.identify = 1;
    	
    	if (bl != NULL) m = bl->m;
    	
    	count = 0;
    	range = (int)sqrt((float)amount) +2;
    	
    	for ( i = 0; i < amount; i++) {
    		if (bl != NULL)
    			map->search_freecell(bl, 0, &mx, &my, range, range, 0);
    		else {
    			mx = x; my = y;
    			map->search_freecell(NULL, m, &mx, &my, range, range, 1);
    		}
    		
    		count += (map->addflooritem(bl, &item_tmp, 1, m, mx, my, 0, 0, 0, 4, false) != 0) ? 1 : 0;
    	}
    	
    	return count;
    }
    
    // @TODO
    void hBG_bg_ranking_display(struct map_session_data *sd, bool ranked)
    {
    	struct hBG_map_session_data *hBGsd = NULL;
    	
    	nullpo_retv(sd);
    	
    	if ((hBGsd = getFromMSD(sd, 1)) == NULL)
    		return;
    	
    	// print shit.
    	
    }
    
    void hBG_record_mobkills(struct map_session_data *sd, struct mob_data *md)
    {
    	struct battleground_data *bgd = NULL;
    	struct hBG_data *hBGd = NULL;
    	struct hBG_map_session_data *hBGsd = NULL;
    
    	nullpo_retv(sd);
    	nullpo_retv(md);
    
    	if (map->list[sd->bl.m].flag.battleground && sd->bg_id) {
    		int i;
    		if ((bgd = bg->team_search(sd->bg_id)) == NULL)
    			return;
    		if ((hBGd = getFromBGDATA(bgd, 0)) == NULL)
    			return;
    		if ((hBGsd = getFromMSD(sd, 1)) == NULL)
    			return;
    
    		ARR_FIND(0, MAX_BG_MEMBERS, i, bgd->members[i].sd == sd);
    
    		if (i >= MAX_BG_MEMBERS)
    			return;
    
    		switch ( md->class_)
    		{
    		case E_BAPHOMET2:
    		case E_LORD_OF_DEATH2:
    		case E_DARK_LORD:
    		case E_KTULLANUX:
    		case E_DARK_SNAKE_LORD:
    			add2limit(hBGsd->stats.boss_killed, 1, USHRT_MAX);
    			break;
    		case E_TURTLE_GENERAL:
    		case E_APOCALIPS_H:
    			add2limit(hBGsd->stats.guardian_stone_kills, 1, USHRT_MAX);
    			break;
    		case E_FALLINGBISHOP:
    			if (map->list[sd->bl.m].flag.battleground == 2)
    				add2limit(hBGsd->stats.ru_captures, 1, USHRT_MAX);
    			break;
    		case OBJ_NEUTRAL:
    			if (strcmpi(map->list[sd->bl.m].name, "bat_a03") == 0)
    				add2limit(hBGsd->stats.boss_flags, 1, USHRT_MAX);
    			break;
    		case BARRICADE_:
    			if (strcmpi(map->list[sd->bl.m].name, "bat_a01") == 0)
    				add2limit(hBGsd->stats.barricade_kills, 1, USHRT_MAX);
    			break;
    		}
    	}
    }
    
    void hBG_record_damage(struct block_list *src, struct block_list *target, int damage)
    {
    	struct block_list *s_bl = NULL;
    	struct map_session_data *sd = NULL;
    	struct hBG_map_session_data *hBGsd = NULL;
    
    	if (src == NULL || target == NULL || src == target || damage <= 0)
    		return;
    
    	if ((s_bl = battle->get_master(src)) == NULL)
    		s_bl = src;
    
    	if (s_bl->type != BL_PC)
    		return;
    
    	if ((sd = BL_UCAST(BL_PC, s_bl)) == NULL)
    		return;
    
    	if ((hBGsd = getFromMSD(sd, 1)) == NULL)
    		return;
    
    	switch ( target->type)
    	{
    	case BL_PC:
    		{
    			struct map_session_data *tsd = NULL;
    			struct hBG_map_session_data *hBGtsd = NULL;
    
    			if ((tsd = BL_UCAST(BL_PC, target)) == NULL)
    				break;
    			if ((hBGtsd = getFromMSD(tsd, 1)) == NULL)
    				break;
    
    			if (map->list[src->m].flag.battleground && sd->bg_id) {
    				add2limit(hBGsd->stats.total_damage_done, damage, UINT_MAX);
    				add2limit(hBGtsd->stats.total_damage_received, damage, UINT_MAX);
    
    				if (hBGsd->stats.best_damage < damage)
    					hBGsd->stats.best_damage = damage;
    			}
    		}
    		break;
    	case BL_MOB:
    		{
    			struct mob_data *md = BL_UCAST(BL_MOB, target);
    			if (map->list[src->m].flag.battleground && sd->bg_id && md->class_ >= E_BAPHOMET2 && md->class_ <= E_FALLINGBISHOP)
    				add2limit(hBGsd->stats.boss_damage, damage, USHRT_MAX);
    		}
    		break;
    	}
    }
    
    /**
     * Warps a Team
     * @see hBG_warp
     */
    int hBG_team_warp(int bg_id, unsigned short mapidx, short x, short y)
    { // Warps a Team
    	int i;
    	struct battleground_data *bgd = bg->team_search(bg_id);
    
    	if (bgd == NULL) {
    		ShowError("buildin_hBG_team_warp: Invalid teamId %d provided!", bg_id);
    		return false;
    	}
    
    	if (mapidx == 0) { // BG Cemetery (Spawn Point)
    		mapidx = bgd->mapindex;
    		x = bgd->x;
    		y = bgd->y;
    	}
    
    	for (i = 0; i < bgd->count; i++)
    		if (bgd->members[i].sd != NULL)
    			pc->setpos(bgd->members[i].sd, mapidx, x, y, CLR_TELEPORT);
    
    	return true;
    }
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                     @Commands
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    /**
     * Display battleground rankings.
     */
    ACMD(bgrank)
    {
    	char mode[7];
    	char atcmd_output[256];
    	
    	memset(atcmd_output, '\0', sizeof(atcmd_output));
    	
    	if (!*message || sscanf(message, "%7s", mode) < 1) {
    		sprintf(atcmd_output, "Please, enter a battleground mode (usage: @bgrank <ranked/normal>).");
    		clif->message(fd, atcmd_output);
    		return false;
    	}
    	
    	if (strncmpi(mode, "ranked", 7) == 0) {
    		hBG_bg_ranking_display(sd, true);
    	} else if (strncmpi(mode, "normal", 7) == 0) {
    		hBG_bg_ranking_display(sd, true);
    	} else {
    		sprintf(atcmd_output, "Please, enter a battleground mode (usage: @bgrank <ranked/normal>).");
    		clif->message(fd, atcmd_output);
    		return false;
    	}
    	
    	return true;
    }
    
    ACMD(reportafk)
    {
    	struct map_session_data *pl_sd = NULL;
    	struct hBG_data *hBGd = NULL;
    	struct hBG_map_session_data *hBGsd = NULL;
    	struct hBG_map_session_data *hBGpl_sd = NULL;
    	struct battleground_data *bgd = NULL;
    	
    	if ((bgd = bg->team_search(sd->bg_id)) == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL)
    		clif->message(fd, "This command is reserved for Battlegrounds Only.");
    	else if (!(hBGd->leader_char_id == sd->status.char_id) && hBG_config_get("battle_configuration/hBG_reportafk_leaderonly"))
    		clif->message(fd, "This command is reserved for Team Leaders Only.");
    	else if (!*message)
    		clif->message(fd, "Please, enter the character name (usage: @reportafk <name>).");
    	else if ((pl_sd = map->nick2sd(message)) == NULL)
    		clif->message(fd, msg_txt(3)); // Character not found.
    	else if ((hBGpl_sd = getFromMSD(pl_sd, 0)) == NULL)
    		clif->message(fd, "Destination Player is not in battlegrounds.");
    	else if (sd->bg_id != pl_sd->bg_id)
    		clif->message(fd, "Destination Player is not in your Team.");
    	else if (sd == pl_sd)
    		clif->message(fd, "You cannot kick yourself.");
    	else if (!hBGpl_sd->state.afk)
    		clif->message(fd, "The player is not AFK on this Battleground.");
    	else
    	{ // Everything is fine!
    		char atcmd_output[256];
    		
    		 // Kick the player and send a message.
    		bg->team_leave(pl_sd, 2);
    		clif->message(pl_sd->fd, "You have been kicked from Battleground because of your AFK status.");
    		pc->setpos(pl_sd, pl_sd->status.save_point.map, pl_sd->status.save_point.x, pl_sd->status.save_point.y, 3);
    		// Message the source player and announce to team.
    		sprintf(atcmd_output, "%s has been successfully kicked.", pl_sd->status.name);
    		clif->broadcast2(&sd->bl, atcmd_output, (int)strlen(atcmd_output)+1, hBGd->color, 0x190, 20, 0, 0, BG);
    		return true;
    	}
    	
    	return false;
    }
    
    /**
     * Change Team Leader.
     */
    ACMD(leader)
    {
    	struct map_session_data *pl_sd = NULL;
    	struct hBG_data *hBGd = NULL;
    	struct hBG_map_session_data *hBGsd = NULL;
    	struct hBG_map_session_data *hBGpl_sd = NULL;
    	struct battleground_data *bgd = NULL;
    	
    	if ((bgd = bg->team_search(sd->bg_id)) == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL)
    		clif->message(fd, "This command is reserved for Battlegrounds Only.");
    	else if (sd->ud.skilltimer != INVALID_TIMER)
    		clif->message(fd, "Command not allow while casting a skill.");
    	else if (!(hBG_config_get("battle_configuration/hBG_leader_change")))
    		clif->message(fd, "This command is disabled.");
    	else if (!(hBGd->leader_char_id == sd->status.char_id))
    		clif->message(fd, "This command is reserved for Team Leaders Only.");
    	else if (!*message)
    		clif->message(fd, "Please, enter the character name (usage: @leader <name>).");
    	else if ((pl_sd = map->nick2sd(message)) == NULL)
    		clif->message(fd, msg_txt(3)); // Character not found.
    	else if ((hBGpl_sd = getFromMSD(pl_sd, 0)) == NULL)
    		clif->message(fd, "Destination Player is not in battlegrounds.");
    	else if (sd->bg_id != pl_sd->bg_id)
    		clif->message(fd, "Destination Player is not in your Team.");
    	else if (sd == pl_sd)
    		clif->message(fd, "You are already the Team Leader.");
    	else
    	{ // Everything is fine... more or less.
    		char atcmd_output[256];
    		sprintf(atcmd_output, "Team Leader transfered to [%s]", pl_sd->status.name);
    		clif->broadcast2(&sd->bl, atcmd_output, (int)strlen(atcmd_output) + 1, hBGd->color, 0x190, 20, 0, 0, BG);
    		hBGd->leader_char_id = pl_sd->status.char_id;
    		clif->charnameupdate(sd);
    		clif->charnameupdate(pl_sd);
    		return true;
    	}
    	return false;
    }
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                     Script Commands
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    
    /**
     * Send out a battleground announcement.
     * @param mes
     * @param fontColor
     * @param fontType
     * @param fontSize
     * @param fontAlign
     * @param fontY
     */
    BUILDIN(hBG_announce)
    {
    	const char *mes       = script_getstr(st,2);
    	const char *fontColor = script_hasdata(st,3) ? script_getstr(st,3) : NULL;
    	int         fontType  = script_hasdata(st,4) ? script_getnum(st,4) : 0x190; // default fontType (FW_NORMAL)
    	int         fontSize  = script_hasdata(st,5) ? script_getnum(st,5) : 12;    // default fontSize
    	int         fontAlign = script_hasdata(st,6) ? script_getnum(st,6) : 0;     // default fontAlign
    	int         fontY     = script_hasdata(st,7) ? script_getnum(st,7) : 0;     // default fontY
    
    	clif->broadcast2(NULL, mes, (int)strlen(mes) + 1, (unsigned int)strtol(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY, ALL_CLIENT);
    
    	return true;
    }
    
    /**
     * Count the number of logins per IP in battleground
     * @return count of accounts on same ip.
     */
    BUILDIN(hBG_logincount)
    {
    	struct map_session_data *sd = script->rid2sd(st);
    	int i = 0;
    
    	if (sd)
    		i = hBG_countlogin(sd,true);
    
    	script_pushint(st,i);
    	return true;
    }
    
    /**
     * Create a BG Team.
     * @param map_name Respawn Map Name
     * @param map_x Respawn Map X
     * @param map_y Respawn Map Y
     * @param guild_index BG Guild Index
     * @param ev Logout Event
     * @param dev Die Event
     */
    BUILDIN(hBG_team_create)
    {
    	const char *map_name, *ev = "", *dev = "";
    	int x, y, m = 0, guild_index, bg_id;
    
    	map_name = script_getstr(st, 2);
    	if (strcmp(map_name,"-") != 0 && (m = mapindex->name2id(map_name)) == 0) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	x = script_getnum(st, 3);
    	y = script_getnum(st, 4);
    	guild_index = script_getnum(st, 5);
    	ev = script_getstr(st, 6); // Logout Event
    	dev = script_getstr(st, 7); // Die Event
    
    	guild_index = cap_value(guild_index, 0, 12);
    	bg_id = hBG_create(m, x, y, guild_index, ev, dev);
    
    	script_pushint(st, bg_id);
    	return true;
    }
    
    /**
     * Create a Queue
     * @param queue_name Name of the Queue
     * @param jev Join Event
     * @param min_level Minimum level to join the queue.
     * @return queue Id
     */
    BUILDIN(hBG_queue_create)
    {
    	const char *queue_name, *jev;
    	int min_level = 0;
    
    	queue_name = script_getstr(st, 2);
    	jev = script_getstr(st, 3);
    	
    	if (script_hasdata(st, 4))
    		min_level = script_getnum(st, 4);
    
    	script_pushint(st, hBG_queue_create(queue_name, jev, min_level));
    
    	return true;
    }
    
    
    /**
     * Changes/Sets the Queue's Join Event.
     * @param queue_id
     * @param jev On Join Event
     */
    BUILDIN(hBG_queue_event)
    {
    	struct hBG_queue_data *hBGqd;
    	const char *join_event;
    	int q_id;
    
    	q_id = script_getnum(st,2);
    
    	if ((hBGqd = hBG_queue_search(q_id)) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	join_event = script_getstr(st,3);
    
    	safestrncpy(hBGqd->join_event, join_event, sizeof(hBGqd->join_event));
    
    	script_pushint(st, 1);
    	return true;
    }
    
    /**
     * Makes a player join a queue.
     * @param Queue ID
     */
    BUILDIN(hBG_queue_join)
    {
    	int q_id;
    	struct map_session_data *sd = script->rid2sd(st);
    
    	nullpo_retr(false, sd);
    
    	q_id = script_getnum(st,2);
    
    	script_pushint(st, hBG_queue_join(sd, q_id));
    
    	return true;
    }
    
    /**
     * Makes party join a queue.
     * @param Party ID
     * @param Queue ID
     */
    BUILDIN(hBG_queue_partyjoin)
    {
    	int q_id, i, party_id;
    	struct map_session_data *sd;
    	struct party_data *p;
    
    	party_id = script_getnum(st,2);
    
    	if (party_id <= 0 || (p = party->search(party_id)) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	q_id = script_getnum(st,3);
    
    	if (hBG_queue_search(q_id) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	for (i = 0; i < MAX_PARTY; i++) {
    		if ((sd = p->data[i].sd) == NULL)
    			continue;
    		hBG_queue_join(sd,q_id);
    	}
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Makes a player leave a queue.
     * @param Queue ID
     */
    BUILDIN(hBG_queue_leave)
    {
    	int q_id;
    	struct map_session_data *sd = script->rid2sd(st);
    
    	nullpo_retr(false, sd);
    
    	q_id = script_getnum(st,2);
    
    	script_pushint(st, hBG_queue_leave(sd, q_id));
    
    	return true;
    }
    
    /**
     * Request queue information
     * @param Queue ID
     * @param Information Type
     *        0) Users
     *        1) Copy user list to $@qmembers$ variable and return count.
     */
    BUILDIN(hBG_queue_data)
    {
    	struct hBG_queue_data *hBGqd;
    	int q_id = script_getnum(st,2),
    	type = script_getnum(st,3);
    
    	if ((hBGqd = hBG_queue_search(q_id)) == NULL) {
    		script_pushint(st,0);
    		return false;
    	}
    
    	switch (type) {
    		case 0:
    			script_pushint(st, hBGqd->users);
    			return true;
    		case 1: // User List
    		{
    			int j = 0;
    			struct map_session_data *sd;
    			struct hBG_queue_member *head;
    			head = hBGqd->first;
    			while (head) {
    				if ((sd = head->sd) != NULL) {
    					mapreg->setregstr(reference_uid(script->add_str("$@qmembers$"),j),sd->status.name);
    					j++;
    				}
    				head = head->next;
    			}
    			script_pushint(st,j);
    		}
    			return true;
    		default:
    			ShowError("script:hBG_queue_data: unknown queue data type %d.\n", type);
    			break;
    	}
    
    	script_pushint(st, 0);
    	return true;
    }
    
    /**
     * Adds all members in queue to a BG team.
     * @param Queue ID
     * @param Max Team Members
     * @param Respawn Map Name
     * @param Respawn Map X
     * @param Respawn Map Y
     * @param BG Guild Index
     * @param Logout Event
     * @param Die Event
     * @return Battleground Id
     */
    BUILDIN(hBG_queue2team)
    {
    	struct hBG_queue_data *hBGqd;
    	struct hBG_queue_member *qm;
    	const char *map_name, *ev = "", *dev = "";
    	int q_id, max, x, y, i, m=0, guild_index, bg_id;
    
    	q_id = script_getnum(st,2);
    	if ((hBGqd = hBG_queue_search(q_id)) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	max = script_getnum(st,3);
    	map_name = script_getstr(st,4);
    
    	if (strcmp(map_name,"-") != 0 && (m = mapindex->name2id(map_name)) == 0) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	x = script_getnum(st,5);
    	y = script_getnum(st,6);
    	guild_index = script_getnum(st,7);
    	ev = script_getstr(st,8); // Logout Event
    	dev = script_getstr(st,9); // Die Event
    
    	guild_index = cap_value(guild_index, 0, 12);
    
    	if ((bg_id = hBG_create(m, x, y, guild_index, ev, dev)) == 0) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	i = 0; // Counter
    	while ((qm = hBGqd->first) != NULL && i < max && i < MAX_BG_MEMBERS) {
    		if (qm->sd && hBG_team_join(bg_id, qm->sd)) {
    			mapreg->setreg(reference_uid(script->add_str("$@arenamembers"), i), qm->sd->bl.id);
    			hBG_queue_member_remove(hBGqd, qm->sd->bl.id);
    			i++;
    		} else {
    			break; // Failed? Should not. Anyway, to avoid a infinite loop
    		}
    	}
    
    	mapreg->setreg(script->add_str("$@arenamembersnum"), i);
    
    	script_pushint(st, bg_id);
    
    	return true;
    }
    
    /**
     * Joins the first player in the queue to the given team and warps him.
     * @param Queue ID
     * @param Battleground ID
     * @param Spawn Map Name
     * @param Spawn Map X Co-ordinate
     * @param Spawn Map Y Co-ordinate
     */
    BUILDIN(hBG_queue2team_single)
    {
    	const char* map_name;
    	struct hBG_queue_data *hBGqd;
    	struct map_session_data *sd;
    	int x, y, m, bg_id, q_id;
    
    	q_id = script_getnum(st,2);
    
    	if ((hBGqd = hBG_queue_search(q_id)) == NULL || !hBGqd->first || !hBGqd->first->sd) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	bg_id = script_getnum(st, 3);
    	map_name = script_getstr(st, 4);
    
    	if ((m = mapindex->name2id(map_name)) == 0) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	x = script_getnum(st, 5);
    	y = script_getnum(st, 6);
    	sd = hBGqd->first->sd;
    
    	if (hBG_team_join(bg_id, sd)) {
    		hBG_queue_member_remove(hBGqd, sd->bl.id);
    		pc->setpos(sd, m, x, y, CLR_TELEPORT);
    		script_pushint(st, 1);
    	}
    
    	return true;
    }
    /**
     * Check if the given BG Queue can start a BG in the given mode.
     * @param Queue ID
     * @param Type
     * @param Teams
     * @param Required Minimum Players
     * @return 1 can start, 0 cannot start.
     */
    BUILDIN(hBG_queue_checkstart)
    {
    	int q_id, result = 0;
    	struct hBG_queue_data *hBGqd;
    
    	q_id = script_getnum(st,2);
    
    	if ((hBGqd = hBG_queue_search(q_id)) != NULL) {
    		int type, req_min, teams;
    
    		type = script_getnum(st,3);
    		teams = script_getnum(st,4);
    		req_min = script_getnum(st,5);
    
    		switch (type) {
    			case 0: // Lineal, as they Join
    			case 1: // Random
    				if (hBGqd->users >= (req_min * teams))
    					result = 1;
    				break;
    			default:
    				result = 0;
    				break;
    		}
    	}
    
    	script_pushint(st, result);
    
    	return true;
    }
    
    /**
     * Build BG Teams from one Queue
     * @param Queue ID
     * @param Minimum Players
     * @param Maximum Players per Team
     * @param Type
     * @param ... Team ID
     */
    BUILDIN(hBG_queue2teams)
    { // Send Users from Queue to Teams. Requires previously created teams.
    	struct hBG_queue_data *hBGqd;
    	int t, bg_id = 0, total_teams = 0, q_id, min, max, type, limit = 0;
    	int arg_offset = 6;
    	struct map_session_data *sd;
    
    	q_id = script_getnum(st,2); // Queue ID
    	if ((hBGqd = hBG_queue_search(q_id)) == NULL) {
    		ShowError("buildin_hBG_queue2teams: Non existant queue id received %d.\n", q_id);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	min = script_getnum(st,3); // Min Members per Team
    	max = script_getnum(st,4); // Max Members per Team
    	type = script_getnum(st,5); // Team Building Method
    
    	t = arg_offset; // Team ID's to build
    	while (script_hasdata(st,t) && t < MAX_BATTLEGROUND_TEAMS+arg_offset) {
    		bg_id = script_getnum(st,t);
    		if (bg->team_search(bg_id) == NULL) {
    			ShowError("buildin_hBG_queue2teams: Non existant team Id received %d.\n", bg_id);
    			script_pushint(st, 0);
    			return false;
    		}
    		t++;
    	}
    	total_teams = t - arg_offset;
    
    	if (total_teams < 2) {
    		ShowError("buildin_hBG_queue2teams: Less than 2 teams received to build members.\n");
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if (hBGqd->users < min) {
    		ShowError("buildin_hBG_queue2teams: Less than minimum %d queue members received (%d).\n", min, (int) hBGqd->users);
    		script_pushint(st, 0);
    		return false;
    	}
    	// How many players are we going to take from the Queue
    	limit = min(max * total_teams, hBGqd->users);
    
    	switch (type) {
    		case 0: // Lineal - Maybe to keep party together
    		{
    			t = 0;
    			int i = 0;
    			for (i = 0; i < limit; i++) {
    				if ((i%(limit/total_teams)) == 0) // Switch Team
    					bg_id = script_getnum(st,t+arg_offset);
    				
    				if (!hBGqd->first || (sd = hBGqd->first->sd) == NULL)
    					break; // No more people to join Teams
    				
    				hBG_team_join(bg_id, sd);
    				hBG_queue_member_remove(hBGqd, sd->bl.id);
    				
    				// Increment Team counter or break
    				if (t++ >= total_teams)
    					break;
    			}
    		}
    			break;
    		default:
    		case 1: // Random
    		{
    			t = 0;
    			int pos = 0, i=0;
    			struct hBG_queue_member *qm;
    
    			for (i=0; t < limit; i++) {
    				if ((i%(limit/total_teams)) == 0) // Switch Team
    					bg_id = script_getnum(st,t+arg_offset);
    
    				pos = 1 + rand() % (limit - i);
    				
    				if ((qm = hBG_queue_member_get(hBGqd, pos)) == NULL || (sd = qm->sd) == NULL)
    					break;
    
    				hBG_team_join(bg_id, sd);
    				hBG_queue_member_remove(hBGqd, sd->bl.id);
    				
    				// Increment Team Counter or break
    				if (t++ >= total_teams)
    					break;
    			}
    		}
    			break;
    	}
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Fill teams with members from the given Queue.
     * @param Queue ID
     * @param Max Players Per Team
     * @param Balanceing method
     * @param Team 1 ... Team 13
     */
    BUILDIN(hBG_balance_teams)
    {
    	struct hBG_queue_data *hBGqd;
    	struct hBG_queue_member *head;
    	struct battleground_data *bgd, *p_bg;
    	int i, c, q_id, bg_id, m_bg_id = 0, max, min, type;
    	struct map_session_data *sd;
    	bool balanced;
    
    	q_id = script_getnum(st,2);
    
    	if ((hBGqd = hBG_queue_search(q_id)) == NULL || hBGqd->users <= 0) {
    		ShowError("buildin_hBG_balance_teams: Non existant Queue Id or the queue is empty.\n");
    		script_pushint(st, 0);
    		return false;
    	}
    
    	max = script_getnum(st,3);
    	if (max > MAX_BG_MEMBERS)
    		max = MAX_BG_MEMBERS;
    	min = MAX_BG_MEMBERS + 1;
    	type = script_getnum(st, 4);
    
    	i = 5; // Team IDs to build
    	
    	while (script_hasdata(st, i) && i-5 < 13) {
    		bg_id = script_getnum(st, i);
    		if ((bgd = bg->team_search(bg_id)) == NULL) {
    			ShowError("buildin_hBG_balance_teams: Non existant team id received %d.\n", bg_id);
    			script_pushint(st, 0);
    			return false;
    		}
    
    		if (bgd->count < min)
    			min = bgd->count;
    		i++;
    	}
    
    	c = i - 5; // Teams Found
    
    	if (c < 2 || min >= max)
    		return true; // No Balance Required
    
    	if (type < 3) {
    		while ((head = hBGqd->first) != NULL && (sd = head->sd) != NULL) {
    			p_bg = NULL;
    			balanced = true;
    			min = MAX_BG_MEMBERS + 1;
    
    			// Search the Current Minimum and Balance status
    			for (i = 0; i < c; i++) {
    				bg_id = script_getnum(st,i+5);
    				
    				if ((bgd = bg->team_search(bg_id)) == NULL)
    					break; // Should not happen. Teams already check
    				
    				if (p_bg && p_bg->count != bgd->count)
    					balanced = false; // Teams still with different member count
    
    				if (bgd->count < min) {
    					m_bg_id = bg_id;
    					min = bgd->count;
    				}
    				p_bg = bgd;
    			}
    
    			if (min >= max) break; // Balance completed
    
    			if (hBG_config_get("battle_configuration/hBG_balanced_queue") && balanced && hBGqd->users < c)
    				break; // No required users on queue to keep balance
    
    			hBG_team_join(m_bg_id, sd);
    			hBG_queue_member_remove(hBGqd, sd->bl.id);
    
    			if ((bgd = bg->team_search(m_bg_id)) != NULL && bgd->mapindex)
    				pc->setpos(sd, bgd->mapindex, bgd->x, bgd->y, CLR_TELEPORT); // Joins and Warps
    		}
    	} else {
    		ShowError("buildin_hBG_balance_teams: Invalid type %d given for argument #3.\n", type);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Waiting Room to Battleground Teams
     * @param Map Name
     * @param Map X
     * @param Map Y
     * @param BG Guild Index
     * @param Logout Event
     * @param Die Event
     */
    BUILDIN(hBG_waitingroom2bg)
    {
    	struct npc_data *nd;
    	struct chat_data *cd;
    	const char *map_name, *ev = "", *dev = "";
    	int x, y, i, m=0, guild_index, bg_id;
    	struct map_session_data *sd;
    
    	nd = (struct npc_data *)map->id2bl(st->oid);
    
    	if (nd == NULL || (cd = (struct chat_data *)map->id2bl(nd->chat_id)) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	map_name = script_getstr(st,2);
    
    	if (strcmp(map_name, "-") != 0 && (m = mapindex->name2id(map_name)) == 0) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	x = script_getnum(st, 3);
    	y = script_getnum(st, 4);
    	guild_index = script_getnum(st, 5);
    	ev = script_getstr(st, 6); // Logout Event
    	dev = script_getstr(st, 7); // Die Event
    
    	guild_index = cap_value(guild_index, 0, 12);
    
    	if ((bg_id = hBG_create(m, x, y, guild_index, ev, dev)) == 0) { // Creation failed
    		script_pushint(st, 0);
    		return false;
    	}
    
    	for (i = 0; i < cd->users && i < MAX_BG_MEMBERS; i++) {
    		if ((sd = cd->usersd[i]) != NULL && hBG_team_join(bg_id, sd))
    			mapreg->setreg(reference_uid(script->add_str("$@arenamembers"), i), sd->bl.id);
    		else
    			mapreg->setreg(reference_uid(script->add_str("$@arenamembers"), i), 0);
    	}
    
    	mapreg->setreg(script->add_str("$@arenamembersnum"), i);
    
    	script_pushint(st, bg_id);
    
    	return true;
    }
    
    /**
     * Adds the first player from the given NPC's
     * waiting room to BG Team.
     * @param Battleground Id
     * @param Map Name
     * @param Map X
     * @param Map Y
     * @param NPC Name
     */
    BUILDIN(hBG_waitingroom2bg_single)
    {
    	const char* map_name;
    	struct npc_data *nd;
    	struct chat_data *cd;
    	struct map_session_data *sd;
    	int x, y, m, bg_id;
    
    	bg_id = script_getnum(st,2);
    	map_name = script_getstr(st,3);
    
    	if ((m = mapindex->name2id(map_name)) == 0) {
    		script_pushint(st, 0);
    		return false; // Invalid Map
    	}
    
    	x = script_getnum(st,4);
    	y = script_getnum(st,5);
    	nd = npc->name2id(script_getstr(st,6));
    
    	if (nd == NULL || (cd = (struct chat_data *)map->id2bl(nd->chat_id)) == NULL || cd->users <= 0) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if ((sd = cd->usersd[0]) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if (hBG_team_join(bg_id, sd)) {
    		pc->setpos(sd, m, x, y, CLR_TELEPORT);
    		script_pushint(st,1);
    	} else {
    		script_pushint(st,0);
    	}
    
    	return true;
    }
    
    /**
     * Set the Respawn Location of a BG team
     * @param Battleground Id
     * @param Map X
     * @param Map Y
     */
    BUILDIN(hBG_team_setxy)
    {
    	struct battleground_data *bgd;
    	int bg_id;
    
    	bg_id = script_getnum(st,2);
    
    	if ((bgd = bg->team_search(bg_id)) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	bgd->x = script_getnum(st,3);
    	bgd->y = script_getnum(st,4);
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Reveal the location of a BG Team on the minimap.
     * @param Battleground ID
     */
    BUILDIN(hBG_team_reveal)
    {
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    	int bg_id;
    
    	bg_id = script_getnum(st,2);
    
    	if ((bgd = bg->team_search(bg_id)) == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	hBGd->reveal_pos = true; // Reveal Position Mode
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Conceal the location of a BG Team from the minimap.
     * @param Battleground ID
     */
    BUILDIN(hBG_team_conceal)
    {
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    	struct map_session_data *sd;
    	int bg_id,i=0;
    
    	bg_id = script_getnum(st,2);
    
    	if ((bgd = bg->team_search(bg_id)) == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	for (i = 0; i < MAX_BG_MEMBERS; i++) {
    		if ((sd = bgd->members[i].sd) == NULL)
    			continue;
    
    		hBG_send_dot_remove(sd);
    	}
    
    	hBGd->reveal_pos = false; // Conceal Position Mode
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Set Quest for a BG Team
     * @param Battleground ID
     * @param Quest ID
     */
    BUILDIN(hBG_team_setquest)
    {
    	struct battleground_data *bgd;
    	struct map_session_data *sd;
    	int i, bg_id, qid;
    
    	bg_id = script_getnum(st,2);
    	qid = script_getnum(st,3);
    
    	if (bg_id <= 0 || (bgd = bg->team_search(bg_id)) == NULL) {
    		ShowError("buildin_hBG_team_setquest: Invalid Team ID %d given.\n", bg_id);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if (qid <= 0 || quest->db(qid) == NULL) {
    		ShowError("buildin_hBG_team_setquest: Invalid Quest ID %d given.\n", qid);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	for (i = 0; i < MAX_BG_MEMBERS; i++) {
    		if ((sd = bgd->members[i].sd) == NULL)
    			continue;
    
    		quest->add(sd, qid, 0);
    	}
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Set Viewpoint for a player.
     * @see hBG_viewpointmap
     */
    int hBG_viewpointmap_sub(struct block_list *bl, va_list ap)
    {
    	struct map_session_data *sd;
    	int npc_id, type, x, y, id, color;
    	npc_id = va_arg(ap,int);
    	type = va_arg(ap,int);
    	x = va_arg(ap,int);
    	y = va_arg(ap,int);
    	id = va_arg(ap,int);
    	color = va_arg(ap,int);
    	sd = (struct map_session_data *)bl;
    
    	clif->viewpoint(sd,npc_id,type,x,y,id,color);
    
    	return 0;
    }
    
    /**
     * Set Viewpoint on minimap for a player.
     * @param Map Name
     * @param Type
     *         0 = display mark for 15 seconds
     *         1 = display mark until dead or teleported
     *         2 = remove mark
     * @param Map X
     * @param Map Y
     * @param ID (Unique ID of the viewpoint)
     * @param Color
     */
    BUILDIN(hBG_viewpointmap)
    {
    	int type,x,y,id,color,m;
    	const char *map_name;
    
    	map_name = script_getstr(st,2);
    
    	if ((m = map->mapname2mapid(map_name)) < 0) {
    		script_pushint(st, 0);
    		return false; // Invalid Map
    	}
    
    	type=script_getnum(st,3);
    	x=script_getnum(st,4);
    	y=script_getnum(st,5);
    	id=script_getnum(st,6);
    	color=script_getnum(st,7);
    
    	map->foreachinmap(hBG_viewpointmap_sub,m,BL_PC,st->oid,type,x,y,id,color);
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Reveal a monster's location on minimap
     * @param Monster Id
     * @param Type
     *         0 = display mark for 15 seconds
     *         1 = display mark until dead or teleported
     *         2 = remove mark
     * @param Color
     */
    BUILDIN(hBG_monster_reveal)
    {
    	struct block_list *mbl;
    	int id = script_getnum(st,2),
    	flag = script_getnum(st,3),
    	color = script_getnum(st,4);
    
    	if (id == 0 || (mbl = map->id2bl(id)) == NULL || mbl->type != BL_MOB) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	map->foreachinmap(hBG_viewpointmap_sub, mbl->m, BL_PC, st->oid, flag, mbl->x, mbl->y, mbl->id, color);
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Set monster as an ally to a BG Team.
     * @param Monster ID
     * @param Battleground ID
     */
    BUILDIN(hBG_monster_set_team)
    {
    	struct mob_data *md;
    	struct block_list *mbl;
    	int id = script_getnum(st,2),
    	bg_id = script_getnum(st,3);
    
    	if (id == 0 || (mbl = map->id2bl(id)) == NULL || mbl->type != BL_MOB) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	md = (TBL_MOB *)mbl;
    	md->bg_id = bg_id;
    
    	mob_stop_attack(md);
    	mob_stop_walking(md, 0);
    
    	md->target_id = md->attacked_id = 0;
    
    	clif->charnameack(0, &md->bl);
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Set immunity flag to a monster.
     * (making it immune to damage).
     * @param Monster ID
     * @param Flag (0 = Off | 1 = On)
     */
    BUILDIN(hBG_monster_immunity)
    {
    	struct mob_data *md;
    	struct block_list *mbl;
    	struct hBG_mob_data *hBGmd;
    
    	int id = script_getnum(st,2),
    	flag = script_getnum(st,3);
    
    	if (id == 0 || (mbl = map->id2bl(id)) == NULL || mbl->type != BL_MOB) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	md = (TBL_MOB *)mbl;
    
    	if ((hBGmd = getFromMOBDATA(md, 0)) == NULL){
    		CREATE(hBGmd, struct hBG_mob_data, 1);	
    		addToMOBDATA(md, hBGmd, 0, true);
    	}
    	hBGmd->state.immunity = flag;
    
    	return true;
    }
    
    /**
     * Leave a Battleground Team
     */
    BUILDIN(hBG_leave)
    {
    	struct map_session_data *sd = script->rid2sd(st);
    
    	if (sd == NULL || sd->bg_id == 0) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	bg->team_leave(sd,0);
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Finalize battlegrounds and remove
     * teams from the db.
     */
    BUILDIN(hBG_destroy)
    {
    	int bg_id = script_getnum(st, 2);
    
    	if (bg_id <= 0 || bg->team_search(bg_id) == NULL) {
    		ShowError("buildin_hBG_destroy: Invalid BG Id %d provided.\n", bg_id);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	hBG_team_finalize(bg_id, true);
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Clean Battlegrounds without removing
     * the teams from the db.
     */
    BUILDIN(hBG_clean)
    {
    	int bg_id = script_getnum(st, 2);
    
    	if (bg_id <= 0 || bg->team_search(bg_id) == NULL) {
    		ShowError("buildin_hBG_clean: Invalid BG Id %d provided.\n", bg_id);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	hBG_team_finalize(bg_id, false);
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Get user count within an area in a map.
     * @param Battleground ID
     * @param Map Name
     * @param X1
     * @param Y1
     * @param X2
     * @param Y2
     */
    BUILDIN(hBG_getareausers)
    {
    	struct battleground_data *bgd = NULL;
    	struct map_session_data *sd = NULL;
    	const char *map_name;
    	int m, x0, y0, x1, y1, bg_id;
    	int i = 0, c = 0;
    
    	bg_id = script_getnum(st,2);
    	map_name = script_getstr(st,3);
    
    	if ((bgd = bg->team_search(bg_id)) == NULL || (m = map->mapname2mapid(map_name)) < 0) {
    		script_pushint(st,0);
    		return false;
    	}
    
    	x0 = script_getnum(st,4);
    	y0 = script_getnum(st,5);
    	x1 = script_getnum(st,6);
    	y1 = script_getnum(st,7);
    
    	for (i = 0; i < MAX_BG_MEMBERS; i++) {
    		if ((sd = bgd->members[i].sd) == NULL)
    			continue;
    		else if (sd->bl.m != m || sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1)
    			continue;
    		c++;
    	}
    
    	script_pushint(st, c);
    	
    	return true;
    }
    
    /**
     * Update the score on a battleground map.
     * @param Map Name
     * @param Lion Score
     * @param Eagle Score
     */
    BUILDIN(hBG_updatescore)
    {
    	const char *map_name;
    	int m;
    
    	map_name = script_getstr(st,2);
    
    	if ((m = map->mapname2mapid(map_name)) < 0) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	map->list[m].bgscore_lion = script_getnum(st,3);
    	map->list[m].bgscore_eagle = script_getnum(st,4);
    
    	clif->bg_updatescore(m);
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Update Score for a Battleground Team.
     * @param Battleground ID
     * @param Score
     */
    BUILDIN(hBG_update_score_team)
    {
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    	int bg_id = script_getnum(st,2);
    	int score = script_getnum(st,3);
    
    	if (bg_id <= 0) {
    		ShowError("buildin_hBG_update_score_team: Invalid BG Id %d provided.\n", bg_id);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if ((bgd = bg->team_search(bg_id)) == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	hBGd->team_score = score;
    	hBG_update_score_team(bgd);
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Get a Team's Guild Index
     * @param Battleground ID
     * @return Guild Index
     */
    BUILDIN(hBG_get_team_gid)
    {
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    	int bg_id = script_getnum(st,2), guild_id = 0;
    
    	if (bg_id <= 0) {
    		ShowError("buildin_hBG_get_team_gid: Invalid BG Id %d provided.\n", bg_id);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if ((bgd = bg->team_search(bg_id)) != NULL
    		&& (hBGd = getFromBGDATA(bgd, 0)) != NULL)
    		guild_id = hBGd->g->guild_id;
    
    	script_pushint(st, guild_id);
    
    	return true;
    }
    
    /**
     * Get data from a Battleground
     * @param Battleground ID
     * @param Type
     *         0 = User Count
     *         1 = Fill $@bgmembers$ array with user list and return user count.
     *         2 = BG Guild Name
     *         3 = BG Guild Master Name
     *         4 = BG Color
     */
    BUILDIN(hBG_get_data)
    {
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    	int bg_id = script_getnum(st,2);
    	int type = script_getnum(st,3);
    
    	if (bg_id <= 0) {
    		ShowError("buildin_hBG_get_data: Invalid BG Id %d provided.\n", bg_id);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if ((bgd = bg->team_search(bg_id)) == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL) {
    		script_pushint(st, 0);
    		return false;
    	}
    
    	switch (type)
    	{
    		case 0:
    			script_pushint(st, bgd->count);
    			break;
    		case 1: // Users and List
    		{
    			int i, j = 0;
    			struct map_session_data *sd;
    			for (i = 0; i < bgd->count; i++) {
    				if ((sd = bgd->members[i].sd) == NULL)
    					continue;
    				mapreg->setregstr(reference_uid(script->add_str("$@bgmembers$"),j),sd->status.name);
    				j++;
    			}
    			script_pushint(st, j);
    		}
    			break;
    		case 2:
    			script_pushconststr(st,hBGd->g ? hBGd->g->name : "");
    			break;
    		case 3:
    			script_pushconststr(st,hBGd->g ? hBGd->g->master : "");
    			break;
    		case 4:
    			script_pushint(st,hBGd->color);
    			break;
    
    		default:
    			ShowError("script:bg_get_data: unknown data identifier %d\n", type);
    			break;
    	}
    
    	script_pushint(st, 0);
    
    	return true;
    }
    
    /**
     * Battleground Get Item
     * @param Battleground ID
     * @param Item ID
     * @param Item Amount
     */
    BUILDIN(hBG_getitem)
    {
    	int bg_id, nameid, amount;
    
    	bg_id = script_getnum(st,2);
    	nameid = script_getnum(st,3);
    	amount = script_getnum(st,4);
    
    
    	if (bg_id <= 0 || bg->team_search(bg_id) == NULL) {
    		ShowError("buildin_hBG_getitem: Invalid BG Id %d provided.\n", bg_id);
    		script_pushint(st, 0);
    		return false;
    	} else if (nameid <= 0 || itemdb->exists(nameid) == NULL) {
    		ShowError("buildin_hBG_getitem: Invalid Item Id %d provided.\n", nameid);
    		script_pushint(st, 0);
    		return false;
    	} else if (amount <= 0) {
    		ShowError("buildin_hBG_getitem: Invalid Item amount %d provided.\n", amount);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	hBG_team_getitem(bg_id, nameid, amount);
    
    	script_pushint(st, amount);
    
    	return true;
    }
    
    /**
     * Battleground Get Kafra Points
     * @param Battleground ID
     * @param Amount of KP
     */
    BUILDIN(hBG_getkafrapoints)
    {
    	int bg_id, amount;
    
    	bg_id = script_getnum(st, 2);
    	amount = script_getnum(st, 3);
    
    	if (bg_id <= 0 || bg->team_search(bg_id) == NULL) {
    		ShowError("buildin_hBG_getkafrapoints: Invalid BG Id %d provided.\n", bg_id);
    		script_pushint(st, 0);
    		return false;
    	} else if (amount <= 0) {
    		ShowError("buildin_hBG_getkafrapoints: Invalid Kafra Points %d provided.\n", amount);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	hBG_team_get_kafrapoints(bg_id, amount);
    
    	script_pushint(st, amount);
    
    	return true;
    }
    
    /**
     * Battleground get Rewards
     * @param Battleground ID
     * @param Item ID
     * @param Item Amount
     * @param Kafra Points
     * @param Quest ID
     * @param Custom Variable (#KAFRAPOINTS/#CASHPOINTS etc..)
     * @param Custom Variable Add Value
     * @param Battleground Arena (0 EoS | 1 Boss | 2 TI | 3 CTF | 4 TD | 5 SC | 6 CON | 7 RUSH | 8 DOM)
     * @param Battleground Result (0 Won | 1 Tie | 2 Lost)
     */
    BUILDIN(hBG_reward)
    {
    	int bg_id, nameid, amount, kafrapoints, quest_id, add_value, bg_arena, bg_result;
    	const char *var;
    
    	bg_id = script_getnum(st,2);
    	nameid = script_getnum(st,3);
    	amount = script_getnum(st,4);
    	kafrapoints = script_getnum(st,5);
    	quest_id = script_getnum(st,6);
    	var = script_getstr(st,7);
    	add_value = script_getnum(st,8);
    	bg_arena = script_getnum(st,9);
    	bg_result = script_getnum(st,10);
    
    	if (bg_id <= 0 || bg->team_search(bg_id) == NULL) {
    		ShowError("buildin_hBG_reward: Invalid BG Id %d provided.\n", bg_id);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if (nameid <= 0 || itemdb->exists(nameid) == NULL) {
    		ShowError("buildin_hBG_reward: Invalid Item Id %d provided.\n", nameid);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if (nameid > 0 && amount <= 0) {
    		ShowError("buildin_hBG_reward: Invalid Item amount %d provided.\n", nameid);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if (kafrapoints < 0) {
    		ShowError("buildin_hBG_reward: Invalid Kafra Points %d provided.\n", kafrapoints);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if (quest_id < 0 || quest->db(quest_id) == NULL) {
    		ShowError("buildin_hBG_reward: Invalid Quest ID %d provided.\n", quest_id);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if (bg_arena < 0) {
    		ShowError("buildin_hBG_reward: Invalid BG Arena %d provided. \n", bg_arena);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	if (bg_result < 0 || bg_result > 2) {
    		ShowError("buildin_hBG_reward: Invalid BG result type %d provided. (types - 0 Won | 1 Tie | 2 Lost)", bg_result);
    		script_pushint(st, 0);
    		return false;
    	}
    
    	hBG_team_rewards(bg_id, nameid, amount, kafrapoints, quest_id, var, add_value, bg_arena, bg_result);
    
    	script_pushint(st, 1);
    
    	return true;
    }
    
    /**
     * Add Item to XY co-ordinates on Floor.
     * @param Map Name
     * @param Map X
     * @param Map Y
     * @param Item ID
     * @param Item Amount
     */
    BUILDIN(hBG_flooritem2xy)
    {
    	int nameid, amount, m, x, y;
    	const char *mapname;
    	
    	mapname = script_getstr(st,2);
    	
    	if ((m = map->mapname2mapid(mapname)) < 0) {
    		// error message is thrown through mapindex->name2id()
    		script_pushint(st, 0);
    		return false;
    	}
    	
    	x = script_getnum(st,3);
    	y = script_getnum(st,4);
    	nameid = script_getnum(st,5);
    	
    	if (itemdb->search(nameid) == NULL) {
    		ShowError("buildin_hBG_flooritem2xy: Invalid Item Id %d provided.\n", nameid);
    		script_pushint(st, 0);
    		return false;
    	}
    	
    	amount = script_getnum(st,6);
    	
    	if (amount < 1) {
    		ShowError("buildin_hBG_flooritem2xy: Invalid Item amount %d provided.\n", amount);
    		script_pushint(st, 0);
    		return false;
    	}
    	
    	hBG_addflooritem_area(NULL, m, x, y, nameid, amount);
    
    	script_pushint(st, amount);
    
    	return true;
    }
    /**
     * Warps BG Team to destination or Respawn Point
     * @param BG Team
     * @param Map Name
     * @param Map X
     * @param Map Y
     */
    BUILDIN(hBG_warp)
    {
    	int x, y, mapidx, bg_id;
    	const char *map_name;
    
    	bg_id = script_getnum(st,2);
    	map_name = script_getstr(st,3);
    
    	if (!strcmp(map_name,"RespawnPoint")) // Cemetery Zone
    		mapidx = 0;
    	else if ((mapidx = script->mapindexname2id(st,map_name)) == 0)
    		return 0; // Invalid Map
    
    	x = script_getnum(st,4);
    	y = script_getnum(st,5);
    
    	bg_id = hBG_team_warp(bg_id, mapidx, x, y);
    
    	return true;
    }
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                     Map Server Function Pre-Hooks
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    /**
     * NPC Pre-Hooks
     */
    void npc_parse_unknown_mapflag_pre(const char **name, const char **w3, const char **w4, const char **start, const char **buffer, const char **filepath, int **retval)
    {
    	int16 m = map->mapname2mapid(*name);
    
    	if (strcmpi(*w3, "hBG_topscore") == 0) {
    		struct hBG_mapflag *hBG_mf;
    
    		if ((hBG_mf = getFromMAPD(&map->list[m], 0)) == NULL) {
    			CREATE(hBG_mf, struct hBG_mapflag, 1);
    			hBG_mf->hBG_topscore = 1;
    			addToMAPD(&map->list[m], hBG_mf, 0, true);
    		}
    
    		hBG_mf->hBG_topscore = 1;
    
    		hookStop();
    	}
    
    	return;
    }
    
    /**
     * Clif Pre-Hooks
     */
    void clif_charnameupdate_pre(struct map_session_data **sd)
    {
    	unsigned char buf[103];
    	int cmd = 0x195, ps;
    	struct battleground_data *bgd = bg->team_search((*sd)->bg_id);
    	struct hBG_data *hBGd;
    
    	nullpo_retv((*sd));
    
    	if ((*sd)->fakename[0] || bgd == NULL ||
    		(hBGd = getFromBGDATA(bgd, 0)) == NULL || hBGd->g == NULL)
    		return; //No need to update as the guild was not displayed anyway.
    
    	WBUFW(buf,0) = cmd;
    	WBUFL(buf,2) = (*sd)->bl.id;
    	memcpy(WBUFP(buf,6), (*sd)->status.name, NAME_LENGTH);
    	WBUFB(buf,30) = 0;
    	memcpy(WBUFP(buf,54), hBGd->g->name, NAME_LENGTH);
    	
    	ps = (hBGd->leader_char_id == (*sd)->status.char_id)?0:1;
    	memcpy(WBUFP(buf,78), hBGd->g->position[ps].name, NAME_LENGTH);
    
    	// Update nearby clients
    	clif->send(buf, 102, &(*sd)->bl, AREA);
    
    	hookStop();
    }
    //Prevent update Guild Info if you're in BG
    void clif_parse_GuildRequestInfo_pre(int *fd, struct map_session_data **sd)
    {
    	if ((*sd) && (*sd)->bg_id)
    		hookStop();
    	return;
    }
    
    /**
     * Skill Pre-Hooks.
     */
    int skill_check_condition_castbegin_pre(struct map_session_data **sd, uint16 *skill_id, uint16 *skill_lv)
    {
    	nullpo_ret(sd);
    	
    	if (map->list[(*sd)->bl.m].flag.battleground && (*skill_id >= GD_SKILLBASE && *skill_id <= GD_DEVELOPMENT))
    		hookStop(); // Prevent original function from running after return from here.
    	
    	return 1;
    }
    
    int skillnotok_pre(uint16 *skill_id, struct map_session_data **sd)
    {
    	int16 idx, m;
    	nullpo_retr(1, *sd);
    	m = (*sd)->bl.m;
    	idx = skill->get_index(*skill_id);
     
    	if (map->list[m].flag.battleground && (*skill_id >= GD_SKILLBASE && *skill_id <= GD_DEVELOPMENT)) {
    	
    		if (pc_has_permission(*sd, PC_PERM_DISABLE_SKILL_USAGE)) {
    			hookStop();
    			return 1;
    		}
    
    		if (pc_has_permission(*sd, PC_PERM_SKILL_UNCONDITIONAL)) {
    			hookStop();
    			return 0; // can do any damn thing they want
    		}
    
    		if ((*sd)->blockskill[idx]) {
    			clif->skill_fail((*sd), *skill_id, USESKILL_FAIL_SKILLINTERVAL, 0);
    			hookStop();
    			return 1;
    		}
    		hookStop();
    	}
    	return 0;
    }
    
    /**
     * Skill cast end.
     * @param src = source block list.
     * @param bl = target block list
     */
    int skill_castend_nodamage_id_pre(struct block_list **src, struct block_list **bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag)
    {
    	struct map_session_data *sd, *dstsd;
    	struct status_change *tsc;
    	struct status_data *sstatus;
    	struct hBG_map_session_data *hBGsd = NULL;
    	
    	nullpo_retr(1, bl);
    	nullpo_retr(1, src);
    
    	if (!map->list[(*src)->m].flag.battleground || *skill_id != GD_EMERGENCYCALL)
    		return 0;
    	
    	sd = BL_CAST(BL_PC, *src);
    	dstsd = BL_CAST(BL_PC, *bl);
    
    	if ((hBGsd = getFromMSD(sd, 1)) == NULL)
    		return 0;
    
    	tsc = status->get_sc(*bl);
    
    	sstatus = status->get_status_data(*src);
    	
    	switch (*skill_id) {
    		case GD_EMERGENCYCALL:
    		{
    			int dx[9]={-1, 1, 0, 0,-1, 1,-1, 1, 0};
    			int dy[9]={ 0, 0, 1,-1, 1,-1,-1, 1, 0};
    			int i = 0, j = 0;
    			struct guild *g;
    			
    			// i don't know if it actually summons in a circle, but oh well. ;P
    			if (sd && (g = hBG_get_guild(sd->bg_id)) != NULL) {
    				clif->skill_nodamage(*src, *bl, *skill_id, *skill_lv, 1);
    				
    				for (i = 0; i < g->max_member; i++, j++) {
    					if (j>8) j=0;
    					if ((dstsd = g->member[i].sd) != NULL && sd != dstsd && !dstsd->state.autotrade && !pc_isdead(dstsd)) {
    						if (map->getcell((*src)->m, *src, (*src)->x + dx[j], (*src)->y + dy[j], CELL_CHKNOREACH))
    							dx[j] = dy[j] = 0;
    						pc->setpos(dstsd, map_id2index((*src)->m), (*src)->x+dx[j], (*src)->y+dy[j], CLR_RESPAWN);
    					}
    				}
    				guild->block_skill(sd, skill->get_time2(*skill_id, *skill_lv));
    			}
    		}
    			break;
    		case HLIF_HEAL:
    		case AL_HEAL:
    		{
    			struct mob_data *dstmd = BL_UCAST(BL_MOB, *bl);
    			int heal = skill->calc_heal(*src, *bl, *skill_id, *skill_lv, true);
    
    			if (status->isimmune(*bl) || (dstmd && dstmd->class_ == MOBID_EMPELIUM))
    				heal = 0;
    
    			if (dstmd && mob_is_battleground(dstmd))
    				heal = 1;
    
    			if (sd && dstsd && sd->status.partner_id == dstsd->status.char_id && (sd->job&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.sex == 0)
    				heal = heal*2;
    
    			if (tsc && tsc->count)
    			{
    				if (tsc->data[SC_KAITE] && !(sstatus->mode&MD_BOSS))
    				{ //Bounce back heal
    					if (src == bl)
    						heal=0; //When you try to heal yourself under Kaite, the heal is voided.
    					else {
    						bl = src;
    						dstsd = sd;
    					}
    				} else if (tsc->data[SC_BERSERK]) {
    						heal = 0; //Needed so that it actually displays 0 when healing.
    				}
    			}
    
    			if (sd && dstsd && heal > 0 && sd != dstsd)
    			{
    				if (map->list[(*src)->m].flag.battleground && sd->bg_id && dstsd->bg_id)
    				{
    					if (sd->bg_id == dstsd->bg_id)
    						add2limit(hBGsd->stats.healing_done, heal, UINT_MAX);
    					else
    						add2limit(hBGsd->stats.wrong_healing_done, heal, UINT_MAX);
    				}
    			}
    		}
    			break;
    	}
    	
    	hookStop();
    	return 0;
    }
    
    /**
     * Status Pre-Hooks
     */
    int status_get_guild_id_pre(const struct block_list **bl)
    {
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    	int bg_id;
    
    	nullpo_ret((*bl));
    
    	if ((*bl)->type == BL_PC
    		&& (bg_id = bg->team_get_id((struct block_list *)*bl)) > 0
    		&& (bgd = bg->team_search(bg_id)) != NULL
    		&& (hBGd = getFromBGDATA(bgd, 0)) != NULL
    		&& hBGd->g)
    	{
    		hookStop();
    		return hBGd->g->guild_id;
    	}
    
    	return 0;
    }
    
    int status_get_emblem_id_pre(const struct block_list **bl)
    {
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    	int bg_id;
    	
    	nullpo_ret(bl);
    
    	if ((*bl)->type == BL_PC
    		&& (bg_id = bg->team_get_id((struct block_list *)(*bl))) > 0
    		&& (bgd = bg->team_search(bg_id)) != NULL
    		&& (hBGd = getFromBGDATA(bgd, 0)) != NULL && hBGd->g)
    	{
    		hookStop();
    		return hBGd->g->emblem_id;
    	}
    
    	return 0;
    }
    
    /**
     * Guild Pre-Hooks
     */
    // Check if guild is null and don't run BCT checks if true.
    bool guild_isallied_pre(int *guild_id, int *guild_id2)
    {
    	struct guild *g = guild->search(*guild_id);
    	
    	if (g == NULL) {
    		hookStop();
    		return false;
    	}
    	
    	return false;
    }
    
    /**
     * Unit Pre-Hooks
     */
    int unit_free_pre(struct block_list **bl, clr_type *clrtype)
    {
    	nullpo_retr(0, (*bl));
    
    	if ((*bl)->type == BL_PC) {
    		struct map_session_data *sd = BL_UCAST(BL_PC, (*bl));
    		struct hBG_queue_data *hBGqd = NULL;
    		struct battleground_data *bgd = NULL;
    		struct hBG_data *hBGd = NULL;
    		struct hBG_map_session_data *hBGsd = NULL;
    
    		if ((hBGqd = getFromMSD(sd, 0)) && hBG_queue_member_search(hBGqd, sd->bl.id))
    			hBG_queue_member_remove(hBGqd, sd->bl.id);
    
    		if (sd->bg_id != 0
    			&& (bgd = bg->team_search(sd->bg_id)) != NULL
    			&& (hBGd = getFromBGDATA(bgd, 0)) != NULL
    			&& (hBGsd = getFromMSD(sd, 1)) != NULL) {
    			bg->team_leave(sd, 1);
    			hBGsd->stats.total_deserted++;
    		}
    
    		removeFromMSD(sd, 1);
    	}
    
    	return 0;
    }
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                     Map Server Function Post-Hooks
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    
    /**
     * Battle Post-Hooks
     */
    void battle_consume_ammo(struct map_session_data *sd, int skill_id, int lv)
    {
    	int qty = 1;
    	struct hBG_map_session_data *hBGsd = getFromMSD(sd, 1);
    
    	if (battle->bc->arrow_decrement == 0 || hBGsd == NULL)
    		return;
    
    	if (skill)
    		qty = max(1, skill->get_ammo_qty(skill_id, lv));
    
    	if (sd->equip_index[EQI_AMMO] >= 0) {
    		if (sd->bg_id && map->list[sd->bl.m].flag.battleground)
    			add2limit(hBGsd->stats.ammo_used, qty, UINT_MAX);
    	}
    }
    
    // Check target immunity
    int battle_check_target_post(int retVal, struct block_list *src, struct block_list *target, int flag)
    {
    	if (retVal == 1 && target->type == BL_MOB) {
    		struct mob_data *md = BL_UCAST(BL_MOB, target);
    		struct hBG_mob_data *hBGmd = NULL;
    
    		if (md == NULL || (hBGmd = getFromMOBDATA(md, 0)) == NULL)
    			return retVal;
    
    		if (hBGmd != NULL && hBGmd->state.immunity) {
    			hookStop();
    			return retVal;
    		}
    	}
    
    	return retVal;
    }
    
    /**
     * Clif Post-Hooks
     */
    void clif_parse_LoadEndAck_post(int fd, struct map_session_data *sd)
    {
    	clif->charnameupdate(sd);
    	/* Display emblem on head of char [lucaslsb] */
    	if (hBG_enabled && sd->state.changemap && map->list[sd->bl.m].flag.battleground)
    		clif->map_type(sd, MAPTYPE_BATTLEFIELD);
    	if (hBG_enabled && map->list[sd->bl.m].flag.battleground)
    		clif->map_property(sd, MAPPROPERTY_AGITZONE);
    	return;
    }
    //Send charname_update every time you see someone in BG
    void clif_getareachar_unit_post(struct map_session_data *sd, struct block_list *bl)
    {
    	if (bl->type == BL_PC) {
    		struct map_session_data *tsd = BL_CAST(BL_PC, bl);
    		clif->charnameupdate(tsd);
    		return;
    	}
    }
    void clif_parse_UseSkillToId_post(int fd, struct map_session_data *sd)
    {
    	uint16 skill_id;
    	/* uint16 skill_lv; */
    	int target_id;
    	const struct s_packet_db *packet = clif->packet(RFIFOW(fd,0));
    	struct battleground_data *bgd;
    	struct hBG_data *hBGd;
    	
    	if (!sd->bg_id)
    		return;
    	else if ((bgd = bg->team_search(sd->bg_id)) == NULL || (hBGd = getFromBGDATA(bgd, 0)) == NULL)
    		return;
    
    	/* skill_lv = RFIFOW(fd,packet->pos[0]); */
    	skill_id = RFIFOW(fd,packet->pos[1]);
    	target_id = RFIFOL(fd,packet->pos[2]);
    	
    	if (skill_id >= GD_SKILLBASE && skill_id < GD_MAX && hBGd->leader_char_id == sd->status.char_id)
    			unit->skilluse_id(&sd->bl, target_id, skill_id, guild->checkskill(hBG_get_guild(sd->bg_id), skill_id));
    }
    
    /**
     * Server tells 'sd' player client the abouts of 'dstsd' player
     */
    void clif_getareachar_pc_post(struct map_session_data *sd,struct map_session_data *dstsd)
    {
    	if (sd->bg_id && dstsd->bg_id && sd->bg_id == dstsd->bg_id)
    			clif->hpmeter_single(sd->fd, dstsd->bl.id, dstsd->battle_status.hp, dstsd->battle_status.max_hp);
    }
    
    /**
     * PC Post hooks
     */
    void pc_update_idle_time_post(struct map_session_data* sd, enum e_battle_config_idletime type)
    {
    	struct hBG_map_session_data *hBGsd = NULL;
    	struct battleground_data *bgd = bg->team_search(sd->bg_id);
    	struct hBG_data *hBGd = NULL;
    	
    	nullpo_retv(sd);
    	
    	if (bgd && (hBGd = getFromBGDATA(bgd, 0)) && (hBGsd = getFromMSD(sd, 1)) && hBGsd->state.afk) {
    		char output[256];
    		/* Reset AFK status */
    		sprintf(output, "%s : %s is no longer AFK.", sd->status.name, hBGd->g->name);
    		hBG_send_chat_message(bgd, sd->bl.id, sd->status.name, output, (int)strlen(output) + 1);
    		hBGsd->state.afk = 0;
    	}
    }
    
    bool pc_authok_post(bool ret, struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, const struct mmo_charstatus *st, bool changing_mapservers)
    {
    	if (sd) {
    		WFIFOHEAD(chrif->fd, 14);
    		WFIFOW(chrif->fd, 0) = PACKET_INTER_BG_STATS_REQ;
    		WFIFOL(chrif->fd, 2) = sd->status.account_id;
    		WFIFOL(chrif->fd, 6) = sd->status.char_id;
    		WFIFOL(chrif->fd, 10) = sd->fd;
    		WFIFOSET(chrif->fd, 14);
    	}
    	
    	return ret;
    }
    
    /**
     * Character Interface Post-Hooks
     */
    /**
     * Requests saving of hBG Statistics and sends data to char-server.
     *
     * @param sd pointer to map session data.
     * @param flag as an indicator to tell char-server if character is quitting.
     * @return boolean.
     */
    bool chrif_save_post(bool ret, struct map_session_data *sd, int flag)
    {
    	struct hBG_map_session_data *hBGsd = NULL;
    	int len = 13 + sizeof(struct hBG_stats);
    	
    	nullpo_retr(false, sd);
    	
    	if ((hBGsd = getFromMSD(sd, 1)) == NULL)
    		return ret;
    
    	if (flag == 1) // Logout from BG! Do not save anything.
    		return ret;
    
    	WFIFOHEAD(chrif->fd, len);
    	WFIFOW(chrif->fd, 0) = PACKET_INTER_BG_STATS_SAVE; // 0x9000 Packet ID
    	WFIFOL(chrif->fd, 2) = sd->status.account_id; // Account Id
    	WFIFOL(chrif->fd, 6) = sd->status.char_id; // Char Id
    	WFIFOB(chrif->fd, 12) = (flag==1); //Flag to tell char-server this character is quitting.
    	memcpy(WFIFOP(chrif->fd, 13), &hBGsd->stats, sizeof(struct hBG_stats)); // hBG statistics.
    	WFIFOSET(chrif->fd, len);
    	
    	return ret;
    }
    
    /**
     * Status Post Hooks
     */
    int status_damage_post(int ret, struct block_list *src, struct block_list *target,int64 in_hp, int64 in_sp, int walkdelay, int flag)
    {
    	struct map_session_data *sd = NULL;
    	struct hBG_map_session_data *hBGsd = NULL;
    
    	nullpo_retr(ret, target);
    
    	if (src == NULL)
    		return ret;
    
    	if (src->type != BL_PC || (sd = BL_UCAST(BL_PC, src)) == NULL)
    		return ret;
    	if (map->list[src->m].flag.battleground == 0)
    		return ret;
    	if ((hBGsd = getFromMSD(sd, 1)) == NULL)
    		return ret;
    
    	hBG_record_damage(src, target, (int) in_hp);
    
    	return ret;
    }
    
    /**
     * Receives and allocates map session data with bg statistics
     * from char-server.
     *
     * @param fd as socket descriptor handle
     */
    void hBG_statistics_parsefromchar(int fd)
    {
    	struct map_session_data *sd = NULL;
    	struct hBG_map_session_data *hBGsd = NULL;
    	struct hBG_stats *stats = NULL;
    	/* int account_id = RFIFOL(fd, 2), char_id = RFIFOL(fd, 6); */
     	int char_fd = RFIFOL(fd,10);
    	
    	nullpo_retv(sockt->session[char_fd]);
    
    	if ((sd = sockt->session[char_fd]->session_data) == NULL)
    		return;
    
    	if ((hBGsd = getFromMSD(sd, 1)) == NULL) {
    		CREATE(hBGsd, struct hBG_map_session_data, 1);
    		addToMSD(sd, hBGsd, 1, false);
    	}
    	
    	if ((stats = getFromSession(sockt->session[fd], 0)) == NULL)
    		memcpy(&hBGsd->stats, RFIFOP(fd, 14), sizeof(struct hBG_stats));
    	else
    		memcpy(&hBGsd->stats, stats, sizeof(struct hBG_stats));
    }
    
    /**
    * Battleground Interface Overload [lucaslsb]
    */
    
    /**
     * Remove a player from a team.
     * @param sd pointer to session data.
     * @param flag type of leave.
     * @return Amount of player in the BG or 0 on failure.
     */
    int bg_team_leave_overload(struct map_session_data *sd, enum bg_team_leave_type flag)
    { // Single Player leaves team
    	int i;
    	struct battleground_data *bgd;
    	struct hBG_map_session_data *hBGsd;
    	struct hBG_data *hBGd;
    	struct map_session_data *pl_sd;
    	struct guild *g;
    
    	nullpo_ret(sd);
    	
    	if (!sd->bg_id)
    		return 0;
    	else if ((hBGsd = getFromMSD(sd, 1)) == NULL)
    		return 0;
    	else if ((bgd = bg->team_search(sd->bg_id)) == NULL)
    		return 0;
    	else if ((hBGd = getFromBGDATA(bgd, 0)) == NULL)
    		return 0;
    
    	// Packets
    	hBG_send_dot_remove(sd);
    	
    	// Reset information.
    	sd->bg_id = 0;
    	hBGsd->bg_kills = 0;
    	
    	// Remove battleground items if any.
    	hBG_member_remove_bg_items(sd);
    
    	// Remove Guild Skill Buffs
    	status_change_end(&sd->bl, SC_GUILDAURA, INVALID_TIMER);
    	status_change_end(&sd->bl, SC_GDSKILL_BATTLEORDER, INVALID_TIMER);
    	status_change_end(&sd->bl, SC_GDSKILL_REGENERATION, INVALID_TIMER);
    
    	// Refresh Guild Information
    	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);
    		clif->guild_emblem(sd, g);
    	} else {
    		hBG_send_leave_single(sd, sd->status.name, "Leaving Battle...");
    	}
    
    	clif->charnameupdate(sd);
    	clif->guild_emblem_area(&sd->bl);
    
    	ARR_FIND(0, MAX_BG_MEMBERS, i, bgd->members[i].sd == sd);
    
    	if (i < MAX_BG_MEMBERS) // Removes member from BG
    		memset(&bgd->members[i], 0, sizeof(struct battleground_member_data));
    	
    	ARR_FIND(0, MAX_BG_MEMBERS, i, hBGd->g->member[i].sd == sd);
    	
    	if (i < MAX_BG_MEMBERS) // removes member from BG Guild
    		memset(&hBGd->g->member[i].sd, 0, sizeof(hBGd->g->member[i].sd));
    	
    	if (hBGd->leader_char_id == sd->status.char_id)
    		hBGd->leader_char_id = 0;
    	
    	if (--bgd->count > 0) {
    		for (i = 0; i < MAX_BG_MEMBERS; i++) { // Update other BG members
    			if ((pl_sd = bgd->members[i].sd) == NULL)
    				continue;
    			
    			if (!hBGd->leader_char_id) { // Set new Leader first on the list
    				hBGd->leader_char_id = pl_sd->status.char_id;
    				clif->charnameupdate(pl_sd);
    			}
    			
    			switch (flag) {
    				case 3: hBG_send_expulsion(pl_sd, sd->status.name, "Kicked by AFK Status..."); break;
    				case 2: hBG_send_expulsion(pl_sd, sd->status.name, "Kicked by AFK Report..."); break;
    				case 1: hBG_send_expulsion(pl_sd, sd->status.name, "User has quit the game..."); break;
    				case 0: hBG_send_leave_single(pl_sd, sd->status.name, "Leaving Battle..."); break;
    			}
    			
    			hBG_guild_window_info(pl_sd);
    			hBG_send_emblem(pl_sd, hBGd->g);
    			hBG_send_guild_member_list(pl_sd);
    		}
    	}
    
    	if (bgd && strlen(bgd->logout_event) && flag)
    		npc->event(sd, bgd->logout_event, 0);
    	
    	return bgd->count;
    }
    
    /**
    * Clif Interface Overload [lucaslsb]
    */
    void clif_sendbgemblem_area_overload(struct map_session_data *sd)
    {
    	int cmd = 0x2dd;
    	const struct s_packet_db *packet = clif->packet(cmd);
    	unsigned char buf[33];
    	nullpo_retv(sd);
    	if (hBG_enabled)
    		return; // Prevents display of conventional emblems
    	WBUFW(buf, 0) = cmd;
    	WBUFL(buf, 2) = sd->bl.id;
    	safestrncpy((char*)WBUFP(buf, 6), sd->status.name, NAME_LENGTH); // name don't show in screen.
    	WBUFW(buf, 30) = sd->bg_id;
    	clif->send(buf, packet->len, &sd->bl, AREA);
    }
    
    void clif_sendbgemblem_single_overload(int fd, struct map_session_data *sd)
    {
    	int cmd = 0x2dd;
    	const struct s_packet_db *packet = clif->packet(cmd);
    	nullpo_retv(sd);
    	if (hBG_enabled)
    		return; // Prevents display of conventional emblems
    	WFIFOHEAD(fd, 32);
    	WFIFOW(fd, 0) = cmd;
    	WFIFOL(fd, 2) = sd->bl.id;
    	safestrncpy(WFIFOP(fd, 6), sd->status.name, NAME_LENGTH);
    	WFIFOW(fd, 30) = sd->bg_id;
    	WFIFOSET(fd, packet->len);
    }
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                     Char Server Functions
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    /**
     * Character Server Saving of hBG Statistics
     *
     * @param fd socket descriptor handle
     */
    void char_bgstats_tosql(int fd)
    {
    	struct hBG_stats pstats = {0}, *stats = NULL;
    	int account_id = 0, char_id = 0;
    	/* int flag = 0; */
    	
    	nullpo_retv(sockt->session[fd]);
    	
    	account_id = RFIFOL(fd, 2);
    	char_id = RFIFOL(fd, 6);
    	/* flag = RFIFOB(fd, 12); */
    	
    	if ((stats = getFromSession(sockt->session[fd], 0)) == NULL) {
    		CREATE(stats, struct hBG_stats, 1);
    		addToSession(sockt->session[fd], stats, 0, true);
    	}
    	
    	memcpy(&pstats, RFIFOP(fd, 13), sizeof(struct hBG_stats));
    	
    	if (memcmp(stats, &pstats, sizeof(struct hBG_stats))) {
    		if (SQL_ERROR == SQL->Query(inter->sql_handle,
    			"REPLACE INTO `char_bg_stats` ("
    			"`char_id`, "
    			"`best_damage`, `total_damage_done`, `total_damage_received`, "
    			"`ti_wins`, `ti_lost`, `ti_tie`, "
    			"`eos_flags`, `eos_bases`, `eos_wins`, `eos_lost`, `eos_tie`, "
    			"`boss_killed`, `boss_damage`, `boss_flags`, `boss_wins`, `boss_lost`, `boss_tie`, "
    			"`dom_bases`, `dom_off_kills`, `dom_def_kills`, `dom_wins`, `dom_lost`, `dom_tie`, "
    			"`td_kills`, `td_deaths`, `td_wins`, `td_lost`, `td_tie`, "
    			"`sc_stolen`, `sc_captured`, `sc_dropped`, `sc_wins`, `sc_lost`, `sc_tie`, "
    			"`ctf_taken`, `ctf_captured`, `ctf_dropped`, `ctf_wins`, `ctf_lost`, `ctf_tie`, "
    			"`emperium_kills`, `barricade_kills`, `guardian_stone_kills`, `conquest_wins`, `conquest_losses`, "
    			"`ru_captures`, `ru_wins`, `ru_lost`, `ru_skulls`,"
    			"`kill_count`, `death_count`, `wins`, `losses`, `ties`, `wins_as_leader`, `losses_as_leader`, `ties_as_leader`, `total_deserted`, `score`, `points`, `ranked_points`, `ranked_games`,"
    			"`sp_heal_potions`, `hp_heal_potions`, `yellow_gemstones`, `red_gemstones`, `blue_gemstones`, `poison_bottles`, `acid_demostration`, `acid_demostration_fail`, "
    			"`support_skills_used`, `healing_done`, `wrong_support_skills_used`, `wrong_healing_done`, "
    			"`sp_used`, `zeny_used`, `spiritb_used`, `ammo_used`)"
    			" VALUES "
    			"('%d',"
    			"'%d','%u','%u',"
    			"'%d','%d','%d','%d',"
    			"'%d','%d','%d','%d','%d',"
    			"'%u','%d','%d','%d','%d','%d',"
    			"'%d','%d','%d','%d','%d','%d',"
    			"'%d','%d','%d','%d','%d',"
    			"'%d','%d','%d','%d','%d','%d',"
    			"'%d','%d','%d','%d','%d','%d',"
    			"'%d','%d','%d','%d','%d',"
    			"'%d','%d','%d',"
    			"'%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d',"
    			"'%u','%u','%u','%u','%u','%u','%u','%u',"
    			"'%u','%u','%u','%u',"
    			"'%u','%u','%u','%u')",
    			char_id,
    			pstats.best_damage, pstats.total_damage_done, pstats.total_damage_received,
    			pstats.ti_wins,pstats.ti_lost,pstats.ti_tie,
    			pstats.eos_flags,pstats.eos_bases,pstats.eos_wins,pstats.eos_lost,pstats.eos_tie,
    			pstats.boss_killed,pstats.boss_damage,pstats.boss_flags,pstats.boss_wins,pstats.boss_lost,pstats.boss_tie,
    			pstats.dom_bases,pstats.dom_off_kills,pstats.dom_def_kills,pstats.dom_wins,pstats.dom_lost,pstats.dom_tie,
    			pstats.td_kills,pstats.td_deaths,pstats.td_wins,pstats.td_lost,pstats.td_tie,
    			pstats.sc_stolen,pstats.sc_captured,pstats.sc_dropped,pstats.sc_wins,pstats.sc_lost,pstats.sc_tie,
    			pstats.ctf_taken,pstats.ctf_captured,pstats.ctf_dropped,pstats.ctf_wins,pstats.ctf_lost,pstats.ctf_tie,
    			pstats.emperium_kills,pstats.barricade_kills,pstats.guardian_stone_kills,pstats.conquest_wins,pstats.conquest_losses,
    			pstats.ru_captures,pstats.ru_wins,pstats.ru_lost, pstats.ru_skulls,
    			pstats.kill_count,pstats.death_count,pstats.wins,pstats.losses,pstats.ties,pstats.wins_as_leader,pstats.losses_as_leader,
    			pstats.ties_as_leader,pstats.total_deserted,pstats.score,pstats.points,pstats.ranked_points,pstats.ranked_games,
    			pstats.sp_heal_potions, pstats.hp_heal_potions, pstats.yellow_gemstones, pstats.red_gemstones,
    			pstats.blue_gemstones, pstats.poison_bottles, pstats.acid_demostration, pstats.acid_demostration_fail,
    			pstats.support_skills_used, pstats.healing_done, pstats.wrong_support_skills_used, pstats.wrong_healing_done,
    			pstats.sp_used, pstats.zeny_used, pstats.spiritb_used, pstats.ammo_used))
    		{
    			Sql_ShowDebug(inter->sql_handle);
    		} else {
    			memcpy(stats, &pstats, sizeof(struct hBG_stats));
    			ShowInfo("Saved char (AID/CID: %d/%d) - BG Statistics [by Smokexyz].\n", account_id, char_id);
    		}
    	}
    }
    
    void char_bgstats_fromsql(int fd)
    {
    	struct hBG_stats temp_stats = { 0 }, *stats = NULL;
    	int account_id = 0, char_id = 0, char_fd = 0, len = 0;
    	struct SqlStmt *stmt = SQL->StmtMalloc(inter->sql_handle);
    
    	if (stmt == NULL) {
    		SqlStmt_ShowDebug(stmt);
    		return;
    	}
    	
    	account_id = RFIFOL(fd,2);
    	char_id = RFIFOL(fd, 6);
    	char_fd = RFIFOL(fd, 10);
    	
    	if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT "
    		"`best_damage`,`total_damage_done`,`total_damage_received`,`ru_skulls`,`ti_wins`,`ti_lost`,`ti_tie`,`eos_flags`,`eos_bases`,`eos_wins`," // 0-9
    		"`eos_lost`,`eos_tie`,`boss_killed`,`boss_damage`,`boss_flags`,`boss_wins`,`boss_lost`,`boss_tie`,`td_kills`,`td_deaths`," //10-19
    		"`td_wins`,`td_lost`,`td_tie`,`sc_stolen`,`sc_captured`,`sc_dropped`,`sc_wins`,`sc_lost`,`sc_tie`,`ctf_taken`," //20-29
    		"`ctf_captured`,`ctf_dropped`,`ctf_wins`,`ctf_lost`,`ctf_tie`,`emperium_kills`,`barricade_kills`,`guardian_stone_kills`,`conquest_wins`,`conquest_losses`,"//30-39
    		"`kill_count`,`death_count`,`wins`,`losses`,`ties`,`wins_as_leader`,`losses_as_leader`,`ties_as_leader`,`total_deserted`,`score`,"//40-49
    		"`points`,`sp_heal_potions`,`hp_heal_potions`,`yellow_gemstones`,`red_gemstones`,`blue_gemstones`,`poison_bottles`,`acid_demostration`,`acid_demostration_fail`,`support_skills_used`,"//50-59
    		"`healing_done`,`wrong_support_skills_used`,`wrong_healing_done`,`sp_used`,`zeny_used`,`spiritb_used`,`ammo_used`,`ranked_points`,`ranked_games`,`ru_wins`,"//60-69
    		"`ru_lost`,`ru_captures`,`dom_bases`,`dom_off_kills`,`dom_def_kills`,`dom_wins`,`dom_lost`,`dom_tie`"//70-79
    		" FROM `char_bg_stats` WHERE `char_id` = ?")
    		|| SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, sizeof char_id)
    		|| SQL_ERROR == SQL->StmtExecute(stmt)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_UINT, &temp_stats.best_damage, sizeof temp_stats.best_damage, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_UINT, &temp_stats.total_damage_done, sizeof temp_stats.total_damage_done, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_UINT, &temp_stats.total_damage_received, sizeof temp_stats.total_damage_received, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT, &temp_stats.ru_skulls, sizeof temp_stats.ru_skulls, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_USHORT, &temp_stats.ti_wins, sizeof temp_stats.ti_wins, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_USHORT, &temp_stats.ti_lost, sizeof temp_stats.ti_lost, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_USHORT, &temp_stats.ti_tie, sizeof temp_stats.ti_tie, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 7, SQLDT_USHORT, &temp_stats.eos_flags, sizeof temp_stats.eos_flags, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_USHORT, &temp_stats.eos_bases, sizeof temp_stats.eos_bases, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_USHORT, &temp_stats.eos_wins, sizeof temp_stats.eos_wins, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 10, SQLDT_USHORT, &temp_stats.eos_lost, sizeof temp_stats.eos_lost, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 11, SQLDT_USHORT, &temp_stats.eos_tie, sizeof temp_stats.eos_tie, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 12, SQLDT_USHORT, &temp_stats.boss_killed, sizeof temp_stats.boss_killed, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 13, SQLDT_UINT, &temp_stats.boss_damage, sizeof temp_stats.boss_damage, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 14, SQLDT_USHORT, &temp_stats.boss_flags, sizeof temp_stats.boss_flags, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 15, SQLDT_USHORT, &temp_stats.boss_wins, sizeof temp_stats.boss_wins, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 16, SQLDT_USHORT, &temp_stats.boss_lost, sizeof temp_stats.boss_lost, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 17, SQLDT_USHORT, &temp_stats.boss_tie, sizeof temp_stats.boss_tie, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 18, SQLDT_USHORT, &temp_stats.td_kills, sizeof temp_stats.td_kills, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 19, SQLDT_USHORT, &temp_stats.td_deaths, sizeof temp_stats.td_deaths, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 20, SQLDT_USHORT, &temp_stats.td_wins, sizeof temp_stats.td_wins, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 21, SQLDT_USHORT, &temp_stats.td_lost, sizeof temp_stats.td_lost, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 22, SQLDT_USHORT, &temp_stats.td_tie, sizeof temp_stats.td_tie, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 23, SQLDT_USHORT, &temp_stats.sc_stolen, sizeof temp_stats.sc_stolen, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 24, SQLDT_USHORT, &temp_stats.sc_captured, sizeof temp_stats.sc_captured, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 25, SQLDT_USHORT, &temp_stats.sc_dropped, sizeof temp_stats.sc_dropped, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 26, SQLDT_USHORT, &temp_stats.sc_wins, sizeof temp_stats.sc_wins, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 27, SQLDT_USHORT, &temp_stats.sc_lost, sizeof temp_stats.sc_lost, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 28, SQLDT_USHORT, &temp_stats.sc_tie, sizeof temp_stats.sc_tie, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 29, SQLDT_USHORT, &temp_stats.ctf_taken, sizeof temp_stats.ctf_taken, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 30, SQLDT_USHORT, &temp_stats.ctf_captured, sizeof temp_stats.ctf_captured, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 31, SQLDT_USHORT, &temp_stats.ctf_dropped, sizeof temp_stats.ctf_dropped, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 32, SQLDT_USHORT, &temp_stats.ctf_wins, sizeof temp_stats.ctf_wins, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 33, SQLDT_USHORT, &temp_stats.ctf_lost, sizeof temp_stats.ctf_lost, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 34, SQLDT_USHORT, &temp_stats.ctf_tie, sizeof temp_stats.ctf_tie, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 35, SQLDT_USHORT, &temp_stats.emperium_kills, sizeof temp_stats.emperium_kills, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 36, SQLDT_USHORT, &temp_stats.barricade_kills, sizeof temp_stats.barricade_kills, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 37, SQLDT_USHORT, &temp_stats.guardian_stone_kills, sizeof temp_stats.guardian_stone_kills, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 38, SQLDT_USHORT, &temp_stats.conquest_wins, sizeof temp_stats.conquest_wins, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 39, SQLDT_USHORT, &temp_stats.conquest_losses, sizeof temp_stats.conquest_losses, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 40, SQLDT_USHORT, &temp_stats.kill_count, sizeof temp_stats.kill_count, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 41, SQLDT_USHORT, &temp_stats.death_count, sizeof temp_stats.death_count, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 42, SQLDT_USHORT, &temp_stats.wins, sizeof temp_stats.wins, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 43, SQLDT_USHORT, &temp_stats.losses, sizeof temp_stats.losses, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 44, SQLDT_USHORT, &temp_stats.ties, sizeof temp_stats.ties, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 45, SQLDT_USHORT, &temp_stats.wins_as_leader, sizeof temp_stats.wins_as_leader, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 46, SQLDT_USHORT, &temp_stats.losses_as_leader, sizeof temp_stats.losses_as_leader, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 47, SQLDT_USHORT, &temp_stats.ties_as_leader, sizeof temp_stats.ties_as_leader, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 48, SQLDT_USHORT, &temp_stats.total_deserted, sizeof temp_stats.total_deserted, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 49, SQLDT_INT, &temp_stats.score, sizeof temp_stats.score, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 50, SQLDT_INT, &temp_stats.points, sizeof temp_stats.points, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 51, SQLDT_UINT, &temp_stats.sp_heal_potions, sizeof temp_stats.sp_heal_potions, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 52, SQLDT_UINT, &temp_stats.hp_heal_potions, sizeof temp_stats.hp_heal_potions, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 53, SQLDT_UINT, &temp_stats.yellow_gemstones, sizeof temp_stats.yellow_gemstones, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 54, SQLDT_UINT, &temp_stats.red_gemstones, sizeof temp_stats.red_gemstones, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 55, SQLDT_UINT, &temp_stats.blue_gemstones, sizeof temp_stats.blue_gemstones, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 56, SQLDT_UINT, &temp_stats.poison_bottles, sizeof temp_stats.poison_bottles, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 57, SQLDT_UINT, &temp_stats.acid_demostration, sizeof temp_stats.acid_demostration, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 58, SQLDT_UINT, &temp_stats.acid_demostration_fail, sizeof temp_stats.acid_demostration_fail, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 59, SQLDT_UINT, &temp_stats.support_skills_used, sizeof temp_stats.support_skills_used, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 60, SQLDT_UINT, &temp_stats.healing_done, sizeof temp_stats.healing_done, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 61, SQLDT_UINT, &temp_stats.wrong_support_skills_used, sizeof temp_stats.wrong_support_skills_used, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 62, SQLDT_UINT, &temp_stats.wrong_healing_done, sizeof temp_stats.wrong_healing_done, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 63, SQLDT_UINT, &temp_stats.sp_used, sizeof temp_stats.sp_used, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 64, SQLDT_UINT, &temp_stats.zeny_used, sizeof temp_stats.zeny_used, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 65, SQLDT_UINT, &temp_stats.spiritb_used, sizeof temp_stats.spiritb_used, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 66, SQLDT_UINT, &temp_stats.ammo_used, sizeof temp_stats.ammo_used, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 67, SQLDT_UINT, &temp_stats.ranked_points, sizeof temp_stats.ranked_points, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 68, SQLDT_USHORT, &temp_stats.ranked_games, sizeof temp_stats.ranked_games, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 69, SQLDT_USHORT, &temp_stats.ru_wins, sizeof temp_stats.ru_wins, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 70, SQLDT_USHORT, &temp_stats.ru_lost, sizeof temp_stats.ru_lost, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 71, SQLDT_USHORT, &temp_stats.ru_captures, sizeof temp_stats.ru_captures, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 72, SQLDT_USHORT, &temp_stats.dom_bases, sizeof temp_stats.dom_bases, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 73, SQLDT_USHORT, &temp_stats.dom_off_kills, sizeof temp_stats.dom_off_kills, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 74, SQLDT_USHORT, &temp_stats.dom_def_kills, sizeof temp_stats.dom_def_kills, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 75, SQLDT_USHORT, &temp_stats.dom_wins, sizeof temp_stats.dom_wins, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 76, SQLDT_USHORT, &temp_stats.dom_lost, sizeof temp_stats.dom_lost, NULL, NULL)
    		|| SQL_ERROR == SQL->StmtBindColumn(stmt, 77, SQLDT_USHORT, &temp_stats.dom_tie, sizeof temp_stats.dom_tie, NULL, NULL)
    		|| SQL_SUCCESS != SQL->StmtNextRow(stmt))
    	{
    		temp_stats.score = 2000;
    	}
    	
    	ShowInfo("Loaded char (AID/CID: %d/%d) - BG Statistics [by Smokexyz]\n", account_id, char_id);
    	
    	if ((stats = getFromSession(sockt->session[fd], 0)) == NULL) {
    		CREATE(stats, struct hBG_stats, 1);
    		memcpy(stats, &temp_stats, sizeof(struct hBG_stats));
    		addToSession(sockt->session[fd], stats, 0, true);
    	} else if (memcmp(stats, &temp_stats, sizeof(struct hBG_stats))) {
    		memcpy(stats, &temp_stats, sizeof(struct hBG_stats));
    	}
    
    	SQL->StmtFree(stmt);
    
    	len = 14 + sizeof(struct hBG_stats);
    	WFIFOHEAD(fd, len);
    	WFIFOW(fd, 0) = PACKET_MAP_BG_STATS_GET;
    	WFIFOL(fd, 2) = account_id;
    	WFIFOL(fd, 6) = char_id;
    	WFIFOL(fd, 10) = char_fd;
    	memcpy(WFIFOP(fd, 14), &temp_stats, sizeof(struct hBG_stats));
    	WFIFOSET(fd, len);
    }
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                     Battle Configuration Parsing                    *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    void hBG_config_read(const char *key, const char *val)
    {
    	int value = config_switch (val);
    
    	if (strcmpi(key,"battle_configuration/hBG_enabled") == 0) {
    		if (value < 0 || value > 1) {
    			ShowWarning("Received Invalid Setting %d for hBG_enabled, defaulting to 0.\n", value);
    			return;
    		}
    		hBG_enabled = value;
    	} else if (strcmpi(key, "battle_configuration/hBG_from_town_only") == 0) {
    		if (value < 0 || value > 1) {
    			ShowWarning("Received Invalid Setting %d for hBG_from_town_only, defaulting to 0.\n", value);
    			return;
    		}
    		hBG_from_town_only = value;
    	} else if (strcmpi(key, "battle_configuration/hBG_ip_check") == 0) {
    		if (value < 0) {
    			ShowWarning("Received Invalid Setting %d for hBG_ip_check, defaulting to 0.\n", value);
    			return;
    		}
    		hBG_ip_check = value;
    	} else if (strcmpi(key, "battle_configuration/hBG_idle_announce") == 0) {
    		if (value < 0) {
    			ShowWarning("Received Invalid Setting %d for hBG_idle_announce, defaulting to 60 seconds.\n", value);
    			hBG_idle_announce = 60;
    		} else {
    			hBG_idle_announce = value;
    		}
    	} else if (strcmpi(key, "battle_configuration/hBG_idle_autokick") == 0) {
    		if (value < 0) {
    			ShowWarning("Received Invalid Setting %d for hBG_idle_autokick, defaulting to 5 minutes (300s).\n", value);
    			hBG_idle_autokick = 300;
    		} else {
    			hBG_idle_autokick = value;
    		}
    	} else if (strcmpi(key, "battle_configuration/hBG_reportafk_leaderonly") == 0) {
    		if (value < 0 || value > 1) {
    			ShowWarning("Received Invalid Setting %d for hBG_reportafk_leaderonly, defaulting to 0.\n", value);
    			hBG_reportafk_leaderonly = 0;
    		} else {
    			hBG_reportafk_leaderonly = value;
    		}
    	} else if (strcmpi(key, "battle_configuration/hBG_balanced_queue") == 0) {
    		if (value < 0 || value > 1) {
    			ShowWarning("Received Invalid Setting %d for hBG_balanced_queue, defaulting to 0.\n", value);
    			return;
    		}
    		hBG_balanced_queue = value;
    	} else if (strcmpi(key, "battle_configuration/hBG_reward_rates") == 0) {
    		if (value < 0) {
    			ShowWarning("Received invalid setting %d for hBG_reward_rates, defaulting to 100.\n", value);
    			hBG_reward_rates = 100;
    		} else {
    			hBG_reward_rates = value;
    		}
    	} else if (strcmpi(key, "battle_configuration/hBG_xy_interval") == 0) {
    		if (value < 1000) {
    			ShowWarning("Received Invalid Setting %d for hBG_xy_interval. (min: %d, max: %d) Defaulting to 1000ms. \n", value, 1000, INT_MAX);
    			hBG_xy_interval = 1000;
    		} else {
    			hBG_xy_interval = value;
    		}
    	} else if (strcmpi(key, "battle_configuration/hBG_ranked_mode") == 0) {
    		if (value < 0 || value > 1) {
    			ShowWarning("Received Invalid Setting %d for hBG_ranked_mode, defaulting to 0.\n", value);
    			hBG_ranked_mode = 0;
    		} else {
    			hBG_ranked_mode = value;
    		}
    	} else if (strcmpi(key, "battle_configuration/hBG_leader_change") == 0) {
    		if (value < 0 || value > 1) {
    			ShowWarning("Received Invalid Setting %d for hBG_leader_change, defaulting to 0.\n", value);
    			hBG_leader_change = 0;
    		} else {
    			hBG_leader_change = value;
    		}
    	}
    }
    
    int hBG_config_get(const char *key)
    {
    	if (strcmpi(key, "battle_configuration/hBG_enabled") == 0)
    		return hBG_enabled;
    	else if (strcmpi(key, "battle_configuration/hBG_from_town_only") == 0)
    		return hBG_from_town_only;
    	else if (strcmpi(key, "battle_configuration/hBG_ip_check") == 0)
    		return hBG_ip_check;
    	else if (strcmpi(key, "battle_configuration/hBG_idle_announce") == 0)
    		return hBG_idle_announce;
    	else if (strcmpi(key, "battle_configuration/hBG_idle_autokick") == 0)
    		return hBG_idle_autokick;
    	else if (strcmpi(key, "battle_configuration/hBG_reportafk_leaderonly") == 0)
    		return hBG_reportafk_leaderonly;
    	else if (strcmpi(key, "battle_configuration/hBG_balanced_queue") == 0)
    		return hBG_balanced_queue;
    	else if (strcmpi(key, "battle_configuration/hBG_reward_rates") == 0)
    		return hBG_reward_rates;
    	else if (strcmpi(key, "battle_configuration/hBG_xy_interval") == 0)
    		return hBG_xy_interval;
    	else if (strcmpi(key, "battle_configuration/hBG_ranked_mode") == 0)
    		return hBG_ranked_mode;
    	else if (strcmpi(key, "battle_configuration/hBG_leader_change") == 0)
    		return hBG_leader_change;
    
    	return 0;
    }
    
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *                       Plugin Handling
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    /* run when server starts */
    HPExport void plugin_init(void)
    {
    	int interval = hBG_config_get("battle_configuration/hBG_xy_interval");
    
    	if (SERVER_TYPE == SERVER_TYPE_CHAR) {
    		addPacket(PACKET_INTER_BG_STATS_REQ, 14, char_bgstats_fromsql, hpParse_FromMap);
    		addPacket(PACKET_INTER_BG_STATS_SAVE, 13 + sizeof(struct hBG_stats), char_bgstats_tosql, hpParse_FromMap);
    	}
    	
    	if (SERVER_TYPE == SERVER_TYPE_MAP) {
    		addPacket(PACKET_MAP_BG_STATS_GET, 14+sizeof(struct hBG_stats), hBG_statistics_parsefromchar, hpChrif_Parse);
    		
    		/* Function Pre-Hooks */
    		addHookPre(npc, parse_unknown_mapflag, npc_parse_unknown_mapflag_pre);
    		addHookPre(clif, charnameupdate, clif_charnameupdate_pre);
    		addHookPre(clif, pGuildRequestInfo,clif_parse_GuildRequestInfo_pre);
    		addHookPre(status, get_guild_id, status_get_guild_id_pre);
    		addHookPre(status, get_emblem_id, status_get_emblem_id_pre);
    		addHookPre(guild, isallied, guild_isallied_pre);
    		addHookPre(skill, check_condition_castbegin, skill_check_condition_castbegin_pre);
    		addHookPre(skill, not_ok, skillnotok_pre);
    		addHookPre(skill, castend_nodamage_id, skill_castend_nodamage_id_pre);
    		addHookPre(unit, free, unit_free_pre);
    		
    		/* Function Post-Hooks */
    		addHookPost(clif, pLoadEndAck, clif_parse_LoadEndAck_post);
    		addHookPost(clif, pUseSkillToId, clif_parse_UseSkillToId_post);
    		addHookPost(clif, getareachar_pc, clif_getareachar_pc_post);
    		addHookPost(clif, getareachar_unit, clif_getareachar_unit_post);
    		addHookPost(pc, update_idle_time, pc_update_idle_time_post);
    		addHookPost(pc, authok, pc_authok_post);
    		addHookPost(chrif, save, chrif_save_post);
    		addHookPost(status, damage, status_damage_post);
    		
    		addHookPost(battle, check_target, battle_check_target_post);
    		
    		/* @Commands */
    		addAtcommand("bgrank", bgrank);
    		addAtcommand("reportafk", reportafk);
    		addAtcommand("leader", leader);
    		
    		/* Script Commands */
    		addScriptCommand("hBG_team_create","siiiss", hBG_team_create);
    		addScriptCommand("hBG_queue_create","ss?", hBG_queue_create);
    		addScriptCommand("hBG_queue_event","is", hBG_queue_event);
    		addScriptCommand("hBG_queue_join","i", hBG_queue_join);
    		addScriptCommand("hBG_queue_partyjoin","ii", hBG_queue_partyjoin);
    		addScriptCommand("hBG_queue_leave","i", hBG_queue_leave);
    		addScriptCommand("hBG_queue_data","ii", hBG_queue_data);
    		addScriptCommand("hBG_queue2team","iisiiiss", hBG_queue2team);
    		addScriptCommand("hBG_queue2team_single","iisii", hBG_queue2team_single);
    		addScriptCommand("hBG_queue2teams","iiiiii*", hBG_queue2teams);
    		addScriptCommand("hBG_queue_checkstart","iiii", hBG_queue_checkstart);
    		addScriptCommand("hBG_balance_teams","iiiii*", hBG_balance_teams);
    		addScriptCommand("hBG_waitingroom2bg","siiiss", hBG_waitingroom2bg);
    		addScriptCommand("hBG_waitingroom2bg_single","isiis", hBG_waitingroom2bg_single);
    		addScriptCommand("hBG_team_setxy","iii", hBG_team_setxy);
    		addScriptCommand("hBG_team_reveal","i", hBG_team_reveal);
    		addScriptCommand("hBG_team_conceal","i", hBG_team_conceal);
    		addScriptCommand("hBG_team_setquest","ii", hBG_team_setquest);
    		addScriptCommand("hBG_viewpointmap","siiiii", hBG_viewpointmap);
    		addScriptCommand("hBG_monster_reveal","iii", hBG_monster_reveal);
    		addScriptCommand("hBG_monster_set_team","ii", hBG_monster_set_team);
    		addScriptCommand("hBG_monster_immunity","ii", hBG_monster_immunity);
    		addScriptCommand("hBG_leave","", hBG_leave);
    		addScriptCommand("hBG_destroy","i", hBG_destroy);
    		addScriptCommand("hBG_clean","i", hBG_clean);
    		addScriptCommand("hBG_get_data","ii", hBG_get_data);
    		addScriptCommand("hBG_getareausers","isiiii", hBG_getareausers);
    		addScriptCommand("hBG_updatescore","sii", hBG_updatescore);
    		addScriptCommand("hBG_team_updatescore", "ii", hBG_update_score_team);
    		addScriptCommand("hBG_team_guildid","i", hBG_get_team_gid);
    		addScriptCommand("hBG_getitem","iii", hBG_getitem);
    		addScriptCommand("hBG_getkafrapoints","ii", hBG_getkafrapoints);
    		addScriptCommand("hBG_reward","iiiiisiii", hBG_reward);
    		addScriptCommand("hBG_flooritem2xy", "siiii", hBG_flooritem2xy);
    		addScriptCommand("hBG_warp", "isii", hBG_warp);
    		
    		hBG_queue_db = idb_alloc(DB_OPT_RELEASE_DATA);
    		timer->add_func_list(hBG_send_xy_timer, "hBG_send_xy_timer");
    		timer->add_interval(timer->gettick() + interval , hBG_send_xy_timer, 0, 0, interval);
    	}
    }
    
    /* triggered when server starts loading, before any server-specific data is set */
    HPExport void server_preinit(void)
    {
    	if (SERVER_TYPE == SERVER_TYPE_MAP) {
    		addBattleConf("battle_configuration/hBG_enabled", hBG_config_read, hBG_config_get, true);
    		addBattleConf("battle_configuration/hBG_from_town_only", hBG_config_read, hBG_config_get, true);
    		addBattleConf("battle_configuration/hBG_ip_check", hBG_config_read, hBG_config_get, true);
    		addBattleConf("battle_configuration/hBG_idle_announce", hBG_config_read, hBG_config_get, true);
    		addBattleConf("battle_configuration/hBG_idle_autokick", hBG_config_read, hBG_config_get, true);
    		addBattleConf("battle_configuration/hBG_balanced_queue", hBG_config_read, hBG_config_get, true);
    		addBattleConf("battle_configuration/hBG_reward_rates", hBG_config_read, hBG_config_get, true);
    		addBattleConf("battle_configuration/hBG_xy_interval", hBG_config_read, hBG_config_get, true);
    		addBattleConf("battle_configuration/hBG_ranked_mode", hBG_config_read, hBG_config_get, true);
    		addBattleConf("battle_configuration/hBG_leader_change", hBG_config_read, hBG_config_get, true);
    	}
    }
    
    /* run when server is ready (online) */
    HPExport void server_online(void)
    {
    	if (SERVER_TYPE == SERVER_TYPE_MAP) {
    		hBG_build_guild_data();
    		ShowStatus("%s v%s has been initialized. [by Smokexyz]\n", pinfo.name, pinfo.version);
    		// clif interface overloading [lucaslsb]
    		bg->team_leave = &bg_team_leave_overload;
    		clif->sendbgemblem_area = &clif_sendbgemblem_area_overload;
    		clif->sendbgemblem_single = &clif_sendbgemblem_single_overload;
    	}
    }
    
    static int queue_db_final(union DBKey key, struct DBData *data, va_list ap)
    {
    	struct hBG_queue_data *hBGqd = DB->data2ptr(data);
    	
    	if (hBGqd)
    		hBG_queue_members_finalize(hBGqd); // Unlink all queue members
    	
    	return 0;
    }
    
    /* run when server is shutting down */
    HPExport void plugin_final(void)
    {
    	if (SERVER_TYPE == SERVER_TYPE_MAP) {
    		hBG_queue_db->destroy(hBG_queue_db, queue_db_final);
    		ShowInfo ("%s v%s has been finalized. [by Smokexyz]\n", pinfo.name, pinfo.version);
    	}
    }

     

    hBG.c: In function ‘atcommand_reportafk’:
    hBG.c:2040:31: warning: unused variable ‘hBGsd’ [-Wunused-variable]
      struct hBG_map_session_data *hBGsd = NULL;
                                   ^
    hBG.c: In function ‘atcommand_leader’:
    hBG.c:2084:31: warning: unused variable ‘hBGsd’ [-Wunused-variable]
      struct hBG_map_session_data *hBGsd = NULL;
                                   ^
    hBG.c: In function ‘status_get_guild_id_pre’:
    hBG.c:3776:31: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
       && (bg_id = bg->team_get_id((struct block_list *)*bl)) > 0
                                   ^
    hBG.c: In function ‘status_get_emblem_id_pre’:
    hBG.c:3797:31: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
       && (bg_id = bg->team_get_id((struct block_list *)(*bl))) > 0
                                   ^
            PLUGIN  hBG

    Using this plugin.

     


  15. Someone please help.

    How to solve these warnings.

    hBG.c: In function ‘atcommand_reportafk’:
    hBG.c:2040:31: warning: unused variable ‘hBGsd’ [-Wunused-variable]
      struct hBG_map_session_data *hBGsd = NULL;
                                   ^
    hBG.c: In function ‘atcommand_leader’:
    hBG.c:2084:31: warning: unused variable ‘hBGsd’ [-Wunused-variable]
      struct hBG_map_session_data *hBGsd = NULL;
                                   ^
    hBG.c: In function ‘status_get_guild_id_pre’:
    hBG.c:3776:31: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
       && (bg_id = bg->team_get_id((struct block_list *)*bl)) > 0
                                   ^
    hBG.c: In function ‘status_get_emblem_id_pre’:
    hBG.c:3797:31: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
       && (bg_id = bg->team_get_id((struct block_list *)(*bl))) > 0
                                   ^
            PLUGIN  hBG

     


  16. Good day!

    Where did the maxcount went? I wanted to limit number of specific skill in land like traps.

    // 13 maxcount: max amount of skill instances to place on the ground when
    //    player_land_skill_limit/monster_land_skill_limit is enabled. For skills
    //    that attack using a path, this is the path length to be used.

     

×
×
  • Create New...

Important Information

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