Aller au contenu


[SCRIPTS] Aide Générale, FAQ et Tutos


  • Ce sujet est fermé Ce sujet est fermé
13 réponses à ce sujet

#1 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 10:15

Quelques notions de base pour éviter les problèmes
Aide sur certaines fonctions script
Simulation des Opérateurs Logiques
Nouvelles Fonctions de Tribunal
Trouver les fonctions disponibles dans l'exe du TESCS
Syntaxe de la fonction GetPos
Timer et exécution des scripts
Erreur de Script : Fonction StartCombat
Déclaration et initialisation de variables
Contrôle du climat
Faire courir un PNJ
Accéder à une variable extérieure à un script


#2 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 10:16

[size=18]Quelques notions de base pour éviter les problèmes

Syntaxe

La syntaxe des scripts dans Morrowind est assez laxiste. Il y a cependant certaines règles à respecter pour éviter les erreurs inopinées.

- Utilisez des guillemets autour des id, particulièrement si l'id comporte un espace.

- "Espacez" les expressions: If ( var == 1 ) et non If (var==1)

- En revanche, évitez les espaces autour des -> : "Player"->Additem et non "Player" -> Additem

- Evitez les opérations dans les If (Merci à Dradeel):

Set variable to ( ( Var1 / 2 ) * (Var2 + 4) )

If ( variable == 10 )

    instructions ici

EndIf
et non
If ( ( Var1 / 2 ) * (Var2 + 4) )

    instructions ici

EndIf

- Déclarer vos variables au début du script

Scripts locaux et scripts globaux:

Un script local est un script attaché à un objet ou un acteur. Il s'exécutera automatiquement quand le perso se trouve dans la même cell que l'objet pour les intérieurs et dans la même cell ou une cell adjacente pour les extérieur. Il arrêtera de s'exécuter dès que le perso quitte les cells en question.

Un script global est indépendant et doit être explicitement lancé par la commande:

StartScript nomduscript

De même, il ne pourra être arrêté qu'explicitement par la commande

StopScript nomduscript

Dans Tribunal, il est possible de lancer automatiquement un script global en l'ajoutant à la liste des Start Scripts dans le TESC. (Gameplay -> Edit Start Scripts)

Variables locales et variables globales

Une variable locale est propre à un script, et sera donc attachée à l'objet ou l'acteur auquel ce script est attaché. Dans le cas où un même script est attaché à plusieurs objets, la valeur d'une variable locale reste propre à l'objet.

Il est possible de référencer une variable locale dans un autre script en utilisant la syntaxe script.variablelocale ou objet.variablelocale. On peut ainsi modifier sa valeur "de l'extérieur":

Set "monpnj".variablelocale to 12

Set "monpnj".variablelocale to mavariable

If ( "monpnj".variablelocale >= 20 )


marchent. En revanche:

Set mavariable to "monpnj".variablelocale ne marche pas.


Une variable globale est indépendante. Elle doit être créée (déclarée) dans le TESC (Gameplay -> Globals). Sa valeur est sauvegardée dans la save. Attention: si vous désinstallez un mod contenant des globales, celle-ci resteront dans la save en conservant leurs valeurs.

Il est possible de référencer une variable globale dans n'importe quel script ou dialogue.

Fonctionnement des scripts ou comment éviter les boucles et les pertes en ressource

Les scripts de Morrowind sont exécutés à chaque frame tant qu'ils sont actifs. Il est donc important de s'assurer qu'ils ne boucleront pas, ou n'exécuteront pas inutilement leurs instructions. (en gros, imaginez qu'il y a une instruction WHILE actif --- ENDWHILE autour du script)

Pour cela, on utilise des flags. Exemples:

Pour éviter un inventaire qui rame:

If ( MenuMode == 1 )

    Return

EndIf
Pour éviter que le script s'exécute si l'objet est disabled:

If ( GetDisabled == 1 )

    Return

EndIf
Pour éviter que le script s'exécute si le PNJ est mort:

If ( GetHealth <= 0 )

    Return

EndIf
Pour éviter qu'une instruction ne boucle:

Short done 



If ( done == 1 )

    Return

EndIf



If ( condition == vraie )

    [Instructions]

    Set done to 1

EndIf

Ceci est particulièrement important pour des instructions telles que "StartCombat", "ForceGreeting" ou les boucles "While --- EndWhile"

Utilisation de script dans les dialogues:

Le champ "Result" des dialogues peut contenir des instructions de script. Contrairement aux scripts eux-mêmes, ceci a l'avantage de ne s'éxécuter qu'une fois, et non en boucle.

#3 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 10:26

[size=18]Aide sur certaines fonctions script

Question de Daederius :

Il y a quelques fonctions que j'arrive pas à definir le sens, vous pouvez m'aider SVP

HitOnMe, ObjectID
OnPCHitMe
OnKockout
HurtStandingActor, float
GetLOS, ObjectID
me donner un exemple d'utilisation de FadeIn time

Réponse par Gilbertus :

HitOnMe, ObjectID

C'est le fait qu'un objectID a touché le demandeur de la fonction touché, généralement l'objectID est une arme.

ex:
if ( HitOnMe, "steel dagger" == 1 )
messageBox, "Ouille!"
endif

if ( "NPC"->HitOnMe, "steel dagger" == 1 )
messageBox, "Ouille!"
endif


OnPCHitMe
Ce n'est pas une fonction
En gros cela signifie que l'objet (NPC, creature, coffre) a été touché (par une arme) de l'emetteur de la fonction
if ("NPC".OnPCHitMe == 1)
...
endif

if ("coffre".OnPCHitMe == 1)
...eclater le coffre
endif


OnKockout
MORRO est feneant il aurait du faire la fonction Onknockedout qui est plus explicite.


HurtStandingActor, float
float est exprimé en secondes et doit être negatif pour blesser l'acteur.
comprenne qui pourra ?


GetLOS, ObjectID
if ("NPC"->GetLOS, "steel dagger") == 1 )
.messageBox, "Je vois une dague"
endif
ligne de vue sur OBJECTID


exemple de FadeIn time
Il y n 2 dans le jeu
script RaceCheck
script MaestriusScript
Les mots s'arrêtent à ALMSIVI
(Exceptés ceux qui ont la priorité à droite -- Nérévar)

#4 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 10:49

[size=18]Simulation des Opérateurs Logiques

Il n'y a pas d'opérateur logique dans les scripts de Morrowind. Pas de AND, OR, XOR. On peut toutefois les "simuler" à l'aide de IF:

AND (ET logique. Toutes les conditions doivent être vraies)

Imbriquer les instructions IF -- ENDIF

If ( condition1 == vraie )

    If ( condition2 ==  vraie )

        [instructions ici]

    EndIF

EndIf
OR (OU logique. Il suffit qu'une condition soit vraie)

Pour éviter de répéter les instructions pour chaque condition, utiliser une variable:

Short macondition



IF ( condition1 == vraie )

    Set macondition to 1

ElseIf ( condition2 == vraie )

    Set macondition to 1

EndIf



If ( macondition == 1 )

     [instructions ici]

EndIF
XOR (OU exclusif. Les conditions doivent avoir des valeurs logiques différentes: il faut qu'une porte soit ouverte ou fermée)

Mélanger les méthodes pour OR et AND:

short macondition



IF ( Condition1 == Vraie )

    If ( Condition2 == Fausse )

         Set macondition to 1

    EndIf

ElseIf ( Condition1 == Fausse )

    If ( Condition2 == Vraie )

        Set macondition to 1

    EndIf

EndIf



If ( macondition == 1 )

     [instructions ici]

EndIf

Les mots s'arrêtent à ALMSIVI
(Exceptés ceux qui ont la priorité à droite -- Nérévar)

#5 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 10:58

Nouvelles Fonctions de Tribunal

Lord Mortim : posté le samedi 9 novembre 2002
Vu sur Morrowind France :

Citation:
Voici en vrac, d'apres les noms on devrait pouvoir deduire a quoi ça sert.
short GetPCSneaking
short GetPCRunning
short GetPCJumping
float GetScale
SetScale newScale
ModScale scaleChange
float GetWaterLevel
SetWaterLevel newLevel -- interiors only
ModWaterLevel levelChange -- interiors only
EnableLevitation
DisableLevitation
PlaceItem objectID X Y Z ZRot
PlaceItemCell objectID CellID X Y Z ZRot
short GetWeaponType
short GetArmorType armorPart
short HasItemEquipped itemID
ForceRun
ClearForceRun
short GetForceRun
ForceJump
ClearForceJump
short GetForceJump
ForceMoveJump
ClearForceMoveJump
short GetForceMoveJump
short GetCollidingPC
short GetCollidingActor
HurtCollidingActor damage
AddToLevCreature "levcreaname" "creature" level
AddToLevItem "levitemname" "item" level
RemoveFromLevCreature "levcreaname" "creature" level
RemoveFromLevItem "levitemname" "item" level
float GetSquareRoot number
ExplodeSpell "spellName" -- must be Touch spell
SetDelete flag -- set to 1 after disable for housekeeping
short GetWeaponDrawn
short GetSpellReadied  


Citation:
SetScale  


Et voilà qui devrait en rendre plus d'un heureux  

Récapitulatif des fonctions, anciennes et nouvelles


http://perso.wanadoo...ao/fonction.htm
Les mots s'arrêtent à ALMSIVI
(Exceptés ceux qui ont la priorité à droite -- Nérévar)

#6 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 11:17

[size=18]Trouver les fonctions disponibles dans l'exe du TESCS

[b]Question de Lord Mortim

Je souhaiterais faire un plug permettant de créer des sorts sans avoir à passer par un intermédiaire. Je me demandais donc s'il existe une fonction permettant d'appeler le menu de création de sorts.

[b]Réponse par Gilbertus

Non je ne pense pas que les fonctions soient directement accessibles,
pour avoir une liste exhaustive de toutes les foncions accessibles par le TESC tu recherche avec un editeur dans l'exe du TESC
"ADD NEW FUNCTIONS BEFORE THIS ONE!!!"
derrière ceci tu as la liste complète des noms de fonctions que comprend le TESC et nib de MENU et de beaucoup d'autres choses aussi.
Les mots s'arrêtent à ALMSIVI
(Exceptés ceux qui ont la priorité à droite -- Nérévar)

#7 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 11:25

[size=18]Syntaxe de la fonction GetPos

Question de Lord Mortim :

c'est à propos de la fonction getPos.

lorsqu'utilisée ainsi :

Set var to GetPos X

Ca marche normalement comme indiqué dans l'aide. Je récupère normalement la position de l'objet appelant sur l'axe X.

Maintenant lorsque je fais ça :

Set var to player->GetPos X

J'obtient un message "X variable inconnue". Le "compilateur" ne sembles pas apprécier la combinaison de Set et l'appel d'une fonction sur un autre objet. En effet, je peux très bien faire :

player->GetPos X

Ca marche, mais evidemment, ça ne sert à rien puique je ne récupère pas la valeur de retour.

Réponse de Lord Mortim :

Ca y est, j'ai trouver. Il faut faire :

Set var to "player"->GetPos axis

C'est tout de même très bizarre cette histoire.
Les mots s'arrêtent à ALMSIVI
(Exceptés ceux qui ont la priorité à droite -- Nérévar)

#8 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 11:28

[size=18]Timer et exécution des scripts

Question de Daederius :

pour le timer j'suis un peu dans le brouillard !

pour un test je fais juste un affichage de la valeur du timer:
...
if ( timer<15)
messagebox "timer=%3f " timer
endif
...

comme resultats il me mets des trucs du genre :
timer=1.12
timer=1.253
timer=1.751
timer=2.33

donc si je pige bien, le script est executé plus de 4 fois par seconde !

bon mon probleme c'est avec un script du jeu :
Akula_doors

dont voici un extrait :
---------------------------------------------------
if ( timer < 9 )
Rotate X 20 ;above line rotates the crank itself
Akula_door00->Rotate Z -10
Akula_door01->Rotate Z 10
;above two lines open the doors.
;you may need to adjust the times or the rotate value.
;right now they open over 9 seconds to about 100 degrees.
endif
...
------------------------------------------------------------------
Ce script permets bien de faire pivoter la porte de 10° en 10° durant 10 secondes(0 à 9) pour avoir 100 degré au total !

Donc ici pour que ça marche il faut qu'il soit executé toutes les secondes ?

Hors j'ai vu plus haut qu'il est executé plusieurs fois en 1 seconde !


[b]Réponse de Lord Mortim

Les scripts actifs (ceux qui sont dans la meme cell que le joueur) sont exécutés une fois par frame. La durée d'une framme est la durée que met le moteur à executer tous les scripts, faire les tests, animer les personnages, etc...

La durée d'une frame est donc variable. La fonction GetSecondsPassed te retourne le temps écoulé depuis la dernière frame. Et comme en une seconde, il y a plusieurs frames (heureusement d'ailleurs !), les scripts sont exécutés plusieurs fois par seconde.

Mais pour ce qui est de la méthode rotate, tu n'as pas à te soucier de cela. Cette méthode prend en paramètre l'angle que doit parcourir la rotation en une seconde, et calcule toute seule les rotations correspondantes à chaque frame, en fonction de la vitesse du moteur.

En d'autres termes, la fonction Rotate Z 10 fera tourner l'objet de 10 degré par seconde sur l'axe Z et ce quelque soit le nombre d'itération réalisés par seconde.

#9 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 11:41

[size=18]Erreur de Script : Fonction StartCombat

Question de Baran Dai :

Bon ben tout est dans le titre...
POur le script en question, le voici:

Begin entrainement_script 



Short onPCEquip 



if ( onPCEquip == 1 ) 

    "npc_training_pc"->StartCombat, player 

    Return 

else 

    "npc_training_pc"->StopCombat, player 

    Return 

endif 



End


En fait il s'agit d'un script qui s'applique sur une arme: si le joueur dégaine son arme, alors "npc_training_pc" l'attaque. Dès que le joueur la range, le npc arrête de l'attaquer.

Là où ça foire c'est que dès que je sors l'arme, le npc m'envoie les insultes habituelles mais a un comportement non belliqueux(se gratte la tête, regarde partout, marche, ...). Dès que je range l'arme, il arrête de m'insulter et pis c'est tout...  

Bref où est le problème???


[b]Réponse de Lord Mortim

La variable OnPCEquip reste à 1 tant que l'arme est équipée. Autrement dit, les instructions startcombat et stopcombat sont exécutées à chaque itération du script. Peut être que c'est ça qui bloque le pnj.

Peut être que tu devrais essayer de faire un truc dans ce genre

Begin entrainement_script 



Short onPCEquip 



Short state; state = 1 si l'arme est équipée, 0 sinon 



if ( state == 0 ) 

    if ( onPCEquip == 1 ) 

        "npc_training_pc"->StartCombat, player 

         set state to 1 

        Return 

    endif 

endif 



if ( state == 1 ) 

    if ( onPCEquip == 0 ) 

        "npc_training_pc"->StopCombat, player 

        set state to 0 

        Return 

    endif 

endif 



End
De cette manière, l'instruction startcombat n'est lançée qu'une fois quand le joueur équipe son arme. L'instruction stopcombat une fois aussi quand le joueur la deséquippe.

#10 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 11:45

[size=18]Déclaration et initialisation de variables

Question de Nem :

J'ai lu qu'annoncer une fonction la remettait à zéro. Est ce vraiment le cas ? [...] Comment créer une variable qui serait anoncé à l'achat d'un guar de charge (par exemple) et qui ne serait pas mise à zéro à chaque tour du script ?


[b]Réponse de Gilbertus

Qu'entends tu par "annoncer une fonction" ?

Les variable locales au demarrage du script sont toutes à zéro et le script est toujours actif tant que l'on ne quitte pas la CELL dans laquelle le script agit. Toujours actif ne signifie pas réinitialiser chaque variable en permanence mais signifie execution en boucle des instructions. Les definitions de variables ne sont pas du coding proprement dit et ne font pas partie de la partie executee en boucle.

Par contre si tu fais un stopscript et un startscript à ce moment là tes variables sont réinitialisées.

#11 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 12:03

[size=18]Contrôle du climat

Question de Trebonus :

Avec quel script on change le temps, je voudrais activer un leviers pour changer la meteo

Réponse de Lord Mortim

ChangeWeather

ChangeWeather, RegionID, NoType

ChangeWeather, "West Gash", 4


change le temps de la région spécifiée. Le temps commencera à changer immédiatement. Une nouvelle météo sera re-sélectionnée après 12 heures.

Numéros des types de temps:

0 Clair
1 Nuageux
2 Brouillard
3 Couvert
4 Pluie
5 Orage
6 Tempête de Cendres
7 Fléau

Voir aussi:

ModRegion, RegionID, var_clair, var_nuageux, var_brouillard, var_couvert, var_pluie, var_orage, var_cendres, var_fleau

[b]GetCurrentWeather


#12 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 12:11

[size=18]Faire courir un PNJ

Question de Daederius :

avec aiTravel le personnage se deplace en marchant
est ce qu'on peut le faire courrir et comment ?


[b]Réponse de Lord Mortim

A la suite d'investigations ménés par plusieurs moddeurs, dont Gilles_k, Ethaniel, Kry et moi-même, nous avons par hasard trouver une fonction qui devrait faire ton bonheur.

"pnj"->ForceRun

Pour le forçer et courrir.

"pnj"->ClearForceRun

pour arrêter la course.


[b]Réponse d'Ethaniel

Et en plus si tu fais
player->Forcejump ou
player->Forcemovejump
il saute partout.

#13 Virgo

Virgo

    ménagère Dremora


Posté 02 juin 2003 - 12:36

[size=18]Accéder à une variable extérieure à un script


question d'Arsenick007
est-il possible d'utiliser dans un script une variable utiliser par un autre?

je m'explique:

pour mon mod throwing kit je pensai fair un livre de connaissance dwemers et quand le PJ le lit il obtien la capaciter de cree des armes dwemers : pour le livre et le journal pas de probleme la ou ca me pose un probleme c'est dans le script du kit lui meme : si avec le livre je fait un script qui met la variable livrelu a 1 est-ce que je peut recupere cette variable le script du kit (genre if livrelu == 1 .... )? si oui comment?

réponse de gilles_k
Tout à fait Arsenick007, comme une variable normale.
A ceci prêt évidement qu'elle sera sauvegardé donc toujours active quand tu rechargera la sauvegarde.

Je doit dire que ceci est une bonne idée d'utiliser une variable globale.

réponse de Lord Mortim
Ben lorsque le joueur lis ton livre, tu lui met une annotation dans son journal. exemple : Journal "Secret Dwemer" 20. Disons que dans l'index 20 tu as le texte "En lisant le livre trucmuch, j'ai appris comment fabriquer gnagnagna". Ensuite dans ton script tu testes avec GetJournalIndex si l'index est supérieur où égal à 20.

exemple :

if( GetJournalIndex "Secret Dwemer" >= 20 )
// On fait apparaitre le menu de création d'arme dwemer
else
MessageBox "Vous ne savez pas fabriquer d'arme dwemer"
endif

Réponse de Virgo

Il est aussi possible d'accéder à une variable locale d'un autre script en utilisant la syntaxe:

nomduscript.variable ou iddelobjet.variable

où iddelobjet est l'objet auquel est attaché le script.

Ces variables extérieures peuvent être utilisées dans:

Set iddelobjet.variable to n (où n est une valeur littérale ou une variable globale ou du script en cours)

et

[b]If ( idedelobjet.variable == n )


Mais pas

[b]Set variable to idelobjet.variable
, qui ne provoquera pas d'erreur mais donnera toujours 0.

#14 Lord Mortim

Lord Mortim

    Spontanément magique


Posté 24 mars 2004 - 12:26

Liste des fonctions

De Jilin :

http://www.uesp.net/...scommands.shtml

liste des fonctions de script, avec une description, un script referant, le truc le plus complet que je connaisse ( en anglais )
Sans doute il fut un temps, appelé l'âge d'or,
Où l'homme pour son Dieu n'avait que la Nature,
Et coulait une vie aussi douce que pure...
Pour le sage éclairé, ce temps existe encore.

Sylvain Maréchal, Dieu et les prêtres




0 utilisateur(s) li(sen)t ce sujet

0 membre(s), 0 invité(s), 0 utilisateur(s) anonyme(s)