Page 1 sur 1
[SCRIPT] - Créature invisible change de comportement si son maître devient visible
Posté : mar. 29 août 2017, 15:05
par Faust
Bonjour,
Je bloque sur un script pour ma créature.
La créature en question est un familier qui peut changer de forme, dès lors ou sa forme change, son script de comportement change. Dans sa forme initiale la créature ne peut pas attaquer les ennemis, elle agit uniquement en fonction des actions de son invocateur.
Dès lors ou la créature prend sa forme humaine, dès que l'invocateur se cache dans l'ombre, la créature fait de même. J'ai entré un script qui ordonne à la créature de rester invisible si l'invocateur est invisible, même ci ceux-ci ont un ennemi en vue.
Je souhaiterai que la créature attaque dans chacune de ces conditions:
Si elle n'est pas invisible
Si l'invocateur devient visible
Si l'ennemi attaque l'invocateur malgré son invisibilité
Le problème que je rencontre intervient dans le cas où la créature (le familier) et l'invocateur sont invisibles, et que l'invocateur attaque la créature ennemie (par la même occasion l'invocateur devient visible). Le familier décide d'attaquer la créature ennemie uniquement à la fin de son effet "cacher dans l'ombre" au lieu d'attaquer lorsque l'invocateur engage le combat.
Voici le script que j'ai essayé:
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
Hide()
Continue()
END
IF
StateCheck(Myself,STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
IF
See(NearestEnemyOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
IF
See([EVILCUTOFF])
StateCheck(LastSummonerOf(Myself),STATE_NORMAL)
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
IF
Die()
THEN
RESPONSE #100
ReallyForceSpellDead(Myself,ILLUSION_DEATH) // SPIN835.SPL (No such index)
DestroySelf()
END
IF
ActionListEmpty()
See(LastSummonerOf(Myself))
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
Continue()
END
Posté : mar. 29 août 2017, 17:49
par Cocrane
Salut Faust,
ton explication est claire et détaillée.
Ca donne l'impression que le code avec les conditions"Ennemis visible" et "Invocateur visible" n'agit pas. P.E que le changement de statut de l'invocateur met du temps à se rafraîchir.
Attention à "MoveToObjectFollow" qui pour moi ne s'arrête jamais.
A lecture de ton code, je te propose l'évolution suivante en
gras.
// ennemi visible. J'attaque l’ennemi si mon maitre est visible
IF
See(NearestEnemyOf(Myself)) // A tester aussi: ActuallyInCombat
StateCheck(LastSummonerOf(Myself),STATE_NORMAL) // !StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE) // A tester à la place: inverse de invisible avec "!" devant
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
Hide()
Continue()
END
// Je suis mon invocateur, si nous sommes invisibles.
IF
StateCheck(Myself,STATE_INVISIBLE)
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
// block non utile: la créature attaque uniquement si l'invocateur est visible.
IF
See(NearestEnemyOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
IF
Die()
THEN
RESPONSE #100
ReallyForceSpellDead(Myself,ILLUSION_DEATH) // SPIN835.SPL (No such index)
DestroySelf()
END
IF
ActionListEmpty()
See(LastSummonerOf(Myself))
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
Continue()
END
Cocrane
Posté : mar. 29 août 2017, 20:05
par Faust
Cocrane a écrit :Salut Faust,
ton explication est claire et détaillée.
Ca donne l'impression que le code avec les conditions"Ennemis visible" et "Invocateur visible" n'agit pas. P.E que le changement de statut de l'invocateur met du temps à se rafraîchir.
Attention à "MoveToObjectFollow" qui pour moi ne s'arrête jamais.
A lecture de ton code, je te propose l'évolution suivante en
gras.
// ennemi visible. J'attaque l’ennemi si mon maitre est visible
IF
See(NearestEnemyOf(Myself)) // A tester aussi: ActuallyInCombat
StateCheck(LastSummonerOf(Myself),STATE_NORMAL) // !StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE) // A tester à la place: inverse de invisible avec "!" devant
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
Hide()
Continue()
END
// Je suis mon invocateur, si nous sommes invisibles.
IF
StateCheck(Myself,STATE_INVISIBLE)
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
// block non utile: la créature attaque uniquement si l'invocateur est visible.
IF
See(NearestEnemyOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
IF
Die()
THEN
RESPONSE #100
ReallyForceSpellDead(Myself,ILLUSION_DEATH) // SPIN835.SPL (No such index)
DestroySelf()
END
IF
ActionListEmpty()
See(LastSummonerOf(Myself))
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
Continue()
END
Cocrane
Salut Cocrane,
Un grand merci pour ton intervention!
J'ai suivi ton conseil, j'ai utilisé
!StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE) et ai retiré le block suivant:
// block non utile: la créature attaque uniquement si l'invocateur est visible.
IF
See(NearestEnemyOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
Du coup tout fonctionne au poil, la créature attaque uniquement si son invocateur est visible!
Merci! :oui:
Posté : mar. 29 août 2017, 20:53
par Cocrane
Ravi que ça fonctionne.
C'est souvent à cause de pas grand chose.
Cocrane
Posté : mer. 30 août 2017, 10:32
par Faust
En modifiant un petit peu, tout fonctionne correctement, auparavant après un certains nombre de "se cacher dans l'ombre" le familier restait visible et suivait l'invocateur qui était lui invisible. Avec ce script, s'est réglé:
IF
See([EVILCUTOFF])
!StateCheck(Myself,STATE_INVISIBLE)
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
IF
See(NearestEnemyOf(Myself))
!StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
OR(2)
See(NearestEnemyOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
Hide()
Continue()
END
IF
StateCheck(Myself,STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Hide()
Continue()
END
IF
StateCheck(Myself,STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
IF
ActionListEmpty()
See(LastSummonerOf(Myself))
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
Continue()
END
IF
Die()
THEN
RESPONSE #100
ReallyForceSpellDead(Myself,ILLUSION_DEATH) // SPIN835.SPL (No such index)
DestroySelf()
END
Posté : mer. 30 août 2017, 12:36
par Cocrane
Il y a une partie du code qui me gène. Il a pas mal changé.
// j'attaque si ennemi visible et si mon maitre est visible
IF
See(NearestEnemyOf(Myself))
!StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
OR(2)
See(NearestEnemyOf(Myself)) // Déjà écrit au dessus donc c'est inutile fausse ton test "OR(2)"
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY) // Je ne connais pas le statut "STATE_IMPROVEDINVISIBILITY"
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
Je remplacerai du coup part:
IF
See(NearestEnemyOf(Myself))
OR(2)
!StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
// Ce block existe deux fois dans ton code. Une fois suffit normalement.
IF
StateCheck(Myself,STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
// Pour les deux blocks, je ne suis pas sur de comprendre ce que tu veux. Si la créature voit l'invocateur qu'il soit invisible ou non, elle se cache?
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
Hide()
Continue()
END
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Hide()
Continue()
END
Cocrane
Posté : mer. 30 août 2017, 13:08
par Faust
Cocrane a écrit :Il y a une partie du code qui me gène. Il a pas mal changé.
// j'attaque si ennemi visible et si mon maitre est visible
IF
See(NearestEnemyOf(Myself))
!StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
OR(2)
See(NearestEnemyOf(Myself)) // Déjà écrit au dessus donc c'est inutile fausse ton test "OR(2)"
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY) // Je ne connais pas le statut "STATE_IMPROVEDINVISIBILITY"
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
Je remplacerai du coup part:
IF
See(NearestEnemyOf(Myself))
OR(2)
!StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
// Ce block existe deux fois dans ton code. Une fois suffit normalement.
IF
StateCheck(Myself,STATE_INVISIBLE)
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
// Pour les deux blocks, je ne suis pas sur de comprendre ce que tu veux. Si la créature voit l'invocateur qu'il soit invisible ou non, elle se cache?
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
Hide()
Continue()
END
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Hide()
Continue()
END
Cocrane
Concernant OR, ça ne change pas l'intégralité de la condition? Si je ne rajoute pas "
See(NearestEnemyOf(Myself))" cette partie sera toujours prise en compte ?
"STATE_IMPROVEDINVISIBILITY" est le statut de la créature qui se trouve sous l'effet d'invisibilité partielle après avoir attaqué alors qu'elle était invisible. Cette créature ne peut donc pas être ciblée avec un sort (Détection faussée, Poussière de fée, etc....)
Du coup dans ces deux conditions je veux qu'elle se cache (la créature à la capacité de se fondre dans l'ombre, comme un rôdeur).
Dans ce cas ça fonctionne si je remplace par le block suivant?
IF
See(LastSummonerOf(Myself))
OR(2)
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Hide()
Continue()
END
Edit: en remplaçant par:
IF
See(NearestEnemyOf(Myself))
OR(2)
!StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
Le familier attaque l'ennemie malgré que son invocateur soit invisible, je pense donc que la condition OR nécessite de rajouter la première partie du block, car cela fonctionnait avec mon précédent script.
EDIT:2
Idem pour:
IF
See(LastSummonerOf(Myself))
OR(2)
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Hide()
Continue()
END
La créature ne redevient pas invisible lorsque je le veux.
Posté : mer. 30 août 2017, 14:14
par Cocrane
Ok pour STATE_IMPROVEDINVISIBILITY. Je découvre avec ton explication et ça change la logique.
IF
See(NearestEnemyOf(Myself))
OR(2)
!StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
!StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY) // Si pas invisibilité partielle
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
Ca devrait résoudre le problème d'attaque.
Par contre, si tu veux la créature "cacheé" lorsque l'invocateur est invisible ou partiellement invisible, le code me semble bon.
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
Hide()
Continue()
END
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Hide()
Continue()
END
je fusionnerai même les deux blocks vu que l'objectif est le même:
IF
See(LastSummonerOf(Myself))
Or(2)
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Hide()
Continue()
END
Cocrane
Posté : mer. 30 août 2017, 16:09
par Faust
Cocrane a écrit :Ok pour STATE_IMPROVEDINVISIBILITY. Je découvre avec ton explication et ça change la logique.
IF
See(NearestEnemyOf(Myself))
OR(2)
!StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
!StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY) // Si pas invisibilité partielle
THEN
RESPONSE #100
Attack([EVILCUTOFF])
END
Ca devrait résoudre le problème d'attaque.
Par contre, si tu veux la créature "cacheé" lorsque l'invocateur est invisible ou partiellement invisible, le code me semble bon.
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
THEN
RESPONSE #100
Hide()
Continue()
END
IF
See(LastSummonerOf(Myself))
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Hide()
Continue()
END
je fusionnerai même les deux blocks vu que l'objectif est le même:
IF
See(LastSummonerOf(Myself))
Or(2)
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
THEN
RESPONSE #100
Hide()
Continue()
END
Cocrane
J'ai remodifié un peu:
IF
See(NearestEnemyOf(Myself))
OR(2)
!StateCheck(Myself,STATE_INVISIBLE)
// Comme STATE_IMPROVEDINVISIBILITY rend l'invocateur partiellement
!StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
//visible, je veux que le familier attaque, donc je l'ai retiré, car dans les
THEN
// deux cas l'invocateur peut être attaqué.
RESPONSE #100
Attack([EVILCUTOFF])
END
IF
See(LastSummonerOf(Myself))
Or(2)
StateCheck(LastSummonerOf(Myself),STATE_INVISIBLE)
// le familier devient invisible si l'invocateur est invisible ou
StateCheck(LastSummonerOf(Myself),STATE_IMPROVEDINVISIBILITY)
//partiellement invisible
THEN
RESPONSE #100
Hide()
Continue()
END
IF
StateCheck(Myself,STATE_INVISIBLE)
// Si la créature devient invisible, elle suit l'invocateur
THEN
RESPONSE #100
MoveToObjectFollow(LastSummonerOf(Myself))
END
Ca marche très bien et le script est beaucoup plus clair!
Merci pour le coup de main Cocrane.