- par exemple qui pourrait être invoqué
- par exemple qui ne contient aucun modèle 3D mais est utilisé pour obtenir un effet spécial (coup de poing enchanté, lanceur de sort, etc)
- par exemple qui ne peux pas être utilisé par le joueur
- par exemple qui comme il ne peux être rammassé, encombre la sauvegarde
Le premier script que j'avais fait est celui-ci :
ScriptName AARFSLSelfDisableOnDropAndPlayerScript ; Script d'objet // Object script ; ; Ce script sert à faire disparaître un objet jetté à terre ou ajouté au joueur. ; This script is used to destroy an object dropped on the ground or added to the player ; L'arme est abandonnée // The weapon is dropped Begin OnDrop RemoveMe End ; Si l'arme est ajoutée au joueur // If the weapon is added to the player Begin OnAdd player RemoveMe End ; Bug : le joueur s'en équippe // Bug : the player equip it Begin OnEquip player RemoveMe MessageBox "Mauvais joueur ! SVP jouez correctement... Cet objet n'est pas pour vous !" ; MessageBox "Bad gamer ! Please play correctly... This object is not for you !" End
Problèmes :
- le bloc Begin ondrop est foireux : risque de CTD en mode menu et aucun effet si un ennemi perd son épée (il est désarmé).
- l'objet n'est supprimé que s'il est ajouté au joueur (il le ramasse), si un compagnon le ramasse, lui, il aura l'objet
J'ai donc tenté d'améliorer ce script :
scn aaShehaiSelfDisableOnDeathScript ; Script d'objet // Object script short MustBeDestroy short Dropped ref RefContainer ref RefCatcher ; Si l'arme est jetée // If the weapon is dropped Begin OnDrop set MustBeDestroy to 1 End ; Si l'arme est ajoutée à un acteur // If the weapon is added to an actor Begin OnAdd if (MustBeDestroy == 1) RemoveMe endif End ; Bug : un acteur s'en équippe // Bug : an actor equip it Begin OnEquip if (MustBeDestroy == 1) RemoveMe endif End Begin GameMode set RefContainer to GetContainer if (RefContainer <= 0) set MustBeDestroy to 1 set RefCatcher to PlaceAtMe aaShehaiCreaNull 1 RefCatcher.Disable RefCatcher.Kill Activate RefCatcher elseif (RefContainer > 0 && RefContainer.GetDead == 1) set MustBeDestroy to 1 RemoveMe endif ; if ((Dropped == 1 || RefContainer <= 0) && MustBeDestroy == 0) ; elseif (Dropped == 1 || (RefContainer > 0 && (RefContainer.GetDead == 1 || RefContainer.GetIsCreature == 0 || RefContainer.IsActor == 0) && MustBeDestroy == 0) ; if (RefContainer != RefOldContainer) ; if (RefContainer != 0) ; MessageBox "Removed" ; RemoveMe ; elseif (RefContainer == 0 && RefOldContainer != 0) ; MessageBox "On old" ; RemoveMe RefOldContainer ; elseif (RefContainer == 0 && RefOldContainer == 0) ; MessageBox "On player" ; RemoveMe player ; endif ; set RefOldContainer to RefContainer ; endif EndJ'ai laissé les commentaires s'il y a des idées à reprendre. J'aurais bien voulu que ça fonctionne aussi avec une arme invoquée, en fait.
Pour explication :
MustBeDestroy est une variable qui sert à signale que l'objet doit être détruit.
RefCatcher est un attrapeur : en fait une créature qui me sert juste à attraper l'objet puis je la tue, comme la créature n'est pas une référence persistente, elle sera détruite avec l'épée (si elle la possède toujours) au bout de 3 jours. Et comme je la désactive, le joueur ne peu pas la voir et donc fouiller son inventaire ou se prendre les pieds dedans.
Quand l'objet n'est pas dans un container (RefCatcher = 0), je signale que l'objet doit être détruit et je le fait ramasser par l'attrapeur mort.
Si l'objet est dans un container mort, je retire l'objet. Donc normalement l'objet devrait être supprimé avant même que les mouches ne pondent sur l'attrapeur mort. Une épée scriptée ainsi et posée au sol dans une cellule initialement disparait sans qu'on ai eu le temps de le remarquer.
Le problème :
- Si un un acteur (et cela inclu le joueur) invoque l'épée, il peux l'utiliser.
- L'épée est en quest item, donc il est censé ne pas pouvoir la perdre et la fin du sort lui retire l'épée.
=> Oui, mais si le joueur ne perd pas l'épée, comment faire pour qu'un PNJ ou une créature ne la perde pas ?
- J'ai créé une nouvelle créature qui possède initialement cette épée. L'épée ne s'envole pas et la créature ne dispose pas du sort d'invocation. Cependant, à la mort de la créature qui est désarmée (car l'épée est un objet de quête ?), l'épée ne disparaît pas et "MustBeDestroy" vaut 1.
=> Comment supprimer un objet lorsqu'il quitte un inventaire, qu'il est jetté ou bien lorsque l'acteur est désarmé ?
Bon comme je suis content et que j'ai envie de me gratifier, je me reprend :"Comme je suis très intelligent"...J'ai trouvé une solution, cependant, je me demande si lorsque l'objet est à terre, je le transfère au joueur ou à ma créature invisible ? C'est-à-dire que si je le transfère au joueur, on va entendre un petit "slack" comme lorsqu'on ramasse un objet à terre. Ce n'est pas la cas avec la créature, mais je n'utilise pas de "CreateFullActorCopy" parceque l'objet est supprimé de l'inventaire de la créature et le script est sur l'objet... En fait ça veut dire que pour supprimer le clone de mon attrapeur créé avec "createfullactorcopy" je devrais utiliser "deletefullactorcopy", après ajout de l'objet, oui, mais là, j'ai risque de bug...enfin, y a peu être un moyen... bon, en attendant, je me demande si c'est mieux de créer une créature qu'on tue direct ou de transférer l'objet au joueur pour qu'il se supprime tout seul ?
ScriptName AARFSLSelfDisableOnDropAndPlayerScript ; Script d'objet // Object script; ; Ce script sert à faire disparaître un objet jetté à terre ou ajouté au joueur. ; This script is used to destroy an object dropped on the ground or added to the player short MustBeDestroy ref RefContainer ref RefCatcher float timer ; Si l'arme est jetée ou donnée // If the weapon is dropped or given Begin OnDrop set MustBeDestroy to 1 set timer to 0.1 End Begin GameMode set RefContainer to GetContainer if (RefContainer > 0) ; Si le container est mort ou qu'il n'est pas un acteur // If the container is dead or if it is not an actor if (MustBeDestroy == 0) if (RefContainer.GetDead == 1 || (RefContainer.GetIsCreature == 0 && RefContainer.IsActor == 0)) set MustBeDestroy to 1 set timer to 0.1 RemoveMe endif ; Si l'arme doit être détruite et qu'elle est reprise // If the weapon must be destroyed and if it's picked else RemoveMe endif else if (MustBeDestroy == 0) set MustBeDestroy to 1 set timer to 0.1 else if (timer > 0) set timer to (timer - GetSecondsPassed) else Activate player endif endif endif End
Modifié par beeratwork, 06 mai 2010 - 11:29.