Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
library UltimateChat initializer onInit uses optional GradientText
/***************************************************************************************************
* *
* Ultimate Chat System v3.2 *
* ***** *
* by Dalvengyr *
* *
* A smooth, full-featured, light-weight chat system that would improves your game performance and *
* make it more elegant. Supports various advanced features, they are all explained in the main *
* thread. *
* *
* Requirements: *
* - JNGP *
* hiveworkshop.com/forums/tools-560/jassnewgenpack-5d-227445/ *
* *
* Optional: *
* - GradientText by Dalvengyr *
* hiveworkshop.com/forums/submissions-414/snippet-gradienttext-249151/ *
* *
* How to install: *
* - Copy UltimateChat folder at trigger editor into your map *
* - Follow further instructions at: *
* hiveworkshop.com/forums/2499069-post2.html *
* *
* Link: *
* hiveworkshop.com/forums/spells-569/ultimate-chat-system-v1-4-a-249369/ *
* *
* APIs: *
* *
* 1. Add a restricted word anytime *
* function AddRestrictedWord takes string s returns nothing *
* *
* 2. Force a player to open chat window *
* function OpenUCSChatWindow takes integer pn returns nothing *
* *
* 3. Force a player to close chat window *
* function CloseUCSChatWindow takes integer pn returns nothing *
* *
* 4. Send ALL message from a player *
* function SendUCSChatAll takes integer sender, string msg returns nothing *
* *
* 5. Send TEAM message from a player *
* function SendUCSChatTeam takes integer sender, string msg returns nothing *
* *
* 6. Send SYSTEM (debug) message to a player *
* function SendUCSChatSystem takes integer reciever, string msg returns nothing *
* *
* 7. Send PRIVATE message from & to a player *
* function SendUCSChatPrivate takes integer sender, integer reciever, string msg returns nothing *
* *
* 8. Register event which fires when a player recieves a message *
* function TriggerRegisterUCSChatEvent takes trigger t, integer whichEvent returns nothing *
* *
* 9. Get sender on chat event *
* function GetUCSSender takes nothing returns player *
* *
* 10. Get recipient on chat event *
* function GetUCSReciever takes nothing returns player *
* *
* 11. Get sent message string on chat event *
* function GetUCSMessage takes nothing returns string *
* *
***************************************************************************************************/
globals
public string array PLAYER_COLOR
public string array PLAYER_NAME
/***************************************************************************************************
* *
* CONFIGURATIONS *
* *
* 1. Interfaces *
* */
// Title will be shown at the top of chat window
private constant string TITLE = "|cffffd800UltimateChatSystem v3.2|r"
// Prefix for [PRIVATE] messages
private constant string PM_PREFIX = "[|cffe6a200Private|r]"
// Prefix for [SYSTEM] messages
private constant string SM_PREFIX = "[|cffe6a200System|r]"
// Prefix for [TEAM] messages
private constant string TM_PREFIX = "[|cffe6a200Team|r]"
// Prefix for [ALL] messages
private constant string AM_PREFIX = "[|cffe6a200All|r]"
// Time tag format: TIME_BRACKET1 + MINUTE + TIME_DEVIDER + SECOND + TIME_BRACKET2
private constant string TIME_BRACKET1 = "["
private constant string TIME_DEVIDER = ":"
private constant string TIME_BRACKET2 = "]"
// Symbol after chat sender name
private constant string EQUATION_SYMBOL = ":"
/* *
* 2. Commands *
* */
// Prefix to identity a command. Ex: -reject2
private constant string CMD_PREFIX = "-"
// Command to open chat window
private constant string CMD_OPEN = "open"
// Command to close chat window
private constant string CMD_CLOSE = "close"
// Command to clear saved history
private constant string CMD_CLEAR = "clear"
// Command to add a player to reject list. The command must be followed by target player's number
private constant string CMD_BAN = "reject"
// Command to remove a player from reject list. The command must be followed by target player's number
private constant string CMD_UNBAN = "unreject"
// Another command for your personal needs. Ex: ^thetime
private constant string CMD_SPECIAL = "^"
/* *
* 3. Messagings *
* */
// Prefix to identity a message target. Ex: *pm2
private constant string MSG_PREFIX = "*"
// To send a message to all players
private constant string MSG_ALL = "all"
// To send a message to all allies
private constant string MSG_TEAM = "team"
// To send a message to specific player
private constant string MSG_PRIVATE = "pm"
/* *
* 4. Options *
* */
// X position of the chat window
private constant real WINDOW_X = 0.0
// Y position of the chat window
private constant real WINDOW_Y = 0.0
// Max messages that will be shown at screen
private constant integer WINDOW_SIZE = 21
// Max messages that will be saved
private constant integer MAX_SAVED = 30
// Maximum length of entered message
private constant integer MAX_LENGTH = 128
// True to attach time tag on each message
private constant boolean SHOW_TIME_TAG = true
// True to show title at the top of chat window
private constant boolean SHOW_TITLE = true
// True to allow player to scroll up/down
private constant boolean SCROLL_ENABLED = true
// Lock the camera when scrolling
private constant boolean SCROLL_LOCK_CAMERA = true
// Set the scroll rate
private constant real SCROLL_RATE = 0.1
// Delay before auto-scrolling started
private constant real SCROLL_DELAY = 0.4
// Timer to check flooding. 0 to disable anti-flood
private constant integer FLOOD_CHECK_TIMER = 5
// Max message every FLOOD_CHECK_TIMER seconds
private constant integer FLOOD_CHAT_MAX = 5
/* *
* 5. Notifications *
* (You may disable these notifications by setting them to null) *
* */
// Will be shown when player enters invalid command
private constant string NOTIFICATION_1 = "|CFFFF0000INVALID COMMAND|r"
// Will be shown when player enters too long message
private constant string NOTIFICATION_2 = "|CFFFF0000MESSAGE OVERSIZED|r"
// Will be shown when pm target is unidentified
private constant string NOTIFICATION_3 = "|CFFFF0000INVALID RECIPIENT|r"
// Will be shown when pm target is unavailable
private constant string NOTIFICATION_4 = "|CFFFF0000RECIPIENT IS UNAVAILABLE|r"
// Will be shown when player floods
private constant string NOTIFICATION_5 = "|CFFFF0000DON'T FLOOD!|r"
// Will be shown when player sends pm successfuly. Ex: "|CFF00FF00PRIVATE MESSAGE HAS BEEN SENT|r"
private constant string NOTIFICATION_6 = null
// Will be shown if message contains one of restricted words
private constant string NOTIFICATION_7 = "|CFFFF0000MESSAGE CONTAINS RESTRICTED WORD(S)|r"
// Will be shown if reject/unreject target is invalid
private constant string NOTIFICATION_8 = "|CFFFF0000UNABLE TO REJECT/UNREJECT TARGET|r"
// Will be shown when target has been successfuly added/removed to reject list
private constant string NOTIFICATION_9 = "|CFF00FF00TARGET HAS BEEN ADDED/REMOVED TO/FROM REJECT LIST|r"
endglobals
/* *
* 6. Nickname colors *
* */
private function initName takes nothing returns nothing
set PLAYER_COLOR[0] = "|CFFFF0303" // Player 1
set PLAYER_COLOR[1] = "|CFF0042FF"
set PLAYER_COLOR[2] = "|CFF00FFFF"
set PLAYER_COLOR[3] = "|CFF540081"
set PLAYER_COLOR[4] = "|CFFFFFF01"
set PLAYER_COLOR[5] = "|CFFFE8A0E"
set PLAYER_COLOR[6] = "|CFF20C000"
set PLAYER_COLOR[7] = "|CFFE55BB0"
set PLAYER_COLOR[8] = "|CFF959697"
set PLAYER_COLOR[9] = "|CFF7EBFF1"
set PLAYER_COLOR[10] = "|CFF106246"
set PLAYER_COLOR[11] = "|CFF4E2A04" // Player 12
endfunction
/* *
* END OF CONFIGURATIONS *
* *
***************************************************************************************************/
private keyword Box
globals
private boolean array Open
private force array RejectList
private integer GameTime = 0
private integer array ScrollInt
private integer array ScrollDirection
private integer array LastChatCtgry
private integer array LastPMTarget
private integer array FloodCounter
private integer array FloodTimer
private integer array MessageTotal
private integer array CommandSize
private player EVT_Reciever = null
private player EVT_Sender = null
private real EVT_Trigger = -1
private real array ScrollDelay
private string EVT_Message = ""
private string GameTimes = "00" + TIME_DEVIDER + "00"
private timer array SwearTimer[11]
private trigger RestrictTrigger = CreateTrigger()
private trigger ChatTrigger = CreateTrigger()
private trigger ScrollTrigger = CreateTrigger()
private unit array CameraLocker
private Box array MessageBox[11]
constant integer EVENT_CHAT_ANY = 0
constant integer EVENT_CHAT_ALL = 1
constant integer EVENT_CHAT_TEAM = 2
constant integer EVENT_CHAT_PRIVATE = 3
constant integer EVENT_CHAT_SYSTEM = 4
private constant player PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
endglobals
private struct Box
string array str[MAX_SAVED]
static method create takes nothing returns thistype
return allocate()
endmethod
endstruct
private function initSize takes nothing returns nothing
set CommandSize[0] = StringLength(CMD_OPEN)
set CommandSize[1] = StringLength(CMD_CLOSE)
set CommandSize[2] = StringLength(CMD_CLEAR)
set CommandSize[3] = StringLength(CMD_BAN)
set CommandSize[4] = StringLength(CMD_UNBAN)
set CommandSize[5] = StringLength(CMD_SPECIAL)
set CommandSize[6] = StringLength(MSG_ALL)
set CommandSize[7] = StringLength(MSG_TEAM)
set CommandSize[8] = StringLength(MSG_PRIVATE)
set CommandSize[10] = StringLength(CMD_PREFIX)
set CommandSize[11] = StringLength(MSG_PREFIX)
endfunction
private function recycleInbox takes integer pn returns nothing
local integer i = 1
loop
exitwhen i == MAX_SAVED
set MessageBox[pn].str[i] = MessageBox[pn].str[i + 1]
set i = i + 1
endloop
set MessageBox[pn].str[MAX_SAVED] = ""
endfunction
private function updateWindow takes integer pn returns nothing
local integer i
local integer ext
local player p = Player(pn)
if GetLocalPlayer() == p then
call ClearTextMessages()
endif
static if SHOW_TITLE then
call DisplayTimedTextToPlayer(p, WINDOW_X, WINDOW_Y, 0., TITLE)
endif
// Adding spaces between the first shown message and the title
if MessageTotal[pn] < WINDOW_SIZE + ScrollInt[pn] then
set i = 0
set ext = WINDOW_SIZE - MessageTotal[pn] + ScrollInt[pn]
loop
exitwhen i >= ext
call DisplayTimedTextToPlayer(p, WINDOW_X, WINDOW_Y, 0., " ")
set i = i + 1
endloop
endif
// This calculation is to determine the scroll position and to
// avoid displaying the whole saved messages, so more effective
set i = MessageTotal[pn] - WINDOW_SIZE + 1 - ScrollInt[pn]
if i < 0 then
set i = 0
endif
set ext = MessageTotal[pn] - ScrollInt[pn]
// Display messages
loop
exitwhen i > ext
if MessageBox[pn].str[i] != "" and MessageBox[pn].str[i] != null then
call DisplayTimedTextToPlayer(p, WINDOW_X, WINDOW_Y, 0., MessageBox[pn].str[i])
endif
set i = i + 1
endloop
endfunction
private function showDebug takes integer pn, string msg returns nothing
local player rb
local string mb
// Why? Simply because AI can not read messages so just dont
// process things if the target is AI, to save times
if GetPlayerController(Player(pn)) == MAP_CONTROL_USER then
if MessageTotal[pn] >= MAX_SAVED then
call recycleInbox(pn)
else
set MessageTotal[pn] = MessageTotal[pn] + 1
endif
// Process the message
static if SHOW_TIME_TAG then
set MessageBox[pn].str[MessageTotal[pn]] = SM_PREFIX + " " + TIME_BRACKET1 + GameTimes + TIME_BRACKET2 + " " + msg
else
set MessageBox[pn].str[MessageTotal[pn]] = SM_PREFIX + " " + msg
endif
if Open[pn] then
call updateWindow(pn)
endif
// Generate the event
set rb = EVT_Reciever
set mb = EVT_Message
set EVT_Reciever = Player(pn)
set EVT_Message = msg
set EVT_Trigger = EVENT_CHAT_SYSTEM
set EVT_Trigger = EVENT_CHAT_ANY
set EVT_Trigger = -1
set EVT_Reciever = rb
set EVT_Message = mb
endif
endfunction
private function saveMessage takes integer ctgry, integer pn, string msg returns nothing
local player rb = EVT_Reciever
set EVT_Reciever = Player(pn)
// Process things if only the target is player. Same reason
// as above
if GetPlayerController(EVT_Reciever) == MAP_CONTROL_USER then
if MessageTotal[pn] >= MAX_SAVED then
call recycleInbox(pn)
else
set MessageTotal[pn] = MessageTotal[pn] + 1
endif
set MessageBox[pn].str[MessageTotal[pn]] = msg
if Open[pn] then
call updateWindow(pn)
endif
endif
set EVT_Trigger = ctgry
set EVT_Trigger = EVENT_CHAT_ANY
set EVT_Trigger = -1
set EVT_Reciever = rb
endfunction
private function processMessage takes integer ctgry, integer pn, string msg returns nothing
local integer i = 0
local player sb = EVT_Sender
local string mb = EVT_Message
set EVT_Sender = Player(pn)
set EVT_Message = msg
if ctgry == EVENT_CHAT_ALL then
// If time tag is shown, then attach it
static if SHOW_TIME_TAG then
set msg = AM_PREFIX + " " + TIME_BRACKET1 + GameTimes + TIME_BRACKET2 + " " + PLAYER_NAME[pn] + EQUATION_SYMBOL + " " + msg
else
set msg = AM_PREFIX + " " + PLAYER_NAME[pn] + EQUATION_SYMBOL + " " + msg
endif
// Save the processed message to the recipients
loop
exitwhen i > 11
if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
if not IsPlayerInForce(EVT_Sender, RejectList[i]) then
call saveMessage(ctgry, i, msg)
endif
endif
set i = i + 1
endloop
elseif ctgry == EVENT_CHAT_PRIVATE then
static if SHOW_TIME_TAG then
set msg = PM_PREFIX + " " + TIME_BRACKET1 + GameTimes + TIME_BRACKET2 + " " + PLAYER_NAME[pn] + EQUATION_SYMBOL + " " + msg
else
set msg = PM_PREFIX + " " + PLAYER_NAME[pn] + EQUATION_SYMBOL + " " + msg
endif
if GetPlayerSlotState(Player(LastPMTarget[pn])) == PLAYER_SLOT_STATE_PLAYING then
if not IsPlayerInForce(EVT_Sender, RejectList[LastPMTarget[pn]]) then
if NOTIFICATION_6 != null then
call showDebug(pn, NOTIFICATION_6)
endif
call saveMessage(ctgry, LastPMTarget[pn], msg)
endif
elseif NOTIFICATION_4 != null then
call showDebug(pn, NOTIFICATION_4)
endif
elseif ctgry == EVENT_CHAT_TEAM then
static if SHOW_TIME_TAG then
set msg = TM_PREFIX + " " + TIME_BRACKET1 + GameTimes + TIME_BRACKET2 + " " + PLAYER_NAME[pn] + EQUATION_SYMBOL + " " + msg
else
set msg = TM_PREFIX + " " + PLAYER_NAME[pn] + EQUATION_SYMBOL + " " + msg
endif
loop
exitwhen i > 11
if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
if not IsPlayerInForce(EVT_Sender, RejectList[i]) then
if IsPlayerAlly(EVT_Sender, Player(i)) then
call saveMessage(ctgry, i, msg)
endif
endif
endif
set i = i + 1
endloop
endif
set EVT_Message = mb
set EVT_Sender = sb
endfunction
private function checkWord takes nothing returns boolean
local integer id = GetPlayerId(GetTriggerPlayer())
if NOTIFICATION_7 != null and TimerGetRemaining(SwearTimer[id]) == 0 then
call showDebug(id, NOTIFICATION_7)
endif
// Whithin this duration chatEvent function below won't be triggered
call TimerStart(SwearTimer[id], .01, false, null)
return false
endfunction
private function chatEvent takes nothing returns boolean
local integer pn = GetPlayerId(GetTriggerPlayer())
local integer len
local integer t
local string msg
// If no forbidden word was detected
if TimerGetRemaining(SwearTimer[pn]) == 0 then
set msg = GetEventPlayerChatString()
if SubString(msg, 0, CommandSize[10]) == CMD_PREFIX then
set len = StringLength(CMD_PREFIX)
if SubString(msg, len, len + CommandSize[0]) == CMD_OPEN then
set Open[pn] = true
call updateWindow(pn)
elseif SubString(msg, len, len + CommandSize[1]) == CMD_CLOSE then
set Open[pn] = false
if GetLocalPlayer() == GetTriggerPlayer() then
call ClearTextMessages()
endif
elseif SubString(msg, len, len + CommandSize[2]) == CMD_CLEAR then
set MessageTotal[pn] = 0
set ScrollInt[pn] = 0
if Open[pn] then
call updateWindow(pn)
endif
elseif SubString(msg, len, len + CommandSize[3]) == CMD_BAN then
// Get the target's id
set t = S2I(SubString(msg, len + CommandSize[3], len + CommandSize[3] + 2))
// If the target is valid
if t != pn and t > -1 and t < 12 then
if NOTIFICATION_9 != null then
call showDebug(pn, NOTIFICATION_9)
endif
call ForceAddPlayer(RejectList[pn], Player(t))
elseif NOTIFICATION_8 != null then
call showDebug(pn, NOTIFICATION_8)
endif
elseif SubString(msg, len, len + CommandSize[4]) == CMD_UNBAN then
set t = S2I(SubString(msg, len + CommandSize[4], len + CommandSize[4] + 2))
if t != pn and t > -1 and t < 12 then
if NOTIFICATION_9 != null then
call showDebug(pn, NOTIFICATION_9)
endif
call ForceRemovePlayer(RejectList[pn], Player(t))
elseif NOTIFICATION_8 != null then
call showDebug(pn, NOTIFICATION_8)
endif
elseif NOTIFICATION_1 != null then
call showDebug(pn, NOTIFICATION_1)
endif
elseif SubString(msg, 0, CommandSize[11]) == MSG_PREFIX then
set len = StringLength(MSG_PREFIX)
if SubString(msg, len, len + CommandSize[6]) == MSG_ALL then
if StringLength(msg) - len - CommandSize[6] - 1 <= MAX_LENGTH then
// Generate the anti-flood
set FloodTimer[pn] = FLOOD_CHECK_TIMER
set FloodCounter[pn] = FloodCounter[pn] + 1
set LastChatCtgry[pn] = EVENT_CHAT_ALL
// If flooding is not occured
if FloodCounter[pn] <= FLOOD_CHAT_MAX then
static if LIBRARY_GradientText then
set msg = GradientText(msg)
endif
// Pass the message to other function (process it)
call processMessage(EVENT_CHAT_ALL, pn, SubString(msg, len + CommandSize[6] + 1, StringLength(msg)))
elseif NOTIFICATION_5 != null then
call showDebug(pn, NOTIFICATION_5)
endif
elseif NOTIFICATION_2 != null then
call showDebug(pn, NOTIFICATION_2)
endif
elseif SubString(msg, len, len + CommandSize[8]) == MSG_PRIVATE then
if StringLength(msg) - len - CommandSize[8] - 1 <= MAX_LENGTH then
set FloodTimer[pn] = FLOOD_CHECK_TIMER
set FloodCounter[pn] = FloodCounter[pn] + 1
set LastChatCtgry[pn] = EVENT_CHAT_PRIVATE
if FloodCounter[pn] <= FLOOD_CHAT_MAX then
// Get target's id
set t = S2I(SubString(msg, len + CommandSize[8], len + CommandSize[8] + 2))
// If target is valid
if t != pn and t > -1 and t < 12 then
set LastPMTarget[pn] = t
static if LIBRARY_GradientText then
set msg = GradientText(msg)
endif
call processMessage(EVENT_CHAT_PRIVATE, pn, SubString(msg, len + CommandSize[8] + StringLength(I2S(t + 1)) + 1, StringLength(msg)))
elseif NOTIFICATION_3 != null then
call showDebug(pn, NOTIFICATION_3)
endif
elseif NOTIFICATION_5 != null then
call showDebug(pn, NOTIFICATION_5)
endif
elseif NOTIFICATION_2 != null then
call showDebug(pn, NOTIFICATION_2)
endif
// If chat TEAM
elseif SubString(msg, len, len + CommandSize[7]) == MSG_TEAM then
if StringLength(msg) - len - CommandSize[7] - 1 <= MAX_LENGTH then
set FloodTimer[pn] = FLOOD_CHECK_TIMER
set FloodCounter[pn] = FloodCounter[pn] + 1
set LastChatCtgry[pn] = EVENT_CHAT_TEAM
if FloodCounter[pn] <= FLOOD_CHAT_MAX then
static if LIBRARY_GradientText then
set msg = GradientText(msg)
endif
call processMessage(EVENT_CHAT_TEAM, pn, SubString(msg, len + CommandSize[7] + 1, StringLength(msg)))
elseif NOTIFICATION_5 != null then
call showDebug(pn, NOTIFICATION_5)
endif
elseif NOTIFICATION_2 != null then
call showDebug(pn, NOTIFICATION_2)
endif
elseif NOTIFICATION_1 != null then
call showDebug(pn, NOTIFICATION_1)
endif
// If message contains no command or messaging prefix.
// Allows player to repeat previous messaging prefix
elseif SubString(msg, 0, CommandSize[5]) != CMD_SPECIAL then
if StringLength(msg) <= MAX_LENGTH then
set FloodCounter[pn] = FloodCounter[pn] + 1
set FloodTimer[pn] = FLOOD_CHECK_TIMER
if FloodCounter[pn] <= FLOOD_CHAT_MAX then
static if LIBRARY_GradientText then
set msg = GradientText(msg)
endif
call processMessage(LastChatCtgry[pn], pn, msg)
elseif NOTIFICATION_5 != null then
call showDebug(pn, NOTIFICATION_5)
endif
elseif NOTIFICATION_2 != null then
call showDebug(pn, NOTIFICATION_2)
endif
endif
endif
return false
endfunction
private function time takes nothing returns nothing
local string s1
local string s2
local integer i
// Process the anti-flood timer
set i = 0
loop
exitwhen i > 11
if FloodTimer[i] == 0 then
set FloodCounter[i] = 0
else
set FloodTimer[i] = FloodTimer[i] - 1
endif
set i = i + 1
endloop
set GameTime = GameTime + 1
set s1 = I2S(GameTime/60)
set s2 = I2S(GameTime - (GameTime/60) * 60)
if StringLength(s1) == 1 then
set s1 = "0" + s1
endif
if StringLength(s2) == 1 then
set s2 = "0" + s2
endif
set GameTimes = s1 + TIME_DEVIDER + s2
endfunction
private function scrollLoop takes nothing returns boolean
local integer i = 0
local integer c = 0
loop
exitwhen i > 11
if ScrollDirection[i] > 0 then
set c = c + ScrollDirection[i]
if ScrollDelay[i] <= 0 then
if ScrollDirection[i] == 1 then
if ScrollInt[i] < MessageTotal[i] - 1 then
set ScrollInt[i] = ScrollInt[i] + 1
endif
elseif ScrollDirection[i] == 2 then
if ScrollInt[i] > 0 then
set ScrollInt[i] = ScrollInt[i] - 1
endif
endif
if Open[i] then
call updateWindow(i)
endif
else
set ScrollDelay[i] = ScrollDelay[i] - SCROLL_RATE
endif
endif
set i = i + 1
endloop
// If no one is scrolling then turn off the trigger
if c == 0 then
call DisableTrigger(ScrollTrigger)
endif
return false
endfunction
private function scrollOn takes integer i returns nothing
if Open[i] then
call updateWindow(i)
endif
static if SCROLL_LOCK_CAMERA then
call SetUnitX(CameraLocker[i], GetCameraTargetPositionX())
call SetUnitY(CameraLocker[i], GetCameraTargetPositionY())
if GetLocalPlayer() == GetTriggerPlayer() then
call SetCameraTargetController(CameraLocker[i], 0, 0, false)
endif
endif
endfunction
private function scrollOff takes nothing returns boolean
local integer pn = GetPlayerId(GetTriggerPlayer())
set ScrollDirection[pn] = 0
// Release camera without reseting any field
call RemoveUnit(CameraLocker[pn])
set CameraLocker[pn] = CreateUnit(PASSIVE, 'ewsp', 0, 0, 0)
call ShowUnit(CameraLocker[pn], false)
return false
endfunction
private function scrollUp takes nothing returns boolean
local integer i = GetPlayerId(GetTriggerPlayer())
if ScrollDirection[i] == 0 and Open[i] then
set ScrollDirection[i] = 1
set ScrollDelay[i] = SCROLL_DELAY
if SCROLL_DELAY > 0 and ScrollInt[i] < MessageTotal[i] - 1 then
set ScrollInt[i] = ScrollInt[i] + 1
endif
call scrollOn(i)
endif
if not IsTriggerEnabled(ScrollTrigger) then
call EnableTrigger(ScrollTrigger)
endif
return false
endfunction
private function scrollDown takes nothing returns boolean
local integer i = GetPlayerId(GetTriggerPlayer())
if ScrollDirection[i] == 0 and Open[i] then
set ScrollDirection[i] = 2
set ScrollDelay[i] = SCROLL_DELAY
if SCROLL_DELAY > 0 and ScrollInt[i] > 0 then
set ScrollInt[i] = ScrollInt[i] - 1
endif
call scrollOn(i)
endif
if not IsTriggerEnabled(ScrollTrigger) then
call EnableTrigger(ScrollTrigger)
endif
return false
endfunction
private function onInit takes nothing returns nothing
local trigger t1 = CreateTrigger()
local trigger t2 = CreateTrigger()
local trigger t3 = CreateTrigger()
local integer i = 0
local player p
call initName()
call initSize()
loop
exitwhen i > 11
set p = Player(i)
if GetPlayerController(p) == MAP_CONTROL_USER and GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
static if SCROLL_ENABLED then
call TriggerRegisterPlayerEvent(t1, p, EVENT_PLAYER_ARROW_UP_DOWN)
call TriggerRegisterPlayerEvent(t2, p, EVENT_PLAYER_ARROW_DOWN_DOWN)
call TriggerRegisterPlayerEvent(t3, p, EVENT_PLAYER_ARROW_UP_UP)
call TriggerRegisterPlayerEvent(t3, p, EVENT_PLAYER_ARROW_DOWN_UP)
static if SCROLL_LOCK_CAMERA then
set CameraLocker[i] = CreateUnit(PASSIVE, 'ewsp', 0., 0., 0.0)
call ShowUnit(CameraLocker[i], false)
endif
endif
call TriggerRegisterPlayerChatEvent(ChatTrigger, p, "", false)
set SwearTimer[i] = CreateTimer()
set FloodTimer[i] = 0
set FloodCounter[i] = 0
set LastChatCtgry[i] = EVENT_CHAT_ALL
set MessageBox[i] = Box.create()
set MessageTotal[i] = 0
set RejectList[i] = CreateForce()
set ScrollDirection[i] = 0
set ScrollInt[i] = 0
endif
set Open[i] = false
set PLAYER_NAME[i] = PLAYER_COLOR[i] + GetPlayerName(p) + "|R"
set i = i + 1
endloop
static if SCROLL_ENABLED then
call TriggerRegisterTimerEvent(ScrollTrigger, SCROLL_RATE, true)
call TriggerAddCondition(ScrollTrigger, Condition(function scrollLoop))
call TriggerAddCondition(t1, Condition(function scrollUp))
call TriggerAddCondition(t2, Condition(function scrollDown))
call TriggerAddCondition(t3, Condition(function scrollOff))
call DisableTrigger(ScrollTrigger)
else
call DestroyTrigger(t1)
call DestroyTrigger(t2)
call DestroyTrigger(t3)
set t1 = null
set t2 = null
set t3 = null
endif
call TriggerAddCondition(RestrictTrigger, Condition(function checkWord))
call TriggerAddCondition(ChatTrigger, Condition(function chatEvent))
call TimerStart(CreateTimer(), 1, true, function time)
endfunction
// API functions
function AddRestrictedWord takes string s returns nothing
local integer i = 0
local player p
call DestroyTrigger(ChatTrigger)
set ChatTrigger = CreateTrigger()
// Reset chat trigger. Indeed slower, but increase system's functionality
loop
exitwhen i > 11
set p = Player(i)
call TriggerRegisterPlayerChatEvent(RestrictTrigger, p, s, false)
if GetPlayerController(p) == MAP_CONTROL_USER and GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
call TriggerRegisterPlayerChatEvent(ChatTrigger, p, "", false)
endif
set i = i + 1
endloop
call TriggerAddCondition(ChatTrigger, Condition(function chatEvent))
endfunction
function OpenUCSChatWindow takes integer pn returns nothing
set Open[pn] = true
call updateWindow(pn)
endfunction
function CloseUCSChatWindow takes integer pn returns nothing
set Open[pn] = false
if GetLocalPlayer() == Player(pn) then
call ClearTextMessages()
endif
endfunction
function SendUCSChatAll takes integer sender, string msg returns nothing
call processMessage(EVENT_CHAT_ALL, sender, msg)
endfunction
function SendUCSChatPrivate takes integer sender, integer reciever, string msg returns nothing
if sender != reciever and reciever >= 0 and reciever < 12 then
set LastPMTarget[sender] = reciever
call processMessage(EVENT_CHAT_PRIVATE, sender, msg)
endif
endfunction
function SendUCSChatTeam takes integer sender, string msg returns nothing
call processMessage(EVENT_CHAT_TEAM, sender, msg)
endfunction
function SendUCSChatSystem takes integer reciever, string msg returns nothing
call showDebug(reciever, msg)
endfunction
function TriggerRegisterUCSChatEvent takes trigger t, integer whichEvent returns nothing
call TriggerRegisterVariableEvent(t, SCOPE_PRIVATE + "EVT_Trigger", EQUAL, whichEvent)
endfunction
function GetUCSSender takes nothing returns player
return EVT_Sender
endfunction
function GetUCSReciever takes nothing returns player
return EVT_Reciever
endfunction
function GetUCSMessage takes nothing returns string
return EVT_Message
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library GradientText /* v3.2 */ requires HexString
/********************************************************************************************
* *
* 'Gradient Text' *
* ***** *
* by Dalvengyr *
* *
* Description: *
* This library is used to convert inputted string into the degradated one based on given *
* or specified color code. *
* *
* !! ADD_PREFIX at HexString library must be "false" !! *
* *
* Requirement: *
* - HexString by Bannar aka Spinnaker *
* hiveworkshop.com/forums/jass-resources-412/snippet-hexstring-248993/ *
* - JNGP *
* *
* APIs *
* *
* 1. Create gradations for inputed string *
* *
* function GradientText takes string s returns string *
* *
* 2. Create gradations for inputed string with specific color code and size. Size is in *
* percentage *
* *
* function GradientTextEx takes string s, string code1, string code2, integer size returns string
* *
********************************************************************************************/
globals
// Configuration //
// For identifying a color code. Don't use "|c" !!
public constant string IDENTIFIER = "#"
// You are recommended to keep this as true. Will delete any character '|'
private constant boolean DELETE = true
// Furthermore, edit them by your own risk
private constant integer LENGTH = StringLength(IDENTIFIER)
private string array String
private integer array Integer
endglobals
private function addGradation takes string s, string code1, string code2, integer len returns string
local boolean b
if len > 1 and code1 != code2 then
set String[0] = ""
set Integer[0] = 1
// Convert hex code to integer
set Integer[1] = HS2I(SubString(code1, 0, 2))
set Integer[2] = HS2I(SubString(code1, 2, 4))
set Integer[3] = HS2I(SubString(code1, 4, 6))
// Set the color interval from code1 to code2 devided by length of string
set Integer[4] = (HS2I(SubString(code2, 0, 2)) - Integer[1]) / (len + 1)
set Integer[5] = (HS2I(SubString(code2, 2, 4)) - Integer[2]) / (len + 1)
set Integer[6] = (HS2I(SubString(code2, 4, 6)) - Integer[3]) / (len + 1)
loop
exitwhen Integer[0] > len
set String[4] = SubString(s, Integer[0] - 1, Integer[0])
if String[4] != " " then
set b = true
static if DELETE then
if String[4] == "|" then
set b = false
endif
endif
if b then
// Convert integer to hex code
set String[1] = I2HS(Integer[1] + Integer[4] * Integer[0], false)
set String[2] = I2HS(Integer[2] + Integer[5] * Integer[0], false)
set String[3] = I2HS(Integer[3] + Integer[6] * Integer[0], false)
// Attach '0' if hex code only contains one letter
set Integer[8] = 1
loop
exitwhen Integer[8] > 3
if StringLength(String[Integer[8]]) == 1 then
set String[Integer[8]] = "0" + String[Integer[8]]
endif
set Integer[8] = Integer[8] + 1
endloop
set String[0] = String[0] + "|cff" + String[1] + String[2] + String[3] + String[4]
endif
else
set String[0] = String[0] + " "
endif
set Integer[0] = Integer[0] + 1
endloop
else
static if DELETE then
// Search for symbol '|' first
set Integer[0] = 0
loop
exitwhen Integer[0] > len
if SubString(s, Integer[0], Integer[0] + 1) == "|" then
set s = SubString(s, 0, Integer[0]) + SubString(s, Integer[0] + 1, len)
set len = len - 1
endif
set Integer[0] = Integer[0] + 1
endloop
endif
set String[0] = "|cff" + code1 + s
endif
return String[0]
endfunction
function GradientText takes string s returns string
local string code1 = ""
local string code2 = ""
local string grad
local integer i = 0
local integer t = 0
local integer dex1
local integer dex2
local integer len = StringLength(s)
// t is used to save last search point in the loop
// dex1(2) is used to save found hex code's position
loop
exitwhen i > len
if SubString(s, i, i + LENGTH) == IDENTIFIER then
// If first code is still empty then save found code to it
if code1 == "" then
set t = i
set dex1 = i
set code1 = SubString(s, i + LENGTH, i + LENGTH + 6)
// Remove found code from string
set s = SubString(s, 0, i) + SubString(s, i + LENGTH + 6, len)
set len = len - (LENGTH + 6)
else
set dex2 = i
set code2 = SubString(s, i + LENGTH, i + LENGTH + 6)
set s = SubString(s, 0, i) + SubString(s, i + LENGTH + 6, len)
set len = len - (LENGTH + 6)
if HS2I(code1) >= 0 and HS2I(code2) >= 0 then
set grad = addGradation(SubString(s, dex1, dex2), code1, code2, dex2 - dex1)
else
set grad = SubString(s, dex1, dex2)
debug call BJDebugMsg("Invalid color code: " + code1 + " - " + code2)
endif
// Insert the result into string s
set s = SubString(s, 0, dex1) + grad + SubString(s, dex2, len)
// Preparation to search for another hex code
set code1 = code2
set t = t + StringLength(grad)
set i = t
set len = len - (dex2 - dex1) + t
set dex1 = t
endif
endif
set i = i + 1
endloop
if code1 != "" then
if code2 == "" then
// If there is only one found hex code
if HS2I(code1) >= 0 then
// Use function addGradation to remove symbol '|' before inserting hex code
set s = SubString(s, 0, dex1) + addGradation(SubString(s, dex1, len), code1, code1, len - dex1) + "|r"
debug else
debug call BJDebugMsg("Invalid color code: " + code1 + " - " + code2)
endif
else
set s = s + "|r"
endif
endif
return s
endfunction
function GradientTextEx takes string s, string code1, string code2, integer size returns string
local boolean b = true
local integer len = StringLength(s)
local integer sz = R2I(len * (size * .01))
local integer i = 0
local integer mod
local string res = ""
// If specified code is invalid then skip the rest
if HS2I(code1) < 0 or HS2I(code2) < 0 or StringLength(code1) != 6 or StringLength(code2) != 6 then
debug call BJDebugMsg("Invalid color code: " + code1 + " - " + code2)
return s
endif
// Avoid critical error
if sz < 1 then
set sz = 1
endif
// Loop to insert hex code into string based on given size
loop
set mod = i - (i/sz) * sz
if mod == 0 then
if b then
set res = res + IDENTIFIER + code1
else
set res = res + IDENTIFIER + code2
endif
set b = not b
endif
if i <= len then
set res = res + SubString(s, i, i + 1)
endif
exitwhen i >= len and mod == 0
set i = i + 1
endloop
return GradientText(res)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*****************************************************************************
*
* HexString v1.0.0.3
* by Bannar aka Spinnaker
*
* Performs conversions from hexadecimal numbers to strings and vice versa.
*
* Credits to TheDamien for hash formula from original Ascii project
*
******************************************************************************
*
* private constant boolean ADD_PREFIX
* whether to add or not the "0x" prefix; used only in I2HS function
*
*
* function I2HS takes integer hex, boolean upper returns string
* returns hexadecimal representation of hex as string
*
* function HS2I takes string s returns integer
* returns integral number retrieved from s representing number in hexadecimal convention
*
*****************************************************************************/
library HexString
globals
/**
Config
*/
private constant boolean ADD_PREFIX = false
endglobals
globals
private string array Id2CharMap // (16)
private integer array Int2IdMap // (16)
endglobals
function I2HS takes integer hex, boolean upper returns string
local string s = ""
local integer div
loop
set div = hex/16
set s = Id2CharMap[hex - div * 16] + s
set hex = div
exitwhen hex == 0
endloop
if ( upper ) then
set s = StringCase(s, true)
endif
static if ( ADD_PREFIX ) then
set s = "0x" + s
endif
return s
endfunction
function HS2I takes string s returns integer
local integer size = StringLength(s)
local integer hex = 0
local integer it = 0
local integer key
local string char
if ( SubString(s, 0, 2) == "0x" ) then
set s = SubString(s, 2, size)
set size = size - 2
endif
loop
exitwhen it == size
set char = SubString(s, it, it+1)
set key = Int2IdMap[StringHash(char) / 0x1F0748 + 0x3EA]
debug if (key == 0) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "DEBUG: Hex::HS2I Invalid string character.")
debug return -1
debug endif
set hex = hex*16 + (key-1)
set it = it+1
endloop
return hex
endfunction
private module HexInit
private static method onInit takes nothing returns nothing
set Id2CharMap[0] = "0"
set Id2CharMap[1] = "1"
set Id2CharMap[2] = "2"
set Id2CharMap[3] = "3"
set Id2CharMap[4] = "4"
set Id2CharMap[5] = "5"
set Id2CharMap[6] = "6"
set Id2CharMap[7] = "7"
set Id2CharMap[8] = "8"
set Id2CharMap[9] = "9"
set Id2CharMap[10] = "a"
set Id2CharMap[11] = "b"
set Id2CharMap[12] = "c"
set Id2CharMap[13] = "d"
set Id2CharMap[14] = "e"
set Id2CharMap[15] = "f"
set Int2IdMap[883] = 1
set Int2IdMap[1558] = 2
set Int2IdMap[684] = 3
set Int2IdMap[582] = 4
set Int2IdMap[668] = 5
set Int2IdMap[538] = 6
set Int2IdMap[672] = 7
set Int2IdMap[1173] = 8
set Int2IdMap[71] = 9
set Int2IdMap[277] = 10
set Int2IdMap[222] = 11
set Int2IdMap[178] = 12
set Int2IdMap[236] = 13
set Int2IdMap[184] = 14
set Int2IdMap[1295] = 15
set Int2IdMap[1390] = 16
endmethod
endmodule
private struct Hex extends array
implement HexInit
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*
This is an example how to send messages to specific player
*/
function Trig_Init_Actions takes nothing returns nothing
local integer id = GetPlayerId(GetEnumPlayer())
call DisplayTimedTextToPlayer(Player(id), 0., 0., 0., "Welcome!\n\nPress ESC to open/close chat window")
// Display [SYSTEM] messages
call SendUCSChatSystem(id, "|cffffd800Type \"*all or team\" to send message to all or allied players|r")
call SendUCSChatSystem(id, "|cffffd800Type \"*pm\" followed by target player's id to send private message to that player. Ex: \"*pm1 Hi!\" will send \"Hi!\" message to player 2|r")
call SendUCSChatSystem(id, "|cffffd800- You don't need to enter messaging prefix all the time -|r")
call SendUCSChatSystem(id, "|cffffd800Type \"-open\" to open chat window or \"-close\" to close chat window|r")
call SendUCSChatSystem(id, "|cffffd800Type \"-clear\" to clear chat history|r")
// Sends private message from Triggs to player
call SendUCSChatPrivate(1, id, "Hello, " + UltimateChat_PLAYER_NAME[id] + ", welcome! I've been waiting for you!")
call SendUCSChatPrivate(1, id, "You can reject my messages by typing -reject1")
call SendUCSChatPrivate(1, id, "You could make degradated message by typing: " + GradientText_IDENTIFIER + "<colorcode> your message " + GradientText_IDENTIFIER + "<colorcode>")
call SendUCSChatPrivate(1, id, "Ex: " + GradientText_IDENTIFIER + "ffff00Hello there, enjoy the system" + GradientText_IDENTIFIER + "ff0000 with result: " + GradientText(GradientText_IDENTIFIER + "ffff00Hello there, enjoy the system" + GradientText_IDENTIFIER + "ff0000"))
call SendUCSChatPrivate(1, id, "Anyway, enjoy your time here...")
endfunction
function InitTrig_Meet_n_Greet_Msg takes nothing returns nothing
call ForForce(bj_FORCE_ALL_PLAYERS, function Trig_Init_Actions)
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*
This is an example how to make a BOT chat
*/
function reply takes nothing returns boolean
// Check the recipient
if GetUCSReciever() == Player(1) then
// Check the message
if GetUCSMessage() == "Hi" or GetUCSMessage() == "hi" or GetUCSMessage() == "Hello" or GetUCSMessage() == "hello" then
call SendUCSChatPrivate(1, GetPlayerId(GetUCSSender()), "Hello, human. :)")
elseif GetUCSMessage() == "thnks" or GetUCSMessage() == "thanks" or GetUCSMessage() == "thank you" or GetUCSMessage() == "ty" then
call SendUCSChatPrivate(1, GetPlayerId(GetUCSSender()), "You are welcome :3")
elseif GetUCSMessage() == "who is dalvengyr" or GetUCSMessage() == "whos dalvengyr" or GetUCSMessage() == "who is Dalvengyr" or GetUCSMessage() == "whos Dalvengyr" then
call SendUCSChatPrivate(1, GetPlayerId(GetUCSSender()), "Dalvengyr is the creator of this system <3")
else
call SendUCSChatPrivate(1, GetPlayerId(GetUCSSender()), "I don't understand :(")
endif
endif
return false
endfunction
function InitTrig_BOT_Chat takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterUCSChatEvent(t, EVENT_CHAT_ANY)
call TriggerAddCondition(t, Condition(function reply))
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*
This is an example how to show sent Private Message. But first, go to configuration at main trigger
then set NOTIFICATION_6 to null
*/
function show takes nothing returns boolean
call SendUCSChatSystem(GetPlayerId(GetUCSSender()), "You -> " + UltimateChat_PLAYER_NAME[GetPlayerId(GetUCSReciever())] + ": " + GetUCSMessage())
return false
endfunction
function InitTrig_Show_PM takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterUCSChatEvent(t, EVENT_CHAT_PRIVATE)
call TriggerAddCondition(t, Condition(function show))
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*
This is an example how to open/close chat window using another way. You can disabled default chat
command by setting them to null. As example:
private constant string CMD_OPEN = null
*/
globals
boolean array open
endglobals
function esc takes nothing returns boolean
local integer id = GetPlayerId(GetTriggerPlayer())
if open[id] then
call CloseUCSChatWindow(id)
call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 0, "Chat window is currently closed")
else
call OpenUCSChatWindow(id)
endif
set open[id] = not open[id]
return false
endfunction
function InitTrig_Esc_OpenClose takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
call TriggerRegisterPlayerEvent(t, Player(0), EVENT_PLAYER_END_CINEMATIC)
call TriggerRegisterPlayerEvent(t, Player(3), EVENT_PLAYER_END_CINEMATIC)
call TriggerAddCondition(t, Condition(function esc))
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
library RestrictWord initializer ini requires UltimateChat
// This is just example how to restrict word(s). But you may do it anytime even when in-game
// and remove this trigger as well.
private function ini takes nothing returns nothing
/***************************************************************************************************
* Restricted Words *
***************************************************************************************************/
// function AddRestrictedWord takes string s returns nothing
call AddRestrictedWord("word1")
call AddRestrictedWord("word2")
call AddRestrictedWord("word3")
call AddRestrictedWord("word4")
call AddRestrictedWord("word5")
/**************************************************************************************************/
endfunction
endlibrary