Page 1 sur 1

Script de retrait d'objets après craft

Posté : 09 déc. 2012, 17:29
par Jason Bourne
D'abord j'espère que je commence ce sujet dans la bonne section.

Je voudrais faire un script qui retire certains objets après avoir quitté ou désactivé l'enclume.
J'ai utilisé "Event OnDesactivate" car je ne savais pas quoi mettre mais cela ne marche pas. Dans le création kit, quand je sauvegarde il n'y a aucune erreur mais dans le jeu cela ne marche pas. Voici mon script (oui je sais il est trèèèèès... long) Je tiens à écrire que cela peut gâcher votre expérience de jeu donc ne faîtes pas ce script chez vous sauf si vous le voulez vraiment! S'il vous plait ne me dites pas que je suis un tricheur, je ne fais cela que pour tester des mods de forge ou bien d'ajout d'armes/armures dans la forge. Merci de votre compréhension. (j'en fais pas un peu trop?)
► Afficher le texte
PS: J'espère que cela n'a pas déjà été demandé. Excusez moi si cela l'a déjà été, je n'ai rien trouvé dans la section recherche. Si tel est le cas merci de bien vouloir supprimer mon message ou de le remettre dans le bon sujet et/ou la bonne section.
PS2: Les autres personnes qui ont des problèmes pour leurs scripts peuvent poster sur ce sujet si aucun autre sujet n'a déjà été créé pour ce type de problème/demande. => Gerauld dit NON.

Re: Aide Scripts

Posté : 10 déc. 2012, 21:02
par Gerauld
Hors-sujet
Tu es dans la bonne section avec une bonne question à poser même si je ne vois pas l'intérêt du script en lui-même (à part si tu as un autre script qui t'ajoute ces éléments quand tu actives ton enclume), il peut être l'occasion d'introduire le travail sur les formlists et même mieux sur les tableaux. Il ne faut pas avoir peur de poster dans la mauvaise section. Au pire, j'effectue un déplacement du sujet..Je ne mors que très rarement..
L'event ondesactivate n'existe pas donc ne déclenchera jamais. Dans ton cas, le mieux sera d'utiliser un event onactivate et de faire patienter le script jusqu'à la fermeture de la fenêtre de craft. Il existe aussi des fonctions SKSE permettant directement de détecter la fermeture de ces menus mais ce serait utiliser un bulldozer pour écraser une mouche.

On va commencer par un exemple avec formlist. Il se peut qu'il y ai une ou deux erreurs de compilation l'ayant directement fait ici et non dans Papyrus. A tester donc.

Je n'ai pas compris pourquoi tu les testais deux à deux mais si c'est important pour ton idée, dis le moi, je te présenterai une autre version du script.

Donc, pour en revenir au permier exemple, il est basé sur l'utilisation d'une formlist que l'on balaye avec une variable baptisée index. Il suffit de glisser les objets que tu veux supprimer à la fin du craft dans la formlist (baptisée malistedobjets dans cet exemple).
A chaque fois, on compte le nombre d'objets et on les retirent s'il y en a.
Afin de ne pas supprimer les objets dès le début du craft, on attends, après l'activation par le joueur que celui-ci puisse à nouveau switcher entre les vues, ce qui signifiera que le craft est terminé (petite astuce made in nounours mais il y a d'autres moyens d'arriver au même résultat).

Code : Tout sélectionner

Scriptname ExempleAvecFormList extends objectreference

actor property playerref auto   ; se remplira en faisant autofill
formlist property malistedobjets auto ,il faut créer une formlist avec tout les objets à virer

auto state attente   ; j'attends
     Event onactivate(objectreference akactivator)   ; que l'on m'active
           if akactivator == playerref   ; et que ce soit le joueur
               gotostate("busy")  ; j'empêche une deuxième activation du script en le passant dans un état occupé.
               while !game.IsCamSwitchControlsEnabled()
                       ; J'attends de pouvoir switcher de caméra, ce qui voudra dire que le craft est terminé. 
                       ; Petite astuce made in nounours
               endwhile  
               int index = 0   ; index qui va se ballader dans la formlist pour faire tous les objets
               int nb = 0   ; cela correspondra au nombre présent dans l'inventaire de chaque objet
               while index < malistedobjets.getsize() ; tant que je n'ai pas balayé toute la liste
                     nb = playerref.getitemcount(malistedobjets.getat(index))  ; je regarde combien j'ai d'objets
                     if nb > 0   ; s'il y en a
                          playerref.removeitem(malistedobjets.getat(index), nb, true)  ; je les supprime tous. 
                                   ;Tu peux remplacer nb par une autre valeur si tu souhaites les garder à partir d'un certain nombre.
                     endif 
                     index += 1  ; je passe à l'objet suivant de la liste
                endwhile
               gotostate("attente")  ; je reviens à l'état attente vu que j'ai fini mon script.
      endif
    endevent
endstate

state busy
    ;Le script est déjà lancé donc inutile de le relancer. Ne sert normalement à rien ici mais peut servir pour d'autres types d'objets
endstate
Normalement, cela devrait marcher. N'oublie pas de remplir les propriétés après avoir attaché le script à ton enclue. Ce script étant directement attaché sur un objet, il faudra, pour le tester, partir d'une sauvegarde hors de la cell concernée donc sans enclume à procximité pour que cela puisse être pris en compte.

Re: [Demande] Script de retrait d'objets après craft

Posté : 11 déc. 2012, 20:14
par Jason Bourne
J'avais fait 2 par 2 parce que je ne sais pas si il faut mettre ça (pour un nombre de 3 objets):
► Afficher le texte
Ou si il faut retirer un "&" à la deuxième suite de "&" et retirer une parenthèse à la fin?

Sinon merci je vais tester ça de suite.

Re: [Demande] Script de retrait d'objets après craft

Posté : 11 déc. 2012, 20:45
par Gerauld
le && signifie "ET" et || signifie "OU". &&& n'existe pas.
Si tu mets
if Game.GetPlayer().GetItemCount(IngotIron) < 1) && (Game.GetPlayer().GetItemCount(IngotGold) < 1)
cela signifie :
Si le joueur a moins d'un lingot de fer ET moins d'un lingot d'or

Si tu mets
if Game.GetPlayer().GetItemCount(IngotIron) < 1) || (Game.GetPlayer().GetItemCount(IngotGold) < 1)
Cela signifie :
Si le joueur a moins d'un lingot de fer OU si le joueur a moins d'un lingot d'or.

Si tu veux ajouter des objets (20 en cas d'absence de l'nventaire) à l'activation et en retirer ensuite, il faudrait faire :

Code : Tout sélectionner

Scriptname ExempleAvecFormListettableau extends objectreference

actor property playerref auto   ; se remplira en faisant autofill
formlist property malistedobjets auto ;il faut créer une formlist avec tout les objets à virer
int[] memoire ;je créé un tableau pour garder en mémoire le nombre d'objets détenus avant ajout
 
Event OnInit()  ;ceci se déclenche quand le script s'initialise, avant l'activation donc
    memoire = New int[60] ;je prends large car on ne peut mettre de variable pour définir un tableau
EndEvent

auto state attente   ; j'attends
     Event onactivate(objectreference akactivator)   ; que l'on m'active
           if akactivator == playerref   ; et que ce soit le joueur
               gotostate("busy")  ; j'empêche une deuxième activation du script en le passant dans un état occupé.
               int index = 0   ; index qui va se ballader dans la formlist pour faire tous les objets
               int nb = 0   ; cela correspondra au nombre présent dans l'inventaire de chaque objet
               while index < malistedobjets.getsize() ; tant que je n'ai pas balayé toute la liste
                     memoire[index] = playerref.getitemcount(malistedobjets.getat(index))  ; je regarde combien j'ai d'objets et je garde ça en mémoire
                     if memoire[index] == 0   ; si le joueur n'en a pas dans son inventaire
                          playerref.additem(malistedobjets.getat(index), 20, true)  ; J'en ajoute 20
                     endif
                     index += 1  ; je passe à l'objet suivant de la liste
                endwhile
               while !game.IsCamSwitchControlsEnabled()
                       ; J'attends de pouvoir switcher de caméra, ce qui voudra dire que le craft est terminé.
                       ; Petite astuce made in nounours
               endwhile 
               index = 0   ; je n'oublie pas de remettre l'index à 0
               while index < malistedobjets.getsize() ; tant que je n'ai pas balayé toute la liste
                     nb = playerref.getitemcount(malistedobjets.getat(index))  ; je regarde combien j'ai d'objets
                     if nb > memoire[index]   ; s'il y en a
                          playerref.removeitem(malistedobjets.getat(index), nb - memoire[index], true)  ; je retire ceux qui ont été éventuellement ajoutés pour revenir au nombre gardé en mémoire
                                   ;Tu peux remplacer nb par une autre valeur si tu souhaites les garder à partir d'un certain nombre.
                     endif
                     index += 1  ; je passe à l'objet suivant de la liste
                endwhile
               gotostate("attente")  ; je reviens à l'état attente vu que j'ai fini mon script.
      endif
    endevent
endstate

state busy
    ;Le script est déjà lancé donc inutile de le relancer. Ne sert normalement à rien ici mais peut servir pour d'autres types d'objets
endstate
Si on veut dans tous les cas ajouter 20 objets puis revenir au nombre initial, il faut faire :

Code : Tout sélectionner

Scriptname ExempleAvecFormListettableau extends objectreference
actor property playerref auto   ; se remplira en faisant autofill
formlist property malistedobjets auto ;il faut créer une formlist avec tout les objets à virer
int[] memoire ;je créé un tableau pour garder en mémoire le nombre d'objets détenus avant ajout

Event OnInit()  ;ceci se déclenche quand le script s'initialise, avant l'activation donc
	memoire = New int[60] ;je prends large car on ne peut mettre de variable pour définir un tableau
	; ce nombre doit être supérieur à la longueur de ta formlist
EndEvent

auto state attente   ; j'attends
	Event onactivate(objectreference akactivator)   ; que l'on m'active
		if akactivator == playerref   ; et que ce soit le joueur
			gotostate("busy")  ; j'empêche une deuxième activation du script en le passant dans un état occupé.
			int index = 0   ; index qui va se ballader dans la formlist pour faire tous les objets
			int nb = 0   ; cela correspondra au nombre présent dans l'inventaire de chaque objet
			while index < malistedobjets.getsize() ; tant que je n'ai pas balayé toute la liste
				memoire[index] = playerref.getitemcount(malistedobjets.getat(index))  ; je regarde combien j'ai d'objets et je garde ça en mémoire
				playerref.additem(malistedobjets.getat(index), 20, true)  ; J'en ajoute 20 tout le temps
				index += 1  ; je passe à l'objet suivant de la liste
			endwhile
			while !game.IsCamSwitchControlsEnabled()
				; J'attends de pouvoir switcher de caméra, ce qui voudra dire que le craft est terminé.
				; Petite astuce made in nounours
			endwhile
			index = 0   ; je n'oublie pas de remettre l'index à 0
			while index < malistedobjets.getsize() ; tant que je n'ai pas balayé toute la liste
				nb = playerref.getitemcount(malistedobjets.getat(index))  ; je regarde combien j'ai d'objets
				if nb > memoire[index]   ; s'il y en a plus qu'avant m'ajout
					playerref.removeitem(malistedobjets.getat(index), nb - memoire[index], true)  ; je retire ceux qui ont été éventuellement ajoutés pour revenir au nombre gardé en mémoire
				elseif nb < memoire[index] ; si j'en ai moins qu'avant
					playerref.additem(malistedobjets.getat(index), memoire[index] - nb, true)
					;j'ajoute la différence pour avoir le même nombre qu'au début
				endif
				index += 1  ; je passe à l'objet suivant de la liste
			endwhile
			gotostate("attente")  ; je reviens à l'état attente vu que j'ai fini mon script.
		endif
	endevent
endstate

state busy
	;Le script est déjà lancé donc inutile de le relancer. Ne sert normalement à rien ici mais peut servir pour d'autres types d'objets
endstate

Re: [Demande] Script de retrait d'objets après craft

Posté : 28 déc. 2012, 09:35
par Gerauld
Hors-sujet
Juste pour savoir si je peux passer le sujet en résolu, n'ayant pas eu de nouvelles depuis longtemps....