Page 1 sur 1
[script] script lancé par un objet
Posté : dim. 19 janv. 2020, 21:20
par Cocrane
J'ai crée un objet qui permet d'invoquer un créature à votre service.
L'objet et le sort d'invocation fonctionne.
Je désire ajouter la règle suivante: l'objet est utilisable uniquement par le Charname.
A ma connaissance, on ne peut pas bloquer sur le Charname facilement (case à cocher dans l'objet).
Je pense que la meilleure manière est la suivante:
- lancer un script par l'objet au lieu du sort.
- le script teste si l'objet est dans l'équipement du Charname. Si c'est le cas, il lance le sort.
J'utilse Set AI Script [82] au niveau de l'objet.
Le script est le suivant:
IF
HasItem("cohelm01",PLAYER1)
THEN
RESPONSE #100
ForceSpellRES("cohelm01",PLAYER1)
END
Le sort ne se lance pas. Si je remplace par un script Basique idem (génération d'un son ou apparition d'une créature). L'objet ne lance pas le script visiblement.
Où est le problème?
Existe t'il une solution plus simple?
Le fichier joint info.jpg n’est plus disponible.
Cocrane
Posté : ven. 24 janv. 2020, 09:05
par rivvers
Bonjour,
c'est le nom de l'objet qu'il faut indiquer dans la fonction HasItem (donc MISCP64) non le nom du script
edit :
j'aurais plutôt utilisé l'opcode 309 dans l'objet et complété les scripts baldur.bcs et baldur25.bcs avec quelque chose comme ça :
IF
Global("Flag", "LOCALS", 1)
InPartySlot(Myself, 0)
HasItemEquipedReal("MISCP64", Myself)
THEN
SetGlobal("Flag", "LOCALS", 0)
ForceSpellRES("cohelm01", Myself)
END
dans tous les cas je te déconseille l'utilisation de l'opcode 82 avec le type AREA, à moins que ce ne soit justement utilisable que dans une zone bien définie ?
Posté : sam. 25 janv. 2020, 16:40
par Cocrane
[/code]Merci pour ton retour.
Effectivement il y a une erreur que j'avais corrigé. Mais ca ne résout pas le problème.
Pour ta proposition de code:
- l’événement doit être déclenché par l'objet quand tu cliques. Il ne faut pas le lancer via BALDUR.BCS
- HasItem suffit pour savoir qui et quoi.
J'ai finalement trouvé la solution pour que tout fonctionne et il y a plusieurs choses à gérer.
Voici la recette XD
1-Paramétrage de l'objet (cohelm01.ITM)
- ajouter l'effet Set AI Script [82], choisir override. Je ne parviens à rien avec les autres.
> une fois le script lancé, il est actif et il tourne en boucle. Il faut donc gérer le problème.
Code : Tout sélectionner
[cohelm01.baf]
// Le PLAYER possède l'objet et la créature n'est pas invoquée.
IF
HasItem("MISCP64",Player1)
Global("CO_horreur_top","GLOBAL",0)
THEN
RESPONSE #100
SetGlobal("CO_horreur_top","GLOBAL",1)
ReallyForceSpellRES("COHELM01",Player1)
ChangeAIScript("",OVERRIDE) // on retire le script du PLAYER1: évite au script de tourner en boucle
END
// Cas d'un autre PLAYER cherchant à utiliser l'objet: il ne se passe rien et on arrête le script.
// Nécessaire car si l'objet est placé ensuite sur le PLAYER1. L'invocation se lancera quand même sans demande d'invocation. (les conditions sont réunies)
IF
!HasItem("MISCP64",Player1)
THEN
RESPONSE #100
ChangeAIScript("",OVERRIDE) // on retire le script du PLAYERx: évite au script de tourner en boucle
END
2-Paramétrage d'un script à placer sur la créature invoquée.
A sa mort, il faut réinitialiser la variable à 0 pour une future invocation.
Code : Tout sélectionner
[cohelm02.baf]
IF
die()
THEN
RESPONSE #100
SetGlobal("CO_horreur_top","GLOBAL",0)
ReallyForceSpellDead(Myself,RED_HOLY_MIGHT)
END
3-Paramétrage du sort (.SPL)
4-Paramétrage de l'effet pour l'invocation
L'horreur guerrière vous salue. :-)
Il reste un cas à gérer, l'horreur guerrière arrive au terme de son invocation et ne meurt pas. La variable ne va pas se ré-initialiser.
J'ai essayé d'utiliser EXISTS mais c'est limité à la carte en cours et mon test n'a pas marché.
Je peux:
- mettre un TIMER pour réinitialiser la variable mais je trouve la solution un peu lourde.
- autoriser une seule invocation par jour (plus besoin de la variable). Actuellement c'est le prix du sang.
On peut utiliser cette logique pour rendre utilisable un objet uniquement par le PLAYER1.
Cocrane
Posté : sam. 25 janv. 2020, 19:04
par rivvers
Pourquoi ne pas rajouter un effet avec le delay adéquat dans le sort cohelm01 pour mettre la variable CO_horreur_top à 0 grâce à l'opcode n°265 ?
Je crois que cela pourrait résoudre le problème si l'horreur guerrière venait au terme de son invocation.
L'invocation s'effectue si un autre joueur utilise l'objet et que Player1 le possède également ?
Posté : sam. 25 janv. 2020, 21:56
par Cocrane
Pourquoi ne pas rajouter un effet avec le delay adéquat dans le sort cohelm01 pour mettre la variable CO_horreur_top à 0 grâce à l'opcode n°265 ? Je crois que cela pourrait résoudre le problème si l'horreur guerrière venait au terme de son invocation.
DELAY() est une idée. Dans ce cas, je le vois dans le script de la créature. Au bou de tant de temps, la créature disparait. Il faut penser à ajouter de l'effet visuel de désinvocation.
L'invocation s'effectue si un autre joueur utilise l'objet et que Player1 le possède également ?
Si l'objet existait en deux exemplaires et qu'il était placé sur le PLAYER1 et le PLAYERX, le code pourrait fonctionner sur un clic objet sur le PLAYERX.
Mais j'ai prévu un seul exemplaire. :-)
Cocrane
Posté : dim. 26 janv. 2020, 12:51
par rivvers
D'accord ! Je serai plutôt partisan de ta solution, bien que plus complexe, elle me parait plus propre que la version que j'ai proposé.
En rajoutant la condition InPartySlot(Myself, 0) pour le lancement du sort, tu enlèves efficacement tout risque de dérapage si un joueur venait à utiliser des commandes et rendrait, par la même occasion, ton système efficace pour d'autres créateurs qui souhaitaient l'utiliser pour un objet existant en plusieurs exemplaires...
Posté : dim. 26 janv. 2020, 17:18
par Freddy_Gwendo
Le hic, c'est que tu supprimes le script du slot override, indispensable pour la linéarité du jeu. Essaie plutôt le slot Race qui, de mémoire, n'est pas utilisé par les PJ, ou alors par très peu (c'est celui que j'ai décidé d’utiliser pour mes kits après plusieurs essais).
Posté : dim. 26 janv. 2020, 23:11
par Cocrane
Freddy>
Je partage ton avis, RACE est mieux que OVERRIDE. Mais lorsque j'ai testé avec RACE (je change OVERRIDE partout), ca ne marchait plus... Je peux tenter une dernière fois maintenant que tout le code est "stable". Vu que tu me dis que ca marche chez toi. :-)
Rivers>
Code : Tout sélectionner
En rajoutant la condition InPartySlot(Myself, 0) pour le lancement du sort, tu enlèves efficacement tout risque de dérapage
si un joueur venait à utiliser des commandes et rendrait, par la même occasion, ton système efficace pour d'autres créateurs
qui souhaitaient l'utiliser pour un objet existant en plusieurs exemplaires...
Effectivement, tu fais bien d'insister. (j'ai la tête dure parfois)
InPartySlot(Myself, 0) va vérifier que le code est lancé sur le PLAYER1. Du coup, le sort ne sera jamais lancé sur un autre PLAYER.
Du coup le code sur l'objet donnera cela au final (à tester):
Code : Tout sélectionner
IF
InPartySlot(Myself, 0) // Script lancé via PLAYER1
HasItem("MISCP64",PLAYER1) // PLAYER1 possède l'objet
Global("CO_horreur_top","GLOBAL",0) // La créature n'est pas invoquée en ce moment.
THEN
RESPONSE #100
SetGlobal("CO_horreur_top","GLOBAL",1)
ReallyForceSpellRES("cohelm01",PLAYER1)
ChangeAIScript("",OVERRIDE)
END
// Cas d'un autre PLAYER cherchant à utiliser l'objet
IF
!HasItem("MISCP64",PLAYER1)
THEN
RESPONSE #100
ChangeAIScript("",OVERRIDE)
END
Posté : lun. 27 janv. 2020, 16:00
par rivvers
Il est délicat de proposer un axe d'amélioration ou une autre approche sans donner l'impression de l'imposer... Loin de moi l'idée de stopper ou de canaliser un élan créatif.
Ton idée est fonctionnelle même si comme l'a indiqué Freddy, certains problèmes pointent le bout de leur nez.
OVERRIDE est plus conseillé que AREA, RACE plus que OVERRIDE. Mais qu'importe le choix, nous ne pouvons que limiter la casse et prier pour que personne n'utilise un mod qui inclut des PJ ayant des scripts RACE.
La solution que j'ai proposé dans mon premier post n'est pas confronté à ce problème et c'est bien l'utilisation de l'objet qui déclenchera le sort (c'est d'ailleurs le seul intérêt de l'objet : mettre la variable flag à 1 qui donne le feu vert au script de lancer le sort sur player1, la nuance c'est que le script est toujours actif donc nous n'avons rien à inventer pour le lancer). Mais elle implique de charger un peu plus les deux scripts "universels", pour un objet pourquoi pas. Mais si un créateur un peu zélé venait à inventer 50 objets magiques top cool pour le protagoniste ? Mais elle a, je crois, l'avantage de ne pas générer d'incompatibilité avec d'autres mods.
edit :
d'ailleurs je remarque qu'il pourrait ne pas fonctionner correctement, 'Myself' n'est pas une cible valide dans ce script
fin de l'edit
Il y a bien une solution propre en utilisant un splstate unique, mais là encore, il faut prier pour qu'aucun créateur n'utilise le même pour ses sorts... Et comme chacun fait à sa sauce...
Je vais continuer à creuser.
Posté : lun. 27 janv. 2020, 21:27
par Cocrane
Code : Tout sélectionner
Il est délicat de proposer un axe d'amélioration ou une autre approche sans donner l'impression de l'imposer... Loin de moi l'idée de stopper ou de canaliser un élan créatif.
Si il y a ambiguïté, j’apprécie l'échange et je ne me suis pas senti stoppé dans mon élan. Au contraire, en général, l'échange d'idées est stimulant et enrichissant. :-)
Code : Tout sélectionner
Il y a bien une solution propre en utilisant un splstate unique, mais là encore, il faut prier pour qu'aucun créateur n'utilise le même pour ses sorts... Et comme chacun fait à sa sauce...
"SPLSTATE?"
SPL pour sort? State? pour static? :-) Tu m'as perdu.
Si tu as envie de trouver la solution idéale, je suis curieux de voir une autre façon de faire qui marche bien. Sans Script pour filtrer, je ne vois pas.
Posté : mar. 28 janv. 2020, 07:56
par rivvers
Stimulant et enrichissant : tout est dit
Cette solution utilisera quand même un script, pour s'assurer qu'il s'agit bien du Player1 mais une seule fois dans la partie et pour tous les objets (c'est plus appréciable que le
nombre_de_créatures multipliés par le
nombre_d'objet toutes les secondes).
Les splstate (
spl pour sort et
state pour état) renseignent une valeur binaire, ils informent sur l'état du joueur à un instant précis. Ils sont très souvent ajoutés puis gérés manuellement (via des fichiers eff, itm, spl ou bcs le plus souvent). Par exemple, le splstate n°24, nommé BARKSKIN, s'il est activé, indique que le personnage subit les effets du sort Peau d'écorce (la liste complète se trouve dans le fichier SPLSTATE.IDS, d'où leur nom). Leur nombre est limité, c'est pourquoi si différents créateurs venaient à utiliser le même splstate cela peut occasionner des résultats quelque peu imprévus.
La technique est très simple en apparence : nous activons en début de partie un splstate précis pour le Player1 (par l'opcode n°328) puis nous bloquons les effets de l'objet ou du sort si le splstate est inactif (par l'opcode n°318 ou 324).
Cela fonctionnerait très bien si la cible est Myself mais je me rends compte qu'il sera nécessaire de bidouiller si ce n'était pas le cas...
Cette solution ne semble pas aussi propre qu'espéré.
Posté : mer. 29 janv. 2020, 15:39
par rivvers
J'avoue n'avoir pas été totalement honnête... J'ai volontairement omis d'aborder le problème sous un angle en pensant pouvoir trouver une solution alternative et propre. J'ai échoué !
Voici donc ce qui est certainement la solution la plus efficace :
Posté : mer. 29 janv. 2020, 18:07
par Freddy_Gwendo
Malheureusement, Cocrane modde sur BGT.
Posté : mer. 29 janv. 2020, 22:02
par rivvers
Voilà une information qui change la donne... Les deux dernières solutions sont exclues d'office !?
Posté : dim. 02 févr. 2020, 00:14
par Cocrane
Effectivement je suis toujours sur BGT.
J'ai pas encore joué les autres versions après le trône de Bhaal.
On reste donc sur notre dernier script. :-p