int 
jacy(mixed *grupa)
{
	mixed *druzyna=TP->query_team();
	if ((grupa-druzyna)==({})) return 1;
	if (grupa==grupa-druzyna) return -1;
	return 0;
}

int 
czy_nasi(object *grupa)
{
	return jacy(grupa)==1;
}

int
czy_nie_nasi(object *grupa)
{
	return jacy(grupa)==-1;
}


int
stworz(string str)
{
	if (!str || !(wildmatch("grupe*",str) || wildmatch("formacje*",str)))
		return notify_fail("Co chcesz stworzyc? grupe?\n");
	if (!TP->query_team())
		return notify_fail("Musisz byc dowodca grupy, zeby moc uzywac tej komendy.\n");
	if (wildmatch("grupe*",str))
	{
		object *czlonkowie;
		string nazwa, str_czlonkow;
		mapping grupy;
		object *druzyna, *grupa;
		int tmp=-1;
		sscanf(str, "grupe %s %s", nazwa, str_czlonkow);
		if (!nazwa) sscanf(str, "grupe %s", nazwa);
		else parse_command(str_czlonkow, environment(TP), "'z' %l:"+PL_DOP, czlonkowie);
		if (!(grupy=TP->query_prop(RZ_GRUPY_BOJOWE))) grupy = ([]);
		czlonkowie=NORMAL_ACCESS(czlonkowie, 0, 0);
		if (!czlonkowie) czlonkowie=({});
		if (!nazwa)
			return notify_fail("Musisz podac nazwe tworzonej grupy.\n");
		grupa=czlonkowie;
		if (!grupa) grupa=({});
		druzyna=TP->query_team();
		if ((grupa-druzyna)==({})) tmp=1;
		if (sizeof(grupa)==sizeof(grupa-druzyna)) tmp=0;
		if (tmp==-1) 
			return notify_fail("Wszyscy czlonkowie jednej grupy musza jednoczesnie byc lub nie byc w twojej druzynie.\n");
		grupy[nazwa]=czlonkowie;
		TP->add_prop(RZ_GRUPY_BOJOWE, grupy);
		write("Stworzyles grupe "+nazwa+((sizeof(czlonkowie))? (" zlozona z "+COMPOSITE_LIVE(czlonkowie, PL_DOP)):"" ) + "\n");	
		if (tmp) czlonkowie->catch_msg(QCIMIE(TP, PL_MIA) +"dolaczyl cie do grupy "+nazwa+".\n");
	}
	return 1;
}

int
dolacz(string str)
{
	string do_czego;
	object *kogo;
	mapping grupy;
	object *druzyna, *grupa;
	int tmp=-1;
	if (!TP->query_team()) return 0;
	parse_command(str, environment(TP), "%l:"+PL_BIE+" 'do' %s", kogo, do_czego);
	if (!kogo) return !write("Kogo chcesz dolaczyc?\n");
	if (!do_czego) return !write("Do czego chcesz kogos dolaczyc?\n");
	grupy=TP->query_prop(RZ_GRUPY_BOJOWE);
	if (!grupy || !grupy[do_czego]) return !write("Grupa " + do_czego +" nie istnieje. Musisz ja wpierw stworzyc.\n");
	kogo=NORMAL_ACCESS(kogo, 0, 0);
	druzyna=TP->query_team();
	grupa=grupy[do_czego];
	grupa-=kogo;
	grupa+=kogo;
	if ((grupa-druzyna)==({ })) tmp=1;
	if (sizeof(grupa)==sizeof(grupa-druzyna)) tmp=0;
	if (tmp==-1)
		return !write("Wszyscy czlonkowie jednej grupy musza jednoczesnie byc lub nie byc w twojej druzynie.\n");
	grupy[do_czego]=grupa;
	write("Dolaczyles "+COMPOSITE_LIVE(kogo, PL_BIE) +" do "+do_czego+"\n");
	TP->add_prop(RZ_GRUPY_BOJOWE, grupy);	
	if (tmp) kogo->catch_msg(QCIMIE(TP, PL_MIA) +"dolaczyl cie do grupy "+do_czego+".\n");
	return 1;
}

int 
pokaz_grupe()
{
	object *grupa=TP->query_team_others();
	string *wrogowie;
	int i,n;
	if (!sizeof(grupa)) return notify_fail("Nie jestes czlonkiem zadnej grupy!");
	write("\tCzlonkowie twojej druzyny: \t\t Wrogowie:\n");
	for (i=0;i<sizeof(grupa);i++) 
	{
		wrogowie=grupa[i]->query_enemy(-1);
		write(grupa[i]->query_Imie()+ ":\t\t\t\t");
		for(n=0;n<sizeof(wrogowie);n++) write(wrogowie[n]->query_Imie()+", ");
		write("\n");
	}
	return 1;
}

int
pokaz(string str)
{
	mixed grupy;
	mixed *opisy=({0,0});
	int n;
	if (str=="podwladnych") return pokaz_grupe();
	if (str!="grupy") return 0;
	write("\t\tStworzyles nastepujace druzyny:\n");
	grupy=TP->query_prop(RZ_GRUPY_BOJOWE);
	opisy[0]=m_indices(grupy);
	opisy[1]=m_values(grupy);
	for (n=0; n<sizeof(opisy[0]);n++)
	{
		if (opisy[1][n]!=({}))
			write("\n"+opisy[0][n]+"\t"+ COMPOSITE_LIVE(opisy[1][n], PL_MIA));
		else
			write("\n"+opisy[0][n]+"\t"+ " pusta.");	
		if (sizeof(opisy[1][n])>0 && opisy[1][n][0]->query_leader()==TP) write("\t\t Grupa sojusznicza.");
	}
	write("\n");
	return 1;
}

int
wyklucz(string str)
{
	object *kogo;
	string grupa;
	mapping grupy;
	string *nazwy_grup;
	int n, i, czy_byl;
	if (!TP->query_team()) return notify_fail("Nie jestes dowodca druzyny!\n");
	if (!str) return notify_fail("Kogo chcesz wykluczyc z grupy bojowej?\n");
	parse_command(str, environment(TP), "%l:"+PL_BIE+" [z] [grupy]/[druzyny]",kogo);
	if (!kogo) return notify_fail("Kogo chcesz wykluczyc z grupy?\n");
 	grupy=TP->query_prop(RZ_GRUPY_BOJOWE);
 	if (!grupy) return notify_fail("Nie stworzyles zadnych grup.\n");
 	nazwy_grup=m_indices(grupy);
 	kogo=NORMAL_ACCESS(kogo,0,0);
	i=sizeof(kogo)-1;
	for (;i>=0;i--)
	{
 		grupa=0;
 		n=sizeof(nazwy_grup)-1;
 		for (;n>=0;n--)
 			if (member_array(kogo[i],grupy[nazwy_grup[n]])!=-1) grupa=nazwy_grup[n];
 		if (grupa)
 		{
 			write("Wykluczyles "+
 				kogo[i]->short(PL_BIE)+" z "+
 					grupa+"\n");
 			grupy[grupa]-=({kogo[i]});
 			if (kogo[i]->query_leader()==TP) kogo[i]->catch_msg(QCIMIE(TP, PL_MIA)+ " wykluczyl cie z grupy "+grupa+"\n");
			czy_byl=1;
 		}
 	}
 	if (!czy_byl) write("Ale " +COMPOSITE_LIVE(kogo, PL_MIA)+" nie "+((sizeof(kogo)>1)?"sa":"jest") +" w zadnej grupie.\n");
 	return 1;
}

/* 	
 * 	Zdecydowalem sie zrobic test na wykonanie rozkazu dla calej grupy.
 *	W ten spsosob rycerze reaguja jak oddzial, a nie jak pojedyncze 
 *	jednostki: Albo wszyscy wykonuja rozkaz, albo nie.
 *	Zdecydowalem sie tez na tzw. binarny system rozstrzygania:
 *		Albo ktos poslucha, albo nie. 
 */

/*	Stara wersja, pierwotna 	
mixed
wydaj_rozkaz(object *komu=0)
{
	int n, *wyniki, wynik=TP->resolve_task(TASK_ROUTINE, TS_DIS, RZ_DOWODZENIE);
	if (wynik<0 || !komu) return wynik;
	wyniki=komu->resolve_task(TASK_ROUTINE+100-wynik, TS_DIS, RZ_FORMACJE);
	for (n=sizeof(komu)-1, wynik=0;n>=0;n--)
		wynik+=wyniki[n];
	wynik=wynik/sizeof(komu);
	return wynik;
}	

To jest nowa wersja: Zmienilem troszke wspolczynniki, system zostal ten sam.

*/

mixed
wydaj_rozkaz(mixed *komu=0)
{
	int n, *wyniki, wynik=TP->resolve_task(TASK_DIFFICULT, ({TS_DIS, RZ_DOWODZENIE}));
	if (wynik<0 || !komu) return wynik;
	if (!pointerp(komu)) komu=({komu});
	wyniki=komu->resolve_task(TASK_DIFFICULT-2*wynik, ({TS_DIS, RZ_FORMACJE}));
	for (n=sizeof(komu)-1, wynik=0;n>=0;n--)
		wynik+=wyniki[n];
	wynik=wynik/sizeof(komu);
	write_file(LOG, 
		sprintf("Rozkaz: %s\tDis: %-5d Dowodzenie: %-6d %s\tDis: %-5d %-5dSize: \n", 
			TP->query_real_name(), TP->query_stat(SS_DIS), TP->query_skill(RZ_DOWODZENIE),
			komu[0]->query_stat(SS_DIS), komu[0]->query_skill(RZ_FORMACJE), sizeof(komu)));	
		return wynik;
}	


//	gatak A na B
// 	gatak dhor na orki


int
atak(string str)
{
	string *nazwy_grup, grupa, *czlony=explode(str," ");
	string pat,*pattern=({"%l:"+PL_MIA,"'na'","%l:"+PL_BIE});
	object *wrogowie, *nasi;
	mapping grupy=TP->query_prop(RZ_GRUPY_BOJOWE);
	int n;
	if (sizeof(czlony)<3)
		return notify_fail("Zbyt mala liczba argumentow.\n");


	if (grupy) 
		nasi=grupy[czlony[0]];				
	if (nasi)
	{
		pattern-=({pattern[0]});
		czlony-=({czlony[0]});
	}
	if (grupy) 
		wrogowie=grupy[czlony[sizeof(czlony)-1]];				
	if (wrogowie)
	{
		pattern=pattern[0..-2];
		czlony=czlony[0..-2];
	}
	str=implode(czlony," ");
	pat=implode(pattern," ");			
	if (wrogowie)
	{
		if (!nasi)
		{
			parse_command(str,Env,pat,nasi);
			nasi=NORMAL_ACCESS(nasi,0,0);
		}
	}
	else
		if (nasi) 
		{
			parse_command(str,Env,pat,wrogowie);
			wrogowie=NORMAL_ACCESS(wrogowie, 0, 0);
		}
		else 
		{
			parse_command(str,Env,pat,nasi,wrogowie);
			nasi=NORMAL_ACCESS(nasi, 0, 0);
			wrogowie=NORMAL_ACCESS(wrogowie, 0, 0);
		}
	if (!sizeof(nasi))
	       return notify_fail("Komu chcesz wydac rozkaz ataku?\n");
	if (!czy_nasi(nasi)) 
		return notify_fail("Wszyscy, ktorym wydajesz rozkaz musza byc w twojej druzynie.\n");
	if (!sizeof(wrogowie)) 
		return notify_fail("Na kogo "+((sizeof(nasi)>1)?"maja":"ma")+ " zaatakowac " + COMPOSITE_LIVE(nasi, PL_MIA)+"?\n");
	if (wydaj_rozkaz(nasi)<=0) return !write("Wydaje ci sie, ze twoj rozkaz przeszedl bez echa.\n");
	n=sizeof(wrogowie);
	nasi->attack_object(wrogowie[random(n)]);
	nasi->catch_msg("Slyszysz "+QIMIE(TP, PL_BIE)+" rozkazujacego ci zaatakowac "+COMPOSITE_LIVE(wrogowie,PL_BIE)+". Bez wahania wypelniasz rozkaz.\n");
	write("Wydaje ci sie, ze twoj rozkaz dotarl do "+COMPOSITE_LIVE(nasi,PL_DOP)+".\n");
	// To jeszcze wersja bez zadnych testow. 
}

// gzaslon A B
// gzaslon dhor yarpsa

int
zmien_wrogow(object *kto, object *kogo)
{
	object *wrogowie;
	int i,n,t;
	while(sizeof(kogo))
	{
		wrogowie=kogo[0]->query_enemy(-1);
		t=sizeof(wrogowie)-1;
		for (t;t>=0;t--)
		{
			if (environment(wrogowie[t])!=Env || 
				wrogowie[t]->query_attack()!=kogo[0])
					wrogowie=wrogowie[0..-1];
		}
		for (t=0,n=0;t<sizeof(wrogowie);t++,n++)
		{
			if (n>=sizeof(kto)) n=0;
			wrogowie[t]->attack_object(kto[n]);
		}
		kogo-=({kogo[0]});
	}
}


int 
zaslon(string str)
{
	string *nazwy_grup, grupa, *czlony=explode(str," ");
	object *kto, *kogo, *wrogowie;
	mapping grupy=TP->query_prop(RZ_GRUPY_BOJOWE);
	int n,i,t;
	if (sizeof(czlony)<2)
		return notify_fail("Zbyt mala liczba argumentow.\n");

	if (grupy) 
	{
		kto=grupy[czlony[0]];				
		kogo=grupy[czlony[sizeof(czlony)-1]];				
	}
	if (kogo)
	{
		czlony=czlony[0..-2];
	}
	if (kto)
	{
		czlony-=({czlony[0]});
	}
	str=implode(czlony," ");
	if (kogo)
	{
		if (!kto)
		{
			parse_command(str,Env,"%l:"+PL_MIA,kto);
			kto=NORMAL_ACCESS(kto,0,0);
		}
	}
	else
		if (kto) 
		{
			parse_command(str,Env,"%l:"+PL_BIE,kogo);
			kogo=NORMAL_ACCESS(kogo, 0, 0);
		}
		else 
		{
			parse_command(str,Env,"%l:"+PL_MIA+" %l:"+PL_BIE, kto, kogo);
			kto=NORMAL_ACCESS(kto, 0, 0);
			kogo=NORMAL_ACCESS(kogo, 0, 0);
		}
	if (!sizeof(kto))
	       return notify_fail("Komu chcesz wydac rozkaz ataku?\n");
	if (!czy_nasi(kto)) 
		return notify_fail("Wszyscy, ktorym wydajesz rozkaz musza byc w twojej druzynie.\n");
	if (!sizeof(kogo)) 
		return notify_fail("Kogo "+(sizeof(kto)>1)?"maja":"ma"+ " zaslonic " + COMPOSITE_LIVE(kto, PL_MIA)+"?\n");
/*	while(sizeof(kogo))
	{
		wrogowie=kogo[0]->query_enemy(-1);
		t=sizeof(wrogowie)-1;
		for (t;t>=0;t--)
		{
			if (environment(wrogowie[t])!=Env || 
				wrogowie[t]->query_attack()!=kogo[0])
					wrogowie=wrogowie[0..-1];
		}
		for (t=0,n=0;t<sizeof(wrogowie);t++,n++)
		{
			if (n>=sizeof(kto)) n=0;
			wrogowie[t]->attack_object(kto[n]);
		}
		kogo-=({kogo[0]});
	}
*/
	if (wydaj_rozkaz(kto)<=0) return !write("Wydaje ci sie, ze twoj rozkaz przeszedl bez echa.\n");
	zmien_wrogow(kto, kogo);	
	kto->catch_msg("Slyszysz glos "+QIMIE(TP, PL_DOP) +" polecajacy ci zaslonic "+COMPOSITE_LIVE(kogo, PL_BIE)+". Bez wahania wykonujesz rozkaz.\n");
	kogo->catch_msg("Na rozkaz "+QIMIE(TP, PL_DOP)+" "+COMPOSITE_LIVE(kto, PL_MIA)+" rzuca"+((sizeof(kto)>1)?"":"ja")+" sie zaslonic cie przed ciosami wrogow.\n");
	// Jak wyzej, bez testow.
}

// gschowaj A za B
// gschowaj dhor za yarpsem


int
schowaj(string str)
{
	string *nazwy_grup, grupa, *czlony=explode(str," ");
	object *kto, *kogo, *wrogowie;
	mapping grupy=TP->query_prop(RZ_GRUPY_BOJOWE);
	int n,i,t;
	if (sizeof(czlony)<3)
		return notify_fail("Zbyt mala liczba argumentow.\n");
	if (grupy) 
	{
		kto=grupy[czlony[0]];				
		kogo=grupy[czlony[sizeof(czlony)-1]];				
	}
	if (kogo)
	{
		czlony=czlony[0..-2];
	}
	if (kto)
	{
		czlony-=({czlony[0]});
	}
	str=implode(czlony," ");
	if (kogo)
	{
		if (!kto)
		{
			parse_command(str,Env,"%l:"+PL_MIA+" 'za'",kto);
			kto=NORMAL_ACCESS(kto,0,0);
		}
	}
	else
		if (kto) 
		{
			parse_command(str,Env,"'za' %l:"+PL_BIE,kogo);
			kogo=NORMAL_ACCESS(kogo, 0, 0);
		}
		else 
		{
			parse_command(str,Env,"%l:"+PL_MIA+"'za' %l:"+PL_BIE, kto, kogo);
			kto=NORMAL_ACCESS(kto, 0, 0);
			kogo=NORMAL_ACCESS(kogo, 0, 0);
		}
	if (!sizeof(kto))
	       return notify_fail("Komu chcesz wydac rozkaz ataku?\n");
	if (!czy_nasi(kto)) 
		return notify_fail("Wszyscy, ktorym wydajesz rozkaz musza byc w twojej druzynie.\n");
	if (!sizeof(kogo)) 
		return notify_fail("Za kogo "+(sizeof(kto)>1)?"maja":"ma"+ " sie schowac " + COMPOSITE_LIVE(kto, PL_MIA)+"?\n");
/*		
	while(sizeof(kogo))
	{
		wrogowie=kogo[0]->query_enemy(-1);
		t=sizeof(wrogowie)-1;
		for (t;t>=0;t--)
		{
			if (environment(wrogowie[t])!=Env || 
				wrogowie[t]->query_attack()!=kogo[0])
					wrogowie=wrogowie[0..-1];
		}
		for (t=0,n=0;t<sizeof(wrogowie);t++,n++)
		{
			if (n>=sizeof(kto)) n=0;
			wrogowie[t]->attack_object(kto[n]);
		}
		kogo-=({kogo[0]});
	}
*/
	if (wydaj_rozkaz(kto)<=0) return !write("Wydaje ci sie, ze twoj rozkaz przeszedl bez echa.\n");
	zmien_wrogow(kogo,kto);	
	kto->catch_msg("Na rozkaz "+QIMIE(TP, PL_DOP)+" wycofujesz sie za "+COMPOSITE_LIVE(kogo, PL_BIE)+"\n");
	kogo->catch_msg("Na rozkaz "+QIMIE(TP, PL_DOP)+" "+COMPOSITE_LIVE(kto, PL_MIA)+" wycofuje sie za ciebie.\n");
	// Jak wyzej, bez testow.
}


int
gpomoc()
{
	write("Komendy sluzace do dowodzenia formacjami: \n\n"+
		"- gstworz grupe <nazwa> [z <kogo>]\n"+
		"- gdolacz <kogo> do <nazwa>\n"+
		"- gwyklucz <kogo>\n"+
		"- gpokaz [podwladnych]\n"+
		"- gatak <kto> na <kogo>\n"+
		"- gzaslon <kto> <kogo>\n"+
		"- gschowaj <kto> za <kim>\n\n"+
		"Wszedzie <kto>/<kogo> oznacza albo bezposrednie wskazanie: \"dhor\", \"orki\", albo nazwe grupy.\n");
		return 1;
		
}
		