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

Votes taken by Frank-95

view post Posted: 7/1/2017, 12:34     +1Frank's Mod V2 - Gothic II & La Notte del Corvo
È giunto il momento del rilascio, penserete voi? Beh quasi.

Dopo mesi di stallo a causa di mancanza di tempo e voglia nel fare il restyling dei mondi, e senza trovare nessuno a darmi una mano, ho deciso di mettere insieme quello che avevo per rilasciare una demo; anzi non solo demo anche beta: una beta di una demo :P
Con questo che cosa intendo? Che il gioco è giocabile, quando inserivo nuove caratteristiche le testavo bene prima di passare alla successiva, e oggi e ieri ho testo se crashasse al cambio del mondo, e non succede. Però non è bilanciato! O meglio, ho provato a fare un bilanciamento da me, ma purtroppo mi servono diverse opinioni da parte vostra. Contando sempre che nella versione definitiva avevo in progetto di aggiungere un'altra vasta area di gioco, e diversi mostri in più: i mostri ci sono e posso essere aggiunti tramite marvin, ma non sono inseriti nel gioco. Inoltre ormai non parlo più di patch, bensì di mod, viste tutte le caratteristiche aggiunte. Vi faccio notare, che sono quasi tutte fatte da me, e tra tutte le mod in circolazione (anche tedesche), la mia è tra quelle con il maggior numero di caratteristiche nuove originali aggiunte personalmente e in maniera pulita, quindi agendo direttamente sulla memoria.

RIPETO, QUESTA NON È UNA VERSIONE COMPLETA NÉ TANTOMENTO STABILE! CHIUNQUE MI DICA, "EH MA MANCANO DIVERSE COSE", LO BANNO. MI SERVE SOLO PER VEDERE SE LE NUOVE CARATTERISTICHE VI PIACCIONO.

In particolare queste sono le cose che sono sicuro di dover completare:
CITAZIONE
RIBILANCIARE TUTTO
RIVEDERE I TEMPI DI ATTESA PER I MOB
RISCRIVERE I PERSONAGGI DI DEBUG
BUG NUOTO DOVUTO A STAMINA (se morite sott'acqua perché finisce la resistenza e quindi la vita, continuerete a nuotare indefinitavamente)
SUONI NUOVI INCANTESIMI MANCANTI
ALCUNE POZIONI AGGIUNTIVE AL TAVOLO ALCHEMICO MANCANTI
ALCUNE ARMI AFFILATE MANCANO
RIVEDERE IL VALORE DELLE SPADE AFFILATE
ESPLOSIONE FRECCIA ESPLOSIVA MANCANTE
AGGIUNGERE MOSTRI
COMPLETARE IL RESTYLING
C'È SOLO UN FORZIERE SOTTOMARINO PER ORA

Quindi chiedo a chiunque voglia giocare questa mod, la massima attenzione ai dettagli! Scrivetevi tutti i bug, glitch, o parti mancanti che trovate! Anche se vi sembrano banali, a me possono essere sfuggite! In particolare quando si smette di moddare per un po' di tempo e poi si riprende è sempre difficile ricordarsi ciò che manca. Quindi vi prego di segnalarmi qualsiasi cosa, o sarà inutile che l'ho postata qui.

Quetso è l'elenco dei cambiamenti:

Bugfixes
CITAZIONE
- Migliorata la telecamera per gli schermi 16:9 e 16:10 non più necessario grazie al systempack
- L'eroe ora riceverà esperienza quando aggiungerà alla ciurma Lares e Lester
- Sekob sarà immortale solo dal momento in cui compariranno i cercatori fino alla fine della missione
- Risolto il problema di assegnamento dei punti esperienza dopo il borseggiamento di alcuni personaggi (Cavalorn, Franco, Francis, Valentino, Salandril, Dobar, Engor): ora sarà analogo a quello de lNdC (non era stato aggiornato)
- Il video dell'attacco degli orchi non farà più crashare il gioco
- Risolto il problema che non ti permetteva di risolvere la missione dei banditi nella torre a Jharkendar
- L'eroe ora da giustamente un elisir curativo a Pardos invece di tre essenze curative nel caso questa opzione è selezionata
- Risolto il problema in cui i draghi occasionalmente non generavano trofei
- Ora la missione "Briganti e manifesto da ricercato" potrà essere completata in ogni caso dopo aver parlato con dexter
- Rimosso l'exploit che ti permetteva di vendere i corni di bestia d'ombra a Buster, metterlo fuori gioco, riprenderli e venderglieli di nuovo
- Martin non ti venderà più il grasso di ratto talpa ne lo troverai più sulla nave; così l'argano si potrà aprire solo dopo aver parlato con enhim in modo tale da non poter rendere la missione irrealizzabile
- Risolto un problema in cui Biff ripeteva un dialogo all'infinito
- Durante il test del fuoco Igaraz non scomparirà più dal gioco occasionalmente a causa di un errato waypoint
- Durante il test del fuoco Agon attaccherà per uccidere in ogni caso
- Risolto il problema per il quale Igaraz non ti attaccava quando possedeva una runa vuota durante il test del fuoco
- Se atterrerai Wasili non potrai più riprendere le vecchie monete d'oro
- Angar non cambierà più arma dopo essersene andato dalla valle delle miniere
- L'eroe non potrà più andare al castello del drago di roccia se diego lo sta seguendo
- Hagen non può più iniziare un dialogo con l'eroe se questi è trasformato in una pecora ;) (ma chi è che ha mai sperimentato questo bug?)
- Risolto il bug per il quale trasformandosi mentre si ha equipaggiato un arma che aumenta o diminuisce gli attributi, questi cambiamenti diventano permanenti
- Non si potrà più ottenere rune congelando e poi uccidendo i nemici
- Non potrete più ricomprare l'almanacco dei posseduti da Vatras
- Non potrete ripetere il dialogo con Mika per prendere punti esperienza all'infinito
- I maghi scheletro evocheranno un massimo di 5 scheletri per impedire scheletri infiniti
- Corretto errore di visualizzazione delle informazioni di alcune armi (Lama da guerra pesante di metallo, Spada lunga di metallo, Spada a due mani di metallo)
- Esteban ora possederà la chiave del suo forziere
- Il drago di fuoco ora è immortale prima di averci parlato
- Non potrete più rubare la chiave a Salandril se l'avete già atterrato e presa
- Corretti alcuni errori di visualizzazione di alcune armature
- Cavalorn tornerà alla sua postazione originale dopo la missione dell'ornamento
- Risolto l'exploit che ti permetteva di vendere a Francis il suo libro paga, stenderlo, riprenderlo e rivenderlo di nuovo
- Se dopo aver atterrato Salandril non prenderete le azioni ve le darà lui cosicché non dovrete riatterrarlo per prenderle e completare la missione
- Corretto il bug per il quale non venivano mostrati gli effetti grafici durante il rituale dell'acqua dopo aver rimosso la pietra dalla sua postazione
- Corretti dei bug grafici di alcune armature
- Correto il bug per il quale Lares non ti accompagnava più da nessuna parte dopo averti accompagnato da onar
- Il capo branco degli squartatori ora comparirà in ogni caso per evitare che se uccidi tutto il branco senza parlare con bilgot, questo non si presenti rendendo impossibile la missione di lutero (e sarà un po' più forte)
- Non rischierete più di imparare due volte lo stesso talento da alligator jack
- I mostri evocati non si attaccheranno più a vicenda
- Ridotti i crash dovuti ad effetti con troppi canali alfa (too many alphapolys)
- Adesso è possibile andare e tornare nello spiazzo con l'arco magico senza usare trucchi (DA RIFARE)
- Ora diego insegnerà come aumentare la forza anche a khorinis
- Cavalorn non vestirà l'armatura dell'anello a khorinis
- Non troverete più il sangue di drago in un punto del tesoro a Jharkendar
- I compagni ora attaccheranno anche i cercatori e non più i mostri evocati
- Risolto il bug per il quale potevate dare le scaglie a Jan atterrarlo e riprenderle
- Risolto il bug per il quale a volte Rosi e Till non lasciavano il gruppo alla fattoria
- Non potrete più recuperare la merce venduta a Cipher e Hodges se li atterrerete
- Risolto il bug per il quale i corpi degli schiavi liberati a Jharkendar rimanevano lì
- Corretti alcuni errori della spada di Alrik
- Se aprirete l'inventario durante il caricamento di un incantesimo non vi si bloccherà più il gioco, ma si annullerà semplicemente l'incantesimo
- Risolto il bug per il quale durante la sfida con rod, equipaggiavi l'arma più forte invece che l'arma di rod
- I draghi non si bloccheranno più quando uscirete dal loro raggio di attacco da mischia
- L'effetto magico sulla statua di Innos al monastero non scomparirà più dopo qualche tempo
- Non pioverà più dentro le piccole costruzioni
- Non andrete più automaticamente ad Irdorath quando vi avvicinerete al letto ma dovrete dormire
- Risolto il bug per il quale i mostri non erano più immuni ad un tipo di danno se indossavano una protezione
- Anche i mostri avranno l'inventario

Bilanciamento
CITAZIONE
- Lares può provvedere alla via facile per accedere a tutte e tre le gilde
- L'ammazza draghi e l'ascia del berserker non potranno più essere comprate, ma dovranno essere trovate durante l'avventura
- Bartok ora è più forte, così è meno difficile tenerlo vivo nella foresta durante la relativa missione
- Gestath e Godar non potranno più insegnare come ottenere i trofei dei draghi. Per impararli dovrete leggere dei tomi che potrete comprare da due rivenditori
- Le pergamene per incantesimi consumeranno ora 5, 10 o 15 mana (quelle degli incantesimi da "caricare" rimarranno invariate)
- La runa rimpicciolisci consuma ora 250 mana
- Gli XP d'ambiente sono aumentati di 100 in ogni capitolo
- Lo stunt bonus è ora di 1000
- Ribilanciamento di alcuni valori delle armature (anche per renderle più proporzionate a gothic 1)
- Intelligenza artificiale durante il combattimento migliorata
- Gaan indosserà l'armatura da ranger anche davanti al passo delle miniere
- Gli orchi guerrieri saranno equipaggiati casualmente con l'ascia media o pesante
- Alcuni orchi presenti dall'inizio del gioco a khorinis saranno "semplici" esploratori e non guerrieri
- Il drago non morto non genererà più né sangue né scaglie in caso si possedesse questa abilità
- Diminuito il costo di apprendimento delle abilità del fuoco fatuo (vista la loro utilità pratica)
- Ribilanciato il valore di alcuni trofei e la quantità con cui vengono generati (DA BILANCIARE)
- Alcuni banditi avranno un armatura migliore, altri peggiore, a causa della presenza di tre e non più due armature da bandito
- Ribilanciati i valori di rigenerazione del cibo e piante
- Gaan è un po'più forte così avrà meno possibilità di morire
- Nessun cacciatore di draghi avrà l'armatura pesante dal momento che è stata una creazione di Bennet successiva (solo se porterete Bennet ad Irdorath, Gorn ce l'avrà), e alcuni che avevano quella media ora avranno quella leggera
- I maghi dell'acqua avranno tutti la veste leggera eccetto Saturas e Vatras
- I golem sono in generale più forti e la loro forza è data dal loro elemento nello stesso ordine dei draghi (DA BILANCIARE)
- I non-morti saranno immuni alle freccie mentre i troll non più (seppure con una difesa molto alta) (DA BILANCIARE)
- Il troll oscuro sarà più forte di prima (DA BILANCIARE)
- L'orco colonello sarà più forte degli orchi d'elité (i quali non fanno più critico al 100% come prima)
- Le pergamene per paladini verrano vendute solo ai paladini ad eccezione delle tre di più basso livello sempre in quantità limitata
- L'incantesimo paura non farà più scappare i membri del gruppo
- Aumentata leggermente l'esperienza ricevuta dalle profezione di abuyin
- Vatras aumenterà il tuo mana per ogni tavoletta di pietra che gli porterai (potranno essere portate anche a Irdorath)
- Vatras potrà aumentare il tuo potere magico fino a 300 ad Irdorath
- Potenziate le lacrime di Innos
- La pozione di neoras e l'embarla firgasto aumenteranno l'attributo dominante e non sempre la forza (quindi anche il mana in caso siate maghi)
- Alzati i valori di aumento del costo del mana (50,80,110,140 invece di 30,60,90,120) (DA BILANCIARE)
- Tempesta di fuoco superiore è un po' più forte (DA BILANCIARE)
- Pesantemente ribilanciati gli attributi di tutti gli npc (alcuni npc senza nome erano semplicemente troppo forti) (DA BILANCIARE)
- Inglobata la Nostalgic Mod di GiuggioTheIdol
- Aggiunte le condizioni per i talenti
- Il talento acrobazie non sarà più appreso automaticamente a 90 di destrezza; inoltre diminuirà i danni da caduta
- Aumentati i danni da caduta
- I draghi non rigenereranno più la loro vita, ma la salute base sarà enormemente più alta (e anche le altre statistiche) (DA BILANCIARE)
- Diminuito l'oro ricevuto dopo il completamento della missione di Till e Rosi
- I maghi dell'acqua insegneranno solo le loro rune, non anche quelle dei maghi del fuoco
- Ora dovrete scegliere a chi dare il libro paga di lehmar, non potrete più darlo a tutti e tre; inoltre non darete subito il libro a Thorben durante il dialogo ma avrete la possibilità di scegliere
- I personaggi con un arma a distanza avranno un limitato numero di frecce, finite le quali attaccheranno con le armi da mischia
- Piccola rigenerazione salute mentre si è seduti
- Aumentata leggermente la benedizione in punti vita dei santuari, e il mana verrà incrementato solo ai maghi e novizi
- Essere l'apprendista di constatin non sarà più una scelta inutile
- Cambiato il sistema di attacco dei cercatori
- Frecce e dardi più veloci
- Maggiore distanza di mira per archi e balestre
- La torcia non cadrà più durante l'estrazione di un'arma ad una mano
- La distanza utile coperta dalle armi non è più arbitraria ma è precisamente quella della mesh
- Il valore delle armi ora è dipendente dalle caratteristiche e non più arbitrario
- Revisione completa delle proprietà di qualsiasi oggetto

Aggiunte
CITAZIONE
- Il gioco chiede conferma per iniziare una nuova partita
- Ora ci saranno tre armature dei banditi in accordo con gothic 1, ma con le texture di gothic 2
- Aggiunta la pelle di lupo bianco e cuore di golem di palude
- Implementato un sistema di scatto (scelta del tasto dal file IGP.ini)
- Migliorata la casualità degli eventi
- Barra del mana sempre visibile *
- Schizzi di sangue sullo schermo quando si è colpiti *
- Nomi colorati per i PNG e mostri (verde se amico, bianco se neutrale, arancione se arrabbiato, rosso se nemico)*
- Implementato sistema della stamina
- Aggiunti i sottotitoli ad alcuni dialoghi degli npc rimosso causa bug
- Introdotti malus dovuti ai colpi dei mostri (e conseguenti pozioni di cura)
- Aggiunti diversi talenti da gothic 3
- Aggiunte le specializzazioni di combattimento e nuove animazioni
- Ora bisognerà aspettare alcuni secondi durante l'utilizzo dei mob per la creazione di oggetti (DA BILANCIARE)
- Ogni drago ora avrà un attacco principale con effetti diversi
- Aggiunti più mostri
- Implementato un menu di stato simile a gothic 3
- Possibilità di trovare forzieri sott'acqua
- Implementati gli scudi
- Rifatto il sistema dei danni
- Aggiunte alcune pozioni nuove
- I mercanti accetteranno solo determinata merce e solo in base alla loro quantità di oro
- All'inizio di un dialogo ci saranno a volte dei saluti relativi allo status del personaggio
- Alcune armi avranno dei nuovi effetti aggiuntivi
- Nuovi metodi e tipi di crafting
- Gli npc con armi a distanza, e l'eroe quando ne avrà una equipaggiata, avranno una faretra

* da sceglierle se attivarle nel file IGP.ini

Stringhe
CITAZIONE
- Corrette tantissime imprecisioni, dialoghi errati o desincronizzati, o nomi in cui vi erano inspiegabilmente tantissimi spazi prima
- Correto il dialogo con Biff in modo tale che così puoi sciegliere la pozione curativa da dargli
- Le munizioni per la balestra magica si chiameranno "dardo magico" e non "vite magica"
- Alcune correzioni nei nomi di alcune armature
- Lo scarabeo si chiamerà ora scarafaggio
- Modifiche minori che probabilmente non noterete nemmeno
- Eliminata la voce della birra "paladino oscuro"
- Corretto il nome di Attile in Attila
- "Rasoio" rinominato in "Laceratore"
- Le pergamene e rune da paladino avranno ora le relative diciture più precise
- Il "troll di caverna" si chiamerà semplicemente "troll"
- Corrette le diciture di "vecchio campo" e "nuovo campo" nei più corretti "Campo Vecchio" e "Campo Nuovo"
- Pepita d'oro (riferito al punto d'estrazione) si chiamerà ora giacimento d'oro
- Corretto la stringa d'apertura nel capitolo 6 da "La Sala di Irdorath" in "Le Sale di Irdorath" e nel capitolo 2 da "Torna alla colonia" in "Ritorno alla colonia"

Texture e mesh
CITAZIONE
- Inglobata la Graphic Overhaul di Vurt
- Utilizzate alcune texture dalla mod di Colmar
- Paesaggi dei mondi rivisitati
- Icone dei talenti in stile gothic 3
- Utilizzate alcune mesh e texture dalla l'Hiver
- Modificati alcuni effetti grafici
- Utilizzate alcune mesh e texture dalla Returning
- Armi aggiornate con mesh e texture della Returning

Per installare la mod:
- Gothic 2 + La notte del Corvo O Gothic 2 Gold
- Patch 2.6 report version 2
- Gothic starter 2.6f
- System pack (non necessario ma consigliatissimo)

Se avete già il SP installato, dovrestare a posto.

Ora scaricate il file da qui, estraetelo con 7-zip e mettete il file mod dentro Data\modvdf, e gli altri file in System.
Il file ini conterrà alla fine delle opzioni che potrete scegliere se abilitare o no (1 abilitato, 0 disabilitato), e la possiblità di scegliere voi i tasti per alcune azioni: scattare (predefinito: U), borseggiare nel sonno aka maestro ladro (predefinito: Z), aprire forzieri sott'acqua (predefinito: V). Per cambiare tasti se questi non vi piacciono, aprite il file TXT scegliete il tasto e scrivete il valore corrispondente nel file ini alla riga opportuna. Cercate di non usare tasti già in uso!!!

Bene, so che non è quello che vi aspettavate, ma c'è tanto da fare, poco tempo, e per quanto riguarda i mondi, poca voglia.

Voglio tante opinioni e critiche costruttive. Ripeto, il primo che dice, "eh ma mancano un sacco di cose, noN rilasciare le cose incomplete", viene perma bannato.
Lanciate il gioco da gothicstarter_mod COME AMMINISTRATORE, e selezionate il file ini corrispondente; controllate che non ci siano spunte sulle caselline a destra, e impstate il livello di log almeno a 5. Se il gioco crasha, aprite zspy, salvate il log e mandatemelo qui INSIEME A COSA STAVATE FACENDO; vedrò se capisco il problema.
CONSIGLIO: usate diversi salvataggi, e salvate ogni volta che dovete cambiare mondo per stare sicuri!

Buon gioco a tutti ;)

Scusate l'errore grossolano ma mi sono accorto che nel file ini dentro l'archivio la voce del file mod è incompleta. Voi troverete così:

CITAZIONE
VDF=

Scrivete questo:

CITAZIONE
VDF=IGP.mod

Se poi vedete che ancora non va spostate il file mod da data/modvdf in data e rinominatelo in .vdf. Così lo avrete installato come patch e funzionerà sicuramente (lanciate comunque da gothic starter il file igp.ini)

Scusate la grossa svista

Edited by Frank-95 - 13/2/2017, 14:50
view post Posted: 12/7/2016, 20:36     +1Cambiare aspetto eroe Gothic 1 - Gothic
Ti ho modificato il post, per favore ricordati il tag code, rende più facile la vita a me, e quindi a te :)

Comunque sono andato a controllare gli script originali e non pensavo che il file continuasse dopo PC_Hero. Il dubbio mi è venuto perché i numeri tra parentesi nell'errore indicano in quale riga esso è presente; così un'altra volta lo sai.

Io ti chiedevo solo PC_Hero perché pensavo che ci fosse solo quella. Evidentemente l'errore era più sotto, quindi per sbaglio avrai modificato anche qualcos'altro.

Ti metto qui il file corretto. Te elimina tutto quello che hai in quel file e copia questo. Ora dovrebbe funzionare:

CODICE
instance PC_Hero(Npc_Default)
{
       name[0] = "Io";
       npcType = npctype_main;
       guild = GIL_None;
       level = 0;
       voice = 15;
       id = 0;
       exp = 0;
       exp_next = 500;
       lp = 0;
       attribute[ATR_STRENGTH] = 10;
       attribute[ATR_DEXTERITY] = 10;
       attribute[ATR_MANA_MAX] = 5;
       attribute[ATR_MANA] = 5;
       attribute[ATR_HITPOINTS_MAX] = 40;
       attribute[ATR_HITPOINTS] = 40;
       Mdl_SetVisual(self,"HUMANS.MDS");
       Mdl_SetVisualBody(self,"hum_body_Naked0",4,1,"Hum_Head_Bald",9,0,-1);
       CreateInvItem(self,ItWr_Fire_Letter_01);
};

instance PC_Hero_L2(Npc_Default)
{
       name[0] = "Io";
       npcType = npctype_main;
       guild = GIL_None;
       level = 2;
       voice = 15;
       id = 0;
       exp = 1500;
       exp_next = 3000;
       lp = 0;
       attribute[ATR_STRENGTH] = 13;
       attribute[ATR_DEXTERITY] = 10;
       attribute[ATR_MANA_MAX] = 5;
       attribute[ATR_MANA] = 5;
       attribute[ATR_HITPOINTS_MAX] = 64;
       attribute[ATR_HITPOINTS] = 64;
       Mdl_SetVisual(self,"HUMANS.MDS");
       Mdl_SetVisualBody(self,"hum_body_Naked0",4,1,"Hum_Head_Bald",9,0,vlk_armor_l);
       EquipItem(self,HeroSword20);
       CreateInvItems(self,ItAmArrow,50);
       EquipItem(self,HeroSword13);
       EquipItem(self,HeroBow13);
};

instance PC_Hero_L5(Npc_Default)
{
       name[0] = "Io";
       npcType = npctype_main;
       guild = GIL_None;
       level = 5;
       voice = 15;
       id = 0;
       exp = 7500;
       exp_next = 10500;
       lp = 0;
       attribute[ATR_STRENGTH] = 25;
       attribute[ATR_DEXTERITY] = 10;
       attribute[ATR_MANA_MAX] = 5;
       attribute[ATR_MANA] = 5;
       attribute[ATR_HITPOINTS_MAX] = 100;
       attribute[ATR_HITPOINTS] = 100;
       Mdl_SetVisual(self,"HUMANS.MDS");
       Mdl_SetVisualBody(self,"hum_body_Naked0",4,1,"Hum_Head_Bald",9,0,-1);
       EquipItem(self,HeroSword25);
       EquipItem(self,HeroBow13);
       CreateInvItems(self,ItAmArrow,50);
};

instance PC_Hero_L7(Npc_Default)
{
       name[0] = "Io";
       npcType = npctype_main;
       guild = GIL_ORG;
       level = 7;
       voice = 15;
       id = 0;
       exp = 14000;
       exp_next = 18000;
       lp = 0;
       attribute[ATR_STRENGTH] = 45;
       attribute[ATR_DEXTERITY] = 35;
       attribute[ATR_MANA_MAX] = 20;
       attribute[ATR_MANA] = 20;
       attribute[ATR_HITPOINTS_MAX] = 160;
       attribute[ATR_HITPOINTS] = 160;
       Mdl_SetVisual(self,"HUMANS.MDS");
       Mdl_SetVisualBody(self,"hum_body_Naked0",4,1,"Hum_Head_Bald",9,0,org_armor_h);
       Npc_SetTalentSkill(self,NPC_TALENT_PICKLOCK,1);
       Npc_SetTalentValue(self,NPC_TALENT_PICKLOCK,60);
       Npc_SetTalentSkill(self,NPC_TALENT_1H,1);
       EquipItem(self,ItMw_1H_Sword_05);
       EquipItem(self,ItRw_Bow_Small_04);
       CreateInvItems(self,ItAmArrow,100);
       CreateInvItems(self,ItMiNugget,50);
       CreateInvItem(self,ItWrWorldmap);
       CreateInvItems(self,ItKeLockpick,30);
       CreateInvItems(self,ItLsTorch,20);
       CreateInvItems(self,ItFo_Potion_Health_03,20);
       CreateInvItems(self,ItFo_Potion_Mana_03,20);
};

instance PC_Hero_L11(Npc_Default)
{
       name[0] = "Io";
       npcType = npctype_main;
       guild = GIL_SLD;
       level = 11;
       voice = 15;
       id = 0;
       exp = 33000;
       exp_next = 39000;
       lp = 0;
       attribute[ATR_STRENGTH] = 60;
       attribute[ATR_DEXTERITY] = 45;
       attribute[ATR_MANA_MAX] = 50;
       attribute[ATR_MANA] = 50;
       attribute[ATR_HITPOINTS_MAX] = 220;
       attribute[ATR_HITPOINTS] = 220;
       Mdl_SetVisual(self,"HUMANS.MDS");
       Mdl_SetVisualBody(self,"hum_body_Naked0",4,1,"Hum_Head_Bald",9,0,sld_armor_h);
       Npc_SetTalentSkill(self,NPC_TALENT_PICKLOCK,1);
       Npc_SetTalentValue(self,NPC_TALENT_PICKLOCK,60);
       Npc_SetTalentSkill(self,NPC_TALENT_1H,2);
       Npc_SetTalentSkill(self,NPC_TALENT_BOW,1);
       EquipItem(self,ItMw_1H_Sword_Long_05);
       EquipItem(self,ItRw_Bow_Long_02);
       CreateInvItems(self,ItAmArrow,100);
       CreateInvItems(self,ItMiNugget,400);
       CreateInvItems(self,ItKeLockpick,30);
       CreateInvItems(self,ItLsTorch,20);
};

instance PC_Hero_L13(Npc_Default)
{
       name[0] = "Io";
       npcType = npctype_main;
       guild = GIL_SLD;
       level = 13;
       voice = 15;
       id = 0;
       exp = 45500;
       exp_next = 52500;
       lp = 0;
       attribute[ATR_STRENGTH] = 65;
       attribute[ATR_DEXTERITY] = 50;
       attribute[ATR_MANA_MAX] = 50;
       attribute[ATR_MANA] = 50;
       attribute[ATR_HITPOINTS_MAX] = 250;
       attribute[ATR_HITPOINTS] = 250;
       Mdl_SetVisual(self,"HUMANS.MDS");
       Mdl_SetVisualBody(self,"hum_body_Naked0",4,1,"Hum_Head_Bald",9,0,sld_armor_h);
       Npc_SetTalentSkill(self,NPC_TALENT_PICKPOCKET,1);
       Npc_SetTalentValue(self,NPC_TALENT_PICKPOCKET,60);
       Npc_SetTalentSkill(self,NPC_TALENT_SNEAK,1);
       Npc_SetTalentSkill(self,NPC_TALENT_PICKLOCK,1);
       Npc_SetTalentValue(self,NPC_TALENT_PICKLOCK,60);
       Npc_SetTalentSkill(self,NPC_TALENT_1H,2);
       Npc_SetTalentSkill(self,NPC_TALENT_BOW,1);
       EquipItem(self,ItMw_1H_Sword_Broad_01);
       EquipItem(self,ItRw_Bow_Long_04);
       CreateInvItems(self,ItAmArrow,100);
       CreateInvItems(self,ItMiNugget,400);
       CreateInvItems(self,ItKeLockpick,50);
       CreateInvItems(self,ItLsTorch,20);
};

instance HeroSword13(C_Item)
{
       name = "Spada rovinata";
       mainflag = ITEM_KAT_NF;
       flags = ITEM_SWD;
       material = MAT_METAL;
       value = 27;
       damage[DAM_INDEX_BARRIER] = 13;
       damagetype = DAM_EDGE;
       range = 100;
       visual = "ItMw1hSwordold01.3DS";
};

instance HeroSword20(C_Item)
{
       name = "Spada";
       mainflag = ITEM_KAT_NF;
       flags = ITEM_SWD;
       material = MAT_METAL;
       value = 31;
       damage[DAM_INDEX_BARRIER] = 20;
       damagetype = DAM_EDGE;
       range = 100;
       visual = "ItMw1hSword01.3DS";
};

instance HeroSword25(C_Item)
{
       name = "Spada";
       mainflag = ITEM_KAT_NF;
       flags = ITEM_SWD;
       material = MAT_METAL;
       value = 31;
       damage[DAM_INDEX_BARRIER] = 25;
       damagetype = DAM_EDGE;
       range = 100;
       visual = "ItMw1hSword01.3DS";
};

instance HeroBow13(C_Item)
{
       name = "Balestra";
       mainflag = ITEM_KAT_FF;
       flags = ITEM_BOW;
       material = MAT_WOOD;
       value = 35;
       damage[DAM_INDEX_BARRIER] = 13;
       damagetype = DAM_POINT;
       munition = ItAmArrow;
       visual = "ItRwLongbow.mms";
};

instance XP_Map(C_Item)
{
       name = "Mappa XP";
       mainflag = ITEM_KAT_DOCS;
       flags = 0;
       value = 1000;
       visual = "ItWr_Map_01.3ds";
       material = MAT_LEATHER;
       scemeName = "MAP";
       on_state[0] = Use_XP_Map;
};


func void Use_XP_Map()
{
       CreateInvItems(self,ItMiNugget,1000);
       hero.lp = hero.lp + 20;
       PrintScreen("Erz +1000",-1,40,"font_10_book.tga",10);
};


Tra l'altro vedo che non hai cambiato la texture. Se vuoi ricorda che è il numero dopo "hum_head_bold" che devi modificare con quello che vedi nel nome della texture
view post Posted: 8/7/2016, 18:12     +1Cambiare aspetto eroe Gothic 1 - Gothic
Non è che non serve a nulla, ma secondo me, che posso dire di avere un bel po' di esperienza nel modding di gothic, non è necessario.

Comunque si. Se cambi la mesh pony tutti i personaggi col codino ne saranno affetti purtroppo.

Allora ti dico prima i passaggi, poi se non funziona lo faccio io. Considera inoltre che visto che stiamo andando a modificare gli script non è più necessario fare alcuna modifica a mesh e texture.

Scarica gli script da qui "il supporto da me organizzato" -> "italian advanced modkit".
Scarica GothicSourcer 3.15 da qui, basta che clicchi su gothicsourcer_V3.15.7z ma ti servirà 7zip per estrarlo (programma che consiglio sempre di usare al posto di roba come WinRar o peggio WinZip).

Estrai tutto e apri gothic sourcer. Vai su file -> open solution -> e seleziona il file "G2 Italian Correct Scripts.gsc" che trovi dentro la certella SolG2 dell'archivio.
Dagli tempo che carichi, e poi vedrai delle voci sulla sinistra. Clicca col destro su GOTHIC e poi fai "set as active project"; questo perché gothic sourcer può compilare solo un file alla volta e tutte quelle voci sono diversi file decompilati che gestiscono cose diverse.

Apri il menu a tendina della voce gothic e apri il file Story -> Npc -> PC_Hero.d. Questo è il file dell'eroe. Ora senza chiuderlo apri il file AI -> AI_Intern -> AI_Constant.d. Segnati la mesh che vuoi utilizzare che avrà un nome tipo hum_head_xxx.mmb, e la texture che avrà un nome tipo Hum_Head_Vxxx_C0-C.tex.

Ora guarda la riga che contiene la funzione Mdl_SetVisualBody

CODICE
Mdl_SetVisualBody(self,"hum_body_Naked0",9,0,"Hum_Head_Pony",Face_N_Player,0,NO_ARMOR);


Invece di "Hum_Head_Pony" metti il nome della mesh che vuoi senza l'estensione. Per Face_N_Player devi andare su AI_Constant, scorrere in basso dove vedrai tutte le varie constanti del tipo "Face_xxx" assegnate ad un numero; li devi copiare quella relativa al numero che hai visto sulla texture (per esempio Hum_Head_V124_C0-C.tex devi prendere Face_L_ToughBart_Quentin che corrisponde a 124) e copiarla al posto di Face_N_Player.

Fatto ciò, SALVA, e accanto alla scritta Gothic 2 nel menu vedrai tre pulsanti. Clicca su quello con la freccetta verso il basso, nel dubbio scorrici sopra con il cursore e clicca su quello che dice compile.
Per vedere il processo di compilazione (se funziona, o se da degli errori), clicca sui punti interrogativi più in basso, che apriranno una finestrella. Lascia che finisca, e se da 0 errors vuol dire che tutto è andato bene.
Dentro la cartella troverai un file chiamato gothic.dat che dovrai sostituire a quello originale che sta in _work/data/scripts/_compiled

Dimmi come va
view post Posted: 8/7/2016, 14:08     +1Cambiare aspetto eroe Gothic 1 - Gothic
Il problema è che la texture della faccie dell'eroe è usata solo da lui, ma la mesh della testa no. Quindi cambieresti anche la mesh di molto altri png. Ti sta bene così?

Tra l'altro mi sembra eccessivo estrarre tutti i volumi se non sai quello che stai facendo :/ Se ti va bene quanto scritto sopra bene, alrimento vedo. Magari te lo faccio io al volo e ti mando il file, perché richiede anche la modifica degli script
view post Posted: 22/2/2016, 09:26     +1Nuovo Set di armature per Gothic 2: Idee?? - Modding Gothic saga
Per mod grafica intendo una mod che modifica solo mesh e textures, o al più i mondi.

Comunque buon lavoro allora :1202225063py8.gif: :1202225063py8.gif: Se ti serve una mano per lo scripting chiedi pure
view post Posted: 18/2/2016, 18:54     +1Frasi di Gothic - Sondaggi gotici e Fatti strani
"I'll never get this open without the right key...", che quando ero più piccolo non riuscivo proprio a capire che dicesse XD
view post Posted: 3/8/2015, 18:00     +3Italian Final Patch - Gothic II & La Notte del Corvo
Uff, che faticaccia ragazzi, dopo aver visto l'andazzo e la quantità di tempo a mia disposizione (almeno quest'estate) ho capito che da solo non ce la farò mai :P
So essere abbastanza veloce per quanto riguarda gli script ma quando si tratta di modellazzione o affini ci metto un casino di tempo.
Per questo chiedo a voi gentilmente di darmi una mano un po' più pratica quando volete e quando avete tempo (tanto non c'è fretta :D). In particolare mi servirebbe:

1) uno con idee originali e che abbia giocato a gothic molte volte da conoscere bene il bilanciamento originale ed eventualmente modificarlo. Non dovrete utilizzare nessun programma speciale, perché il buon vecchio frank ha preparato un foglio di calcolo ben formattato solo per voi, poi penserò io a rendere effettive le modifiche. In questo file ci sarà infatti una pagina con tutti i mostri, una con armature ed elmi ed una le armi. Di tutto ciò ci saranno oggetti originali e nuovi di cui le mesh sono state create dal buon mr.slash che ha fatto un lavorone, e selezionate da me. Serve avere un'ottima visione di gioco e originalità perché tutto ciò che vi passerà in mente e scriverete lì io farò, effetti delle armi (intendo proprio effetti speciali tipo quello dell'artiglio), dei mostri, statistiche, insomma tutto quello che volete. In più se vedrete qualcosa qui che vi piace e volete aggiungere, avrete carta bianca per decidere le statistiche, effetti speciali, e come trovarlo, basta che me lo sappiate indicare precisamente; eccetto per le texture ed armature che dovranno passare prima da me :D
Chiunque voglia provare, o almeno vedere prima cosa ho preparato per voi qui potrete scaricare il file (se ecel non lo legge vi servirà openoffice ma spero che nel 2015 ce lo avete :D)

2) uno a cui piaccia ristilizzare il mondo; mi spiego. Come sapete sono partito come base dalla mod di vurt e non dalla l'hiver per diversi motivi. Tuttavia, ammetto che molte cose della l'hiver erano nettamente superiori a quelle di vurt, in particolare gli interni e la città. Così ho preso in prestito alcune cose da quella mod e aggiunte pazientemente alla mia. La casa di vatras o la taverna al porto per esempio. In più ho importato qualche vob e in futuro aggiungerò almeno un dungeon (nuovo). Dunque mi servirebbe uno che ha voglia di aggiungere vob quà e là per la città e in futuro in un dungeon. Ovviamente dico quà e là ma non intendo a caso :D A chi si offrirà farò vedere cosa ho aggiunto come esempio, insegnerò a muoversi e ad aggiungere semplici vob tramite lo spacer. Per ora è un lavoro che non richiede molto tempo visto che ho aggiunto veramente poche cose. Però ecco non sono mai stato una cima in arredamento di interni quindi se qualcuno volesse sarebbe ben gradito, perché questo è ciò che mi prende l'85% del tempo. Purtroppo chi vuole provare questo lo potrà fare ma a fine agosto perché domani parto e non posso mandargli tutti i file che gli servirebbero.


Grazie mille a chiunque voglia dare una piccola mano, io da solo non ce la faccio più :(

Edited by Frank-95 - 8/8/2015, 18:37
view post Posted: 23/4/2015, 14:32     +1Italian Final Patch - Gothic II & La Notte del Corvo
Se non superano i 10 MB direi che si può fare allora ;)

Comunque ho finito il migliora armatura e tunica, ora ne sto facendo un altro.

La questione che mi preme di più invece è la questione del combattimento per la quale vorrei la vostra opinione.

Io ora sono in possesso di 6 nuove animazioni da combattimento: due per gli scudi, due per le armi ad una mano e due per le armi a due mani. In totale avremmo quindi:

- Combattimento base
- Combattimento ad una mano migliorato 1° livello (originale)
- Combattimento ad una mano migliorato 2° livello (originale)
- Combattimento a due mani migliorato 1° livello (originale)
- Combattimento a due mani migliorato 2° livello (originale)
- Combattimento ad una mano utilizzabile solo per fioretti 1° livello (o armi che richiedono destrezza poiché nell'animazione tiene la spada davanti come nella scherma)
- Combattimento ad una mano utilizzabile solo per fioretti 2° livello (come sopra)
- Combattimento a due mani migliorato 1° livello (coattissimo ed utilizzabile per qualsiasi tipo di armi a due mani)
- Combattimento a due mani migliorato 2° livello (come sopra)
- Combattimento con lo scudo 1° livello
- Combattimento con lo scudo 2° livello

Ora la mia idea era creare delle sorte di specializzazioni di combattimento che ti danno animazioni ed effetti aggiuntivi sui critici.
Per esempio io avrei voluto mantenere l'animazione di base di combattimento finché non si sceglie una specializzazione a prescindere dalla percentuale di critico che sarà comunque necessaria per specializzarsi.
Inoltre, finché non ti specializzi il critico invece di essere 10x (originale) sarà solo, diciamo, 5x. A seconda della specializzazione avrei voluto poi aggiungere effetti aggiuntivi.
Le specializzazioni a cui avevo pensato erano:
- Scudo (per le armi ad una mano)
- Fioretti (armi che richiedono destrezza, SENZA scudo)
- Spade a due mani
- Asce a due mani
- Mazze a due mani

Lo scudo vabbe da protezione aggiuntiva, e magari il critico aumenta da 5 a 6/7
Per il fioretto aumenterei parecchio il critico, da 5 a 10, e magari aggiungerei una sorta di "penetrazione armatura" cioè che gli diminuisce LEGGERMENTE l'armatura per il combattimento
Per le mazze pesanti, volevo aumentare poco il critico, da 5 a 6, e aggiungere un effetto "stun", cioè che ti buttano a terra.
Per le spade e asce pesanti invece, devo decidere, comunque pensavo un aumento discreto del critico, da 5 a 7/8, e un effetto di sanquinamento, cioè di perdita continua della vita.
Inoltre il danno base delle armi a due mani sarà più ingente ma l'animazione più lenta. Che ne dite?

Proposte?
view post Posted: 23/3/2015, 10:08     +1Italian Final Patch - Gothic II & La Notte del Corvo
Comunque per tutti quanti vi svelo in anteprima qualcosa sulla nuova versione.

1) Menu stile G3

2) Nuove animazioni

3) Scudi

4) Completamente integrata con la mod di vurt

5) Avvelenamento ed indebolimento dai mostri

6) Nuovi talenti

7) Probabilmente nuove armi/armi magiche

8) Nuovo sistema di colpi critici

;)
view post Posted: 25/2/2015, 13:09     +1[Tutorial] Classi C_NPC e C_ITEM in dettaglio - Gothic II & La Notte del Corvo
Ciao a tutti. Questo sarà un'appendice in cui spiegherò più dettagliatamente le proprietà delle classi e i possibili valori, cosa che non potevo fare senza dilungarmi troppo nelle lezioni specifiche.
Esse infatti servono per capire quali proprietà sono necessarie per mostri e umani, qui vediamo invece tutti i possibili valori.

C_NPC

CODICE
class C_Npc
{
       var int id;
       var string name[5];
       var string slot;
       var string effect;
       var int npcType;
       var int flags;
       var int attribute[ATR_INDEX_MAX];
       var int HitChance[MAX_HITCHANCE];
       var int protection[PROT_INDEX_MAX];
       var int damage[DAM_INDEX_MAX];
       var int damagetype;
       var int guild;
       var int level;
       var func mission[5];
       var int fight_tactic;
       var int weapon;
       var int voice;
       var int voicePitch;
       var int bodymass;
       var func daily_routine;
       var func start_aistate;
       var string spawnPoint;
       var int spawnDelay;
       var int senses;
       var int senses_range;
       var int aivar[100];
       var string wp;
       var int exp;
       var int exp_next;
       var int lp;
       var int bodyStateInterruptableOverride;
       var int noFocus;
};


id: identificativo ASSOLUTO degli npc. Potete inserire un qualsiasi numero che non sia ripetuto ma è buona norma seguire delle norme: Ogni gilda infatti ha gli identificati che aumentano di uno da un numero iniziale (900 per contadini, 1000 per banditi, ecc..). Uno stesso personaggio presente in più mondi possiede classi diverse per ogni mondo o l'id è lo stesso ma moltiplato per 10 (con uno zero in più alla fine).

name[5]: l'unica posizione dell'array utilizzata è name[0]. Questa indica il nome che comparirà sul personaggio

slot: non usata

effect: non usata

npcType: indica il tipo di npc (generico = senza nome con dialogo standard; principale: con nome e dialoghi personalizzati)

    • NPCTYPE_AMBIENT: personaggio generico

    • NPCTYPE_MAIN: personaggio principale

    • NPCTYPE_FRIEND: amico

    • da qui in poi ci sono diverse eccezioni

    • NPCTYPE_OCAMBIENT: personaggio generico di campo vecchio

    • NPCTYPE_OCMAIN: personaggio principale di campo vecchio

    • NPCTYPE_BL_AMBIENT: personaggio generico dentro il campo dei banditi a jharkendar

    • NPCTYPE_TAL_AMBIENT: personaggio generico fuori dal campo dei banditi a jharkendar

    • NPCTYPE_BL_MAIN: personaggio principale dentro il campo dei banditi a jharkendar


flags: proprietà speciali degli npc

    • NPC_FLAG_FRIEND: amico

    • NPC_FLAG_IMMORTAL: personaggio immortale

    • NPC_FLAG_GHOST: fantasma


attribute[ATR_INDEX_MAX]: attributi degli npc

    • ATR_HITPOINTS: vita attuale

    • ATR_HITPOINTS_MAX: vita massima

    • ATR_MANA: mana

    • ATR_MANA_MAX: mana massimo

    • ATR_STRENGTH: forza

    • ATR_DEXTERITY: destrezza

    • ATR_REGENERATEHP: rigenerazione vita al secondo (non usato)

    • ATR_REGENERATEMANA: rigenerazione mana al secondo (non usato)


HitChance[MAX_HITCHANCE]: possibilità di critico e di centrare il bersaglio

    • NPC_TALENT_UNKNOWN: non usato

    • NPC_TALENT_1H: percentuale di critico ad una mano

    • NPC_TALENT_2H: percentuale di critico a due mani

    • NPC_TALENT_BOW: percentuale di prendere il persaglio con l'arco (dipende anche dalla distanza)

    • NPC_TALENT_CROSSBOW: percentuale di prendere il persaglio con la balestra (dipende anche dalla distanza)


protection: varie protezioni

    • PROT_BARRIER: protezione dalla barriera suppongo, non usato

    • PROT_BLUNT: protezione da colpi contundenti

    • PROT_EDGE: protezione da armi da taglio

    • PROT_FIRE: protezione dal fuoco

    • PROT_FLY: protezione dai colpi che ti fanno volare (golem, troll, ecc..)

    • PROT_MAGIC: protezione dalla magia

    • PROT_POINT: protezione da frecce e dardi

    • PROT_FALL: protezione da caduta


damage: danno di una specifica tipologia di colpi (ne possono essere usati più d'uno se il danno viene da diverse fonti contemporaneamente)

    • DAM_INDEX_BARRIER: danni dalla barriera suppongo, non usato

    • DAM_INDEX_BLUNT: danni da colpi contundenti

    • DAM_INDEX_EDGE: danni da armi da taglio

    • DAM_INDEX_FIRE: danni dal fuoco

    • DAM_INDEX_FLY: danni dai colpi che ti fanno volare (golem, troll, ecc..)

    • DAM_INDEX_MAGIC: danni dalla magia

    • DAM_INDEX_POINT: danni da frecce e dardi

    • DAM_INDEX_FALL: danni da caduta


damageType: il tipo di danno applicato se non si utilizzano armi (possono essere applicate più tipologie per volta utilizzando l'unione |)

    • DAM_BARRIER: danni dalla barriera suppongo, non usato

    • DAM_BLUNT: danni da colpi contundenti

    • DAM_EDGE: danni da armi da taglio

    • DAM_FIRE: danni dal fuoco

    • DAM_FLY: danni dai colpi che ti fanno volare (golem, troll, ecc..)

    • DAM_MAGIC: danni dalla magia

    • DAM_POINT: danni da frecce e dardi

    • DAM_FALL: danni da caduta


guild: gilda di appartenenza (con ciò non viene conclusa la lista di mostri perché come noterete alcuni hanno la stessa gilda ma diverso aivar)

    • GIL_NONE: nessuna gilda

    • GIL_HUMAN: gilda speciale, usata SOLO nel file Species.d per impostare gli stessi valori a tutti gli umani

    • GIL_PAL: paladini

    • GIL_MIL: miliziani

    • GIL_VLK: cittadini

    • GIL_KDF: maghi del fuoco

    • GIL_NOV: novizi

    • GIL_DJG: cacciatori di draghi

    • GIL_SLD: mercenari

    • GIL_BAU: contadino

    • GIL_BDT: banditi

    • GIL_STRF: schiavi

    • GIL_DMT: cercatori

    • GIL_OUT: per chi è fuori dalle zone principali

    • GIL_PIR: pirati

    • GIL_KDW: maghi dell'acqua

    • GIL_EMPTY_D: vuota

    • GIL_PUBLIC: utilizzata solo nei portali (cambi di zone esterna/interna) per delimitare le zone pubbliche

    • GIL_SEPERATOR_HUM: classe utilizzata dall'IA per delimitare tutte le gilde umane e non

    • GIL_MEATBUG: scarafaggi

    • GIL_SHEEP: pecore

    • GIL_GOBBO: goblin

    • GIL_GOBBO_SKELETON: goblin scheletri

    • GIL_SUMMONED_GOBBO_SKELETON: goblin scheletri evocati

    • GIL_SCAVENGER: saprofagi

    • GIL_GIANT_RAT: ratti giganti

    • GIL_GIANT_BUG: raziatori dei campi

    • GIL_BLOODFLY: sanguimosche

    • GIL_WARAN: lucertole

    • GIL_WOLF: lupi

    • GIL_SUMMONED_WOLF: lupi evocati

    • GIL_MINECRAWLER: scavaragni

    • GIL_LURKER: predatori

    • GIL_SKELETON: scheletri

    • GIL_SUMMONED_SKELETON: scheletri evocati

    • GIL_SKELETON_MAGE: scheletri maghi

    • GIL_ZOMBIE: zombie

    • GIL_SNAPPER: squartatori

    • GIL_SHADOWBEAST: bestie d'ombra

    • GIL_SHADOWBEAST_SKELETON: bestie d'ombra non-morte

    • GIL_HARPY: arpie

    • GIL_STONEGOLEM: golem di pietra

    • GIL_FIREGOLEM: golem di fuoco

    • GIL_ICEGOLEM: golem di ghiaccio

    • GIL_SUMMONED_GOLEM: golem evocati

    • GIL_DEMON: demoni

    • GIL_SUMMONED_DEMON: demoni evocati

    • GIL_TROLL: troll

    • GIL_SWAMPSHARK: squali di palude

    • GIL_DRAGON: draghi

    • GIL_MOLERAT: ratti talpa

    • GIL_ALLIGATOR: alligatori

    • GIL_SWAMPGOLEM: golem di palude

    • GIL_STONEGUARDIAN: sentinella di pietra

    • GIL_GARGOYLE: pantera

    • GIL_EMPTY_A: vuota

    • GIL_SUMMONEDGUARDIAN: sentinella di pietra evocata

    • GIL_SUMMONEDZOMBIE: zombie evocato

    • GIL_EMPTY_B: vuota

    • GIL_SEPERATOR_ORC: classe utilizzata dall'IA per separare le gilde di mostri e di orchi

    • GIL_ORC: orchi

    • GIL_FRIENDLY_ORC: orchi amichevoli

    • GIL_UNDEADORC: orchi non morti

    • GIL_DRACONIAN: uomini lucertola

    • GIL_EMPTY_X: vuota

    • GIL_EMPTY_Y: vuota

    • GIL_EMPTY_Z: vuota


level: livello del npc

mission[MAX_MISSIONS]: non usato

fight_tactic: tattiche di combattimento (i nomi sono gli stessi delle gilde)

    • FAI_HUMAN_COWARD

    • FAI_HUMAN_NORMAL

    • FAI_HUMAN_STRONG

    • FAI_HUMAN_MASTER

    • FAI_MONSTER_COWARD: i mostri "giovani" all'inizio del gioco

    • FAI_NAILED: deprecata usata per umani. Usare invece FAI_HUMAN_XXX

    • FAI_GOBBO

    • FAI_SCAVENGER

    • FAI_GIANT_RAT

    • FAI_GIANT_BUG

    • FAI_BLOODFLY

    • FAI_WARAN

    • FAI_WOLF

    • FAI_MINECRAWLER

    • FAI_LURKER

    • FAI_ZOMBIE

    • FAI_SNAPPER

    • FAI_SHODOWBEAST

    • FAI_HARPY

    • FAI_STONEGOLEM

    • FAI_DEMON

    • FAI_TROLL

    • FAI_SWAMPSHARK

    • FAI_DRAGON

    • FAI_MOLERAT

    • FAI_ORC

    • FAI_DRACONIAN

    • FAI_ALLIGATOR

    • FAI_GARGOYLE

    • FAI_BEAR: ???????

    • FAI_STONEGUARDIAN


weapon: non usata

voice: la voce degli npc durante i dialoghi generici non sottotitolati. Ci 17 voci disponibili tranne la 15 che è dell'eroe

voicePitch: non usata

bodymass: non usata

daily_routine: routine giornaliera (quelle con l'asterisco richiedono un mob)

    • TA_Announce_Herold: lettura del discorso dal patibolo

    • TA_Cook_Cauldron*: cucinare col calderone

    • TA_Cook_Pan*: cucinare con la padella

    • TA_Dance: ballare

    • TA_FleeToWp: scappare verso un waypoint

    • TA_Follow_Player: seguire il giocatore

    • TA_Guard_Passage: fare le guardia agli ingressi

    • TA_Guide_Player: guidare il giocatore

    • TA_Pee: fare pipì

    • TA_Pick_FP: scavare per terra col piccone

    • TA_Pick_Ore: estrarre il metallo dai giacimenti

    • TA_Play_Lute: suonare il liuto

    • TA_Potion_Alchemy*: miscelare pozioni

    • TA_Practice_Magic: fare pratica di magia

    • TA_Pratice_Sword: fare pratica con la spada

    • TA_Pray_Sleeper_FP: pregare il dormiente

    • TA_Pray_Sleeper*: pregare il dormiente

    • TA_Pray_Innos_FP: pregare innos

    • TA_Pray_Innos*: pregare innos

    • TA_Preach_Vatras: omelia di vatras

    • TA_Read_Bookstand*: leggere un libro

    • TA_Repair_Hut: riparare il rifugio

    • TA_Roast_Scavenger: arrostire il saprofago

    • TA_RunToWP: correre verso un waypoint

    • TA_Sit_Bench*: sedersi su una panchina

    • TA_Sit_Campfire: sedersi attorno al fuoco

    • TA_Sit_Chair*: sedersi su una sedia

    • TA_Sit_Throne*: sedersi sul trono

    • TA_Sleep*: dormire

    • TA_Smalltalk: chiacchierata

    • TA_Smith_Anvil*: battere il metallo sull'incudine

    • TA_Smith_Cool*: raffredare il metallo nell'acqua

    • TA_Smith_Fire*: riscaldare il metallo nella forgia

    • TA_Smith_Sharp*: affilare il metallo sulla pietra

    • TA_Smoke_Joint: fumarsi una canna

    • TA_Smoke_Waterpipe*: fumare il narghilè

    • TA_Spit_Fire: ???

    • TA_Stand_ArmsCrossed: stare in piedi a braccia incrociate

    • TA_Stand_Drinking: stare in piedi a bere

    • TA_Stand_Eating: stare in piedi mangiando

    • TA_Stand_Guarding: stare in piede a fare la guardia

    • TA_Stand_WP: stare in piedi

    • TA_Stomp_Herb*: tritare le erbe nel calderone

    • TA_Sweep_FP: pulire con la scopa

    • TA_Wash_FP: lavare per terra

    • TA_Stand_Sweeping: pulire con la scopa

    • TA_Rake_FP: usare la vanga nei campi

    • TA_Cook_Stove: cucinare ai fornelli

    • TA_Saw*: segare

    • TA_Circle: rituale dei maghi

    • TA_Stand_Dementor: cercatori in piedi

    • TA_Guard_Hammer: fare la guardia al martello di innos

    • TA_Study_WP*: studiare

    • TA_Concert: concerto

    • TA_Sleep_Deep: dormire profondamente

    • TA_RangerMeeting: incontro dell'anello dell'acqua

    • TA_Ghost: fantasma in piedi

    • TA_GhostWusel: fantasma che vaga


start_aistate: stato di partenza. Non usato in genere per gli umani tranne per banditi (ZS_Bandit), e cercatori (ZS_Stand_Dementor), usare quindi solo in questi casi. Per i mostri viene usato generalmente ZS_MM_AllScheduler

spawnPoint: non usata

spawnDelay: non usata

senses: i sensi con i quali gli npc percepiscono altri (se ne possono utilizzare più d'uno con l'unione |)

    • SENSE_SEE: vista

    • SENSE_HEAR: udito

    • SENSE_SMELL: olfatto


senses_range: l'ampiezza dei sensi

    • PERC_DIST_SUMMONED_ACTIVE_MAX: per i mostri evocati

    • PERC_DIST_MONSTER_ACTIVE_MAX: per tutti gli altri mostri

    • PERC_DIST_ORC_ACTIVE_MAX: per gli orchi

    • PERC_DIST_DRAGON_ACTIVE_MAX: per i draghi


aivar[100]: variabili dell'IA tenute in un array. Non posso elencarvele tutte perché sono 89 e molte di queste hanno tanti valori possibili diversi. Sono tutte contenute in AI_Contasts con il prefisso AIV_

exp: l'attuale esperienza

exp_next: l'esperienza per passare di livello. Nel file B_GivePlayerXP, nell'omonia funzioen troverete la formula per calcolarla

lp: gli lp attuali

bodyStateInterruptableOverride: se è impostato su vero l'npc non può essere interrotto in nessun caso

noFocus: se è impostato su vero non compariranno il nome e la vita dell'npc al focus


Passiamo ora gli oggetti:

C_ITEM


CODICE
class C_Item
{
       var int id;
       var string name;
       var string nameID;
       var int hp;
       var int hp_max;
       var int mainflag;
       var int flags;
       var int weight;
       var int value;
       var int damagetype;
       var int damageTotal;
       var int damage[DAM_INDEX_MAX];
       var int wear;
       var int protection[PROT_INDEX_MAX];
       var int nutrition;
       var int cond_atr[3];
       var int cond_value[3];
       var int change_atr[3];
       var int change_value[3];
       var func magic;
       var func on_equip;
       var func on_unequip;
       var func on_state[4];
       var func owner;
       var int ownerGuild;
       var int disguiseGuild;
       var string visual;
       var string visual_change;
       var string effect;
       var int visual_skin;
       var string scemeName;
       var int material;
       var int munition;
       var int spell;
       var int range;
       var int mag_circle;
       var string description;
       var string text[6];
       var int count[6];
       var int inv_zbias;
       var int inv_rotx;
       var int inv_roty;
       var int inv_rotz;
       var int inv_animate;
};


id: non usato per gli oggetti

name: il nome dell'oggetto (apparirà al focus)

nameID: non usato

hp: non usato

hp_max: non usato

mainflag: la tipologia principale principali dell'oggetto

    • ITEM_KAT_NONE: varie

    • ITEM_KAT_NF: armi corpo a corpo

    • ITEM_KAT_FF: armi a distanza

    • ITEM_KAT_MUN: munizioni

    • ITEM_KAT_ARMOR: armature

    • ITEM_KAT_FOOD: cibo

    • ITEM_KAT_DOCS: documenti

    • ITEM_KAT_POTIONS: pozioni

    • ITEM_KAT_LIGHT: sorgenti luminose???

    • ITEM_KAT_RUNE: rune

    • ITEM_KAT_MAGIC: anelli, amuleti e cinture

    • ITEM_KAT_KEYS: non usato (usare ITEM_KAT_NONE per le chiavi)


flags: attributi secndari dell'oggetto

    • ITEM_DAG: obsoleto!

    • ITEM_SWD: spade ad una mano

    • ITEM_AXE: asce ad una mano

    • ITEM_2HD_SWD: spade a due mani

    • ITEM_2HD_AXE: asce a due mani

    • ITEM_SHIELD: scudi (non usato)

    • ITEM_BOW: archi

    • ITEM_CROSSBOW: balestre

    • ITEM_RING: anelli

    • ITEM_AMULET: amuleti

    • ITEM_BELT: cinture

    • ITEM_DROPPED: oggetti caduti a terra (INTERNO NON UTILIZZARE!)

    • ITEM_MISSION: oggetti di missione; se un npc che ha un oggetto avente questa flag, dovesse morire, il corpo non scomparirà per non precludere il completamento della missione

    • ITEM_MULTI: impilabile (più d'uno nello stesso slot)

    • ITEM_NFOCUS: INTERNO NON UTILIZZARE!

    • ITEM_CREATEAMMO: crea munizione automaticamente (non usato)

    • ITEM_NSPLIT: non impilabile nello stesso slot

    • ITEM_DRINK: obsoleto!

    • ITEM_TORCH: torcia

    • ITEM_THROW: obsoleto!

    • ITEM_ACTIVE: INTERNO NON UTILIZZARE!


weight: non usato

value: valore in oro

damageType: il tipo di danno applicato se non si utilizzano armi

    • DAM_BARRIER

    • DAM_BLUNT

    • DAM_EDGE

    • DAM_FIRE

    • DAM_FLY

    • DAM_MAGIC

    • DAM_POINT

    • DAM_FALL


damageTotal: il danno total dell'arma

damage: danno di una specifica tipologia di colpi (ne possono essere usati più d'uno se il danno viene da diverse fonti contemporaneamente)

    • DAM_INDEX_BARRIER

    • DAM_INDEX_BLUNT

    • DAM_INDEX_EDGE

    • DAM_INDEX_FIRE

    • DAM_INDEX_FLY

    • DAM_INDEX_MAGIC

    • DAM_INDEX_POINT

    • DAM_INDEX_FALL


wear: l'effetto che si avrà indossando l'oggetto

    • WEAR_TORSO: per le armature

    • WEAR_HEAD: per gli elmi

    • WEAR_EFFECT: per tutti gli altri oggetti equipaggiabili NON ARMI (anelli, cinture, amuleti, pergamene, ecc..)


protection: varie protezioni

    • PROT_BARRIER

    • PROT_BLUNT

    • PROT_EDGE

    • PROT_FIRE

    • PROT_FLY

    • PROT_MAGIC

    • PROT_POINT

    • PROT_FALL


nutrition: non usato

cond_atr[3]: array di tre elementi che indica gli attributi necessari per l'equippagiamento (se ne può usare uno slo come tutti e tre)

cond_value[3]: ad ogni elemento di cond_atr va specificato un valore

change_atr[3]: probabilmente il cambio di un attributo dopo l'equippaggiamento, non viene mai usato perché ciò avviene in altri modi, non testato!

change_value[3]: rispettivo aumento dell'attributi in change_atr

magic: non usato

on_equip: nome della funzione che viene chiamata all'equipaggiamento (usato anche per modificare gli attributi)

on_unequip: nome della funzione che viene chiamata al disequipaggiamento

on_state[4]: in genere viene utilizzato solo on_state[0], indica la funzione che viene chiamata ad ogni uso

owner: utilizzato solo nel caso del martello sacro indica il possessore dell'oggetto

ownerGuild: indica la gilda posseditrice dell'oggetto (non usato)

disguiseGuild: probabilmente la gilda che rifiuta quell'ogggetto (non usato)

visual: la visuale 3D dell'oggetto, scrivere qui il nome del file .3ds non compilato

visual_change: la visuale 3D dell'armature indossata, scrivere qui il nome del file .asc non compilato

effect: l'effetto che verrà applicato sopra l'oggetto (qui una lista)

visual_skin: forse (???) se l'oggetto si vede sulla pelle, forse perché tale attributo è usato praticamente sempre ma sempre impostato su 0

scemeName: indica una stringa di riconoscimento dell'oggetto, vedere altri oggetti simili per l'utilizzo

material: indica il materiale dell'oggetto e quindi il suono che farà quando cadrà a terra

    • MAT_WOOD: legno

    • MAT_STONE: pietra

    • MAT_METAL: metallo

    • MAT_LEATHER: cuoio

    • MAT_CLAY: argilla

    • MAT_GLAS: vetro


munition: istanza delle munizioni per le armi a distanza

spell: indica l'incatesimo della pergamena o runa

range: l'ampiezza dell'arma

description: il nome che comparirà nell'inventario (in genere uguale a name)

text[ITM_TEXT_MAX] e count[ITM_TEXT_MAX]: rispettivamente stringa e valore per la descrizione dell'oggetto, ciò che comparirà quando passerete il cursore sopra l'oggetto nell'inventario; massimo 5 valori

inv_zbias: la lontananza della visuale dell'oggetto nell'inventario

inv_rotx e inv_roty e inv_rotxz: la rotazione sullo specifico asse della visuale dell'oggetto nell'inventario

inv_animate: rotazione dinamica della visuale dell'oggetto nell'inventario (non usata e mai testata)



Spero di essere stato abbastanza dettagliato, se avete domande chiedete pure.

Ciao :camberman.gif: :camberman.gif:

Torna all'indice delle lezioni



Edited by Frank-95 - 15/10/2015, 13:50
view post Posted: 23/2/2015, 14:28     +1[Tutorial] Assegnare texture alle mesh - Gothic II & La Notte del Corvo
Come al solito questa non sarà una lezione di grafica 3D né 2D, ma avrà como solo obbiettivo il modding. Il procedimento è assolutamente uguale sia per mesh, morphmesh o qualsiasi tipo di animazione. Provvederò all'inserimento di immagini in seguito, per ora lo manterrò solo scritto.

Allora prima di tutto dovrete avere il plugin krximpexp installato. Secondo poi dovrete avere la vostra mesh, (ma va? :D), DI QUALSIASI TIPO.

CONSIGLIO: consiglio di importare una mesh già esistente simile alla vostra così vi potete regolare bene per le proporzioni. Basta eliminarla alla fine. Per qaunto riguarda invece armi o animazioni, il consiglio è lo stesso ma molto più raccomandato. Infatti qui dovrete tener da conto anche la direzione della mesh (a meno che volete tenere una spada dalla lama :D)

ATTENZIONE: Ciò che scriverò vale per il programma di editor di grafica 3D blender, tuttavia la logica è uguale anche per altri programmi, cambia solo il procedimento.

Allora una volta che è pronta il vostro modello dovete scomporlo in "materiali". Cioè assegnare gruppi di poligoni a materiali diversi, ognuno dei quali è collegato ad una texture. In questo modo potrete gestire meglio il lavoro grafico. Per esempio la veste dei contadini è suddivisa in due materiali: uno per gli abiti e uno per la pelle. Oppure per i cercatori ne hanno uno per il vestito uno per la maschera (si anch'essa è una semplice texture 2D).
Una volta scelto come suddividere i poligoni in diversi materiali (e assegnati ovviamente), nella finestra delle texture dovrete una nuova texture di tipo "image or movie", e sotto dovete scrivere il nome della texture. Se già ce l'avete bene selezionatela, altrimenti selezionate un'immagine qualsiasi, cancellatene il nome e scrivete il nome della texture che creerete. L'importante è NON METTERE IL PERCORSO! Ci deve essere solo il nome del file tga! Per esempio itmeleerest.tga. Quindi dopo aver selezionato il file dovrete eliminare tutto il ciò che non sia il nome.

NOTA: se ciò vi aiuta gestire meglio il tutto potete mantenerlo fino al momento dell'esportazione. Prima di esportarlo però dovrete eliminarlo.

Una volta assegnate anche le texture, aprite un'altra finestra in modo che potete avere la 3D View e contemporaeamente l'UV Image editor. Selezionate i poligoni di un materiale per volta (cliccando sul materiale e poi select) e dovreste vedere nell'uv editor la loro visualizzazione 2D. Cercate di creare una visuale ordinata in modo che potrete (o chi per voi) lavorare meglio sulla texture. Il resto dipende da voi o da chi fa il lavoro grafico. Non sto qui ad insegnare come si modellano immagini 3D o 2D perché io stesso non sono pratico (giusto qualcosa di base), quindi spero che chi si cimenti in questo abbia già qualche esperienza. Un trucchetto comunque è esportare il layout dell'uv cliccando uvs -> export uv layout.


Ricordate, l'importante è esportare con il nome della texture senza percorso e in tga.

Nella prossima lezione ritorneremo agli script e vedremo invece come creare nuove missioni.

Ciao :camberman.gif: :camberman.gif:

Torna all'indice delle lezioni

view post Posted: 19/2/2015, 15:32     +1Gothic2 Modding Video Tutorial - G.M.I.C
A frank-95 production...

Vi presentiamo la prima lezione di modding formato video :D : youtube

I meriti del video vanno a diablo, mentre dei contenuti al sottoscritto.

Lasciate perdere la mia voce semi-albanese semi-rumena del video. Era l'unica rimasta :D

Edited by †DIABLO† - 6/6/2015, 15:13
view post Posted: 18/2/2015, 15:52     +1[Tutorial] Npc e dialoghi - Gothic II & La Notte del Corvo
Nella precedente lezione abbiamo introdotto le caratteristiche del linguaggio di scripting daedalus.

Ora passiamo al nostro primo atto di scripting pratico: la creazione di un npc e di un dialogo.

NOTA: per concludere con la creazione di un npc sarà necesessario utilizzare lo spacer. Alla fine di questa lezione coprirò MOLTO brevemente cosa vi serve sapere per ora. Per una trattazione più approfondita aspettare le lezioni successive.

Allora vediamo subito di iniziare con la creazione di un nuovo npc. Una volta che avete capito come si fa non solo potrete crearne di nuovi ma anche modificare quelli già esistenti. Bene, selezionate gothic come progetto attivo da gothic sourcer (se non l'avete già fatto, tasto destro -> set as active project), poi cliccate nuovament col destro sulla cartella npc -> new script file. PER ORA come nome metteteci quello che volete basta che lo fate finire con un .d. Vi comparirà poi una finestra che vi mostra tutti i file di gothic.dat dalla quale dovrete posizionare il vostro file. Dovete sapere infatti che i file non vengono compilati tutti contemporaneamente ma uno alla volta. Di conseguenza per poter utilizzare una determinata classe/funzione/variabile in un file questa deve essere già stata dichiarata nello stesso file o in un file PRECEDENTEMENTE compilato. Se ciò non avvenisse la compilazione terminerebbe con un errore. Voi quindi scorrete in basso e appena trovate le instanze degli npc (formate da trelettere_numeri_nomepersonaggio.d; non confondetevi con i dialoghi che iniziano con DIA!!), selezionatene una a caso e poi date ok. Questo dirà a gothic di compilare il vostro file dopo il file selezionato. Se spuntate invece il riquadro "insert before cursor", questo verrà compilato prima. Selezionatene uno a caso o in ordine alfabetico, come volete, e date ok. Ecco a voi il vostro primo file aggiunto a gothic.dat :D

Adesso vi ritroverete con un file vuoto. Ora, serve "riempirlo". Tenete aperto un qualsiasi altro file di un NPC come esempio e seguitemi:

CODICE
instance KDF_500_Pyrokar(Npc_Default)
{
       name[0] = "Pyrokar";
       guild = GIL_KDF;
       id = 500;
       voice = 11;
       flags = NPC_FLAG_IMMORTAL;
       npcType = npctype_main;
       B_SetAttributesToChapter(self,6);
       fight_tactic = FAI_HUMAN_STRONG;
       B_SetNpcVisual(self,MALE,"Hum_Head_Bald",Face_N_ImportantOld,BodyTex_N,ItAr_KDF_H);
       Mdl_SetModelFatness(self,1);
       Mdl_ApplyOverlayMds(self,"Humans_Mage.mds");
       B_GiveNpcTalents(self);
       B_SetFightSkills(self,30);
       daily_routine = Rtn_Start_500;
};


func void Rtn_Start_500()
{
       TA_Sit_Throne(8,0,23,0,"NW_MONASTERY_THRONE_01");
       TA_Sit_Throne(23,0,8,0,"NW_MONASTERY_THRONE_01");
};

func void Rtn_RitualInnosEyeRepair_500()
{
       TA_Stand_Guarding(8,0,23,0,"NW_TROLLAREA_RITUAL_02");
       TA_Stand_Guarding(23,0,8,0,"NW_TROLLAREA_RITUAL_02");
};

func void Rtn_RitualInnosEye_500()
{
       TA_Circle(8,0,23,0,"NW_TROLLAREA_RITUAL_02");
       TA_Circle(23,0,8,0,"NW_TROLLAREA_RITUAL_02");
};


Questa è la classe del buon vecchio pyrokar. Vediamo cosa significa riga per riga ciò che c'è scritto:

La prima riga contiene la definizione dell'istanza pyrokar, quindi il nome dell'istanza, e la classe madre (in questo caso il prototipo Npc_Default).
Dalla prima del blocco tra parentesi graffe inizia l'assegnazione di valori alle proprietà della classe.

Se andate a vedere di nuovo la classe originale C_NPC vedrete che name non è semplicemente una stringa ma un array di stringhe, quindi, in altre parole, una lista di stringhe, in questo caso di lunghezza 5. Non è chiaro il perché di ciò (noterete che non tutto quello che hanno fatto i Piranha Bytes ha senso), tuttavia a noi servirà soltanto la prima voce di questo array cioè name[0]. Il valore (tra virgolette per indicare una stringa), sarà il nome che comparirà sopra il personaggio e sopra i dialoghi.

guild invece è un intero. Nella classe constants.d ad ogni gilda è associato un numero. Non tratteremo per ora della creazione di nuove gilde, quindi dovete sceglierne una tra quelle già esistenti (milizia, paladini, mercenari, cacciatori di draghi, contadini, novizi, maghi, pirati, maghi dell'acqua, banditi). Andate a cercare in constants.d quella che vi serve. Se non appartiene a nessuna di queste c'è anche la possibilità di non attribuirne nessuna: GIL_NONE.

id corrisponde all'identificativo del npc. Deve essere UNIVOCO!! Gli unici a non avercelo unico nel gioco originale sono i personaggi di test (storyhelper, charachterhelper, ecc..) e l'eroe che hanno zero. Io però ho assegnato zero solo all'eroe e ai primi 9999, proprio per rimarcare l'univocità ed evitare errori. Ogni gilda ha un id identificativo che aumenta gradualmente. Osservate bene le altre istanze della gilda relativa al vostro personaggio, e scegliete di conseguenza un numero maggiore.

Ora possiamo quindi dare un nome decente alla nostra classe. Le classi degli npc sono infatti date da: GILDA_ID_NOME. E così dovrete rinominare anche il vostro file. Cliccateci col destro nel menu a sinistra -> rename e dategli lo stesso nome terminato da .d.

Bene, vediamo il resto. voice indica la voce che avrà il personaggio, NON durante i dialoghi. Cioè quando impreca, e parla con altri di sottofondo. Cercate un personaggio simile al vostro e dategli lo stesso numero. Non date il numero 15 che è univoco dell'eroe!!

flags nella maggior parte dei casi qui ci sarà zero. Ma capita che così non è. Ci sono tre possibili flag definite sempre in constants.d: npc_flag_immortal, _friend, _ghost. Diciamo che le diciture sono abbastanza chiare, il primo lo rende immortale e viene usato per i personaggi senza i quali non riusciresti a finire il gioco, il secondo viene usato per gli amici (quindi lares, lee, diego, ecc..), il terzo per i fantasmi. Potete anche utilizzarli insieme. Come? Non con un +, ma con il simbolo di unione, per esempio NPC_FLAG_IMMORTAL | NPC_FLAG_FRIEND.

npcType indica il tipo di npc. Fondamentalmente si dividono in tre tipi: main, ambient e friend. Main sono tutti queli con i nomi, quelli che hanno dialoghi propri, ambient sono tutit quelli senza nome che hanno dialoghi "generici", per friend vale lo stesso discorso di flags. Cercate npctype in ai_constants (dentro la cartella ai_intern) e vedete tutti i vari tipi. I numeri dal 3 al 7 indicano semplicemente che: ocmain/ambient sta a campo vecchio, bl_main/ambient, sta DENTRO il campo dei banditi, bl_ambient sta FUORI il campo dei banditi. Siccome penso che voi vogliate inserire personaggi principali alla fine quelli che più userete è npctype_main nel relativo ambiente.

B_SetAttributesToChapter è una funzione che serve ad assegnare valori standard agli attributi dei personaggi. self indica che verranno assegnati all'istanza in cui è chiamata la funzione, e 6 indica che gli verranno assegnati i valori più alti. La funzione la troverete in npc_scripts se volete studiarla/modificarla.

fight_tactic indica che tipo di tattica di combattimento usa. Per gli umani ci sono coward, normal, strong e master.

B_SetNpcVisual crea la visuale del personaggio. I parametri sono self (questo personaggio), il sesso (male, female), la mesh della testa (vedere dentro anims.vdf per i nomi o cercare dentro altre instanze per quello che vi serve) come stringa, la texture della testa (dentro ai_constants vi sono tutte le possibilità, che potete anche vedere da goman aprendo il file textures.vdf), la texture del corpo (lasciate quella standard visto che porterà comunque un vestito o un'armatura), l'ultima è l'instanza dell'armatura che potete vedere in it_Armor o in it_addon_armor).

Mdl_SetModelFatness indica la "stazza" del personaggio. Potete dargli un valore tra -6 e 6 a seconda di quanto lo volete scheletrico od obeso :D

Mdl_ApplyOverlayMds applica un overlay, cioè delle animazioni particolari che si sovrapporanno a quelle di base. Cercate dentro la cartella _work/data/anims/mds_overlay per tutte le possibilità.

B_GiveNpcTalents è una funzione standard che da semplicemente tutti i talenti tranne le acrobazie.

B_SetFightSkills imposta le abilità di combattimento al valore dato come parametro in percentuale. La funzione la trovate sempre in npc_script.

Arriviamo all'ultima, daily_routine. Indica appunto la routine giornaliera. Quella che chiamerete qui sarà quella di partenza, e la potete vedere sotto. Poi queste potranno essere cambiate tramite script. Il nome delle routine DEVE essere Rtn_Nomeroutine_IDpersonaggio. Nelle istruzioni a seguire dovrete impostare che tipo di routine sarà, chiamando la funzione corretta. Le routine le potete trovare in AI -> Human -> TA. I quattro parametri sono: ora inizio, minuto inizio, ora fine, minuto fine. Per indicare che farà tutto il giorno la stessa cosa dovrete inserirla due volte. La prima con l'orario che volete voi, la seconda con lo stesso orario con inizio e fine scambiati. Per esempio dalle 8 alle 22, e dalle 22 alle 8. Così create un ciclo infinito. Il quinto parametro indica il waypoint in cui eseguirete l'azione. A fine lezione una piccola appendice per trovare quello che vi serve.


Bene ora avete il vostro personaggio. Ma non lo troverete nel mondo, perché dovete ancora inserirlo. Aprite npc_globals e create un altra variabile di tipo c_npc col nome del vostro personaggio. Nella funzione B_InitNpcGlobals sotto, create infine la variabile del personaggio così: nomevariabile = Hlp_GetNpc(nomeinstanza). Prendete come modello gli altri!
Infine aprite il file startup. Lì troverete diverse funzioni che rappresentano diverse zone dei mondi. Non posso dirvi dove dovrete metterlo, dovrete capirlo dal nome. newworld significa khorinis, oldworld valle delle miniere, addonworld jharkendar e dragonisland irdorath. Poi ci sono delle sottozone in inglese ma potete benissimo capire più o meno a che zone corrispondono se ci avete mai giocato a gothic :D. Se avete dubbi su questo scrivete pure qui sotto :). Comunque una volta trovata la zona prendete come modello gli altri spawn e chiamate la funzione Wld_InsertNpc(NPC,"WAYPOINT"). Al posto di npc usate la variabile dichiarata in npc_globals e al posto di waypoint, o il waypoint della routine iniziale o uno di quelli standard (li troverete guardando gli altri npc in zona).
Bene ora avete il vostro npc nel gioco :D



Questo però sarà un npc piuttosto piatto poverino. Infatti non vi rivolgerà mai la parola. Creiamo quindi un piccolo dialogo anche per lui.
Create un nuovo file di dialogo in story -> dialoge e come nome DIA_nomeinstanza.d. Come al solito anche questo posizionatelo insieme agli altri dialoghi.

E prendiamo un esempio di dialogo (guarda caso pyrokar :D):

CODICE
instance DIA_Pyrokar_Hagen(C_Info)
{
       npc = KDF_500_Pyrokar;
       nr = 10;
       condition = DIA_Pyrokar_Hagen_Condition;
       information = DIA_Pyrokar_Hagen_Info;
       important = FALSE;
       permanent = FALSE;
       description = "Devo parlare con i paladini. È urgente.";
};


func int DIA_Pyrokar_Hagen_Condition()
{
       if(other.guild == GIL_NOV)
       {
               return TRUE;
       };
};

func void DIA_Pyrokar_Hagen_Info()
{
       AI_Output(other,self,"DIA_Pyrokar_Hagen_15_00");        //Devo parlare con i paladini. È una questione urgente.
       AI_Output(self,other,"DIA_Pyrokar_Hagen_11_01");        //Vuoi dirci come mai vuoi parlare con loro?
       AI_Output(other,self,"DIA_Pyrokar_Hagen_15_02");        //Ho un messaggio urgente da riferirgli.
       AI_Output(self,other,"DIA_Pyrokar_Hagen_11_03");        //E sarebbe?
       AI_Output(other,self,"DIA_Pyrokar_Hagen_15_04");        //Un esercito del male guidato dai draghi si sta radunando nella Valle delle Miniere! Dobbiamo fermarli prima che sia troppo tardi.
       AI_Output(self,other,"DIA_Pyrokar_Hagen_11_05");        //Mmmh. Dovremo valutare le tue parole, novizio. Quando sarà il momento, ti faremo sapere cos'ha deciso il nostro consiglio.
       AI_Output(self,other,"DIA_Pyrokar_Hagen_11_06");        //Nel frattempo faresti meglio a tornare ai tuoi compiti da novizio.
       if(Npc_KnowsInfo(other,DIA_Pyrokar_Auge))
       {
               AI_Output(self,other,"DIA_Pyrokar_ALL_11_07");        //Bene, non vogliamo trattenerti ulteriormente dal fare il tuo lavoro. Ora puoi andare.
               AI_StopProcessInfos(self);
       };
};


La prima è la vera e propria instanza di dialogo. Come vedete eredita infatti da C_INFO. La struttura del nome è DIA_NomePersonaggio_DescrizioneDialogo. Vediamo ora le sue proprietà:

npc indica ovviamente a quale personaggio appartiene il dialogo.

nr è un numero che indica la priorità del dialogo. Numeri più alti posizionano la scelta del dialogo più in alto. Non è assolutamente univoco, quindi ce ne possono essere più d'uno contemporaneamente con lo stesso numero, solo che in quel caso lasciate a gothic l'ordine ;)

condition indica la funzione che determina se il dialogo avverrà o meno

information indica la funzione contenente le stringhe di dialogo

permanent se vero (TRUE) indica che fintanto che ci sono le condizioni il dialogo potrà essere ripetuto

important se vero il dialogo viene iniziato dal npc e non dall'eroe

description indica la stringa che comparirà nelle opzioni di dialogo, da omettere se important è impostato su TRUE


Bene ora passiamo alla condizione di dialogo. È un funzione int cioè ritorna un intero. In daedalus infatti i valori booleani di vero e falso sono rappresentati da interi, 0 è falso, tutti gli altri numeri è vero. In questa funzione sarà presente una condizione if in cui starà a voi impostare la condizione necessaria. Questa è determinata in genere da variabili o stato di missione. Osservate altri dialoghi per capire meglio. Qui non avviene ma in realtà è buona norma fare in modo che la funzione ritorni sempre un valore. Qui per esempio ritorna vero se la gilda dell'eroe è quella dei novizi, ma non ritorna niente se non lo è. In questo caso sarebbe opportuno un ramo else che ritorna falso.

ATTENZIONE: state bene attenti alle condizioni! In quanto tantissimi bug nelle missioni derivano appunto da condizioni male impostate! Inoltre se impostate male le condizioni e nell'istanza di dialogo assegnate sia a important sia a permenent il valore vero, andrete incontro ad un dialogo infinito!!!


Infine arriviamo alla funzione di dialogo. Questa non dovrà ritornare alcun valore, quindi sarà di tipo void. La funzione che dovete chiamare per i dialoghi è AI_Output(PARLANTE,RICEVENTE,"NOMEDIALOGO"). Senza scomodarci ad utilizzare le instanze precise ce ne sono due che fanno al caso nostro: self e other. Sono due instanze variabili, che cambiano a seconda della situazione. Nei dialoghi self corrisponde al npc e other all'eroe. Quindi con AI_Output(self,other,..) parla l'npc viceversa l'eroe. Il nome del dialogo indica il file audio del doppiaggio. Anche se non ce lo avete però è buona norma inserirlo. La struttura è "Nomeistanzadialogo_voceparlante_numerocrescente". Cioè in questo caso il nome del dialogo è DIA_Pyrokar_Hagen, la voce di pyrokar è 11, quella dell'eroe è 15 e quindi a seconda di chi parla si mette l'uno o l'altro. L'ultimo è un numero crescente. Come si fa fa a mettere le stringhe di dialogo quindi? Beh, vedete quei commenti accanto? I commenti (a linea singola!!) accanto ad AI_Output sono gli unici che non vengono ignorati e vengono registrati nel file ou.bin!.
AI_StopProcessInfos(self) indica infine la fine del dialogo.


Bene spero di essere stato chiaro. Qui la questione non è difficile ma si tratta solo di tanta pratica per prendere domestichezza con le condizioni di dialogo e le proprietà degli npc.

Nella prossima lezione parlerò invece di mostri e oggetti.

Ciao :camberman.gif: :camberman.gif:

Torna all'indice delle lezioni



Edited by Frank-95 - 23/2/2015, 19:48
view post Posted: 17/2/2015, 17:51     +1[Tutorial] Daedalus e struttura di Gothic.dat Parte 2 - Gothic II & La Notte del Corvo
Questa è la conclusione della precedente lezione sull'introduzione a daedalus, il linguaggio di scripting di gothic.

Quindi, ricapitolando il post precedente le parole chiave (cioè che non possono essere usate in nessun altro contesto a parte quello originale e i commenti) sono:
CITAZIONE
class const else float func if

instance int prototype return

string var void

Bene, dopo aver quindi visto le parole chiave, e la sintassi generale di daedalus vediamo quali sono le operazioni built-in (native) di questo (debole) linguaggio. Per operazioni intendo quindi tra variabili e/o costanti:

Operatori di calcolo: +, -, *, /, % (addizione, sottrazione, moltiplicazione, divisione, modulo)

Operatori di comparazione: <, <=, >, >=, == , != (minore, minore o uguale, maggiore, maggiore o uguale, uguale*, diverso)

*questa non è un'uguaglianza di assegnazione, cioè assegno alla variabile x questo valore; ma una comparazione cioè controllare se una variabile/costante è uguale ad un altra

Tutti gli operatori di comparazione ritornano o vero o falso, e sono usati nelle condizione if-else.

Operatori booleani: !, &&, || (non, e, o)

Questi sono gli operatori booleani di cui vi parlai due lezioni fa. Anche questi ritornano o vero o falso.

Operatori di bit (insiemistici): &, | (e/intersezione, o/unione)

Questi operatori ritornano un intero che va inteso non come un semplice numero, ma come l'unione (in bit) dei due valori. Per esempio 3 | 4: immaginate due insiemi contenenti un singolo valore ciascuno, 3 e 4. L'unione tra questi due valori genera un insieme contenente entrambi. Questo in daedalus è registrato come un semplice altro numero intero. Su questo numero però possiamo fare altre operazioni insiemistiche. Per esempio molto banalmente se chiamiamiano il nuovo isieme a, a & 3 darà come risultato 3; perché l'intersezione di un insieme contenente 3 e 4 e un altro insieme contenente 3 è un insieme contenente solo il numero 3.

Vediamo ora qualche esempio pratico:

CODICE
var int a;
var int b;

a = 4;
b = 3;

Print(a + b);      //stampa a schermo il valore di a + b, cioè 7

if(a == 7)    //se a è uguale a 7, allora..
{
   Print("a è 7");
}
else    //Altrimenti..
{
   Print("a non è 7");
}
/* questa condizione stamperà "a non è 7", perché è in realtà 4 */

a *= b;

if(a == 12)    //se a è uguale a 12, allora..
{
   Print("a è 12");
}
else
{
   Print("a non è 12");
}
/* questa condizione stamperà "a  è 12", perché non solo abbiamo eseguito la moltiplicazione, ma abbiamo anche assegnato il valore ottenuto ad a scrivendo a *= b. Una scrittura equivalente è infatti a = a * b */

if((a == 12) && (b == 3))    //Se a è uguale a 12 E b è uguale a 3, allora
{
   Print("Corretto!");
}
else if(((a == 12) && (b != 3)) || ((a != 12) && (b == 3)))    //Altrimenti se a è uguale a 12 E b è diverso da 3, OPPURE a è diverso da 12 E b è uguale a 3, allora..
{
   Print("Uno dei due è giusto");
}
else //Altrimenti.. (cioè tutti e due diversi)
{
   Print("Entrambi sbagliati");
}
/*Notate bene qui come ho costruito le condizioni. In particolare guardate le parentesi del secondo punto. Funziona esattamente come nell'algebra: prima le parentesi più interne e via via quelle più esterne. Fate i "calcoli" con vero e falso utilizzando gli operatori booleani e controllate il risultato. Questo stamperà "corretto!" */

if !(a != 12)
{
   Print("corretto!");
}
/* Sorpresa, questo stamperà corretto! Perché? Perchè gli sto dicendo "se a NON è diverso da 12" (ergo è uguale a 12) "allora.." */


Come al solito una volta imparata come funziona la logica filerà tutto liscio come l'olio. Questo immagino possa essere l'argomento un po' più arduo quindi per qualsiasi dubbio scrivete pure qui sotto.


Passiamo oltre e per concludere vediamo un po' la struttura delle cartelle di gothic.dat. Per quanto riguarda i fini della compilazione non è importante dove posizionate i vostri file, tuttavia è utile mantenere la distinzione per una maggiore pulizia di codice.

  • _Intern: cartella contenenti file fondamentali per il corretto funzionamento di gioco. NON CAMBIATE NULLA IN CLASSES.D, e, se non sapete cosa state facendo, nemmeno in constants.d

  • _misk_: cartella a dir la verità inutile, contenente un singolo file, contenente a sua volta una singola funzione mai chiamata nel gioco. Nel dubbio non eliminare. Se avete aggiunto qualche file particolare nella vostra mod che non sta bene da nessun altra parte, mettetelo qui.

  • AI: cartella contenente tutte le funzioni dei comportamenti di mostri e npc


    • AI_Intern: costanti e funzioni di base dell'IA. State attenti quando modificate

    • Human: comportamenti degli NPC

    • Magic: comportamenti di NPC e mostri per quanto riguarda la magia e magie stesse

    • Monster: comportamenti di mostri

    • Test_Scripts: file di debug e test

  • Items: cartella contenente tutti gli oggetti

  • Story: cartella contenente funzioni relative alla storia, npc, mostri e dialoghi

    • B_AssignAmbientInfos: contenente i dialoghi ripetitivi di NPC generici (senza nome)

    • B_Content: contenente funzioni relative alla storia che riguardano in genere il mondo di gioco

    • B_GiveTradeInv: assegnazione degli inventari dei mercanti

    • B_Storycontenente funzioni relative alla storia che riguardano in genere gli NPC

    • Dialog_Mobsi: contenente tutti i "dialoghi" degli oggetti interattivi

    • Dialoge: contenente tutti i dialoghi

    • Events: contenente la gestione degli eventi innescati dal mondo di gioco

    • G_Functions: contenente funzioni chiamate direttamente dal motore di gioco

    • Log_Entries: contenente informazioni e stato di missioni

    • NPC: contenente le istanze di NPC e mostri

    • NPC_Scripts: contenente delle funzioni per la gestione degli NPC


Ultima cosa: a differenza di altri linguaggi di programmazione seri, daedalus non è case sensitive, quindi non fa distinzione tra maiuscole e minuscole. Tutta via è buona norma utilizzare le seguenti impostazioni:
CODICE
func int MiaFunzione()    //Ogni parola inizia con la maiuscola

var int miavariabile         //Tutto minuscolo

const int MIACOSTANTE      //Tutto maiuscolo



Bene per ora è tutto. È stata una lezione piuttosto lunga e impegnativa pure per me, non so se sono stato molto chiaro, non sapevo come porvi alcuni argomenti :P
Se avete dubbi ripeto non esitate a chiedere. Nella prossima lezione vedremo più in dettaglio gli npc e i dialoghi.

Ciao :camberman.gif: :camberman.gif:

Torna all'indice delle lezioni



Edited by Frank-95 - 15/10/2015, 13:39
view post Posted: 17/2/2015, 14:49     +2[Tutorial] Daedalus e struttura di Gothic.dat Parte 1 - Gothic II & La Notte del Corvo
Nella scorsa lezione abbiamo visto come prepare la nostra "postazione di modding" per quanto riguarda lo scripting.
Ora è il momento di capire le caratteristiche del file gothic.dat e come è strutturato gothic.

NOTA BENE: Ovviamente non potrò scrivere il comportamento di OGNI file perché sono diverse migliaia, mi limiterò ad elencare le caratteristiche più importanti. Starà a poi a voi andare a spulciare ogni angolo e capire come si comporta. Io cercherò di darvi gli strumenti per farlo. Comunque come al solito se avete domande chiedete pure.

Cominciamo. Daedalus è un linguaggio di scripting orientato agli oggetti. Esso non è alla base del *motore di gioco* che si basa invece su codici che noi, senza codice sorgente, non possiamo modificare. Daedalus è invece alla base del *gioco* (scusate le ripetizioni :P), cioè ci permette di modificare il comportamento di oggetti, personaggi, mostri, ma non la struttura di questi. Non possiamo per esempio fare in modo che una spada ci parli perché non è previsto dal motore, tuttavia è previsto aggiungere effetti grafici, aumentare il danno ecc.

Ogni "cosa" che vedete quando giocate (a parte il mondo stesso), non è altro che un instanza di un particolare oggetto. Potete immaginare gli oggetti come dei progetti virtuali aventi determinati attributi e le instanze come la realizzazione pratica di questi oggetti aventi gli stessi attributi del progetto ma valori diversi.

Vi faccio un esempio. Ora che avete gothic.dat decompilato (se così non fosse tornate alla lezione precedente) andate nella cartella _intern e aprite il file classes.d. Osservate questa parte:

CODICE
class C_Npc
{
       var int id;
       var string name[5];
       var string slot;
       var string effect;
       var int npcType;
       var int flags;
       var int attribute[ATR_INDEX_MAX];
       var int HitChance[MAX_HITCHANCE];
       var int protection[PROT_INDEX_MAX];
       var int damage[DAM_INDEX_MAX];
       var int damagetype;
       var int guild;
       var int level;
       var func mission[5];
       var int fight_tactic;
       var int weapon;
       var int voice;
       var int voicePitch;
       var int bodymass;
       var func daily_routine;
       var func start_aistate;
       var string spawnPoint;
       var int spawnDelay;
       var int senses;
       var int senses_range;
       var int aivar[100];
       var string wp;
       var int exp;
       var int exp_next;
       var int lp;
       var int bodyStateInterruptableOverride;
       var int noFocus;
};


La prima riga indica che stiamo creado una classe di nome C_NPC. Una classe è proprio il progetto di cui stavamo parlando prima. Questa classe oggetto è la base per tutti gli NPC e, sorpresa, anche per i mostri! Infatti anche essi sono considerati NPC, hanno semplicemente un "corpo diverso".
Se avete esigenze particolari nulla vi vieta di creare altri oggetti classe tutti vostri, basta che non modificate questi altrimenti rischiate che vi crasha gothic :P
Vi spiego ora a cosa si riferiscono queste classi:

C_NPC: npc umani e mostri

C_MISSION: classe contenente lo stato di una missione

C_ITEM: tutti i tipi di oggetti

C_FOCUS: classe contenente le proprietà di focalizzazione (su mostri, umani, ecc..)

C_INFO: dialoghi

C_ITEMREACT: classe non utlizzata

C_SPELL: incantesimi

Come capirete, alla fine tutto ciò che vedrete in gothic.dat deriva in un modo o nell'altro da queste classi. Due cose importanti: uno, in realtà anche queste classi derivano da altre più generiche definite nel motore di gioco; due, queste non sono tutte le classi esistenti in gothic: negli altri file .dat ve ne sono altre che assolvono ad altri scopi.

Adesso cercherò con un corso piuttosto accellerato di parlarvi di sintassi e semantica, un argomento piuttosto lunghetto.
Durante la modifica degli script prima o poi si fa qualche errore, è inevitabile. Ora sta a noi capire di che tipo di errore si tratta.

CITAZIONE
In informatica, la sintassi di un linguaggio di programmazione o di un altro linguaggio formale (di markup, di query e così via) è l'insieme delle regole che una porzione di codice deve seguire per essere considerata conforme a quel linguaggio.

Detto in altre parole, per scrivere in daedalus, dovete seguire delle determinate regole per far capire al compilatore cosa state facendo. Un errore di sintassi provoca l'annullamento della compilazione.

CITAZIONE
Nel campo dell'informatica teorica, il termine semantica formale riguarda i modelli matematici che definiscono formalmente i linguaggi di programmazione o, più generalmente, la computazione stessa.

Cosa significa? A differenza della sintassi che riguarda propriamente come DEVE essere scritto il codice, la semantica studia il suo significato. Cioè potete scrivere bene il codice, ma potrebbe non fare quello che dovrebbe.

Diamo uno sguardo alla sintassi, approfittando per spiegare qualche altra nozioncina, e in seguito vediamo qualche esempio pratico.

Commenti: i commenti sono parti di codice ignorate dal compilatore. Vi servono per spiegare a cosa serve ciò che state scrivendo (se lavorate in gruppo per esempio), o prendere delle note. Ci sono due tipi di sintassi per i commenti
CODICE
//Commenti su di una sola riga

/* Commenti
su più
righe */



Classi: progetti software. Permettono la creazioni di instanze (oggetti), basati su di essi.
CODICE
class NomeClasse
{
   //qui vanno tutti gli attributi (proprietà della classe)
}


Prototipi: possiamo considerarli delle sottoclassi, quindi progetti che rappresentano una gamma più ristretta di oggetti. Essi rappresentano un insieme di istanze, ma più ristretto dell'intera classe (una classe è il progetto di una tv generica, un prototipo possibile è il progetto di una tv led, e l'instanza è la tv led uscita dalla fabbrica, per esempio :D). Il prototipo più utilizzato è Npc_Default. Esso è la base per tutti gli NPC, ma non per i mostri, anche se appartengono entrambi alla classe C_NPC.
CODICE
prototype NomePrototipo(NomeClasse) //tra parentesi il nome della classe da cui eredita gli attributi
{
   //gli attributi devono essere gli stessi della classe madre, ovviamente scegliendo voi il valore
}


Instanze: oggetti software. Possono derivare da classi o da prototipi
CODICE
instance NomeInstanza(NomeClasse O NomePrototipo) //classe O prototipo madre
{
   //attributi
}


Costanti e variabili: sono insiemi di dati aventi un determinato valore, assegnati ad un simbolo (un nome). Le variabili come dice la parola stessa possono mutare, le costanti no. Una variabile è la x che devi trovare in un equazione per esempio, il pi greco è una costante invece. Le variabili e le costanti inoltre sono di un certo tipo, che una volta definito non può essere cambiato. Alla fine della definizione, assegnazione e manipolazione di costanti e variabili ci va un punto e virgola! Non metterlo causerà un errore di sintassi e la fine della compilazione. Le variabili sono gli attributi delle classi di cui abbiamo parlato prima.
CODICE
//possibili tipi in daedalus: string (stringhe letterali), int (numeri interi), float (numeri decimali)

tipocostante nomecostante = valorecostante;    //definizione di una costante al di fuori di funzioni e classi

tipovariabile nomevariabile;    //definizione di variabili dentro o fuori di classi e funzioni
nomevariabile = valorevariabile;    //assegnazione di variabili dentro classi e funzioni



Funzioni: in gothic non ci possono essere pezzi di codice al di fuori di classi o funzioni ad eccezione della dichiarazione di variabili e costanti. Le funzioni servono quindi a definire una porzione di codice che può essere chiamata, una ma anche più volte. Un dialogo per esempio, oppure il cambiamento di un attributo: invece di scrivere ogni volta il codice, si raggruppa tutto in una funzione che può essere chiamata più volte. Una funzione inoltre può avere un determinato "risultato", chiamato valore di ritorno. Questo può essere di tipo string, int o float. In caso non ci sia la funzione verrà definita come void (vuota). Quando si chiama una funzione va messo il ; alla fine
CODICE
func tipodiritorno nomefunzione(tipoparametro1 nomeparametro1, ..., tipoparametroN nomeparametroN)
{
   //operazioni
};


Istruzioni if-else: queste estruzioni sono alla base dei linguaggi di programmazione, sono le prime che si studiano in genere perché sono le più semplici da capire ma anche molto molto importanti. Quando nella lezione precedente vi ho parlato di logica vero/falso è qui che questa entra in gioco. Cosa succede infatti quando creiamo questi rami if-else? Creiamo delle conidizioni. Cioè quello che succederà dipenderà dalle condizioni di partenza. if = se, else if = altrimenti se, else = altrimenti. La sintassi è questa:
CODICE
if(condizione)
{
   //istruzioni
}
else if(altra_condizione)
{
   //istruzioni
}
else
{
   //istruzioni
}

NOTA: non è obbligatorio l'inserimento dei rami else if ed else una volta chiamato il primo if.

Vediamo di fare degli esempi pratici per farvelo entrare in testa. Faremo finta che sia tutto in un unico file per ora:

CODICE
/* Definizione della classe NPC. Tutte le proprietà sono qui semplicemente definite e non assegnate
perché potrebbere assumere qualsiasi valore. Vediamo proprietà (variabili) di tipo int e string.
Si possono notare anche degli array, cioè variabili aventi non un valore del tipo scelto, ma una lista di valori.*/

class C_Npc
{
       var int id;                        //variabile di tipo int
       /*array di tipo string di lunghezza 5: la variabile name avrà quindi 5 valori diversi a seconda della posizione in lista (name[0], name[1], name[2], name[3], name[4])*/
       var string name[5];
       var string slot;
       var string effect;                //variabili di tipo string
       var int npcType;
       var int flags;
       var int attribute[ATR_INDEX_MAX];    //array di tipo int di lunghezza uguale a ATR_INDEX_MAX che è il nome di una costante definita in constants.d
       var int HitChance[MAX_HITCHANCE];
       var int protection[PROT_INDEX_MAX];
       var int damage[DAM_INDEX_MAX];
       var int damagetype;
       var int guild;
       var int level;
       var func mission[5];
       var int fight_tactic;
       var int weapon;
       var int voice;
       var int voicePitch;
       var int bodymass;
       var func daily_routine;
       var func start_aistate;
       var string spawnPoint;
       var int spawnDelay;
       var int senses;
       var int senses_range;
       var int aivar[100];
       var string wp;
       var int exp;
       var int exp_next;
       var int lp;
       var int bodyStateInterruptableOverride;
       var int noFocus;
};


/* Definizione del prototipo Npc_Default che raggruppa tutti gli NPC umani e che eredita dalla classe C_NPC. Vengono assegnati dei valori standard a molte delle proprietà di C_NPC ma non è detto che le manterrà durante la creazione dell'instanza */

prototype Npc_Default(C_Npc)
{
       /* Prima avevamo visto un array intero di nome attribute e di lunghezza pari a ATR_INDEX_MAX. Il valore di quella costante è 5 perché 5 sono gli attributi di un npc, e qui di seguito vengono assegnati i valori di base.*/
       attribute[ATR_STRENGTH] = 10;
       aivar[REAL_STRENGTH] = 10;
       attribute[ATR_DEXTERITY] = 10;
       aivar[REAL_DEXTERITY] = 10;
       attribute[ATR_MANA_MAX] = 10;
       aivar[REAL_MANA_MAX] = 10;
       attribute[ATR_MANA] = 10;
       attribute[ATR_HITPOINTS_MAX] = 40;
       attribute[ATR_HITPOINTS] = 40;
       HitChance[NPC_TALENT_1H] = 0;
       HitChance[NPC_TALENT_2H] = 0;
       HitChance[NPC_TALENT_BOW] = 0;
       HitChance[NPC_TALENT_CROSSBOW] = 0;
       protection[PROT_EDGE] = 0;
       protection[PROT_BLUNT] = 0;
       protection[PROT_POINT] = 0;
       protection[PROT_FIRE] = 0;
       protection[PROT_MAGIC] = 0;
       /* Qui di seguito valori standard di alcune proprietà di C_NPC per gli umani */
       damagetype = DAM_BLUNT;
       senses = SENSE_HEAR | SENSE_SEE;
       senses_range = PERC_DIST_ACTIVE_MAX;
       aivar[AIV_MM_FollowTime] = NPC_TIME_FOLLOW;
       aivar[AIV_FightDistCancel] = FIGHT_DIST_CANCEL;
       bodyStateInterruptableOverride = FALSE;
};


/* E finalmente ecco l'istanza, l'"oggetto" pyrokar. Come vedete non eredita dalla classe C_NPC direttamente come fanno i mostri ma dal prototipo Npc_Default. Una descrizione più approfondita delle proprietà di C_NPC nelle prossime lezioni. */

instance KDF_500_Pyrokar(Npc_Default)
{
       name[0] = "Pyrokar";
       guild = GIL_KDF;
       id = 500;
       voice = 11;
       flags = NPC_FLAG_IMMORTAL;
       npcType = npctype_main;
       B_SetAttributesToChapter(self,6);
       fight_tactic = FAI_HUMAN_STRONG;
       B_SetNpcVisual(self,MALE,"Hum_Head_Bald",Face_N_ImportantOld,BodyTex_N,ItAr_KDF_H);
       Mdl_SetModelFatness(self,1);
       Mdl_ApplyOverlayMds(self,"Humans_Mage.mds");
       B_GiveNpcTalents(self);
       B_SetFightSkills(self,30);
       daily_routine = Rtn_Start_500;
};


/* Esempio di una funzione per un dialogo (non è tutto qui ho preso solo quello che mi serviva) */

func void DIA_Pyrokar_RUNNING_Info()
{
       var int randomizer;                        //Dichiarazione di variabile locale di tipo int
       /* Alla variabile viene assegnato come valore il risultato della funzione Hlp_Random che prende come parametro un intero e da come risultato un intero compreso tra 0 e il parametro meno 1 (2 in questo caso) */
       randomizer = Hlp_Random(3);

       /* Inizia il ciclo di if che si base sul valore di randomizer, quindi sul risultato di Hlp_Random */
       if(randomizer == 0)        //Se il risultato è zero allora...
       {
               AI_Output(self,other,"DIA_Pyrokar_RUNNING_11_00");        //Fino a quando sarai impegnato con la prova, non abbiamo altro da dirti.
       }
       else if(randomizer == 1)                //Altrimenti se il risultato è uno, allora...
       {
               AI_Output(self,other,"DIA_Pyrokar_RUNNING_11_01");        //Perché sei ancora qui? Vai ad affrontare la tua prova!
       }
       else                                //Altrimenti...
       {
               AI_Output(self,other,"DIA_Pyrokar_RUNNING_11_02");        //È il momento di trasformare le tue parole in azioni concrete. Non credi, novizio?
       };
       /* (qui il codice original era un altra else if, ma siccome l'ultimo caso possibile era 2, va bene anche inserire semplicemente else) */
       AI_StopProcessInfos(self);
};


Bene, purtroppo per chi non ha mai programmato può risultare un po' "fuori dall'ordinario", ma fidatevi che una volta capito andrete a manetta. Studiatevi bene la logica vero-falso; non solo per il modding, ma anche per voi perché è davvero importante credetemi.

Nella prossima lezione concluderemo con gli operatori e la truttura di gothic.dat.

Ciao :camberman.gif: :camberman.gif:

Torna all'indice delle lezioni



Edited by Frank-95 - 15/10/2015, 13:34
56 replies since 11/5/2009