Posté le: 11/12/08 20:55 Sujet du message: [vJass] FW SimpleDialogs
Bonjour à tous,
Voici un petit systeme que j'ai fait pour NoK, qui a pour but de simplifier l'utilisation des panneaux de dialogues, en gérant automatiquement la détection du bouton cliqué et ses actions.
Vous pouvez très simplement attacher des unités ou des entiers au panneau/boutons.
Nécessite: JassHelper (vJass)
Jass:
//***************************************************************************************************
// FW Simple Dialogs :
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Version : 1.00
// Author(s) : profet
//
// DESCRIPTION:
// Use the Warcraft3's dialog system becomes a painful task when we attempt to
// create a lot of dialogs in our maps, because it requires to create "dialog
// is clicked" triggers and compare the clicked button with buttons stored in
// variables to get desired actions.
//
// Simple Dialogs takes care of triggers creation and buttons comparisons, and
// automatically execute Actions functions defined for each buttons you created.
//
//
// HOW TO USE?
// As DialogCreate() should only be used to create one dialog per player, the
// system handles it automatically and you'll never have to use this function.
//
// When you want to create a new dialog for a player, you need to call the
// function FWSD_NewDialog(*).
//
// Note: If you previously created a dialog, this will clear the dialog
// window and you'll also never have to use DialogClear().
//
// Adding a button to the last created dialog can be done by using a second
// function FWSD_AddDialogButton(*).
// You can specify an ASCII number hotkey as argument.
//
//
// ATTACHING ACTIONS TO BUTTONS:
// The real advantage of this system is the way it links button's clicks and
// actions.
//
// The second argument of FWSD_AddDialogButton(*) takes a pointer
// to the function to execute, called when the button is clicked.
//
// You can also attach data to the dialog, like units or integer by using
// appropriated functions.
//
//
//***************************************************************************************************
library FWSD
globals
public constant integer MAX_BUTTONS = 7
public constant integer CANCEL_HOTKEY = 512
public constant string CANCEL_DEFAULTSTRING = "< Cancel >"
endglobals
globals
private s_dialog array DIALOG
endglobals
//===========================================================================
//This function is executed when a dialog button is clicked.
//It executes the .clicked() method of the dialog's structure.
private function dialogClicked takes nothing returns nothing
call DIALOG[GetPlayerId(GetTriggerPlayer())].Clicked(GetClickedButton())
endfunction
//===========================================================================
//
struct s_dialog
private dialog h
private integer p
private trigger t = null
private integer btnCount = 0
private integer array btn_int[MAX_BUTTONS]
private button array btn_list[MAX_BUTTONS]
private dialogAction array btn_func[MAX_BUTTONS]
unit dialog_u1 = null
unit dialog_u2 = null
integer dialog_int = 0
method SetTitle takes string title returns nothing
call DialogSetMessage( .h, title )
endmethod
method AddButton takes string text, dialogAction func, integer key, integer attachedInt returns boolean
if( .btnCount<MAX_BUTTONS-1 or (key==CANCEL_HOTKEY and .btnCount<MAX_BUTTONS) )then
set .btn_list[.btnCount] = DialogAddButton( .h, text, key )
set .btn_func[.btnCount] = func
set .btn_int[.btnCount] = attachedInt
set .btnCount = .btnCount + 1
return true
endif
return false
endmethod
method onDestroy takes nothing returns nothing
call DestroyTrigger(.t)
set DIALOG[.p] = 0
endmethod
static method create takes integer p returns s_dialog
local s_dialog this = s_dialog.allocate()
set this.p = p
set this.h = DialogCreate()
set this.t = CreateTrigger()
call TriggerAddAction( this.t, function dialogClicked )
call TriggerRegisterDialogEvent( this.t, this.h )
return this
endmethod
endstruct
//===========================================================================
//This function init a new dialog for specified player.
//When 'keepvars' parameter is set to TRUE, the new dialog keeps data attached to
//the previous dialog (usefull to display many dialogs in the raw).
public function NewDialog takes integer playerid, boolean keepvars returns nothing
if( DIALOG[playerid]==0 )then
set DIALOG[playerid] = s_dialog.create(playerid)
endif
if( not keepvars )then
set DIALOG[playerid].dialog_int = 0
set DIALOG[playerid].dialog_u1 = null
set DIALOG[playerid].dialog_u2 = null
endif
call DIALOG[playerid].Clear()
endfunction
//Defines the title of the last intialized dialog for specified player.
public function SetDialogTitle takes integer playerid, string title returns nothing
if( DIALOG[playerid]!=0 )then
call DIALOG[playerid].SetTitle(title)
endif
endfunction
//Defines the attached units of the last intialized dialog.
public function SetDialogUnits takes integer playerid, unit unit1, unit unit2 returns nothing
if( DIALOG[playerid]!=0 )then
set DIALOG[playerid].dialog_u1 = unit1
set DIALOG[playerid].dialog_u2 = unit2
endif
endfunction
//Defines the attached integer of the last intialized dialog.
public function SetDialogInteger takes integer playerid, integer attachedInt returns nothing
if( DIALOG[playerid]!=0 )then
set DIALOG[playerid].dialog_int = attachedInt
endif
endfunction
//Adds a button to the last initialized dialog.
//The 'key' parameter defines the button's hotkey (ASCII numbers).
public function AddDialogButton takes integer playerid, string text, dialogAction func, integer key, integer data returns boolean
if( DIALOG[playerid]!=0 )then
return DIALOG[playerid].AddButton(text,func,key,data)
endif
return false
endfunction
//Displays the last initialized dialog for specified player.
public function StartDialog takes integer playerid returns nothing
if( DIALOG[playerid]!=0 )then
call DIALOG[playerid].Start()
endif
endfunction
//***************************************************************************************************
function interface dialogAction takes integer playerId, integer buttonId, unit dialogUnit1, unit dialogUnit2, integer dialogInteger returns nothing
//***************************************************************************************************
endlibrary
function ClickedQuest takes integer playerId, integer buttonId, unit dialogUnit1, unit dialogUnit2, integer dialogInteger returns nothing
call BJDebugMsg( "Quest clicked #"+I2S(buttonId+1) )
endfunction
function AvailableQuests takes integer playerId, integer buttonId, unit dialogUnit1, unit dialogUnit2, integer dialogInteger returns nothing
local integer count = 0
local integer decal = FWSD_MAX_BUTTONS-3
local integer min = buttonId*decal //buttonId = current page of the quests list
local integer max = (buttonId+1)*decal
local integer i=0
local string array QUESTS
local integer QUESTS_COUNT = 15
set QUESTS[0] = "Quest 1"
set QUESTS[1] = "Quest 2"
set QUESTS[2] = "Quest 3"
set QUESTS[3] = "Quest 4"
set QUESTS[4] = "Quest 5"
set QUESTS[5] = "Quest 6"
set QUESTS[6] = "Quest 7"
set QUESTS[7] = "Quest 8"
set QUESTS[8] = "Quest 9"
set QUESTS[9] = "Quest 10"
set QUESTS[10] = "Quest 11"
set QUESTS[11] = "Quest 12"
set QUESTS[12] = "Quest 13"
set QUESTS[13] = "Quest 14"
set QUESTS[14] = "Quest 15"
//questbuttons list
loop
exitwhen(i==QUESTS_COUNT)
//if( is_quest_takeable? )then
if(count>=min and count<max)then
call FWSD_AddDialogButton( playerId, QUESTS[i], ClickedQuest, 0, i )
endif
set count=count+1
//endif
set i=i+1
endloop
Joueur - Joueur 1 (Rouge) skips a cinematic sequence Joueur - Joueur 2 (Bleu) skips a cinematic sequence Joueur - Joueur 3 (Cyan) skips a cinematic sequence Joueur - Joueur 4 (Pourpre) skips a cinematic sequence Joueur - Joueur 5 (Jaune) skips a cinematic sequence Joueur - Joueur 6 (Orange) skips a cinematic sequence Joueur - Joueur 7 (Vert) skips a cinematic sequence Joueur - Joueur 8 (Rose) skips a cinematic sequence Joueur - Joueur 9 (gris) skips a cinematic sequence Joueur - Joueur 10 (Bleu clair) skips a cinematic sequence Joueur - Joueur 11 (Vert foncé) skips a cinematic sequence Joueur - Joueur 12 (Marron) skips a cinematic sequence
VERSION ALTERNATIVE
Voilà la nouvelle version de ce système, pas énormément de changements, quelques mises à jours par-ci par-là et optimisations.
N'ayant pas le temps de refaire une passe sur les commentaires et les exemples, je laisse donc la version précédente, mais le fonctionnement est similaire et vous arriverez surement à adapter les explications.
Enjoy
PS: en cas de doute, n'hésitez pas à venir me poser vos questions sur msn.
Jass:
library JSDialog initializer init
//***************************************************************************************************
//* JSDialog
//* ----------
//* Author: Profet
//*
//*
//*
//*
//* To implement, just get a vJass compiler and
//* copy this library/trigger to your map.
//*
//***************************************************************************************************
//* SETTING CONSTANTS
globals
private constant integer MAX_BUTTONS = 7 // Maximum number of buttons by dialog.
private constant integer CANCEL_HOTKEY = 512 // ASCII number of cancel shortcut (Esc=512).
private constant string CANCEL_STRING = "|cffFF0000< Cancel >|r" // Defaut "cancel" button's text.
endglobals
//===========================================================================
//* FUNCTIONS INTERFACES
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// IFuncDialogBtnAction : <p> Id of the player who clicked the button.
// <dialogUnit> Unit attached to the dialog.
// <dialogInteger> Integer value attached to the dialog.
// <btnInteger> Integer value attached to the clicked button.
//
//===========================================================================
function interface IFuncDialogBtnAction takes integer p, unit dialogUnit, integer dialogInteger, string btnString, integer btnInteger returns nothing
//===========================================================================
//* LIBRARY'S CORE
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//*
//* Do NOT modify without a really good reason !!
//*
//===========================================================================
private keyword s_dialog
globals
private s_dialog array DIALOG
endglobals
private function init takes nothing returns nothing
local integer i = 0
loop
exitwhen( i==12 )
set DIALOG[i] = s_dialog.create(i)
set i=i+1
endloop
endfunction
private struct s_dialog
// Dialog's members.
private dialog d
private integer p
private trigger t
private integer dialogInteger = 0
private unit dialogUnit = null
// Constructor.
static method create takes integer p returns s_dialog
local s_dialog this = s_dialog.allocate()
set this.p = p
set this.d = DialogCreate()
set this.t = CreateTrigger()
call TriggerAddAction( this.t, function s_dialog.clicked_Actions )
call TriggerRegisterDialogEvent( this.t, this.d )
return this
endmethod
// .
method Clear takes string title, unit un, integer attachedInt returns nothing
set .dialogUnit = un
set .dialogInteger = attachedInt
call DialogClear(.d)
call DialogSetMessage( .d, title )
set .btnCount = 0
endmethod
// .
method AddButton takes string text, IFuncDialogBtnAction func, integer key, string attachedString, integer attachedInt returns boolean
if( .btnCount<MAX_BUTTONS )then//-1 or (key==CANCEL_HOTKEY and .btnCount<MAX_BUTTONS)
set .btnList[.btnCount] = DialogAddButton( .d, text, key )
set .btnFunc[.btnCount] = func
set .btnString[.btnCount] = attachedString
set .btnInteger[.btnCount] = attachedInt
set .btnCount = .btnCount + 1
return true
endif
return false
endmethod
//===========================================================================
//* PUBLIC FUNCTIONS
//===========================================================================
// Show the specified player's dialog.
public function Show takes integer playerId returns nothing
call DIALOG[playerId].Show()
endfunction
// Remove all buttons from the player's dialog, change it's title and attached values.
public function Clear takes integer playerId, string title, unit attachedUnit, integer attachedInt returns nothing
call DIALOG[playerId].Clear( title, attachedUnit, attachedInt )
endfunction
// Add a button to the player's dialog, return FALSE if there are already too many buttons (MAX_BUTTONS) in the dialog.
public function AddButton takes integer playerId, string text, IFuncDialogBtnAction func, integer key, string attachedString, integer attachedInt returns boolean
return DIALOG[playerId].AddButton( text, func, key, attachedString, attachedInt )
endfunction
// Return the maximum number of buttons by dialog.
public function MaxButtons takes nothing returns integer
return MAX_BUTTONS
endfunction
// Return the default Cancel button string.
public function CancelText takes nothing returns string
return CANCEL_STRING
endfunction
// Return the default Cancel button hotkey.
public function CancelHotkey takes nothing returns integer
return CANCEL_HOTKEY
endfunction
endlibrary
_________________
Bêta Systems:70% Bêta Spells:13% Bêta Arts & graphics:70%
Dernière édition par profet le 26/05/09 18:50; édité 4 fois
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 11/12/08 21:17 Sujet du message:
Je pense que ca serait mieux d'utiliser une fonction interface plutôt.
A moins que l'on ne peut pas .execute() une fonction interface ?
Ca donnerait une erreur de code en compilant si on met un nom de fonction incorrect, au lieu de simplement crasher la map in game en trouvant difficilement l'erreur.
D'ailleurs je ne vois pas d'appel de ExecuteFunc dans ton code
PS : Les commentaires en gris saymoche. _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 12/12/08 21:00 Sujet du message:
On est certes pas obligé de définir un raccourci pour la boite, mais même sans cela un appui sur la touche entrée peut valider un choix involontaire. _________________
Dernière édition par Troll-Brain le 16/07/12 17:44; édité 1 fois
Cela n'est pas dû a une erreur de mon fait, mais à la gestion des panneaux de dialogues de war3 (si on ne définit pas de couleurs de texte pour les boutons, le choix sélectionné apparait en blanc, on peut alors changer avec les fleches du clavier, et valider avec entrée) _________________
Bêta Systems:70% Bêta Spells:13% Bêta Arts & graphics:70%
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 12/12/08 21:09 Sujet du message:
profet a écrit:
Cela n'est pas dû a une erreur de mon fait, mais à la gestion des panneaux de dialogues de war3 (si on ne définit pas de couleurs de texte pour les boutons, le choix sélectionné apparait en blanc, on peut alors changer avec les fleches du clavier, et valider avec entrée)
Y'a mal donne là, je ne parles pas d'erreur de code, j'explique juste pourquoi je n'aime pas les boites de dialogue. _________________
Oui, et s'il n'y avait que ça, mais le retour a la ligne du titre n'est pas pris en compte, impossible de les redimensionner, etc... mais très souvent on ne peut pas s'en passer.
Mais ce système est fait pour se débarrasser de la partie la plus chiante, c'est déjà ça. _________________
Bêta Systems:70% Bêta Spells:13% Bêta Arts & graphics:70%
Brissou de Mourièssou Créateur de sorts, depuis 1936.
Inscrit le: 30 Aoû 2007 Messages: 1510 Sujets: 26 Spécialité en worldedit: Développer des jeux vidéos pour le fun, donc world edit c'est comme faire une addition. Médailles: 2 (En savoir plus...)
Posté le: 12/12/08 21:28 Sujet du message:
Moa je dit ton système y sert à rien, en GUI c'est super facile à faire. Mouahhahaa _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 21/12/08 13:30 Sujet du message:
Tu leak d'une action à chaque fois que tu détruits un trigger, pour éviter ce problème utilise une condition à la place, et même mieux recycle tes triggers aussi. _________________
Inscrit le: 22 Nov 2007 Messages: 677 Sujets: 27 Spécialité en worldedit: Jamais sortir ses projets ?
Posté le: 24/12/08 03:16 Sujet du message:
Il faudrait que tu implante dans le système un moyen simple de faire des sous menu dans les boutons.
Du genre:
AddDialogButtonMenu(integer playerid, string text, s_dialog triggeredDialog)
Enfin personnellement j'utiliserai jamais cette partie du FrameWork , trop compliqué pour pas grand chose (enfin je suis pas près de faire une map avec 50 dialogue différent). _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 26/12/08 16:02 Sujet du message:
Tu pourrais au moins utiliser une condition à la place.
Ca prend 2 min à être modifié.
Je suis d'accord que pour les leaks non résolvables, il ne faut pas trop s'en soucier, mais là c'est sensé être un système, un modèle de référence.
Comme la modification est uber facile, je ne vois pas ce qui te dérange.
T'as même pas l'excuse du "je suis trop occupé IRL". _________________
Toutes les heures sont au format GMT + 1 Heure Aller à la page 1, 2, 3, 4Suivante
Page 1 sur 4
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum