RPG Zone, Italian Forum & Community for role playing video games - ex Gothic Zone

[Tutorial] Mostri ed oggetti, Lezione 6

« Older   Newer »
  Share  
view post Posted on 21/2/2015, 11:31     +1   -1

Gothic Modder

Group:
Moderatore
Posts:
1,391
Rpg Point:
+83
Location:
L'Urbe!

Status:


Nella scorsa lezione abbiamo parlato della creazione di nuovi npc e dialoghi, quindi delle classi C_NPC e C_INFO. Ora completeremo il discorso su C_NPC parlando dei mostri, e parleremo della classe C_ITEM qundi degli oggetti. Anche qui una volta che saprete come crearli saprete come modificarli e viceversa.

NOTA: come ho già accennato in altre lezioni questa non è una guida sull'editing 3D! Qui parlarò di come inserire i vostri lavori (o di altri) nel gioco, non di come crearli!


Iniziamo dai mostri. Create un nuovo file nella cartella story\npc\monster e create un nuovo file chiamato MST_nomemostro.d, e tenetene aperto un altro come esempio. Io userò quello del lupo:

CODICE
prototype Mst_Default_Wolf(C_Npc)
{
       name[0] = "Lupo";
       guild = GIL_WOLF;
       aivar[AIV_MM_REAL_ID] = ID_WOLF;
       level = 6;
       attribute[ATR_STRENGTH] = 30;
       attribute[ATR_DEXTERITY] = 30;
       attribute[ATR_HITPOINTS_MAX] = 60;
       attribute[ATR_HITPOINTS] = 60;
       attribute[ATR_MANA_MAX] = 0;
       attribute[ATR_MANA] = 0;
       protection[PROT_BLUNT] = 30;
       protection[PROT_EDGE] = 30;
       protection[PROT_POINT] = 0;
       protection[PROT_FIRE] = 30;
       protection[PROT_FLY] = 30;
       protection[PROT_MAGIC] = 0;
       damagetype = DAM_EDGE;
       fight_tactic = FAI_WOLF;
       senses = SENSE_HEAR | SENSE_SEE | SENSE_SMELL;
       senses_range = PERC_DIST_MONSTER_ACTIVE_MAX;
       aivar[AIV_MM_ThreatenBeforeAttack] = TRUE;
       aivar[AIV_MM_FollowTime] = FOLLOWTIME_LONG;
       aivar[AIV_MM_FollowInWater] = TRUE;
       aivar[AIV_MM_Packhunter] = TRUE;
       start_aistate = ZS_MM_AllScheduler;
       aivar[AIV_MM_RoamStart] = OnlyRoutine;
};

func void B_SetVisuals_Wolf()
{
       Mdl_SetVisual(self,"Wolf.mds");
       Mdl_SetVisualBody(self,"Wol_Body",DEFAULT,DEFAULT,"",DEFAULT,DEFAULT,-1);
};


instance Wolf(Mst_Default_Wolf)
{
       B_SetVisuals_Wolf();
       Npc_SetToFistMode(self);
       CreateInvItems(self,ItFoMuttonRaw,1);
};

/*queste in realtà stanno dentro il file mst_warg*/
func void B_SetVisuals_BLACKWOLF()
{
       Mdl_SetVisual(self,"Wolf.mds");
       Mdl_SetVisualBody(self,"Warg_Body",DEFAULT,DEFAULT,"",DEFAULT,DEFAULT,-1);
};

instance BlackWolf(Mst_Default_Warg)
{
       name[0] = "Lupo oscuro";
       level = 6;
       aivar[AIV_MM_REAL_ID] = ID_WOLF;
       attribute[ATR_STRENGTH] = 15;
       attribute[ATR_DEXTERITY] = 20;
       attribute[ATR_HITPOINTS_MAX] = 120;
       attribute[ATR_HITPOINTS] = 120;
       attribute[ATR_MANA_MAX] = 0;
       attribute[ATR_MANA] = 0;
       protection[PROT_BLUNT] = 12;
       protection[PROT_EDGE] = 12;
       protection[PROT_POINT] = 12;
       protection[PROT_FIRE] = 12;
       protection[PROT_FLY] = 12;
       protection[PROT_MAGIC] = 12;
       B_SetVisuals_BLACKWOLF();
       Npc_SetToFistMode(self);
       CreateInvItems(self,ItFoMuttonRaw,1);
};


A differenza degli npc che ereditano tutti da Npc_Default, si è soliti far ereditare ai mostri un prototipo creato specificatamente per loro. Questo perché spesso ci sono più varianti di uno stesso mostro, con la maggior parte delle proprietà in comune ma attributi diversi. Qui di seguito parlerò delle proprietà di cui non ho parlato nella scorsa lezione, o che variano leggermente.

guild anche i mostri hanno una "gilda". La potete trovare in constants.d. Questa servirà per gestire le attitudini (neutrale, ostile, amichevole) con le altre specie.

aivar[AIV_MM_REAL_ID] è una particolare voce tra l'elenco di tutte le aivar (variabili dell'ia). Corrisponde grossomodo (molto grosso) all'id degli npc. Infatti due specie di mostri, possono condividere la stessa gilda (stesse attitudini), ma dovrebbero avere diverso ID (non è obbligatorio ma è buona norma). Tutti gli id dei mostri sono dentro ai_constants.d in ai -> ai_intern.

level è il livello dei mostri, ma va? :D Il livello determina l'esperienza che riceverà l'eroe dopo averlo ucciso. Si calcola così: level * XP_PER_VICTORY, che è una costante sempre definita in AI_constants.d.

attribute sono i vari attributi del mostro

protection sono le protezioni dalle armi: blunt = colpi contundenti (pugni in genere), edge = armi, point = frecce, fire = fuoco, fly = caduta :o_o.gif: , magic = magia

damagetype appunto il tipo di danno (in questo caso da taglio)

fight_tactic qui o utilizzate una già esistente o ne create una nuova. Se ne avete proprio bisogno posso creare un tutorial apposta

senses i sensi del mostro. Cioè tramite quali sensi riesce a percepirvi (vista, udito e olfatto)

senses_range l'ampiezza dei sensi del mostro (in genere impostato su max)

(qui di seguito tutte variabili reperibili in ai_constants)

aivar[AIV_MM_ThreatenBeforeAttack] se impostato su true il mostro vi minaccerà prima di attacarvi

aivar[AIV_MM_FollowTime] il tempo di inseguimento

aivar[AIV_MM_FollowInWater] se impostato su true, vi insegue anche in acqua

aivar[AIV_MM_Packhunter] "pack animal" significa letterlalmente "animale da soma", in questo con hunter forse significa cacciatore di gruppo

start_aistate e aivar[AIV_MM_RoamStart] in genere vanno sempre bene se lasciati così come sono. Indicano la routine di base del mostro.


Bene dopo aver creato il prototipo viene ora create una funnzione per creare la visuale del mostro: B_SetVisuals_Wolf()

Mdl_SetVisual(self,"Wolf.mds") significa che andrà ad utilizzare la mesh e le animazioni gestite dal file wolf.mds

Mdl_SetVisualBody è una funzione che prende i seguenti parametri: istanza su cui chiamare la funzione, mesh del corpo, texture del corpo, texture della pelle, mesh della testa, texture dei denti e armatura. Bene spiegamo bene questa funzione. self è banale, stiamo applicando la visuale sulla stessa istanza in cui viene chiamato. Il nome tra virgolette indica la mesh da utilizzare. Infatti seppur lupi, warg e il lupo oscuro condividono le stesse animazioni le mesh sono differenti. O meglio in questo caso lupo e lupo oscuro condividono la stessa mesh ma non la stessa texture. Infatti per i mostri, si è in genere soliti utilizzare tante mesh diverse quante sono le diverse texture da applicarvi, invece di crearne una e scegliere la texture con questa funzione. Di conseguenza il terzo parametro, body texture sarà sempre default. Il quarto è la texture della pelle, non usato quindi lasciato a default. Il quinto è la mesh della testa, che in questo caso non è necessario, siccome stiamo lavorando sui mostri. Il sesto è la texture dei denti, anche in questo lasciate default in quanto non necessaria per i mostri, e l'ultimo è l'armatura, anche qui inutile. Come applicare le texture alle mesh verrà descritto nella successiva lezione.


Questa è la visuale che viene chiamata nell'istanza Wolf. Quindi l'istanza wolf avrà la visuale determinata dai parametri della funzione Mdl_SetiVisualBody, e gli attributi ereditati dal prototipo MST_Wolf. Npc_SetToFistMode è una funzione che imposta il combattimento con i pugni, quindi senza armi.


Vediamo ora un altro esempio importante: il lupo oscuro. Notate come viene creata la funzione B_SetVisuals_BLACKWOLF. È uguale in tutto e per tutto tranne per la mesh, che utilizza quella del warg. L'istanza blackwolf invece, nonostante erediti da MST_Wolf, manterrà tutte le proprietà che caratterizzano l'IA del lupo, ma gli attributi vengono riassegnati. Guardate altre tipologie di mostri e vedrete comportamenti simili.



Passiamo infine agli oggetti. La questione qui è molto più facile. Gli oggetti in gothic sono raggruppati in gruppi divisi poi in diversi file che potete vedere nella cartella items. A seconda di ciò che dovete creare potete inserire l'istanza nel file più coerente oppure crearne uno nuovo, magari nella cartella _misk_.
Qui ci sono diverse tipologia di oggetti, che non posso spiegare tutti una per una. La struttura è la stessa, ma spesso cambiano i parametri. Il segreto è proprio aprire ogni file e vedere come sono strutturati. Prendiamo come esempio un arma:

CODICE
instance ItMw_2H_Special_04(C_Item)
{
       name = NAME_ItMw_2H_Special_04;
       mainflag = ITEM_KAT_NF;
       flags = ITEM_2HD_SWD;
       material = MAT_METAL;
       value = Value_Special_2H_4;
       damageTotal = Damage_Special_2H_4;
       damagetype = DAM_EDGE;
       range = Range_Special_2H_4;
       on_equip = Equip_2H_10;
       on_unequip = UnEquip_2H_10;
       cond_atr[2] = ATR_STRENGTH;
       cond_value[2] = Condition_Special_2H_4;
       visual = "ItMw_110_2h_sword_smith_05.3DS";
       description = name;
       text[2] = NAME_Damage;
       count[2] = damageTotal;
       text[3] = NAME_Str_needed;
       count[3] = cond_value[2];
       text[4] = NAME_ADDON_BONUS_2H;
       count[4] = Waffenbonus_10;
       text[5] = NAME_Value;
       count[5] = value;
};

const int Damage_Special_2H_4 = 180;
const int Condition_Special_2H_4 = 160;
const int Range_Special_2H_4 = 140;
const int Value_Special_2H_4 = 2100;

func void Equip_2H_10()
{
       if(Npc_IsPlayer(self))
       {
               B_AddFightSkill(self,NPC_TALENT_2H,Waffenbonus_10);
       };
};

func void UnEquip_2H_10()
{
       if(Npc_IsPlayer(self))
       {
               B_AddFightSkill(self,NPC_TALENT_2H,-Waffenbonus_10);
       };
};


name contiene il nome che vedrete al focus sulla spada. In questo caso non è scritto direttamente come stringa, ma viene chiamata una costante che contiene il nome. Il motivo è probabilmente perché sono spade da forgiare, e il nome può così essere usato anche per i dialoghi facilmente.

mainflag indica le caratteristiche dell'oggetto. In questo caso indica un arma ravvicinata. Potrete vedere tutte le possibilità in constants.d

flags invece indica le caratteristiche proprie dell'arma. In questo caso una spada a due mani (quindi determina l'animazione da usare). Anche queste le potrete trovare in constants.d. Anche qui farò un appendice in cui descriverò tutte le varie constanti.

material indica il materiale con cui è fatto l'oggetto. Cambia soltato il suono quando collide con altri oggetti.

value indica il valore dell'oggetto quindi a quanto viene venduto. Questo insieme alle condizioni, ampiezza e danno vengono definiti nel file tuning_melee_weapons.

damageTotal indica il danno complessivo dell'arma

damagetype il tipo di danno

range lo spazio in cui la spada colpisce

on_equip chiama la funzione scritta sotto (e definta in Zweihand_EquipBonus per le armi a due mani). All'equipaggiamento dell'arma l'eroe, E SOLO SE È L'EROE (vedi condizione Npc_IsPlayer), guadagna 10 punti bonus sulla percentuale di critico (in questo caso).

on_unequip equivalente ad on_equip ma chiamata al disequippaggiamento

cond_atr è un array che ha come elementi gli attributi necessari a portare l'arma. Se è uno solo viene usato sempre il terzo elemento (cond_atr[2]), ma non so perché.

cond_value è il valore necessario dell'attributo corrispondente per portare l'arma/oggetto

visual la visuale 3D dell'oggetto

description il nome che troverete non al focus, ma quando lo avrete selezionato dall'inventario. In genere uguale a name

text e count sono infine due array (rispettivamente stringa e intero), che corrispondono alla descrizione dell'oggetto. I text sono le stringhe che troverete sulla sinistra nell'inventario (valore, danno, forza richiesta, ecc..), mentre i count è il valore corrispondente sulla destra. NOTA: questi hanno valore puramente descrittivo! Se infatti sbaglierete a scrivere non verranno considerati questi valori ma quelli assegnati sopra.



Bene scusate se sono stato un po' riduttivo su questi ultimi argomenti ma sapete, ci sono tante di quelle sfaccettature che mi viene difficile elencarvele tutte. Preferisco invece darvi gli strumenti per capirle da soli. Infatti con la prossima lezione avrete più chiaro il discorso su animazione/mesh/texture, e nel prossimo appendice descriverò per bene tutti gli attributi delle classi.


Ciao :camberman.gif: :camberman.gif:

Torna all'indice delle lezioni



Edited by Frank-95 - 23/2/2015, 14:32
 
Top
view post Posted on 21/2/2015, 14:02     +1   -1
Avatar

Dark Necromancer (Leader G.M.I.C)

Group:
Moderatore
Posts:
1,854
Rpg Point:
+122
Location:
Calador

Status:


penso proprio che il tutorial su yt ci terrà parecchio incollati! xD ma prima è meglio è
 
Top
1 replies since 21/2/2015, 11:31   94 views
  Share