int 
jacy(mixed *grupa)
{
	mixed *druzyna=TP->query_team();
	if ((grupa-druzyna)==({})) return 1;
	if (sizeof(grupa)==sizeof(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;
}
object *
oczysc_grupe(object *arg_grupa)
{
	object *tmp=({}), *grupa=arg_grupa;
	int i=sizeof(grupa)-1;
	for (;i>=0;i--)
	{
		if (environment(grupa[i])==Env)
			tmp+=grupa[i..i];
	}
	return tmp;
}


int
usun_grupe(string str)
{
	mapping grupy;
	object *czlonkowie;
	if (!str) 
		return notify_fail("Jaka grupe chcesz usunac?\n");
	grupy=TP->query_prop(RZ_GRUPY_BOJOWE);
	czlonkowie=grupy[str];
	if (!czlonkowie) 
		return notify_fail("Grupa "+str+" nie istnieje.\n");
	if (czy_nasi(czlonkowie))
		czlonkowie->catch_msg(QCIMIE(TP, PL_MIA)+" rozwiazal grupe "+str+".\n");
	grupy=m_delete(grupy, str);
	TP->add_prop(RZ_GRUPY_BOJOWE, grupy);
	write("Grupa "+str+" zostala usunieta.\n");
	return 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();
	object *wrogowie;
	int i,n;
	if (!sizeof(grupa)) return notify_fail("Nie jestes dowodca zadnej grupy!\n");
	write("\tDruzyna: \t\t Wrogowie:\n");
	grupa=oczysc_grupe(grupa);
	for (i=0;i<sizeof(grupa);i++) 
	{
		wrogowie=grupa[i]->query_enemy(-1);
		wrogowie=oczysc_grupe(wrogowie);
		write(grupa[i]->query_Imie(TP)+ ":\t\t\t");
		for(n=0;n<sizeof(wrogowie);n++) write(wrogowie[n]->query_Imie(TP)+", ");
		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 notify_fail("Co chcesz zobaczyc? Grupy? Podwladnych?\n");
	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)
		{
			if (!jacy(opisy[1][n]))
				write ("\t\t Grupa mieszana!");
			else if (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;
}


void
moze_rozkazywac(object kto);

/*	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 (TP->query_prop(RZ_WYDAL_ROZKAZ)) 
	{
		write("Musisz zlapac oddech, zanim bedziesz mogl wydac kolejny rozkaz.\n");
		return -1;
	}
	set_alarm(3.0-(itof(random(TP->query_skill(RZ_DOWODZENIE))))/50.0,0.0, &moze_rozkazywac(TP));
	TP->add_prop(RZ_WYDAL_ROZKAZ, 1);
	if (wynik<0 || !komu)
	{ 
		if (wynik<0) write("Wydaje ci sie, ze twoj rozkaz przeszedl bez echa.\n");
		return wynik;
	}

	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_real_name(),
			komu[0]->query_stat(SS_DIS),
			komu[0]->query_skill(RZ_FORMACJE), sizeof(komu)));	
	if (wynik<0) write("Wydaje ci sie, ze twoj rozkaz przeszedl bez echa.\n");
	return wynik;
}	


//	gatak A na B
// 	gatak dhor na orki
int 
zaatakuj_wrogow(object *nasi, object *wrogowie)
{
	int  siz, tmp, n=sizeof(wrogowie);
	object *moga=({}), *nie_moga=({}), *wrogowie_tmp;
	for (siz=sizeof(nasi)-1;siz>=0;siz--)
	{
		wrogowie_tmp=wrogowie;
		while (sizeof(wrogowie_tmp)>0) 
		{
			tmp=random(sizeof(wrogowie_tmp));
			if (F_DARE_ATTACK(nasi[siz], wrogowie_tmp[tmp]))
			{
				if (!nasi[siz]->attack_object(wrogowie_tmp[tmp]))
					moga+=({nasi[siz]});
				else nie_moga+=({nasi[siz]});
				nasi-=({nasi[siz]});
				wrogowie_tmp=0;
			}
			else
			{
				wrogowie_tmp-=({wrogowie_tmp[tmp]});
			}
		}
		if (wrogowie_tmp!=0)
		{
			nie_moga+=({nasi[siz]});
			nasi-=({nasi[siz]});
		}
	}
	if (sizeof(moga))
		write("Wydaje ci sie, ze twoj rozkaz dotarl do "+COMPOSITE_LIVE(moga,PL_DOP)+".\n");		
	else write("Wydaje ci sie, ze twoj rozkaz dotarl do "+COMPOSITE_LIVE(nie_moga,PL_DOP)+".\n");		
	moga->catch_msg("Slyszysz "+QIMIE(TP, PL_BIE)+" rozkazujacego ci zaatakowac "+COMPOSITE_LIVE(wrogowie,PL_BIE)+". Bez wahania wypelniasz rozkaz.\n");
	nie_moga->catch_msg("Slyszysz "+QIMIE(TP, PL_BIE)+" rozkazujacego ci zaatakowac "+COMPOSITE_LIVE(wrogowie, PL_BIE)+", nie jestes jednak w stanie wykonac tego polecenia.\n");
}

int
atak(string str)
{
	string *nazwy_grup, grupa, *czlony;
	string pat,*pattern=({"%l:"+PL_MIA,"'na'","%l:"+PL_BIE});
	object *wrogowie, *nasi;
	mapping grupy=TP->query_prop(RZ_GRUPY_BOJOWE);
	int n;
	
	if (!str || sizeof( ( czlony = explode(str," ") ) )<3)
		return notify_fail("Poprawna skladnia: gatak <kto> na <kogo>.\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);
		}
	nasi=oczysc_grupe(nasi);
	wrogowie=oczysc_grupe(wrogowie);
	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 (!jacy(wrogowie)) 
		return notify_fail("Chyba nie chcesz rozkazac ataku na czlonkow twojej grupy?\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 1;
	zaatakuj_wrogow(nasi, wrogowie);
/*	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"); *\
*/	
	return 1;
}

// 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);
		kogo[0]->stop_fight(wrogowie);
		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;
	object *kto, *kogo, *wrogowie;
	mapping grupy=TP->query_prop(RZ_GRUPY_BOJOWE);
	int n,i,t;
	if (!str || sizeof(czlony=explode(str, " "))<2)
		return notify_fail("Poprawna skladnia: gzaslon <kto> <kogo>.\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);
		}
	kto=oczysc_grupe(kto);
	kogo=oczysc_grupe(kogo);
	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 1;
	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");
        write("Wydaje ci sie, ze twoj rozkaz dotarl do "+COMPOSITE_LIVE(kto,PL_DOP)+".\n");			
        return 1;
}

// gschowaj A za B
// gschowaj dhor za yarpsem

 
int
schowaj(string str)
{
	string *nazwy_grup, grupa, *czlony;
	object *kto, *kogo, *wrogowie;
	mapping grupy=TP->query_prop(RZ_GRUPY_BOJOWE);
	int n,i,t;
	if (!str || sizeof(czlony=explode(str, " "))<3)
		return notify_fail("Poprawna skladnia: gschowaj <kto> za <kogo>.\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);
		}
	kto=oczysc_grupe(kto);
	kogo=oczysc_grupe(kogo); 
	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) || !czy_nasi(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);
		kogo->stop_fight(wrogowie);
		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 1;
	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");
	write("Wydaje ci sie, ze twoj rozkaz dotarl do "+COMPOSITE_LIVE(kto,PL_DOP)+".\n");			
	return 1;

}


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]/[grupy]\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;
}

void
moze_rozkazywac(object kto)
{
	kto->remove_prop(RZ_WYDAL_ROZKAZ);
	kto->catch_msg("Zlapales oddech i jestes gotow wydac kolejny rozkaz.\n");
}
 
