/* Pomysly dotyczace muda: Przede wszystkim trzeba zrobic makro lub funkcje, ktore zwracalo by sciezke do pliku. */ string DIR(int stopien) { string path=file_name(this_object()); string *kat=explode(path,"/"); int n==sizeof(kat)-1-stopien; while (n<=sizeof(kat)-1) kat-=({kat[n]}); path=implode(kat,"/"); return path; } /* I juz. Powinno dzialac... Ale zbyt zmeczylem umysl zeby sie zastanawiac, jak to przetestowac... Mozna by tez wprowadzic osobne jezyki dla roznych domen. Np: grecki, lacina, sanskryt (to chyba Indie), slowianski, germanski, celtycki, angielski, francuski, aztecki, nie wiem jak sie nazywa, ale zydowski, egipski etc, etc... Jesli koszt uczenia jezyka dalo by sie niezvyt wysoki, moglo by byc ciekawie... Po za tym sklanialo by ludzi do trzymania sie jednej domeny i wyrazniej odwzorowywalo roznice... Mozna by zrobic skomplikowany algorytm rozumienia... zalezny od znajomosci tego konkretnego jezyka i pokrewnych. Np: niemiecki i angielski, greka i lacina etc. Zakodowalo by sie raz, a potem tylko ustawialo npcom i ksiazka w jakim sa jezyku. Dodatkowo byly by specjalne komendy dla kazdego jezyka, albo w opcjach ustawialo by sie, jakim teraz mowi i pisze... albo mowi sie jezykiem swojej rasowki, a inaczej trzeba "powiedz po angielsku" i program sprawdza, czy masz taki jezyk chocby troche wyuczony... To sa naprawde poterzne mozliwosci, choc oczywiscie trzeba by to bylo zakodowac :) Ale my lubimy takie rzeczy. Bylby specjalny skill to kazdego jezyka... Na poczatku oczywiscie bylyby tylko dwa... tam gdzie wymagane bylo by uzycie slowa pisanego w opisie, uzywalo by sie np funkcji: jezyk(tekst) i odpowiedniego VBCF'a: set_long("@@cos_tam"); funkcja jezyk by tlumaczyla na zrozumialy dla gracza ciag poprawnych wyrazow i bezsensownych kropek lub czesci slowotworczych... Na dole przerobione say... czyli communicate... i com_to, a reszta to pomocnicze Jeszcze trzeba by przerobic krzyczenie i szeptanie... A w dorabianym kodzie uzywalo by sie tych makr zdefiniowanych nizej. Do dodania w macros.h do_kogo - kto slucha; tekst - cos do powiedzenia; jezyk - jezyk w ktorym jest mowione, na razie mamy SS_GREKA, SS_LACINA; */ #define TJEZYK(do_kogo, jezyk, tekst) ("@@tlumacz:" + file_name(do_kogo) + "|" + jezyk + "|" + tekst + "@@") #define JEZYK(jezyk, tekst) ("@@tlumacz|" + jezyk + "|" + tekst + "@@") // W ss_types.h #define SS_GREKA 80 #define SS_LACINA 81 /* Funkcja pomocnicza, zwraca nasza znajomosc jezyka. Np: Ktos mowi po angielsku, a my znamy niemiecki i greke... Wiec sluchamy po niemiecku, tylko duzoo gorzej... np: 1/5. Jezyki zblizone przechowa sie gdzies w mappingu: */ mapping jezyki_zblizone=([SS_GREKA:({SS_LACINA}),SS_LACINA:({SS_GREKA}),]) // A odpowiednie wywolanie i numer: mapping mow_po_jakiemu=(["grecku":SS_GREKA,"lacinsku":SS_LACINA,]); // Defniowana w player.c int znajomosc_jezyka(int numer_jezyka) { int ten_jezyk, zblizony; int *zblizone=jezyki_zblizone[numer_jezyka]; int n; ten_jezyk=this_player()->query_skill(numer_jezyka); n=sizeof(zblizone)-1; zblizony=this_player()->query_skill(zblizone[0]); for (;n>0;n--) zblizony=MAX(zblizony,this_player()->query_skill(zblizone[n])); return MAX(ten_jezyk,zblizony/5); } /* Teraz najgorsze, czyli tlumacz; jezyk: numer jezyka tekst: tekst mowy. zwraca przetlumaczony tekst; Na razie funkcjonuje to na zasadzie kropek... */ string tlumacz(int jezyk, string tekst) { int n=0; string *nieznane=({".","..","...","....",".....","......",".......","........",".........","..........",".........."}); string *wyrazy=explode(tekst," "); jezyk = znajomosc_jezyka(jezyk); for (;njezyk) wyrazy[n]=nieznane[strlen(wyrazy[n])]; return implode(wyrazy," "); } /* I juz... Oczywiscie w takiej skali w jakiej ma to wystepowac na mudzie nie moga to byc kropki... wyciagniemy do Alvina kod tego jezyka magow, albo napiszemy od nowa... juz nawet mam pomysl, tylko mysle jak wyciagnac znaki szczegolne... Teraz najciekawsze: przerabiamy funkcje mowiace :) */ public int communicate_to(string str, int jezyk) { object *oblist; string r_sound; string qcomp; string tmp1,tmp2; /* We must parse the lower case of the string 'str' since parse_command * does not find capitalized player names, so it would not trigger on * "say to Mercade Greetings!" However, since we want to keep the * capitals in the said text, we store the original text in the variable * 'say_string' and use that later. */ if (!parse_command(lower_case(str), environment(this_player()), "'do' %l:" + PL_DOP + " %s", oblist, str)) { return 0; } oblist = NORMAL_ACCESS(oblist, 0, 0) - ({ this_player(), 0 }); if (!sizeof(oblist) || !strlen(str)) { return 0; } /* In order to be able to use QCOMPLIVE later, we have to query the * COMPOSITE_LIVE macro now, even though the player may not be using * echo. */ qcomp = COMPOSITE_LIVE(oblist, PL_DOP); say_string = extract(say_string, -(strlen(str))); //say_string jest zdeklarowane w standardzie... tego tu nie wkleilem... if (this_player()->query_option(OPT_ECHO)) { write(capitalize(this_object()->actor_race_sound()) + " do " + qcomp + ": " + say_string + "\n"); } else { write("Ok.\n"); } say(QCIMIE(this_object(), PL_MIA) + (r_sound = (" @@race_sound:" + file_name(this_object()) + "@@ do ")) + QCOMPLIVE(PL_DOP) + ": " + JEZYK(jezyk,say_string) + "\n", (oblist + ({ this_player() }) )); oblist->catch_msg(QCIMIE(this_object(), PL_MIA) + r_sound + "ciebie: " + JEZYK(jezyk,say_string) + "\n"); return 1; } /* * Function name: communicate * Description : This function is called whenever the player wants to say * something. We have to put it here rather than in a soul * because people can use the single quote ' as alias for * say. * Arguments : string str - the command line argument. * Returns : int 1/0 - success/failure. */ public varargs int communicate(string str = "") { mixed tmp; int jezyk; if (!strlen(str)) { write("W ostatniej chwili decydujesz sie nic nie mowic.\n"); say(QCIMIE(this_player(), PL_MIA) + " wyglada jakby chcial" + this_player()->koncowka("", "a", "o") + " cos powiedziec, " + "ale w ostatniej chwili sie rozmyslil" + this_player()->koncowka("", "a", "o") + ".\n"); return 1; } if (tmp = query_prop(LIVE_M_MOUTH_BLOCKED)) { write(stringp(tmp) ? tmp : "Nie mozesz z siebie wydobyc glosu.\n"); return 1; } /* We do not want people to add too many spaces and use the say command * as a way to generate emotions themselves. However, we do not want to * waste this on wizards and we also test whether people haven't used * too many spaces. You cannot make an emotion with only a few. This * wildmatch is 40% faster than the explode/implode stuff, so as long * as people don't use 8 spaces more than 40% of the time, this check * pays itself back. */ if (!query_wiz_level() && wildmatch("* *", str)) { str = implode((explode(str, " ") - ({ "" }) ), " "); } /* This is a test for the command 'say to'. If it fails, we just default * to the normal say. */ say_string = str; if (parse_command(lower_case(str), environment(this_player()), "'po' %w %s", tmp1, tmp2)) { if (tmp1) { notify_fail(" Po jakiemu chcesz powiedziec?\n"); if (!jezyk=mow_po_jakiemu[tmp1]) return 0; } } else jezyk=this_player()->query_rodzinny_jezyk(); /* if (wildmatch("do *", str)) { */ if (communicate_to(str,jezyk)) { return 1; } /* } */ if (this_player()->query_option(OPT_ECHO)) { write(capitalize(this_object()->actor_race_sound()) + ": " + str + "\n"); } else { write("Ok.\n"); } say(QCIMIE(this_object(), PL_MIA) + " @@race_sound:" + file_name(this_object()) + "@@: " + JEZYK(jezyk,str) + "\n"); return 1; }