Finally something useful from me
Examples(ripped from my map):
More(a looot more) complex one:
To see the first one work just output something using
To see how the second one works just check
Please take into consideration that the example is ripped off of my map and following globals are not provided(they are placed in other libraries in my map):
JASS:
library ChatCommand uses StringIterator
/*
Made by: edo494
Version: 1.2
Requires: StringIterator - http://www.hiveworkshop.com/forums/jass-resources-412/snippet-stringiterator-246143/
This Library provides very easy way to create game modes
accessed via chat.
There is currently no way to group multiple modes into
one internally like in dota, where -amap means
-allmid -allpick, but can be done externally by user.
If you register 2 switches, and both appear in one
line (-what -ever), it will always trigger them in order
of appearance in the chat(function registered to swtich -what
runs, then function registered to swtich -ever runs)
Currently, even if you type something sensible and then
type some valid switch, it will get triggered. This may
be filtered, but requires some thinking of doing it inteligently.
Example: "hey boys, its nice to -play with you" will still try
to run callback to switch "play" with string "with you"
This resource should be safe for recursive execution, which means
that if in some way to get to trigger the checker from the event
registered to this resource, it should work properly
API:
function AddChatCommand takes string modeString, code callBack returns nothing
- registers new Mode(mode1 in -mode1 etc) and adds callBack object
into it for custom functionality
- please note that "-" is not requested, because it is prepended
to the switch
Example: AddModeString("what", function ...) will trigger when you
type "-what" in chat
function RemoveChatCommand takes string modeString returns nothing
- removes the modeString from the system, so it will no longer be
triggered
- O(log n), worst case is O(n), where n is number of modeStrings
registered
function SetChatCommandDelimiter takes string newDelimiter returns nothing
- sets new delimiter for the system to look for in the strings
- this can be any number of characters
Note: if you use "" or null, it will always consider the whole
message after the switch as ChatCommandString even if there is
another Switch inside the line
Getters:
native GetTriggerPlayer takes nothing returns player
- returns the player that entered the chat mode to chat
function GetChatCommand takes nothing returns string
- returns the string used as switch
Example: "-what else" returns "what"
function GetChatCommandString takes nothing returns string
- returns the string that appears after the mode until
another mode or until the end of string
Example: "-what else or -if something" will return "else or"
or "something", dependsing when you request it.
function GetChatCommandDelimiter takes nothing returns string
- returns the delimiter string
- defaults to "-"
struct ChatCommand extends array
static method command takes nothing returns string
- returns the string used as switch(-what returns "what")
static method sring takes nothing returns string
- returns the string that appears after the mode until
another mode or until the end of string
static method operator delimiter takes nothing returns string
- returns the delimiter string
- defaults to "-"
static method operator delimiter= takes string newDelimiter returns nothing
- sets new delimiter for the system to look for in the strings
- this can be any number of characters
Note: if you use "" or null, it will always consider the whole
message after the switch as ChatCommandString even if there is
another Switch inside the line
*/
globals
private string array modes
private trigger array trig
private integer modesC = 0
private string chatStringTrig = null
private trigger globTrig = CreateTrigger()
private string chatString = null
private string modesDelimiter = "-"
endglobals
struct ChatCommand extends array
static method command takes nothing returns string
return chatStringTrig
endmethod
static method string takes nothing returns string
return chatString
endmethod
static method operator delimiter takes nothing returns string
return modesDelimiter
endmethod
static method operator delimiter= takes string newDelimiter returns nothing
set modesDelimiter = newDelimiter
endmethod
endstruct
function GetChatCommandString takes nothing returns string
return chatString
endfunction
function GetChatCommand takes nothing returns string
return chatStringTrig
endfunction
function GetChatCommandDelimiter takes nothing returns string
return modesDelimiter
endfunction
function SetChatCommandDelimiter takes string newDelimiter returns nothing
set modesDelimiter = newDelimiter
endfunction
function AddChatCommand takes string modeString, code callBack returns nothing
local integer m = modesC
if trig[m] == null and callBack != null then
set trig[m] = CreateTrigger()
endif
set modes[m] = modeString
call TriggerAddCondition(trig[m], Condition(callBack))
set modesC = m + 1
endfunction
function RemoveChatCommand takes string modeString returns nothing
local integer i = modesC - 1
loop
if modes[i] == modeString then
call TriggerClearConditions(trig[i])
set modes[i] = modes[modesC - 1]
call DestroyTrigger(trig[i])
set trig[i] = trig[modesC - 1]
set modesC = i
return
endif
exitwhen i == 0
set i = i - 1
endloop
endfunction
private module m
private static method removeStartingSpaces takes string s returns string
local integer i = 0
local integer e = StringLength(s)-1
local boolean b = false
local string q = ""
loop
set q = SubString(s, i, i+1)
if q != " " then
set b = true
endif
exitwhen i == e or b
set i = i + 1
endloop
return SubString(s, i, e+1)
endmethod
private static method removeTrailingSpaces takes string s returns string
local integer i = 0
local integer e = StringLength(s) - 1
local boolean b = false
if e < 0 then
return s
endif
loop
if SubString(s, e, 1) == " " then
set e = e - 1
else
set b = true
endif
exitwhen b or e <= 1
endloop
return SubString(s, 0, e + 1)
endmethod
private static method onChatEnter takes nothing returns boolean
local string entered = GetEventPlayerChatString()
local StringIterator iter = StringIterator.create(entered)
local string helper = ""
local string outer = ""
local string inner = ""
local integer looper = 0
local string lock1 = ""
local string lock2 = ""
local string lock3 = ""
local string endHelper = ""
local string readDelimiter = ""
local boolean equals = false
loop
call iter.setDelims(" ")
exitwhen iter.end
set helper = iter.read()
set looper = 0
set readDelimiter = SubString(helper, 0, StringLength(modesDelimiter))
set equals = readDelimiter == modesDelimiter or /*
*/ modesDelimiter == "" or modesDelimiter == null
set outer = SubString(helper, StringLength(modesDelimiter), StringLength(helper))
if equals then
loop
if outer == modes[looper] then
set lock1 = chatStringTrig
set chatStringTrig = outer
call iter.setDelims(modesDelimiter)
set inner = removeTrailingSpaces(removeStartingSpaces(iter.read()))
set lock2 = chatString
set lock3 = modesDelimiter
set chatString = inner
call TriggerEvaluate(trig[looper])
set chatStringTrig = lock1
set chatString = lock2
set modesDelimiter = lock3
endif
exitwhen looper == modesC - 1
set looper = looper + 1
endloop
endif
endloop
return false
endmethod
private static method onInit takes nothing returns nothing
local integer i = 0
call TriggerAddCondition(globTrig, Condition(function thistype.onChatEnter))
loop
call TriggerRegisterPlayerChatEvent(globTrig, Player(i), "", false)
exitwhen i == 15
set i = i + 1
endloop
endmethod
endmodule
private struct s extends array
implement m
endstruct
endlibrary
Examples(ripped from my map):
JASS:
scope UserModeClear initializer init
private function clear takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
call ClearTextMessages()
endif
endfunction
private function init takes nothing returns nothing
call AddChatCommand("clear", function clear)
endfunction
endscope
More(a looot more) complex one:
JASS:
scope UserModeCamera initializer init
globals
private real DEFAULT_DISTANCE = 0
private constant string CAMERA_HINT = "|cffffff00-camera|r has following options:\n"/*
*/+"|cffffff00-camera X|r, where X is number - sets the camera distance to X(Default value is 1906)\n"/*
*/+"|cffff0000Note: |rThe distance must be between 100 and 2500\n"/*
*/+"|cffffff00-camera fix|r - fixes the distance of camera to certain value\n"/*
*/+"|cffff0000Note:|r|cffcccc00If you use |r|cffffff00-camera|r|cffcccc00 fix while the camera is fixed, it reverts the effect|r\n"/*
*/+"|cffffff00-camera lock|r - locks the camera to your hero\n"/*
*/+"|cffffff00-camera unlock|r - unlocks the camera to free view\n"/*
*/+"|cffffff00-camera default|r - sets the distance to default distance\n"/*
*/+"|cffffff00-camera toggle|r - toggles the camera mode(if it is locked, it unlocks it and vice versa)\n"/*
*/+"|cffffff00-camera help|r - displays this message\n"/*
*/+"Note: You can also use |cffffff00-cam|r with the same switches"
private constant string CAMERA_ERROR = "|cffff0000Invalid input into -camera|r"
private boolean array cameraLocked
private real array cameraDistances
private integer instances = 0
private boolean array cameraFixed
private timer cameraFix = CreateTimer()
unit array StartingUnits
integer PlayerCount
endglobals
//******************************************************//
/* Handle Camera things */
/* Lock camera to main unit */
private function CamLock takes player p returns nothing
local integer id = GetPlayerId(p)
local unit u = StartingUnits[id]
if not cameraLocked[id] then
if GetLocalPlayer() == p then
call ClearTextMessages()
endif
if GetLocalPlayer() == p then
call SetCameraTargetController(u, 0, 0, true)
call DisplayTimedTextToPlayer(p, 0, 0, 10, "|cffffcc00Camera Mode: |rLocked")
endif
set cameraLocked[id] = true
else
call DisplayTimedTextToPlayer(p, 0, 0, 16, "|cffffcc00Camera|r already locked")
endif
set u = null
endfunction
/* Unlock camera for free movement */
private function CamUnlock takes player p returns nothing
local integer id = GetPlayerId(p)
local unit u = StartingUnits[id]
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real d = 0
if cameraLocked[id] then
if GetLocalPlayer() == p then
call ClearTextMessages()
endif
if GetLocalPlayer() == p then
set d = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
call ResetToGameCamera(0)
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, d, 0)
call SetCameraPosition(x, y)
call DisplayTimedTextToPlayer(p, 0, 0, 10, "|cffffcc00Camera Mode: |rFree")
endif
set cameraLocked[id] = false
else
call DisplayTimedTextToPlayer(p, 0, 0, 16, "|cffffcc00Camera|r already unlocked")
endif
set u = null
endfunction
/* Reset camera for players */
private function CamReset takes nothing returns nothing
local integer i = 0
loop
if cameraFixed[i] then
if GetLocalPlayer() == Player(i) then
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, cameraDistances[i], 0)
endif
endif
exitwhen i == PlayerCount
set i = i + 1
endloop
endfunction
/* Fix cameras distance for player */
private function CamFix takes player p returns nothing
local integer id = GetPlayerId(p)
if GetLocalPlayer() == p then
call ClearTextMessages()
endif
if not cameraFixed[id] then
call DisplayTimedTextToPlayer(p, 0, 0, 16, "Camera has been fixed")
set instances = instances + 1
set cameraFixed[id] = true
if instances == 1 then
call TimerStart(cameraFix, 0.1, true, function CamReset)
endif
else
call DisplayTimedTextToPlayer(p, 0, 0, 16, "Camera has been un-fixed")
set instances = instances - 1
set cameraFixed[id] = false
if instances == 0 then
call PauseTimer(cameraFix)
endif
endif
endfunction
/* Change distance of the Camera */
private function CamDist takes integer value, player triggerer returns nothing
if GetLocalPlayer() == triggerer then
if value < 100 or value > 2500 then
if GetLocalPlayer() == triggerer then
call ClearTextMessages()
endif
call DisplayTimedTextToPlayer(triggerer, 0, 0, 16, "|cffff0000The value after -camera or -cam must be higher or equal to 100 and smaller or equal to 2500|r")
else
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, value, 1 + (value/DEFAULT_DISTANCE))
set cameraDistances[GetPlayerId(triggerer)] = value
endif
endif
endfunction
/* Dispatch entered string */
/* Checking if the entered string is value for zoom,
lock or unlock commands
*/
private function CamDispatch takes nothing returns nothing
local string s = GetChatCommand()
local string q = ""
local integer value = -1
local player p = GetTriggerPlayer()
set value = S2I(s)
if S2I(s) != 0 and SubString(s, 0, 1) != "0" then
call CamDist(value, p)
elseif s == "fix" then
call CamFix(p)
elseif s == "lock" then
call CamLock(p)
elseif s == "unlock" then
call CamUnlock(p)
elseif s == "default" then
call CamDist(R2I(DEFAULT_DISTANCE), p)
elseif s == "toggle" then
if cameraLocked[GetPlayerId(p)] then
call CamUnlock(p)
else
call CamLock(p)
endif
elseif s == "help" then
if GetLocalPlayer() == p then
call ClearTextMessages()
endif
call DisplayTimedTextToPlayer(p, 0, 0, 30, CAMERA_HINT)
else
if GetLocalPlayer() == p then
call ClearTextMessages()
endif
if s != "" or s != null then
call DisplayTimedTextToPlayer(p, 0, 0, 30, CAMERA_ERROR)
endif
call DisplayTimedTextToPlayer(p, 0, 0, 30, CAMERA_HINT)
endif
endfunction
private function init takes nothing returns nothing
local integer i = 0
call AddChatCommand("camera", function CamDispatch)
call AddChatCommand("cam", function CamDispatch)
set DEFAULT_DISTANCE = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
loop
set cameraDistances[i] = DEFAULT_DISTANCE
exitwhen i == PlayerCount
set i = i + 1
endloop
endfunction
endscope
To see the first one work just output something using
BJDebugMsg
and then enter "-clear" into chat as if you were trying to type something to everyone.To see how the second one works just check
global variable CAMERA_HINT
. If you dont want to read the entire variable just download it and type -cam help or -camera help to see it displayed ingame.Please take into consideration that the example is ripped off of my map and following globals are not provided(they are placed in other libraries in my map):
JASS:
integer PlayerCount
unit array StartingUnits
struct ChatMode
->struct ChatCommand
- Overhauled the API:
AddChatMode
->AddChatCommand
RemoveModeString
->RemoveChatCommand
AddChatModeString
->AddChatCommandString
SetChatModeDelimiter
->SetChatCommandDelimiter
GetChatModeSwtich
->GetChatCommand
GetChatModeString
->GetChatCommandString
GetChatModeDelimiter
->GetChatCommandDelimiter
ChatMode.switch
->ChatMode.command
- Changed the behaviour of how the ChatModeString is filled. It was kind of glitched and included trailing and leading spaces("-what ever -what" would output " ever " instead of "ever"). This is now fixed
- Accordingly to the previous mentioned change, I changed the camera example, because the call to
RemoveStartingSpaces
is no longer needed - Optimized the loop quite a bit
- Delimiter that is used is now configurable, instead of hardcoded to "-"
- New functions:
SetChatModeDelimiter takes string newDelimiter returns nothing
GetChatModeDelimiter takes nothing returns string
- New methods:
static method operator delimiter takes nothing returns string
static method operator delimiter= takes string newDelimiter returns nothing
- Added the forgotten function
RemoveModeString
to the API
- initial release
Last edited: