Wikipedista:PiranhaGreg/Pískoviště

Při prvním pohledu na jazyk Daedalus ihned přijde člověku na mysl podobnost s jazykem C/C++. Je to skutečně tak, ale jsou tu některé zásadní rozdíly, o kterých budu hovořit v jiném článku. Podstatné je tedy, že se jedná o skriptovací programovací jazyk, a pokud někdo umí programovat například v C++ má velkou výhodu.

Skripty Gothicu jsou ve složce _WORK\DATA\SCRIPTS a je třeba je rozbalit klasicky při instalaci GMDK. Pokud zabrouzdáme tedy do té složky, najdeme tam složku _COMPILED, kde už jsou hotové scripty připravené pro použití ve hře, složku SYSTEM, kde se mění například nastavení menu a jiné podobné věci a pak složku CONTENT, kde je ten zbytek.

Pokud cokoliv kdekoliv změníme v těchto dvou posledních složkách, je třeba skripty opět přeložit do jazyka, který Gothic umí, a to se dělá z Gothic Starteru při zaškrtnutí Parse scripts a následnému spuštění hry. Gothic pak skripty přepíše do svého vlastního jazyka a uloží ve složce _COMPILED. Pokud ovšem máte někde chybu, přeruší překlad a řekne jaká chyba a na kterém řádku se nachází. Proto doporučuji často parsovat, protože Gothic neuvede soubor, ve kterém je chyba, tak abyste věděli, kde hledat.

POZOR: Nikdy neparsujeme skripty přes Spacer, vždy jen přes hru. Spacer je trochu svéhlavý a neparsuje korektně. Pokud se chcete vyhnout problémům, rovněž nedoporučuji parsovat přes programy jako Gothic Sourcer, vždy k parsování používejte jen hru samotnou. Jednak Gothic Sourcer není dokonalý a jednak si ani nerozumí s většinou skriptovacích paketů.

Pokud budete vytvářet dialogy, je třeba navíc updatnout rovněž OU soubory. To umí dělat Spacer. Nebudu tu ale říkat, jak se to dělá, protože rovněž nedoporučuji přes Spacer tuto činnost vykonávat. Mnohem lepší je použít nástroj, který se nazývá Redefix (autor je Sumpfkrautjunkie z WoG.de). Jednak je asi 100x rychlejší než Spacer, a jednak nedělá takové problémy jako Spacer. Ke stažení je odkaz níže. Po prvním spustění Redefixu stačí jen jednou zadat cestu ke Gothicu (v Einstellungen = Nastavení) a pak klinout na Neu erstellen. Tím Redefix vytvoří OU soubory, což potřebujeme.

Redefix nám taky řekne, zda není někde redundantní definice některých dialogů. Ve svém editačním poli vypíše ty kódy, které jsou někde dvakrát (a pokaždé jinak), což by nemělo být.

Dříve než ale začnete si hrát se skripty, je dobré uvědomit si, co vlastně chci dělat. Pokud jen chceme editovat základní příběh a do něj přidávat postavy, či jiné věci, tak prostě edituji skripty, tak jak jsou. Pokud ale mám svůj vlastní svět, který je na základním příběhu nezávislý, je nejprve vhodné vše nepotřebné odstranit. To samo o sobě by byla dost práce, proto je možno použít již předpřipravené skripty z World of Gothic.de nazvané Verbesserte Bereinigte Scripte (autor je Milgo z WoG.de). Link níže. Těmi pak nahradíme skripty ve složce _WORK\DATA\SCRIPTS. Sice tím dostaneme některé názvy jako rostliny a věci německy, ale to už není tak velký problém. (Případně některé soubory je možno nahradit z anglických skriptů, ale stejně, pokud budete dělat český mod, je třeba si to přeložit.).

Editovat skripty je možno v jakémkoliv textovém editoru, ale já osobně doporučuji Notepad++. Pro zvýraznění syntaxe je možno stáhnout speciální balík, link níže. Osobně to nepoužívám, ale ta možnost existuje.

NPC editovat

Tvorba NPC editovat

Klasické NPCs (ne zvířata a ne orkové) jsou uloženy ve složce _WORK\DATA\SCRIPTS\CONTENT\STORY\NPC. Název souboru je většinou ve tvaru: <zkratka gildy>_<id NPC>_<jmeno NPC>.d takže například: GOR_100_Goral.d Vnitřek souboru pak vypadá následovně (toto je postava z mého modu Thanatos). Nejdříve uvedu nekomentovaný kód, následně pak rozeberu řádek po řádku:

//-----------------------------------------
//---------------Primäre Daten-------------
//-----------------------------------------
instance GOR_100_Goral (Npc_Default)
{
id                             = 100;
name                           = "Goral";
npcType                        = NPCTYPE_AMBIENT;
flags                          = 0;

//-----------------------------------------
//------------------Attribute--------------
//-----------------------------------------
attribute [ATR_STRENGTH]       = 100;
attribute [ATR_DEXTERITY]      = 100;
attribute [ATR_HITPOINTS_MAX]  = 200;
attribute [ATR_HITPOINTS]      = 200;
attribute [ATR_MANA_MAX]       = 150;
attribute [ATR_MANA]           = 150;

//-----------------------------------------
//------------------Protection-------------
//-----------------------------------------
protection [PROT_BLUNT]        =  20;
protection [PROT_EDGE]         =  20;
protection [PROT_POINT]        =  10;
protection [PROT_FIRE]         =   5;
protection [PROT_FLY]          =  15;
protection [PROT_MAGIC]        =  10;

//-----------------------------------------
//------------------Damage-----------------
//-----------------------------------------
damage [DAM_INDEX_BLUNT]       =  80;
damage [DAM_INDEX_EDGE]        =  80;
damage [DAM_INDEX_POINT]       =   0;
damage [DAM_INDEX_FIRE]        =   0;
damage [DAM_INDEX_FLY]         =   0;
damage [DAM_INDEX_MAGIC]       =   0;
damagetype                     =   0;

//-----------------------------------------
//------------------Talents-----------------
//-----------------------------------------
HitChance [NPC_TALENT_1H]       =  20;
HitChance [NPC_TALENT_2H]       =  20;
HitChance [NPC_TALENT_BOW]      =  10;
HitChance [NPC_TALENT_CROSSBOW] =  10;

//-----------------------------------------
//------------------Visuals----------------
//-----------------------------------------
Mdl_ApplyOverlayMds (self,"Humans_Arrogance.mds");
B_SetNpcVisual (self, MALE, "Hum_Head_Fighter", Face_N_ToughBart01, BodyTex_N, ITAR_MIL_M);
Mdl_SetModelFatness (self,1);

//-----------------------------------------
//------------------Inventar Items---------
//-----------------------------------------
CreateInvItems (self,ItPo_Health_01,2);
EquipItem (self,ItMw_1h_Mil_Sword);

//-----------------------------------------
//------------------Sonstiges--------------
//-----------------------------------------
guild                           = GIL_VLK;
level                           = 20;
fight_tactic                    = FAI_HUMAN_MASTER;
weapon                          = ItMw_1h_Mil_Sword;
voice                           = 3;
daily_routine                   = Rtn_Start_100;

//-----------------------------------------
//------------------Sinne------------------
//-----------------------------------------
senses = SENSE_SEE | SENSE_HEAR | SENSE_SMELL;
senses_range = 1000;
};

//-----------------------------------------
//------------------Tagesablauf------------
//-----------------------------------------
func void Rtn_Start_100 ()
{
TA_Sleep(23,15,03,30,"VALE0005");
TA_Stand_Guarding(00,30,07,30,"VALE0006");
TA_Smalltalk(07,30,11,00,"VALE0005");
TA_Stand_WP(11,00,13,00,"VALE0004");
TA_Smalltalk(13,00,21,00,"VALE0005");
TA_Stand_WP(21,00,23,15,"VALE0004");
};

Nyní tedy komentovaný kód:

//-----------------------------------------
//---------------Primäre Daten-------------
//-----------------------------------------
instance GOR_100_Goral (Npc_Default)

Název instance NPC je stejný jako název souboru.

{
id                             = 100;

Jedinečné ID od NPC. Každá postava má svoje vlastní. Nevím proč, ale ID přes 999 mi nefungovaly. Takže doporučuji trojmístné číslo vždy.

name                           = "Goral";
Jedinečné jméno postavy.
npcType                        = NPCTYPE_AMBIENT;

Typ postavy.

flags                          = 0;

Může být: 0 (normální NPC), FLAG_IMMORTAL (nesmrtelný), FLAG_GHOST (duch).

//-----------------------------------------
//------------------Attribute--------------
//-----------------------------------------
attribute [ATR_STRENGTH]       = 100;
attribute [ATR_DEXTERITY]      = 100;
attribute [ATR_HITPOINTS_MAX]  = 200;
attribute [ATR_HITPOINTS]      = 200;
attribute [ATR_MANA_MAX]       = 150;
attribute [ATR_MANA]           = 150;

Různé atributy. Zeshora: síla, obratnost, životy maximálně, životy aktuálně, mana maximálně, mana aktuálně.

//-----------------------------------------
//------------------Protection-------------
//-----------------------------------------
protection [PROT_BLUNT]        =  20;
protection [PROT_EDGE]         =  20;
protection [PROT_POINT]        =  10;
protection [PROT_FIRE]         =   5;
protection [PROT_FLY]          =  15;
protection [PROT_MAGIC]        =  10;

Hodnoty obrany proti různým druhům útoků.

//-----------------------------------------
//------------------Damage-----------------
//-----------------------------------------
damage [DAM_INDEX_BLUNT]       =  80;
damage [DAM_INDEX_EDGE]        =  80;
damage [DAM_INDEX_POINT]       =   0;
damage [DAM_INDEX_FIRE]        =   0;
damage [DAM_INDEX_FLY]         =   0;
damage [DAM_INDEX_MAGIC]       =   0;
damagetype                     =   0;

Hodnoty útoků.

//-----------------------------------------
//------------------Talents-----------------
//-----------------------------------------
HitChance [NPC_TALENT_1H]       =  20;
HitChance [NPC_TALENT_2H]       =  20;
HitChance [NPC_TALENT_BOW]      =  10;
HitChance [NPC_TALENT_CROSSBOW] =  10;

Talenty: jednoruční, dvojruční meč, luk, kuše.

//-----------------------------------------
//------------------Visuals----------------
//-----------------------------------------
Mdl_ApplyOverlayMds (self,"Humans_Arrogance.mds");

Druh chování.

B_SetNpcVisual (self, MALE, "Hum_Head_Fighter", Face_N_ToughBart01, BodyTex_N, ITAR_MIL_M);

Zeshora: muž / žena, hlava, tvář, tělo, brnění / oblečení.

Mdl_SetModelFatness (self,1);

Tloušťka postavy.

//-----------------------------------------
//------------------Inventar Items---------
//-----------------------------------------
CreateInvItems (self,ItPo_Health_01,2);
EquipItem (self,ItMw_1h_Mil_Sword);

Copak naše postava bude mít u sebe.

//-----------------------------------------
//------------------Sonstiges--------------
//-----------------------------------------
guild                           = GIL_VLK;

Zkratka gildy.

level                           = 20;

Level postavy * 10 uvádí množství zkušeností za skolení postavy.

fight_tactic                    = FAI_HUMAN_MASTER;

Druh boje.

weapon                          = ItMw_1h_Mil_Sword;

Zbraň.

voice                           = 3;

Hlas postavy. Vnitřně definované hlasy jsou 1,3,..,14 = muži, 16,17 ženy, 15 hlavní postava. Můžete dát i jiné čísla, ale pak nebudou postavy spolu například hovořit, pokud se o to složitě nepostaráte. Toto číslo nemusí být jedinečné.

daily_routine                   = Rtn_Start_100;

Copak naše postava vlastně bude dělat.

//-----------------------------------------
//------------------Sinne------------------
//-----------------------------------------
senses = SENSE_SEE | SENSE_HEAR | SENSE_SMELL;
senses_range = 1000;
};

Smysly postavy.

//-----------------------------------------
//------------------Tagesablauf------------
//-----------------------------------------
func void Rtn_Start_100 ()
{
TA_Sleep(23,15,03,30,"VALE0005");
TA_Stand_Guarding(00,30,07,30,"VALE0006");
TA_Smalltalk(07,30,11,00,"VALE0005");
TA_Stand_WP(11,00,13,00,"VALE0004");
TA_Smalltalk(13,00,21,00,"VALE0005");
TA_Stand_WP(21,00,23,15,"VALE0004");
};

Toto je rozpis denních rutin naší postavy. Vždy musí korespondovat k 24h cyklu. Druhy a použití denních rutin probírám v jiných tutoriálech. Tak a postava je na světě a stačí ji vložit do světa (ve Startup.d):

Wld_InsertNpc (GOR_100_Goral,"VALE0006");

POZOR: Názvy way/freepointů musí být velkými písmeny. Jak tedy tvořit NPCs? Osobně to dělám tak, že jsem si vytvořil jednu postavu a ostatní pak jen kopíruji od ní a měním hodnoty. To je nejjednodušší cesta. Můžete využít celé řady programů na skriptování postavy, ale žádný není ideální. Doporučuji tedy vzít si tuto postavu, co zde uvádím a jen jí poměnit hodnoty.

Při procházení Wog.de jsem narazil na jeden velmi pěkný program, podle kterého jde postavu vymodelovat. Jmenuje se NPC Viewer a lze v něm nastavit již předdefinované hodnoty (pohlaví, barvu pleti, hlavu, tělo, tvář). Tento program doporučuji používat (link níže).

Jak vybavit postavu? K tomu je dobré použít databanky Gothicu (link níže).

Velikost tvora, NPC editovat

Rozhodně když děláte vlastní modifikaci, chcete, aby byla výjimečná. Už jsme si ukázali, jak se zvířata potahují novými texturami. Teď by to ale chtělo také, abychom mohli udělat některé menší a některé větší. Například stádo zvířat, kde budou malí i velcí stejného druhu. Jak na to? Je to snadné. Našeho tvora už máme. Může to být například lurker. Půjdeme do složky _WORK\DATA\SCRIPTS\CONTENT\STORY\NPC\MONSTER, otevřeme soubor MST_Lurker.d. Vezmeme tuto část kódu:

//*************
//  Lurker
//*************

INSTANCE Lurker (Mst_Default_Lurker)
{
  B_SetVisuals_Lurker();
  Npc_SetToFistMode(self);
};

Zkopírujeme ji a přidáme ještě jeden řádek (navíc změníme ještě jméno instance, abychom neměli dvě stejné).

//*************
//  LurkerA
//*************

INSTANCE LurkerA (Mst_Default_Lurker)
{
  B_SetVisuals_Lurker();
  Mdl_SetModelScale(self, 0.6, 0.6, 0.6);
  Npc_SetToFistMode(self);
};

Funkce Mdl_SetModelScale nám zvíře zmenší nebo zvětší, podle toho, jaká zadáme čísla (0.6 znamená zmenší na 60 procent). Nelze zmenšovat nebo zvětšovat do nekonečna. Osobně jsem vyzkoušel od 0.5 do asi 1.7, ale možná jde i více. A zvíře je hotovo. Máme lurkera malého a zároveň i velkého. Bylo by ovšem ještě vhodné tomu malému dát méně HP a i další statistiky, aby byl nejen menší, ale i slabší. Není třeba definovat celý nový prototyp, stačí jen do instance přidat vlastnosti z prototypu, které chceme změnit:

//*************
//  LurkerA
//*************

INSTANCE LurkerA (Mst_Default_Lurker)
{
  name                          = "Malý Lurker";
  level                         =   4;

  //----- Attributes ----
  attribute [ATR_STRENGTH]      =  55;
  attribute [ATR_DEXTERITY]     =  60;
  attribute [ATR_HITPOINTS_MAX] = 120;
  attribute [ATR_HITPOINTS]     = 120;
  attribute [ATR_MANA_MAX]      =   0;
  attribute [ATR_MANA]          =   0;
	
  //----- Protections ----
  protection [PROT_BLUNT]       =  70;
  protection [PROT_EDGE]        =  70;
  protection [PROT_POINT]       =  70;
  protection [PROT_FIRE]        =  70;
  protection [PROT_FLY]         =  60;
  protection [PROT_MAGIC]       =   0; 
	
  B_SetVisuals_Lurker();
  Mdl_SetModelScale(self, 0.6, 0.6, 0.6);
  Npc_SetToFistMode(self);
};

Vlastnost name nám definuje jméno zvířete, jak ho budeme vidět ve hře. Level pak říká, kolik dostaneme za jeho zabití zkušeností. Atributy a protekce jsou předpokládám jasné. Více o tom v jiném článku.

Odkazy editovat