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

Posts written by Frank-95

view post Posted: 1/6/2017, 09:26     [Tutorial] Introduzione allo scripting - Gothic II & La Notte del Corvo
Se è il letto a darti quel problema sinceramente non ti so dire. FOrse in g1 sono più limitati.

Queste sono le funzioni di g2 se ti possono servire:
CODICE
func void PC_Sleep(var int t)
{
       AI_StopProcessInfos(self);
       PLAYER_MOBSI_PRODUCTION = MOBSI_NONE;
       self.aivar[AIV_INVINCIBLE] = FALSE;
       if(Wld_IsTime(0,0,t,0))
       {
               Wld_SetTime(t,0);
       }
       else
       {
               t = t + 24;
               Wld_SetTime(t,0);
       };
       Wld_StopEffect("DEMENTOR_FX");
       if(SC_IsObsessed == TRUE)
       {
               PrintScreen(PRINT_SleepOverObsessed,-1,-1,FONT_Screen,2);
       }
       else
       {
               PrintScreen(PRINT_SleepOver,-1,-1,FONT_Screen,2);
               hero.attribute[ATR_HITPOINTS] = hero.attribute[ATR_HITPOINTS_MAX];
               hero.attribute[ATR_MANA] = hero.attribute[ATR_MANA_MAX];
       };
       PrintGlobals(PD_ITEM_MOBSI);
       Npc_SendPassivePerc(hero,PERC_ASSESSENTERROOM,NULL,hero);
};

func void sleepabit_s1()
{
       var C_Npc her;
       var C_Npc rock;
       her = Hlp_GetNpc(PC_Hero);
       rock = Hlp_GetNpc(PC_Rockefeller);
       if((Hlp_GetInstanceID(self) == Hlp_GetInstanceID(her)) || (Hlp_GetInstanceID(self) == Hlp_GetInstanceID(rock)))
       {
               self.aivar[AIV_INVINCIBLE] = TRUE;
               PLAYER_MOBSI_PRODUCTION = MOBSI_SleepAbit;
               AI_ProcessInfos(her);
               if(SC_IsObsessed == TRUE)
               {
                       Wld_PlayEffect("DEMENTOR_FX",hero,hero,0,0,0,FALSE);
               };
       };
};


L'argomento di PC_Sleep indica l'ora del risveglio
view post Posted: 1/6/2017, 09:24     Gothic Spacer su Windows 10 - Gothic II & La Notte del Corvo
Comunque evidentemente ti manca quella mesh.. Nel dubbio creane una fittizia random (o duplica una già esistente e rinominala), così quell'errore non te lo da e vedi dove sta sta mesh nel mondo
view post Posted: 31/5/2017, 13:48     [Tutorial] Introduzione allo scripting - Gothic II & La Notte del Corvo
Stai usando mob personalizzati? Nel senso li hai creati te? I waypoint/nomi delle mesh hanno la stessa "struttura" di quelli già esistenti?

Generalmente per i mob, è meglio sempre basarsi su formati già nel gioco
view post Posted: 31/5/2017, 13:47     Gothic Spacer su Windows 10 - Gothic II & La Notte del Corvo
Scusa se ti rispondo dopo tre settimane ma ho avuto gli esami e non loggavo quasi mai :P

Comunque healbody non sta nel gioco originale, quindi devi avere qualche script che la chiama ma non la mesh in questione. Forse la l'hiver?
view post Posted: 2/4/2017, 09:28     [Tutorial] Npc e dialoghi - Gothic II & La Notte del Corvo
Si ma mi devi rimettere il codice se fai dei cambiamenti
view post Posted: 31/3/2017, 20:16     [Tutorial] Npc e dialoghi - Gothic II & La Notte del Corvo
Non ne ho idea, senza sapere come hai proceduto non posso fare ipotesi. Guarda attentamente rouine già fatte compreso l'interno delle funzioni
view post Posted: 31/3/2017, 18:16     [Tutorial] Npc e dialoghi - Gothic II & La Notte del Corvo
Per la posizione puoi provare a creare una variabile oCNpc del pg, e modificare la proprietà
trafoObjToWorld[16]; // 0x003C zMATRIX4

Che è una matrice 4x4 (di cui mi pare gli ultimi 4 sono nulli), che rappresentano in qualche modo la matrice delle rotazioni di eulero. Non so di preciso la relazione, però quando ho fatto gli incantesimi AoE a linea retta ho dovuto capire un po' come funzionasse, e per quello che serve a te questi sono i valori che ti interessano:

CITAZIONE
X position = trafoObjToWorld[3]
Y position = trafoObjToWorld[7]
Z position = trafoObjToWorld[11]

CODICE
var oCNpc a; a = Hlp_GetNpc(npc);
var oCNpc b; b = Hlp_GetNpc(hero);

a.trafoObjToWorld[3] = addf(b.trafoObjToWorld[3], addf(mkf(Hlp_Random(10)),mkf(1)));
...


Praticamente pongo la posizione delle x di a uguale a quella di b e aggiungo un po' di randomicità. Ti potrò sembrare un po' strano il modo in cui l'ho scritto, ma questi valori sono decimali, e daedalus non supporta i decimali se non come costanti (1.4,1.5,ecc..). Per farci delle operazioni devi usare il pacchetto float (che dovrebbe esere insieme ad ikarus). L'utilizzo è semplice perché ad ogni operazione corrisponde una funzione, dovrai solo stare attento alle parentesi:

Questo è quello che devi capire:
Tali float non sono propriamente delle variabili float, ma sono intere. Questo perché daedalus non supporta i float, però sono codificati in una particolare rappresentazione. Fai una prova con print(inttostring(mkf(4))). Vedrai che sono interi, però gothic li interpreta come decimali.

mkf(x) = make x float

quando dovrai fare delle operazioni con interi e decimali, l'intero lo dovrai sempre prima convertire in float con questa funzione; io l'ho usato su mkf(hlp_random(10)) perché hlp_random ritorna un intero

addf(x,y) = x + y

il resto lo vedi nella documentazione. Ti scrivo cosa ho fatto in pseudocodice:

a[x_pos] = b[x_pos] + 1 + Random(10)

Così si sposterà nella zona dell'eroe ma mai precisamente sopra. I numeri sono in centimetri, quindi regolati te (io mi terrai ad almeno mezzo/un metro di distanza). Puoi anche evitare il random e metterci un valore preciso

Non è testato ma dovrebbe funzionare.


Per "eliminare" un npc, come intendi te non si può. Bisogna ucciderlo e teletrasportarlo:
In gothic2:
CODICE
B_KillNpc(npc)
AI_Teleport(np,"TOT")


Tot è un waypoint generalmente in una zona inaccessibile
view post Posted: 31/3/2017, 14:22     [Tutorial] Npc e dialoghi - Gothic II & La Notte del Corvo
Allora per quanto riguarda la bacheca io ho fatto così:

Ti crei la mesh che deve contenere la mesh di un npc dal lato in cui dovrai utilizzarla (vedi per esempio la sedia), ed esportala come asc con il nome "xxx_01.asc" (xxx nome che vuoi). Gli scrivi poi la onStateFunc in maiuscolo per sicurezza, tipo "FUNC"

Poi devi modificare anche le animazioni di humans. Quindi decompila humans.msb, o mds non mi ricordo che estensione ha gothic1, apri il file mds decompilato e aggiungi queste stringhe:

CODICE
ani                        ("t_Board_Stand_2_S0"                        1        "s_Board_S0"        0.1        0.0        M.        "Hum_Guard_Ambient_B_Jue01.asc"                F        1        1)
                       ani                        ("s_Board_S0"                                1        "s_Board_S0"        0.0        0.0        M.        "Hum_Guard_Ambient_B_Jue01.asc"                F        1        1)
                       ani                        ("t_Board_S0_2_Stand"                        1        ""                0.1        0.1        M.        "Hum_Guard_Ambient_B_Jue01.asc"                R        1        1)
                       ani                        ("t_Board_S0_2_S1"                        1        "s_Board_S1"        0.0        0.0        M.        "Hum_Guard_Ambient_B_Jue01.asc"                F        1        24        FPS:10)
                       ani                        ("t_Board_S1_2_S0"                        1        "s_Board_S0"        0.1        0.1        M.        "Hum_Guard_Ambient_B_Jue01.asc"                F        75        85        FPS:10)
                       ani                        ("s_Board_S1"                                1        "s_Board_S1"        0.0        0.0        M.        "Hum_Guard_Ambient_B_Jue01.asc"                F        25        74        FPS:5)


Dove invece di board ci metti il nome func della funzione e ovviamente poi l'animazione la regoli di conseguenza. Io ho usato Hum_Guard_Ambient_B_Jue01.asc che è quella delle guardie quando si mettono a braccia conserte. I numeri dopo F sono i frame iniziali e finali (ed eventualmente la velocità data dagli fps).

Nel file di script basta che ti crei una FUNC_S1 tipo questa:

CODICE
func void Board_S1()
{
       var C_Npc her;
       her = Hlp_GetNpc(PC_Hero);
       if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(her))
       {
               self.aivar[AIV_INVINCIBLE] = TRUE;
               PLAYER_MOBSI_PRODUCTION = MOBSI_Board;
               AI_ProcessInfos(her);
       };
};


E i dialoghi devono avere per npc l'istanza dell'eroe, e la condizione PLAYER_MOBSI_PRODUCTION == MOBSI_Board (invece di board quello che ti pare).

Per rendere effettive le modifiche alle animazioni ti faccio l'esempio di g2 perché non sono esperto delle animazioni di g1 anche se sono quasi uguali:
Io elimino i file humans.msb e humans.mdh compilati (file responsabili solo della gestione, non contengono alcuna animazione). Poi nella cartella anims metto il file humans.mds modificato e il file hum_body_naked.asc che è la mesh degli npc. Poi lanci gothic e compilerà il tutto. Eventualmente se da problemi con le animazioni al primo avvio fallo crashare (quindi non da "esci dal gioco") e riavvia.


Per quanto riguarda la decompilazione si chiama decdat.


Per i mostri parlanti, devi crearli come gli umani, ma cambiare solo e soltanto la visuale. Quindi no gilda da mostro, no routine da mostro. Ti faccio un esempio:

CODICE
instance NpcMostro(Npc_Default)
{
       name[0] = "NpcMostro";
       guild = GIL_NONE;
       id = 121;
       // questi sotto non sono necessari, usa i tuoi
       flags = NPC_FLAG_IMMORTAL;
       npcType = NPCTYPE_FRIEND;
       aivar[AIV_ToughGuy] = TRUE;
       aivar[AIV_ToughGuyNewsOverride] = TRUE;
       aivar[AIV_IGNORE_Murder] = TRUE;
       aivar[AIV_IGNORE_Theft] = TRUE;
       aivar[AIV_IGNORE_Sheepkiller] = TRUE;
       aivar[AIV_IgnoresArmor] = TRUE;
       //////
       B_SetAttributesToChapter(self,0);
       fight_tactic = FAI_HUMAN_COWARD;
       Mdl_SetVisual(self,"HumanS.mds");
       Mdl_ApplyOverlayMds(self,"humans_skeleton.mds");
       Mdl_SetVisualBody(self,"Ske_Body",DEFAULT,DEFAULT,"",DEFAULT,DEFAULT,-1);
       daily_routine = Rtn_Start_121;
};


Quindi niente guild = GIL_WOLF, né start_aistate che sono tipiche dei mostri. Cambia solo le funzione MDL.

Inoltre crea direttamente l'istanza e falla ereditare da Npc_Default se ci sta in gothic 1
view post Posted: 23/2/2017, 14:08     [Tutorial] Npc e dialoghi - Gothic II & La Notte del Corvo
No i WP e FP non possono essere collegati... Eventualmente prova a rinominare anche i WP, ma non penso sia quello il problema. Hai per caso aggiunto WP nuovi?
view post Posted: 19/2/2017, 16:37     [Tutorial] Npc e dialoghi - Gothic II & La Notte del Corvo
Dipende, in alcuni casi si, è necessario che ci sia una certa stringa.

Apri il file ZS_tuaroutine e vedi se c'è qualche chiamata a funzioni relative ai freepoints (FP) come Wld_IsFPAvailable(self,"XXX"), AI_GotoFP(self,"XXX") o Npc_IsOnFP(self,"XXX").

In quel caso rinomina il freepoints lì vicino come FP_XXX_QUELLOCHETIPARE
view post Posted: 14/2/2017, 19:23     Risen 3 - Risen 3 : Titan Lords
Il 3 so che è meglio del secondo sotto vari aspetti. Diablo che ci ha giocato potrà dirti di più
view post Posted: 1/2/2017, 11:14     [Tutorial] Npc e dialoghi - Gothic II & La Notte del Corvo
Ma non è che semplicemente non lo inizializzavi bene?
In gothic 2 hai questo:

CODICE
func void SharpSword_S1()
{
       var C_Npc her;
       her = Hlp_GetNpc(PC_Hero);
       if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(her)) //controlla se è il giocatore che sta usando l'oggetto
       {
               SwordToSharp = Npc_GetEquippedMeleeWeapon(hero);
               self.aivar[AIV_INVINCIBLE] = TRUE; // evita eventuali bug se ti attaccano
               PLAYER_MOBSI_PRODUCTION = MOBSI_SharpSword; //imposta il mob utilizzato (usato da tutti i mob)
               AI_ProcessInfos(her); //iniza il dialogo
       };
};


CODICE
instance PC_SharpSword_End(C_Info)
{
       npc = PC_Hero;
       nr = 999;
       condition = PC_SharpSword_End_Condition;
       information = PC_SharpSword_End_Info;
       permanent = TRUE;
       description = Dialog_Ende;
};


func int PC_SharpSword_End_Condition()
{
       if(PLAYER_MOBSI_PRODUCTION == MOBSI_SharpSword) //presente solo se effetivamente si sta usando la mola
       {
               return TRUE;
       };
};

func void PC_SharpSword_End_Info()
{
       b_endproductiondialog();
};

func void b_endproductiondialog()
{
       AI_StopProcessInfos(self);
       Wld_StopEffect("DEMENTOR_FX"); //per fermare gli eventuali effetti visivi dei cercatori
       self.aivar[AIV_INVINCIBLE] = FALSE;
       SwordToSharp = MEM_NullToInst();
       PLAYER_MOBSI_PRODUCTION = MOBSI_NONE;
};


E in AI_Constants questo:

CODICE
const int         MOBSI_NONE                                        = 0;
const int        MOBSI_SmithWeapon                        = 1;
const int        MOBSI_SleepAbit                                = 2;
const int        MOBSI_MakeRune                                = 3;
const int        MOBSI_PotionAlchemy                        = 4;
const int        MOBSI_PRAYSHRINE                        = 5;        
const int        MOBSI_GOLDHACKEN                        = 6;
const int        MOBSI_PRAYIDOL                                = 7;
const int        MOBSI_SharpSword                        = 8;
const int        MOBSI_CookPan                                = 9;
const int        MOBSI_Board                                        = 10;
const int        MOBSI_CutWood                                = 11;
const int        MOBSI_MakeArrows                        = 12;
const int        MOBSI_WorkWood                                = 13;

var int         PLAYER_MOBSI_PRODUCTION;


Quindi si è necessaria una variabile globale come hai fatto te, ma vedi se c'è già una lista di variabili per altri mob.

Poi in che senso usa una lama per creare una lama grezza? La mola non è la pietra per affilare? In che senso crea?
Comunque in tutti i casi, i mob sono gestiti dal motore. Quindi o giochi con il motore o non puoi farci nulla... Non sta in gothic.dat
788 replies since 11/5/2009