| 05-23-2008, 02:21 AM | #1 |
Pyrogasm helped me a while back to make this system of dialogs for players to ally each other. The goal is that one player can type -ally blue and then the blue player will get a dialog asking if he wishes to ally. He can accept or decline. When someone unallys another player, there is no dialog. When one player unallys anohter, he declares hostility as well. I attached a separate map with the the necessary scripts. I'm hoping Pyrogasm or someone else could take a few minutes and run through the errors, as I tried everything I could think of with my very weak JASS skills. EDIT: This is a link to thread where I originally asked for a script, and then in the last post of the thread I showed the errors I get. http://wc3campaigns.net/showthread.php?t=99105 |
| 05-23-2008, 02:39 AM | #2 |
Um wait, what's wrong with it? And it looks like Cohadar and Pyrogasm gave you some script so what's the problem? |
| 05-23-2008, 03:08 AM | #3 |
There are a lot of syntax and undeclared function errors. They are all explained in the post I linked and you can see them if you try to compile the demo map with New Gen WE. |
| 05-26-2008, 05:52 PM | #4 |
*Ressurected by Request* I can't test right now if his script would compile or not, but be sure that you're using the most recent JNGP, that's important. It's tricky for me to give much valuable feedback on the script you linked to because I'm unfamiliar with cohadar's dialog system (And yes, don't care to familiarize myself with it). It would be particularly valuable if you PMd/harassed Pyro (Who wrote it), as surely the errors are either in the inclusion of the correct libraries in your map, the usage of said libraries in the script, or a stupid syntax error (He's prone to those as well). |
| 05-27-2008, 08:11 AM | #5 |
Yeah, he harassed me, but some of the things that are giving him errors shouldn't be. Like his: JASS:local Dialog D = GetTriggerDialog() if D.GetResult == HK_Y then //Undeclared variable dialog Put this library first ABC://============================================================================== // ABC -- STRUCT ATTACHMENT SYSTEM BY COHADAR -- v5.1 //============================================================================== //============================================================================== // Quick function index: //============================================================================== // // ---------------------------------------------------------------------- // Set Functions - these functions attach struct to a handle // ---------------------------------------------------------------------- // SetTimerStructA(timer, struct) // SetTimerStructB(timer, struct) // SetTimerStructC(timer, struct) // // SetTriggerStructA(trigger, struct) // SetTriggerStructB(trigger, struct) // SetTriggerStructC(trigger, struct) // // SetDialogStructA(dialog, struct) // SetDialogStructB(dialog, struct) // SetDialogStructC(dialog, struct) // // ---------------------------------------------------------------------- // Get Functions - these functions retrieve attached structs // ---------------------------------------------------------------------- // GetTimerStructA(timer) -> struct // GetTimerStructB(timer) -> struct // GetTimerStructC(timer) -> struct // // GetTriggerStructA(trigger) -> struct // GetTriggerStructB(trigger) -> struct // GetTriggerStructC(trigger) -> struct // // GetDialogStructA(dialog) -> struct // GetDialogStructB(dialog) -> struct // GetDialogStructC(dialog) -> struct // // ---------------------------------------------------------------------- // Clear Functions - these functions clear and return attached value // ---------------------------------------------------------------------- // ClearTimerStructA(timer) -> struct // ClearTimerStructB(timer) -> struct // ClearTimerStructC(timer) -> struct // // ClearTriggerStructA(trigger) -> struct // ClearTriggerStructB(trigger) -> struct // ClearTriggerStructC(trigger) -> struct // // ClearDialogStructA(dialog) -> struct // ClearDialogStructB(dialog) -> struct // ClearDialogStructC(dialog) -> struct // //============================================================================== //============================================================================== // DOCUMENTATION: //============================================================================== // // PURPOUSE OF ABC: // * Attaching multiple structs to a <handle> // * Not using stupid game cache. // // * Currently supported <handle> types are timer, trigger and dialog // ABC can NOT be used to attach things to units, // Systems that can attach stuff to units require a mission key // ABC does not have mission keys, witch is one of the reasons it is so fast. // // * These are the only 3 handle types I found that need attaching (except units) // If you have the need for some other handle types please let me know // // HOW TO USE: // * Lets assume you want to attach some spell data to a timer. // You would do the following: // // 1. Create struct that will contain all your data. // 2. call SetTimerStructA(myTimer, myStruct) // // and then you decide you need one more struct on that timer... // // call SetTimerStructB(myTimer, myStruct2) // // Then in a periodic timer you just get the stored value // set myStruct = GetTimerStructA(myTimer) // // In your final itearation of periodic timer // you need to clear stored values // ClearTimerStructA(myTimer) // ClearTimerStructB(myTimer) // If you don't system will start to overflow // // DIFFERENCE FROM v5.0: // * You cannot use SetStructA two times on the same <handle> // without clearing the previous value. // // * ABC v5.0 used to overwrite the old values when you did that. // This caused errors when collisions get over 3 // Since collisions almost never happen in real maps noone noticed this before // Only some hardcore tests will detect this // // * New version of ABC treats overwrite as an error. // BAD: SetStructA(X, value1); SetStructA(X, value2) // GOOD: SetStructA(X, value1); ClearStructA(X); SetStructA(X, value2) // // * HASH_COLLISION_LIMIT is reduced from 8 to 7 to simplyfy algorithms // (using null borders at modulo 8) // This effectively means that you can store around 6000 attachments per hash // before you get an overflow. (used to be 7000) // // * This simplyfication increased ABC speed a little. // // PROS: // * ABC is faster than any gamecache based system. // // * you can attach any struct to any supported <handle> type // // * you CAN attach up to 3 structs on the same <handle> // but only if you use different functions, for example // SetTriggerStructA(), SetTriggerStructB(), SetTriggerStructC() // // * get and set functions are extremelly fast (using hash algorithm) // // * System reports collision, overwrite and overflow. // Basically if you do anything stupid system will tell you. // // * This system will work even if your map leaks // and will NOT slow down because of it. // // * This is the system that spits torment test in the eye. // // * For compatibility with ABC v4.6 look at ABCC library // // // CONS: // * you must manually clean the stored value - REMEMBER THIS RULE!!! // Don't forget to use ClearStruct() functions // // * you should NOT use Get without a Set - REMEMBER THIS RULE!!! // It will simply return a zero and nothing bad will happen, // but it will lag really really bad // (system will report this as an error) // // * System starts to collide if you have more than 1024 structs in one hash. // (you can see this very obviosly with -overload test) // If that happens it can mean one of 2 things: // 1. you are using more than 1024 timers, triggers or dialogs - !? // 2. you forgot to use ClearStruct and you are leaking handles somewhere // if this is the case simply do a search on your code and find // what trigger uses ABC but has no ClearStruct calls. // // DETAILS: // * when struct is detached from <handle> it is not destroyed // you still have to do that manually if necessary // // * ABC will not interfere with other attachemt systems // You can freely use any other system alongside ABC // But if you use only ABC for attachments in your map // you don't have to null local variables. // The reason for this is that gamecache gets abnormaly slow // when you don't null locals, ABC does not have this flaw. // // // SPECIAL THANKS TO: // * NagelBagel - for finding errors in versions 4.3 and 4.4 // * Here-b-Trollz - for testing ABC and for making cool spells with it. // * Toadcop - for being pain in the ass and for pushing me to improve ABC. // * emjlr3 - for pointing out the need for non-generic trigger attachments // * PandaMine - I found a bug in ABC by examining his HSAS vs ABC test // * All those people out there who use and support ABC // Thank you guys. // // HOW TO IMPORT: // * Just create a trigger named ABC // * convert it to text and replace the whole trigger text with this one // //============================================================================== //------------------------------------------------------------------------------ // We will use textmacros to create multiple instances of system //------------------------------------------------------------------------------ //! textmacro ABC takes X, NAME, TYPE //------------------------------------------------------------------------------ // Global arrays represent our hash tables. // System is currently using 3 hash tables per handle type. (A, B, C) //------------------------------------------------------------------------------ globals private $TYPE$ array $TYPE$Key$X$ private integer array $TYPE$Value$X$ private integer $TYPE$maxCollision$X$ = 0 endglobals //------------------------------------------------------------------------------ // returns the maximum collision so far //------------------------------------------------------------------------------ function Get$NAME$Collision$X$ takes nothing returns integer return $TYPE$maxCollision$X$ endfunction //------------------------------------------------------------------------------ // initializes hash arrays to prevent lag when ABC is used for the first time //------------------------------------------------------------------------------ private function Init$NAME$Hash$X$ takes nothing returns nothing set $TYPE$Key$X$[HASH_INDEX_LIMIT] = null set $TYPE$Value$X$[HASH_INDEX_LIMIT] = 0 endfunction //------------------------------------------------------------------------------ // attaches struct to a handle by using hash table //------------------------------------------------------------------------------ function Set$NAME$Struct$X$ takes $TYPE$ t, integer s returns nothing debug local integer collision // hash using 32-bit integer overflow local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS if $TYPE$Key$X$[i] == null then set $TYPE$Value$X$[i] = s set $TYPE$Key$X$[i] = t return endif debug if $TYPE$Key$X$[i] == t then debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] attachment overwrite on $TYPE$ #" +I2S(H2I(t))) debug return debug endif // if function gets below this line we have a collision debug set collision = 1 loop debug if collision >= HASH_COLLISION_LIMIT then debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] overflow") debug return debug endif debug set collision = collision + 1 set i = i + 1 exitwhen $TYPE$Key$X$[i] == null debug if $TYPE$Key$X$[i] == t then debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] attachment overwrite on $TYPE$ #" +I2S(H2I(t))) debug return debug endif endloop debug if collision > $TYPE$maxCollision$X$ then debug call BJDebugMsg("|cFFFF4444Warning: Hash[$X$] maximum collision is now: " + I2S(collision)) debug set $TYPE$maxCollision$X$ = collision debug endif set $TYPE$Value$X$[i] = s set $TYPE$Key$X$[i] = t return endfunction //------------------------------------------------------------------------------ // gets stored struct from a handle //------------------------------------------------------------------------------ function Get$NAME$Struct$X$ takes $TYPE$ t returns integer debug local integer collision // hash using 32-bit integer overflow local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS if $TYPE$Key$X$[i] == t then return $TYPE$Value$X$[i] endif // if function gets below this line we have a collision debug set collision = 1 loop debug if collision >= HASH_COLLISION_LIMIT then debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] : get request on unknown handle") debug return 0 debug endif debug set collision = collision + 1 set i = i + 1 exitwhen $TYPE$Key$X$[i] == t endloop return $TYPE$Value$X$[i] endfunction //------------------------------------------------------------------------------ // clears stored struct from a handle, also returns cleared value //------------------------------------------------------------------------------ function Clear$NAME$Struct$X$ takes $TYPE$ t returns integer debug local integer collision local integer ik local integer ret // hash using 32-bit integer overflow local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS // first find the index on witch key is stored debug set collision = 0 loop debug if collision >= HASH_COLLISION_LIMIT then debug call BJDebugMsg("|cFFFF0000ERROR: Hash[$X$] : clear request on unknown handle") debug return 0 debug endif debug set collision = collision + 1 exitwhen $TYPE$Key$X$[i] == t set i = i + 1 endloop set ik = i set ret = $TYPE$Value$X$[ik] // then find last used key index in bucket loop set i = i + 1 // we use the fact bucket borders (mod 8 indexes) are always null exitwhen $TYPE$Key$X$[i] == null endloop // shift last bucket entry to the place of removed one set $TYPE$Key$X$[ik] = $TYPE$Key$X$[i-1] set $TYPE$Value$X$[ik] = $TYPE$Value$X$[i-1] // clear the previous last bucket entry set $TYPE$Key$X$[i-1] = null return ret endfunction //! endtextmacro //============================================================================== // Macro execution -- this is where real functions get created //============================================================================== library ABC initializer Init globals public constant integer HASH_SIZE = 8192 public constant integer HASH_INDEX_LIMIT = 8190 public constant integer HASH_DOWN = 524288 // 2^19 public constant integer HASH_UP = 2134900736 // 2^22 * 509 public constant integer HASH_BIAS = 4096 // HASH_SIZE / 2 public constant integer HASH_COLLISION_LIMIT = 7 // ABC v5.0 had limit 8 // 509 is the prime closest to 512 endglobals //------------------------------------------------------------------------------ // conversion function used by the system internally // you will not need to use it directly //------------------------------------------------------------------------------ public function H2I takes handle h returns integer return h return 0 endfunction //! runtextmacro ABC("A","Timer","timer") //! runtextmacro ABC("B","Timer","timer") //! runtextmacro ABC("C","Timer","timer") //! runtextmacro ABC("A","Trigger","trigger") //! runtextmacro ABC("B","Trigger","trigger") //! runtextmacro ABC("C","Trigger","trigger") //! runtextmacro ABC("A","Dialog","dialog") //! runtextmacro ABC("B","Dialog","dialog") //! runtextmacro ABC("C","Dialog","dialog") private function Init takes nothing returns nothing call InitTimerHashA() call InitTimerHashB() call InitTimerHashC() call InitTriggerHashA() call InitTriggerHashB() call InitTriggerHashC() call InitDialogHashA() call InitDialogHashB() call InitDialogHashC() endfunction endlibrary //============================================================================== // END OF ABC STRUCT ATTACHMENT SYSTEM //============================================================================== Dialogs://============================================================================== // DIALOG SYSTEM BY COHADAR -- v2.2b //============================================================================== // // PURPOUSE: // * Displaying dialogs the easy way // * Retrieving dialog results the easy way // // // HOW TO USE: // * Dialog is basically a struct wrapper around native dialog // // * First create a dialog, // # local Dialog d = Dialog.create() // // than we add a title, // # call d.SetMessage("Some Text") // // and than we add couple of buttons // # call d.AddButton("First Button", HK_A) // # call d.AddButton("Second Button", HK_B) // # call d.AddButton("Third", HK_C) // // HK_X is a hotkey constant for a button, // there are constants for all letters + numbers 0..9 // hotkeys are not case-sensitive // // now we add a callback method for our dialog // # call d.AddAction( function SomeFunction ) // this is the function witch will be called when a player presses a button // // And finally we show the dialog in one of two ways: // # call d.ShowAll() // Displays dialog to all human players // # call d.Show( player ) // Displays dialog to specified player // // Inside your callback function you can get the clicked Dialog struct like this // local Dialog d = GetTriggerDialog() // and then use d.GetResult() to get the hotkey of a clicked button // // You can also use GetTriggerPlayer() to find out witch player pressed the button // // When you are done with Dialog you can: // # call d.destroy() // destroy it completely // # call d.clear() // or recycle it // // PROS: // * Extremelly easy to use compared to native dialogs // * It is fool-proof and will warn you if you try to do something stupid // // CONS: // * You can have a maximum of 32 dialog buttons, lol // // DETAILS: // * Don't release Dialogs before you are sure user has selected something // I recommend to never destroy Dialogs, // just create them when they are first time called and then show/hide them as needed // // THANKS: // * Magentix for finding the triggeraction leak and suggesting clear method // // REQUIREMENTS: // * ABC v5.1 or higher // // HOW TO IMPORT: // * Just create a trigger named Dialogs // * convert it to text and replace the whole trigger text with this one // //============================================================================== library Dialogs uses ABC globals // Dialog button hotkey constants constant integer HK_ESC = 512 constant integer HK_0 = 48 constant integer HK_1 = 49 constant integer HK_2 = 50 constant integer HK_3 = 51 constant integer HK_4 = 52 constant integer HK_5 = 53 constant integer HK_6 = 54 constant integer HK_7 = 55 constant integer HK_8 = 56 constant integer HK_9 = 57 constant integer HK_A = 65 constant integer HK_B = 66 constant integer HK_C = 67 constant integer HK_D = 68 constant integer HK_E = 69 constant integer HK_F = 70 constant integer HK_G = 71 constant integer HK_H = 72 constant integer HK_I = 73 constant integer HK_J = 74 constant integer HK_K = 75 constant integer HK_L = 76 constant integer HK_M = 77 constant integer HK_N = 78 constant integer HK_O = 79 constant integer HK_P = 80 constant integer HK_Q = 81 constant integer HK_R = 82 constant integer HK_S = 83 constant integer HK_T = 84 constant integer HK_U = 85 constant integer HK_V = 86 constant integer HK_W = 87 constant integer HK_X = 88 constant integer HK_Y = 89 constant integer HK_Z = 90 endglobals globals private constant integer MAX_BUTTONS = 32 // maximum of buttons on dialog endglobals //=========================================================================== // Use this inside dialog action function //=========================================================================== function GetTriggerDialog takes nothing returns Dialog return GetDialogStructA(GetClickedDialog()) // ABC endfunction //=========================================================================== struct Dialog private trigger t = CreateTrigger() private triggeraction a = null private dialog d = DialogCreate() private string messageText = "" private integer button_count = 0 private button array buttons[MAX_BUTTONS] private integer array hotkeys[MAX_BUTTONS] static method create takes nothing returns Dialog local Dialog ret = Dialog.allocate() call TriggerRegisterDialogEvent( ret.t, ret.d ) call SetDialogStructA(ret.d, ret) // ABC return ret endmethod method clear takes nothing returns nothing if .a != null then call TriggerRemoveAction(.t, .a) set .a = null endif set .messageText = "" set .button_count = 0 call DialogClear(.d) endmethod method onDestroy takes nothing returns nothing if .a != null then call TriggerRemoveAction(.t, .a) endif call DestroyTrigger(.t) call ClearDialogStructA(.d) // ABC call DialogDestroy(.d) endmethod method GetResult takes nothing returns integer local button b = GetClickedButton() local integer i = 0 loop exitwhen i >= MAX_BUTTONS if b == .buttons[i] then return .hotkeys[i] endif set i = i + 1 endloop call BJDebugMsg("|c00FF0000Dialog.GetResult: Unknown dialog hotkey") return 0 endmethod method SetMessage takes string messageText returns nothing set .messageText = messageText endmethod method AddButton takes string buttonText, integer hotkey returns nothing if .button_count >= MAX_BUTTONS then call BJDebugMsg("|c00FF0000Dialog.AddButton: Maximum number of dialog buttons is " + I2S(MAX_BUTTONS)) else set .buttons[.button_count] = DialogAddButton( .d, buttonText , hotkey ) set .hotkeys[.button_count] = hotkey set .button_count = .button_count + 1 endif endmethod method AddAction takes code actionFunc returns nothing if .a != null then call BJDebugMsg("|c00FF0000Dialog.AddAction: you cannot set more than one dialog action") else set .a = TriggerAddAction( .t, actionFunc ) endif endmethod method Show takes player whichPlayer returns nothing if .a == null then call BJDebugMsg("|c00FF0000Dialog.Show: You forgot to set a dialog action") endif if .button_count == 0 then call BJDebugMsg("|c00FF0000Dialog.Show: You cannot show dialog with no buttons") else // message must be set before every display because of some bug. call DialogSetMessage( .d, .messageText ) call DialogDisplay(whichPlayer, .d, true) endif endmethod method ShowAll takes nothing returns nothing local integer i = 0 loop exitwhen i>=12 // maximum of human players is 12 if GetPlayerController(Player(i)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then call .Show(Player(i)) endif set i = i + 1 endloop endmethod method Hide takes player whichPlayer returns nothing call DialogDisplay(whichPlayer, .d, false) endmethod method HideAll takes nothing returns nothing local integer i = 0 loop exitwhen i>=12 // maximum of human players is 12 call .Hide(Player(i)) set i = i + 1 endloop endmethod endstruct endlibrary JASS:library AllyDialogs initializer Init needs Dialogs globals //Mess with these! private constant string ALLYPHRASESTART = "-ally " //must be lowercase; include spaces if you want them private constant string UNALLYPHRASESTART = "-unally " //must be lowercase; include spaces if you want them private string REQUESTMESSAGE = "* wants to unally with you.|nDo you accept?" //"*" to signify the use of a player's name private string SENTREQUESTTEXT = "You have requested to ally with *." private string ACCEPTEDTEXT_INITPLAYER = "Your request to ally with * has been accepted. You are now allied with *." private string ACCEPTEDTEXT_TARGETPLAYER = "You have accepted a request to ally with *. You are now allied with *." private string DENIEDTEXT_INITPLAYER = "Your request to ally with * has been denied." private string DENIEDTEXT_TARGETPLAYER = "You have denied a request to ally with *." private string UNALLYTEXT = "You are now unallied with *." private constant string ACCEPTTEXT = "|cffffcc00Y|res" private constant string DENYTEXT = "|cffffcc00N|ro" private constant integer ACCEPTKEY = HK_Y //Hotkeys; check the Dialogs documentation private constant integer DENYKEY = HK_N private constant real XOFF = 0.00 //Message display offsets private constant real YOFF = 0.00 private constant real DISPLAYTIME = 5.00 endglobals private keyword Info globals //Don't mess with these public trigger AllyTrigger = CreateTrigger() //Public so they can be disabled public trigger UnAllyTrigger = CreateTrigger() private Info array Infos endglobals private struct Info player Init player Target static method create takes player Init, player Target, Dialog D returns Info local Info I = Info.allocate() set I.Init = Init set I.Target = Target set Infos[integer(D)] = I return I endmethod endstruct private function GetIdFromName takes string Name returns integer local integer I set Name = StringCase(Name, false) if Name == "red" then return 0 elseif Name == "blue" then return 1 elseif Name == "teal" then return 2 elseif Name == "purple" then return 3 elseif Name == "yellow" then return 4 elseif Name == "orange" then return 5 elseif Name == "green" then return 6 elseif Name == "pink" then return 7 elseif Name == "grey" or Name == "gray" then //2 different spellings return 8 elseif Name == "light blue" or Name == "lightblue" then //2 different spellings return 9 elseif Name == "dark green" or Name == "darkgreen" then //2 different spellings return 10 elseif Name == "brown" then return 11 endif set I = -1 loop set I = I+1 exitwhen I>11 if StringCase(GetPlayerName(Player(I)), false) == Name then return I endif endloop return 0 endfunction private function NameGet takes integer PId returns string if PId == 0 then return "|CFFFF0303"+GetPlayerName(Player(PId))+"|r" elseif PId == 1 then return "|CFF0042FF"+GetPlayerName(Player(PId))+"|r" elseif PId == 2 then return "|CFF1CB619"+GetPlayerName(Player(PId))+"|r" elseif PId == 3 then return "|CFF540081"+GetPlayerName(Player(PId))+"|r" elseif PId == 4 then return "|CFFFFFF01"+GetPlayerName(Player(PId))+"|r" elseif PId == 5 then return "|CFFFE8A0E"+GetPlayerName(Player(PId))+"|r" elseif PId == 6 then return "|CFF20C000"+GetPlayerName(Player(PId))+"|r" elseif PId == 7 then return "|CFFE55BB0"+GetPlayerName(Player(PId))+"|r" elseif PId == 8 then return "|CFF959697"+GetPlayerName(Player(PId))+"|r" elseif PId == 9 then return "|CFF7EBFF1"+GetPlayerName(Player(PId))+"|r" elseif PId == 10 then return "|CFF106246"+GetPlayerName(Player(PId))+"|r" elseif PId == 11 then return "|CFF4E2A04"+GetPlayerName(Player(PId))+"|r" endif return "Player "+I2S(PId) endfunction private function StringReplace takes string S, string N returns string local string S2 local integer I = -1 local integer Mod = StringLength(N)-1 local integer End = StringLength(S) loop set I = I+1 exitwhen I > End-1 if SubString(S, I, I+1) == "*" then set S2 = S set S = SubString(S2, 0, I)+N+SubString(S2, I+1, End) set I = I+Mod set End = End+Mod endif endloop return S endfunction private function Clicked takes nothing returns nothing local Dialog D = GetTriggerDialog() local Info I = Infos[integer(D)] if D.GetResult() == ACCEPTKEY then call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_PASSIVE, true) call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_HELP_REQUEST, true) call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_HELP_RESPONSE, true) call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_SHARED_XP, true) call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_SHARED_SPELLS, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_PASSIVE, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_HELP_REQUEST, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_HELP_RESPONSE, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_SHARED_XP, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_SHARED_SPELLS, true) call DisplayTimedTextToPlayer(I.Init, XOFF, YOFF, DISPLAYTIME, StringReplace(ACCEPTEDTEXT_INITPLAYER, NameGet(GetPlayerId(I.Target)))) call DisplayTimedTextToPlayer(I.Target, XOFF, YOFF, DISPLAYTIME, StringReplace(ACCEPTEDTEXT_TARGETPLAYER, NameGet(GetPlayerId(I.Init)))) else call DisplayTimedTextToPlayer(I.Init, XOFF, YOFF, DISPLAYTIME, StringReplace(DENIEDTEXT_INITPLAYER, NameGet(GetPlayerId(I.Target)))) call DisplayTimedTextToPlayer(I.Target, XOFF, YOFF, DISPLAYTIME, StringReplace(DENIEDTEXT_TARGETPLAYER, NameGet(GetPlayerId(I.Init)))) endif call I.destroy() call D.destroy() endfunction private function UnAlly takes nothing returns nothing local string S = GetEventPlayerChatString() local player Init = GetTriggerPlayer() local player Target = Player(GetIdFromName(SubString(S, StringLength(ALLYPHRASESTART)+1, StringLength(S)))) call SetPlayerAlliance(Init, Target, ALLIANCE_PASSIVE, false) call SetPlayerAlliance(Init, Target, ALLIANCE_HELP_REQUEST, false) call SetPlayerAlliance(Init, Target, ALLIANCE_HELP_RESPONSE, false) call SetPlayerAlliance(Init, Target, ALLIANCE_SHARED_XP, false) call SetPlayerAlliance(Init, Target, ALLIANCE_SHARED_SPELLS, false) call SetPlayerAlliance(Target, Init, ALLIANCE_PASSIVE, false) call SetPlayerAlliance(Target, Init, ALLIANCE_HELP_REQUEST, false) call SetPlayerAlliance(Target, Init, ALLIANCE_HELP_RESPONSE, false) call SetPlayerAlliance(Target, Init, ALLIANCE_SHARED_XP, false) call SetPlayerAlliance(Target, Init, ALLIANCE_SHARED_SPELLS, false) call DisplayTimedTextToPlayer(Init, XOFF, YOFF, DISPLAYTIME, StringReplace(UNALLYTEXT, NameGet(GetPlayerId(Target)))) call DisplayTimedTextToPlayer(Target, XOFF, YOFF, DISPLAYTIME, StringReplace(UNALLYTEXT, NameGet(GetPlayerId(Init)))) endfunction private function Ally takes nothing returns nothing local string S = GetEventPlayerChatString() local Dialog D = Dialog.create() local player P = GetTriggerPlayer() local integer PId = GetIdFromName(SubString(S, StringLength(ALLYPHRASESTART)+1, StringLength(S))) local Info I = Info.create(P, Player(PId), D) call D.SetMessage(StringReplace(REQUESTMESSAGE, NameGet(GetPlayerId(P)))) call D.AddButton(ACCEPTTEXT, ACCEPTKEY) call D.AddButton(DENYTEXT, DENYKEY) call D.AddAction(function Clicked) call D.Show(I.Target) call DisplayTimedTextToPlayer(I.Init, XOFF, YOFF, DISPLAYTIME, StringReplace(SENTREQUESTTEXT,NameGet(PId))) endfunction private function AllyConditions takes nothing returns boolean return StringCase(SubString(GetEventPlayerChatString(), 0, StringLength(ALLYPHRASESTART)), false) == ALLYPHRASESTART endfunction private function UnAllyConditions takes nothing returns boolean return StringCase(SubString(GetEventPlayerChatString(), 0, StringLength(UNALLYPHRASESTART)), false) == UNALLYPHRASESTART endfunction private function Init takes nothing returns nothing local integer I = -1 loop set I = I+1 exitwhen I>11 call TriggerRegisterPlayerChatEvent(AllyTrigger, Player(I), ALLYPHRASESTART, false) call TriggerRegisterPlayerChatEvent(UnAllyTrigger, Player(I), UNALLYPHRASESTART, false) endloop call TriggerAddCondition(AllyTrigger, Condition(function AllyConditions)) call TriggerAddCondition(UnAllyTrigger, Condition(function UnAllyConditions)) call TriggerAddAction(AllyTrigger, function Ally) call TriggerAddAction(UnAllyTrigger, function UnAlly) endfunction endlibrary |
| 05-27-2008, 08:12 PM | #6 |
GetResult is a function, you forgot brackets. JASS:if D.GetResult() == HK_Y then Also bad: JASS:local Dialog D = NewDialog() JASS:local Dialog D = Dialog.create() And finally it is not Substring but SubString EDIT: I would just like to know how did Pyro write this when he does not even have jasshelper... |
| 05-28-2008, 05:52 AM | #7 | |
Quote:
|
| 05-28-2008, 06:40 AM | #8 |
I wrote it and grim001 syntax-checked it. And I've already fixed all those errors (you would've noticed had you read the new code, not the old code) ;) |
| 05-28-2008, 12:10 PM | #9 |
Also save your maps as .w3x, not .w3m (to force expansion add any like - even comment - into custom script) |
| 05-29-2008, 02:01 AM | #10 |
What...? Is that even relevant? Why does it matter? |
| 05-29-2008, 04:59 AM | #11 |
Pyrogasm and Cohadar, thank you both for you help. I've tested this and there are no compiler errors, but in game it it kind of buggy. I made a couple changes, so here it is: JASS:library AllyDialogs initializer Init needs Dialogs globals //Mess with these! private constant string ALLYPHRASESTART = "-ally " //must be lowercase; include spaces if you want them private constant string UNALLYPHRASESTART = "-unally " //must be lowercase; include spaces if you want them private string REQUESTMESSAGE = "* wants to ally with you.|nDo you accept?" //"*" to signify the use of a player's name private string SENTREQUESTTEXT = "You have requested to ally with *." private string ACCEPTEDTEXT_INITPLAYER = "Your request to ally with * has been accepted. You are now allied with *." private string ACCEPTEDTEXT_TARGETPLAYER = "You have accepted a request to ally with *. You are now allied with *." private string DENIEDTEXT_INITPLAYER = "Your request to ally with * has been denied." private string DENIEDTEXT_TARGETPLAYER = "You have denied a request to ally with *." private string UNALLYTEXT = "You are now unallied with *." private constant string ACCEPTTEXT = "|cffffcc00Y|res" private constant string DENYTEXT = "|cffffcc00N|ro" private constant integer ACCEPTKEY = HK_Y //Hotkeys; check the Dialogs documentation private constant integer DENYKEY = HK_N private constant real XOFF = 0.00 //Message display offsets private constant real YOFF = 0.00 private constant real DISPLAYTIME = 5.00 endglobals private keyword Info globals //Don't mess with these public trigger AllyTrigger = CreateTrigger() //Public so they can be disabled public trigger UnAllyTrigger = CreateTrigger() private Info array Infos endglobals private struct Info player Init player Target static method create takes player Init, player Target, Dialog D returns Info local Info I = Info.allocate() set I.Init = Init set I.Target = Target set Infos[integer(D)] = I return I endmethod endstruct private function GetIdFromName takes string Name returns integer local integer I set Name = StringCase(Name, false) if Name == "red" then return 0 elseif Name == "blue" then return 1 elseif Name == "teal" then return 2 elseif Name == "purple" then return 3 elseif Name == "yellow" then return 4 elseif Name == "orange" then return 5 elseif Name == "green" then return 6 elseif Name == "pink" then return 7 elseif Name == "grey" or Name == "gray" then //2 different spellings return 8 elseif Name == "light blue" or Name == "lightblue" then //2 different spellings return 9 elseif Name == "dark green" or Name == "darkgreen" then //2 different spellings return 10 elseif Name == "brown" then return 11 endif set I = -1 loop set I = I+1 exitwhen I>11 if StringCase(GetPlayerName(Player(I)), false) == Name then return I endif endloop return 0 endfunction private function NameGet takes integer PId returns string if PId == 0 then return "|CFFFF0303"+GetPlayerName(Player(PId))+"|r" elseif PId == 1 then return "|CFF0042FF"+GetPlayerName(Player(PId))+"|r" elseif PId == 2 then return "|CFF1CB619"+GetPlayerName(Player(PId))+"|r" elseif PId == 3 then return "|CFF540081"+GetPlayerName(Player(PId))+"|r" elseif PId == 4 then return "|CFFFFFF01"+GetPlayerName(Player(PId))+"|r" elseif PId == 5 then return "|CFFFE8A0E"+GetPlayerName(Player(PId))+"|r" elseif PId == 6 then return "|CFF20C000"+GetPlayerName(Player(PId))+"|r" elseif PId == 7 then return "|CFFE55BB0"+GetPlayerName(Player(PId))+"|r" elseif PId == 8 then return "|CFF959697"+GetPlayerName(Player(PId))+"|r" elseif PId == 9 then return "|CFF7EBFF1"+GetPlayerName(Player(PId))+"|r" elseif PId == 10 then return "|CFF106246"+GetPlayerName(Player(PId))+"|r" elseif PId == 11 then return "|CFF4E2A04"+GetPlayerName(Player(PId))+"|r" endif return "Player "+I2S(PId) endfunction private function StringReplace takes string S, string N returns string local string S2 local integer I = -1 local integer Mod = StringLength(N)-1 local integer End = StringLength(S) loop set I = I+1 exitwhen I > End-1 if SubString(S, I, I+1) == "*" then set S2 = S set S = SubString(S2, 0, I)+N+SubString(S2, I+1, End) set I = I+Mod set End = End+Mod endif endloop return S endfunction private function Clicked takes nothing returns nothing local Dialog D = GetTriggerDialog() local Info I = Infos[integer(D)] if D.GetResult() == ACCEPTKEY then call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_PASSIVE, true) call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_HELP_REQUEST, true) call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_HELP_RESPONSE, true) call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_SHARED_XP, true) call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_SHARED_SPELLS, true) call SetPlayerAlliance(I.Init, I.Target, ALLIANCE_SHARED_VISION, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_PASSIVE, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_HELP_REQUEST, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_HELP_RESPONSE, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_SHARED_XP, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_SHARED_SPELLS, true) call SetPlayerAlliance(I.Target, I.Init, ALLIANCE_SHARED_VISION, true) call DisplayTimedTextToPlayer(I.Init, XOFF, YOFF, DISPLAYTIME, StringReplace(ACCEPTEDTEXT_INITPLAYER, NameGet(GetPlayerId(I.Target)))) call DisplayTimedTextToPlayer(I.Target, XOFF, YOFF, DISPLAYTIME, StringReplace(ACCEPTEDTEXT_TARGETPLAYER, NameGet(GetPlayerId(I.Init)))) else call DisplayTimedTextToPlayer(I.Init, XOFF, YOFF, DISPLAYTIME, StringReplace(DENIEDTEXT_INITPLAYER, NameGet(GetPlayerId(I.Target)))) call DisplayTimedTextToPlayer(I.Target, XOFF, YOFF, DISPLAYTIME, StringReplace(DENIEDTEXT_TARGETPLAYER, NameGet(GetPlayerId(I.Init)))) endif call I.destroy() call D.destroy() endfunction private function UnAlly takes nothing returns nothing local string S = GetEventPlayerChatString() local player Init = GetTriggerPlayer() local player Target = Player(GetIdFromName(SubString(S, StringLength(ALLYPHRASESTART)+1, StringLength(S)))) call SetPlayerAlliance(Init, Target, ALLIANCE_PASSIVE, false) call SetPlayerAlliance(Init, Target, ALLIANCE_HELP_REQUEST, false) call SetPlayerAlliance(Init, Target, ALLIANCE_HELP_RESPONSE, false) call SetPlayerAlliance(Init, Target, ALLIANCE_SHARED_XP, false) call SetPlayerAlliance(Init, Target, ALLIANCE_SHARED_SPELLS, false) call SetPlayerAlliance(Init, Target, ALLIANCE_SHARED_VISION, false) call SetPlayerAlliance(Target, Init, ALLIANCE_PASSIVE, false) call SetPlayerAlliance(Target, Init, ALLIANCE_HELP_REQUEST, false) call SetPlayerAlliance(Target, Init, ALLIANCE_HELP_RESPONSE, false) call SetPlayerAlliance(Target, Init, ALLIANCE_SHARED_XP, false) call SetPlayerAlliance(Target, Init, ALLIANCE_SHARED_SPELLS, false) call SetPlayerAlliance(Target, Init, ALLIANCE_SHARED_VISION, false) call DisplayTimedTextToPlayer(Init, XOFF, YOFF, DISPLAYTIME, StringReplace(UNALLYTEXT, NameGet(GetPlayerId(Target)))) call DisplayTimedTextToPlayer(Target, XOFF, YOFF, DISPLAYTIME, StringReplace(UNALLYTEXT, NameGet(GetPlayerId(Init)))) endfunction private function Ally takes nothing returns nothing local string S = GetEventPlayerChatString() local Dialog D = Dialog.create() local player P = GetTriggerPlayer() local integer PId = GetIdFromName(SubString(S, StringLength(ALLYPHRASESTART)+1, StringLength(S))) local Info I = Info.create(P, Player(PId), D) call D.SetMessage(StringReplace(REQUESTMESSAGE, NameGet(GetPlayerId(P)))) call D.AddButton(ACCEPTTEXT, ACCEPTKEY) call D.AddButton(DENYTEXT, DENYKEY) call D.AddAction(function Clicked) call D.Show(I.Target) call DisplayTimedTextToPlayer(I.Init, XOFF, YOFF, DISPLAYTIME, StringReplace(SENTREQUESTTEXT,NameGet(PId))) endfunction private function AllyConditions takes nothing returns boolean return StringCase(SubString(GetEventPlayerChatString(), 0, StringLength(ALLYPHRASESTART)), false) == ALLYPHRASESTART endfunction private function UnAllyConditions takes nothing returns boolean return StringCase(SubString(GetEventPlayerChatString(), 0, StringLength(UNALLYPHRASESTART)), false) == UNALLYPHRASESTART endfunction private function Init takes nothing returns nothing local integer I = -1 loop set I = I+1 exitwhen I>11 call TriggerRegisterPlayerChatEvent(AllyTrigger, Player(I), ALLYPHRASESTART, false) call TriggerRegisterPlayerChatEvent(UnAllyTrigger, Player(I), UNALLYPHRASESTART, false) endloop call TriggerAddCondition(AllyTrigger, Condition(function AllyConditions)) call TriggerAddCondition(UnAllyTrigger, Condition(function UnAllyConditions)) call TriggerAddAction(AllyTrigger, function Ally) call TriggerAddAction(UnAllyTrigger, function UnAlly) endfunction endlibrary When I play as player one and type "-ally blue" the message comes up and asks me if I want to allyy myself. Also, I may have fixed it, but when I tested with two other people, the -unally command did not unally us. And the unally commands should not have dialogs, they should just unally both players from each other. EDIT: Pyrogasm, you should submit this as a resource if we can get it worked out because I'm sure others could benefit from a system like this. :) |
| 05-29-2008, 05:31 AM | #12 |
What did you change? |
| 05-29-2008, 05:45 AM | #13 |
private string REQUESTMESSAGE = "* wants to ally with you.|nDo you accept?" It said "wants to unally you" and then also I added shared visibility to the alliance. There was also a couple typos somewhere... i don't remember where they were, but they should not have affected it. EDIT: Maybe there wasn't any typos... I can't remember |
| 05-29-2008, 05:50 AM | #14 |
Oh, I see. Is it still buggy in that it asks you to ally yourself, or did you fix that? |
| 05-29-2008, 05:52 AM | #15 |
No, it stills asks me to ally myself (and I only tested once with other players, so it may ask them as well, but I'm not sure). Also, the -unally command displays the message, but both players are still allied. |
