//@unloadnpc match
//@unloadnpc WALL#0
//@loadnpc npc/valhalla/match/battle.txt

-	script	match	-1,{
	function StartMatch;
	function wall;
	function ChkParty;
	function EjectParty;
	function RecallParty;
	function CheckDupe;
	function Reset;
		


	OnPCLoginEvent:
		if (spectator) {
			set spectator,0;
			set Hp,shp;
			set Sp,ssp;
			setoption Option_Invisible, 0;
			sc_end(SC_XMAS);
			warp slastmap$,slastx,slasty;	
		}
		if (contestant) {
			contestant = 0;
			warp .respawnmap$,.respawnx,.respawny;
		}
		end;

	OnMatch:
		mes "[^0000ffMatch Manager^000000]";
		getmapxy(.@map$, @x, @y, 0);
		if (estatus) {
			mes "Sorry, you can't be a spectator while at event map. Use @event and leave then try again.";
			close;
		}
		if (strcharinfo(PC_MAP) == .arena_map$) {
		} else {
			if (getmapflag(strcharinfo(PC_MAP), mf_nowarp)) {
				mes "Sorry, you can't be a match spectator from this map";
				close;
			}
		}
		if (.deadlock && !Hp) {
			mes "You may not use @match when you are dead.";
			close;
		}
		if (getgmlevel() < .GMAccess && !.allowspectator) {
			if (!spectator) {	
				mes "Sorry no ongoing match or spectators are not allowed.";
				close;
			}	
		}
		switch(select(
			 ( (getgmlevel() < .GMAccess)?":":" > ^FF0000GM Menu^000000:")+
			 ( ( 
				(getcharid(CHAR_ID_PARTY) == $@party1 || getcharid(CHAR_ID_PARTY) == $@party2)
				&& .allowspectator && !spectator && strcharinfo(PC_MAP) != .arena_map$ 
				)?" > ^0055FFWarp to Arena^000000:":":")+
			 ( ( 
				(getcharid(CHAR_ID_PARTY) != $@party1 && getcharid(CHAR_ID_PARTY) != $@party2)
				&& .allowspectator && !spectator && strcharinfo(PC_MAP) != .arena_map$ 
				)?" > ^0055FFWatch Match^000000:":":")+
				 ( (spectator)?" > ^0055FFLeave Match Arena^000000:":":")+
			 " > ^777777Close^000000"
		)) {
		case 1: 
			while(1) {
				switch(select(
				 ((getgmlevel() && !.match)?" > Match Type [ ^28bf00"+.mtype$+"^000000 ]:":":")+
				 ((getgmlevel() && !.match && $@charname1$ != "" && $@charname2$ != "")?" > Start Round:":":")+
				 ((getgmlevel() && .match)?" > End Round:":":")+
				 ((getgmlevel() && !.match && !.allowspectator && $@charname1$ != "" && $@charname2$ != "")?" > Invite Spectator:":":")+
				 ((getgmlevel() && !.match )?" > Party 1 [ ^28bf00"+$@charname1$+"^000000 ]:":":")+
				 ((getgmlevel() && !.match )?" > Party 2 [ ^28bf00"+$@charname2$+"^000000 ]:":":")+
				 ((getgmlevel() && !.match && $@charname1$ != "" && $@charname2$ != "" )?" > Recall Players:":":")+	
				 ((getgmlevel() && !.match )?" > Party Size [ ^28bf00"+.Size+"^000000 ]:":":")+
				 ((getgmlevel() && !.match )?" > Allow Dupe Jobs [ "+((.dupejobs)?"^28bf00Yes^000000":"^ff0000No^000000")+" ]:":":")+
				 ((getgmlevel() && !.match )?" > Allow Mobile Only? [ "+((.mobile)?"^28bf00Yes^000000":"^ff0000No^000000")+" ]:":":")+
				 ((getgmlevel() && .match )?" > End Tournament:":":")+
				 ((getgmlevel())?" > Go to Tournament Arena:":":")+
				 " > ^777777Close^000000"
				)) {
				case 1: 
					.@menu$ = "";
					for( .@i = 0; .@i < getarraysize(.mtypes$); .@i++ )
						.@menu$ = .@menu$ + "^FF0000[ "+( .@i+1 )+". ]^0000FF "+.mtypes$[.@i]+":";
					.@select = select( .@menu$ ) - 1;
					.mtype$ = .mtypes$[.@select];
					.mtype = .mtypes[.@select];
					break;
				case 2:
					/* Start Round */
					StartMatch();
					break;
				case 3: /* End Round */
					stopnpctimer;
					playbgmall("07",.arena_map$);
					pvpoff .arena_map$;	
					wall(1);
					mes "Select Round Winner:";
					next;
					switch(select(
					 " > [ ^28bf00"+$@charname1$+"^000000 ]:"+
					 " > [ ^28bf00"+$@charname2$+"^000000 ]:"+
					 " > [ ^28bf00Draw^000000 ]:"+
					 " > ^777777Close^000000"
					)) {
					case 1:
						announce "The "+.mtype$+" battle between [ "+$@charname1$+" ] and [ "+$@charname2$+" ] has ended.   The winner of this round is [ "+$@charname1$+" ]. Next round will commence in a few moments. To watch the match use @match.",bc_all;
						$@mscore1++;
						break;
					case 2:
						announce "The "+.mtype$+" battle between [ "+$@charname1$+" ] and [ "+$@charname2$+" ] has ended.   The winner of this round is [ "+$@charname2$+" ]. Next round will commence in a few moments. To watch the match use @match.",bc_all;
						$@mscore2++;
						break;
					case 3:
						announce "The "+.mtype$+" battle between [ "+$@charname1$+" ] and [ "+$@charname2$+" ] has ended.   This round is a draw. To watch the match use @match.",bc_all;
						break;
					default:
						break;
					}
					.match = 0;
					EjectParty($@party1);
					EjectParty($@party2);
					//Reset(1); Reset(2);
					break;
				case 11: /* End Tournament */
					stopnpctimer;
					playbgmall("07",.arena_map$);
					pvpoff .arena_map$;	
					wall(1);
					mes "Select Round Winner:";
					next;
					switch(select(
					 " > [ ^28bf00"+$@charname1$+"^000000 ]:"+
					 " > [ ^28bf00"+$@charname2$+"^000000 ]:"+
					 " > [ ^28bf00Draw^000000 ]:"+
					 " > ^777777Close^000000"
					)) {
					case 1:
						$@mscore1++;
						break;
					case 2:
						$@mscore2++;
						break;
					case 3:
						break;
					default:
						break;
					}
					wall(1);
					announce "The "+.mtype$+" between [ "+$@charname1$+" ] and [ "+$@charname2$+" ] has ended.",bc_all;
					/* Announce Winner */
					if($@mscore1 > $@mscore2){
						announce "The "+.mtype$+" battle between [ "+$@charname1$+" ] and [ "+$@charname2$+" ] has ended.   The winner of this match is [ "+$@charname1$+" ].",bc_all;
						RecallParty($@party1,.arena_map$, 50, 50);
					}
					if($@mscore1 < $@mscore2){
						announce "The "+.mtype$+" battle between [ "+$@charname1$+" ] and [ "+$@charname2$+" ] has ended.   The winner of this match is [ "+$@charname2$+" ].",bc_all;
						RecallParty($@party2,.arena_map$, 50, 50);
					}
					if($@mscore1 == $@mscore2){
						announce "The "+.mtype$+" battle between [ "+$@charname1$+" ] and [ "+$@charname2$+" ] has ended.   This match is a DRAW.",bc_all;
						RecallParty($@party1,.arena_map$, 50, 50);
						RecallParty($@party2,.arena_map$, 50, 50);
					}
					mapannounce .arena_map$,"Thank you for watching! Please use @match to leave the arena.",bc_all;
					.allowspectator = 0; .match = 0; $@mscore1 = 0; $@mscore1 = 0;
					Reset(1); Reset(2);
					break;
				case 12:
					warp .arena_map$,50,50;
					break;
				case 4:	/* Allow Spectator */
					wall(1);
					if (!.allowspectator) { 
						set .allowspectator,1; 
						announce "The "+.mtype$+" between [ "+$@charname1$+" ] and [ "+$@charname2$+" ] is about to start.  You can watch this match using @match.",bc_all;
					} else { 
						set .allowspectator,0;
					}
					break;

				/* Party vs. Party */		
				case 5:  /* Register Party 1 */
					input .@team1$;
					query_sql( "SELECT `party_id`, `name` FROM `party` WHERE `name` = '"+escape_sql(.@team1$)+"'", $@party1, $@charname1$ );
					if(.debug) dispbottom ""+.@team1$+" "+$@party1;
					if (!$@party1){
						dispbottom("Sorry, I can't find that party");
						Reset(1);
						break;
					}
					if(ChkParty($@party1) || CheckDupe($@party1)){
						Reset(1);
						break;
					} 
					break;
				case 6:  /* Register Party 2 */
					input .@team2$;
					query_sql( "SELECT `party_id`, `name` FROM `party` WHERE `name` = '"+escape_sql(.@team2$)+"'", $@party2, $@charname2$ );
					if (!$@party2){
						dispbottom("Sorry, I can't find that party");
						Reset(2);
						break;
					}
					if(ChkParty($@party2) || CheckDupe($@party2)) Reset(2);
					break;
				case 7: /* Recall */
					pvpoff .arena_map$;
					while(1){
						switch(select(
						 " > Recall [ ^28bf00"+$@charname1$+"^000000 ]:"+
						 " > Recall [ ^28bf00"+$@charname2$+"^000000 ]"
						)) {
						case 1:
							if(ChkParty($@party1) || CheckDupe($@party1)) break;
							RecallParty($@party1,.arena_map$, 79, 50);
							break;
						case 2:
							if(ChkParty($@party2) || CheckDupe($@party2)) break;
							RecallParty($@party2,.arena_map$, 22, 50);
							break;
						default:
							break;
							
						}
					}
					break;
				case 8:  /* Party Size */
					input .Size,1; 
					Reset(1); Reset(2); break;
				case 9: /* Allow dupes? */
					if (!.dupejobs) { set .dupejobs,1; } else { set .dupejobs,0;} 
					Reset(1); Reset(2); break;
				case 10: /* Allow dupes? */
					if (!.mobile) { set .mobile,1; } else { set .mobile,0;} 
					Reset(1); Reset(2); break;
				default:
					close;
				}
			}
		case 2:	
			mes "Please wait until the GM recall's your party to the arena.";
			close;
		case 3:
			getmapxy(.@map$, @x, @y, 0);
			set slastmap$,.@map$;
			set slastx,@x;
			set slasty,@y;
			set spectator,1;
			set shp,Hp;
			set ssp,Sp;
			setoption Option_Invisible, 1;
			sc_start SC_XMAS, 1600000, 0;
			warp .arena_map$,49,49;
			close;
		case 4:
			set spectator,0;
			set Hp,shp;
			set Sp,ssp;
			setoption Option_Invisible, 0;
			sc_end(SC_XMAS);
			warp slastmap$,slastx,slasty;
			close;
		default:
			close;
		}
		end;
	
		OnTimer0001:
			playbgmall("118",.arena_map$);
			end;
		OnTimer5000:
			mapannounce .arena_map$,"The [ "+.mtype$+" ] battle will begin in 5 seconds.",bc_all;
			end;
		OnTimer6000:
			mapannounce .arena_map$,"The [ "+.mtype$+" ] battle will begin in 4 seconds.",bc_all;
			end;
		OnTimer7000:
			mapannounce .arena_map$,"The [ "+.mtype$+" ] battle will begin in 3 seconds.",bc_all;
			end;
		OnTimer8000:
			mapannounce .arena_map$,"The [ "+.mtype$+" ] battle will begin in 2 seconds.",bc_all;
			end;
		OnTimer9000:
			mapannounce .arena_map$,"The [ "+.mtype$+" ] battle will begin in 1 second.",bc_all;
			end;
		OnTimer10000:
			soundeffectall "0_Startgame.wav", 0,.arena_map$,0,0,100,100;
			pvpon .arena_map$;
			wall(2);
			mapannounce .arena_map$,"The [ "+.mtype$+" ] battle has begun .  Goodluck!!!.",bc_all;
			end;

	function Reset {
		if(getarg(0) == 1){
			set $@charname1$,""; set $@party1,0;
		}
		if(getarg(0) == 2){
			set $@charname2$,""; set $@party2,0;
		}	
		set .match,0;
		return;

	}
	function ChkParty {
		// get the charID and accountID of character's party members
		getpartymember(getarg(0), 1);
		getpartymember(getarg(0), 2);

		if ($@partymembercount != .Size) {
			dispbottom("Party member requirement is not met "+$@partymembercount+" / "+.Size);
			return 1;
		}

		// loop through both and use 'isloggedin' to count online party members			
		for (.@i = 0; .@i < $@partymembercount; ++.@i)
			if (isloggedin($@partymemberaid[.@i], $@partymembercid[.@i]))
				.@count_online++;

		if (.@count_online != .Size) {
			dispbottom("Some members in the party is not online");
			return 2;
		}

		// copy the array to prevent players cheating the system
		copyarray(.@partymembercid, $@partymembercid, .Size);

		getpartymember(getarg(0), 1);
		if ($@partymembercount != .Size) {
			dispbottom("Party member requirement is not met "+$@partymembercount+" / "+.Size);
			return 1;
		}

		for (.@i = 0; .@i < $@partymembercount; ++.@i) {
			if (.@partymembercid[.@i] != $@partymembercid[.@i]) {
				dispbottom("Party has made some changes!");
				return 3;
			}
		}

		// Check for player that is on spectator mode
		copyarray(.@partymemberaid, $@partymemberaid, .Size);
		for (.@i = 0; .@i < $@partymembercount; ++.@i) {
			if (getvariableofpc(spectator, .@partymemberaid[.@i])) {
				dispbottom ("Some of the party member is still in spectator mode.");
				return 4;
			}
		}

		// Check for player that is on spectator mode
		copyarray(.@partymemberaid, $@partymemberaid, .Size);
		for (.@i = 0; .@i < $@partymembercount; ++.@i) {
			if (!getvariableofpc(#mobile, .@partymemberaid[.@i]) && .mobile) {
				dispbottom ("Some of the party member is not using mobile client.");
				return 5;
			}
		}

		return 0;
	}

	function StartMatch {
		set .match,1;
		initnpctimer;
		setcell .arena_map$,25,53,25,46,cell_walkable,0;
		setcell .arena_map$,74,46,74,53,cell_walkable,0;
		announce "[Match Manager] The Party War between [ "+$@charname1$+" ] and [ "+$@charname2$+" ] has engaged.  You can watch this match using @match.",bc_all;
		dispbottom "Party Match at "+.arena_map$+" has started";
		pvpoff .arena_map$;
		setnpctimer 0;
		startnpctimer;		
		return;
	}

	function CheckDupe {
		if (.dupejobs) return 0;
		set .@rid, playerattached();	
		getpartymember(getarg(0),2);
		set .@partymembercount, $@partymembercount;
		copyarray .@partydmemberaid[0], $@partymemberaid[0], .@partymembercount;
		for ( .@i = 0; .@i < .@partymembercount; .@i ++) {
			if (attachrid(.@partymemberaid[.@i])) {
				if ( compare( .@tmp_class$ + "|", "|" + Class + "|" ) )
	    				if ( .@rid ) {
        					attachrid(.@rid);
						dispbottom "Party has duplicate job.";
						return 1;	
   					} else {
        					detachrid;
					}				

            			set .@tmp_class$, .@tmp_class$ + "|" + Class;
		
			}
			
		}
    		// Restore RID.
    		if ( .@rid )
        		attachrid(.@rid);
   		else
        		detachrid;
		return 0;
	}

	function EjectParty {
		set .@rid, playerattached();
		// Send all member to room
		getpartymember(getarg(0),2);
		set .@partymembercount, $@partymembercount;
		copyarray .@partymemberaid[0], $@partymemberaid[0], .@partymembercount;
		for ( .@i = 0; .@i < .@partymembercount; .@i ++) {
			if (attachrid(.@partymemberaid[.@i])) {
				sc_end SC_ALL;	
				contestant = 0;
				warp .respawnmap$,.respawnx,.respawny;
			}

		}
    		// Restore RID.
    		if ( .@rid )
        		attachrid(.@rid);
   		else
        		detachrid;
		return;
	}

	function RecallParty {
		set .@rid, playerattached();	
		// Send all member to room
		getpartymember(getarg(0),2);
		set .@partymembercount, $@partymembercount;
		copyarray .@partymemberaid[0], $@partymemberaid[0], .@partymembercount;
		for ( .@i = 0; .@i < .@partymembercount; .@i ++) {
			if (attachrid(.@partymemberaid[.@i])) {
				sc_end SC_ALL;
				contestant = 1;
				warp getarg(1),getarg(2),getarg(3);
			}
		}
    		// Restore RID.
    		if ( .@rid )
        		attachrid(.@rid);
   		else
        		detachrid;
		return;
	}


	function wall {
		if (getarg(0)  == 1) {
			setcell .arena_map$,25,53,25,46,cell_walkable,0;
			setcell .arena_map$,74,46,74,53,cell_walkable,0;
			enablenpc "WALL#1";	
			enablenpc "WALL#2";
			enablenpc "WALL#3";
			enablenpc "WALL#4";
			enablenpc "WALL#5";
			enablenpc "WALL#6";
			enablenpc "WALL#7";
			enablenpc "WALL#8";
			enablenpc "WALL#9";
			enablenpc "WALL#10";
			enablenpc "WALL#11";
			enablenpc "WALL#12";
			enablenpc "WALL#13";
			enablenpc "WALL#14";
			enablenpc "WALL#15";
			enablenpc "WALL#0";
		} else if(getarg(0) == 2) {
			setcell .arena_map$,25,53,25,46,cell_walkable,1;
			setcell .arena_map$,74,46,74,53,cell_walkable,1;
			disablenpc "WALL#1";
			disablenpc "WALL#2";
			disablenpc "WALL#3";
			disablenpc "WALL#4";
			disablenpc "WALL#5";
			disablenpc "WALL#6";
			disablenpc "WALL#7";
			disablenpc "WALL#8";
			disablenpc "WALL#9";
			disablenpc "WALL#10";
			disablenpc "WALL#11";
			disablenpc "WALL#12";
			disablenpc "WALL#13";
			disablenpc "WALL#14";
			disablenpc "WALL#15";
			disablenpc "WALL#0";
		}
		return;	
	}

	OnInit:
		set .GMAccess,1;
		set .match,0;
		set .arena_map$,"guild_vs2";	
		setarray .mtypes$[0],"1 vs 1","Party War";
		setarray .mtypes[0],1,2;			
		set .mtype$,"Party War";	
		set .mtype,2;	
		set .deadlock,1;
		set .allowspectator,0;
		set .dupejobs,0;
		set .mobile,0;
		set $@mscore1,0;
		set $@mscore2,0;
		set .Size,1;
		/* Respawn Area */
		set .respawnmap$,"morocc";
		set .respawnx,175;
		set .respawny,95;
		.debug = 1;
		pvpoff .arena_map$;
		setcell(.arena_map$, 0, 0, 300, 300, cell_nochat, true);
		$@charname1$ = ""; $@charname2$ = "";
		$@party1 = ""; $@party2 = ""; 
		bindatcmd("match","match::OnMatch",0,99);
		
		// Map Flags
		setmapflag .arena_map$, mf_nodrop;
		setmapflag .arena_map$, mf_nosave;
		setmapflag .arena_map$, mf_noicewall;
		setmapflag .arena_map$, mf_nowarp;
		setmapflag .arena_map$, mf_noteleport;
		setmapflag .arena_map$, mf_nobranch;
		setmapflag .arena_map$, mf_notrade;
		setmapflag .arena_map$, mf_nomemo;
		setmapflag .arena_map$, mf_nopenalty;
		setmapflag .arena_map$, mf_partylock;
		setmapflag .arena_map$, mf_noreturn;
		setmapflag .arena_map$, mf_nochat;
		setmapflag .arena_map$, mf_novending;
		//setmapflag .arena_map$, mf_gvg_castle;
		end;
}

guild_vs2,25,53,2	script	WALL#0	8W_SOLDIER,{
	end;		
}

	// Team A	
guild_vs2,25,52,2	duplicate(WALL#0)	WALL#1	8W_SOLDIER
guild_vs2,25,51,2	duplicate(WALL#0)	WALL#2	8W_SOLDIER
guild_vs2,25,50,2	duplicate(WALL#0)	WALL#3	8W_SOLDIER
guild_vs2,25,49,2	duplicate(WALL#0)	WALL#4	8W_SOLDIER
guild_vs2,25,48,2	duplicate(WALL#0)	WALL#5	8W_SOLDIER
guild_vs2,25,47,2	duplicate(WALL#0)	WALL#6	8W_SOLDIER
guild_vs2,25,46,2	duplicate(WALL#0)	WALL#7	8W_SOLDIER

	// Team B
guild_vs2,75,46,6	duplicate(WALL#0)	WALL#8	8W_SOLDIER
guild_vs2,75,47,6	duplicate(WALL#0)	WALL#9	8W_SOLDIER
guild_vs2,75,48,6	duplicate(WALL#0)	WALL#10	8W_SOLDIER
guild_vs2,75,49,6	duplicate(WALL#0)	WALL#11	8W_SOLDIER
guild_vs2,75,50,6	duplicate(WALL#0)	WALL#12	8W_SOLDIER
guild_vs2,75,51,6	duplicate(WALL#0)	WALL#13	8W_SOLDIER
guild_vs2,75,52,6	duplicate(WALL#0)	WALL#14	8W_SOLDIER
guild_vs2,75,53,6	duplicate(WALL#0)	WALL#15	8W_SOLDIER
