• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] Ultimate Chat System Discussion

how good?

  • very bad of execution, better just use wc3 normal chat

    Votes: 0 0.0%
  • lil bit better than wc3 chat

    Votes: 0 0.0%
  • so much better than wc3 normal chat

    Votes: 0 0.0%
  • definitedly better and so much improvements than normal wc3 normal chat

    Votes: 0 0.0%
  • everybody should implement this on every map

    Votes: 0 0.0%

  • Total voters
    2
Status
Not open for further replies.

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
I know this is a little ridiculous, but I need to do this to get more helps.. :p


Okay, foa, UCS is an advanced chat system which my mission is replacing default wc3 chat with this system since this system makes everything easier and cooler. to achieve it, I need helps from you guys. really...


what's good about this system compared to default wc3 chat:
- you can send private message easiliy
- you can check chat history easier, as well as hiding, unhiding, and clearing them (no need to open window which disturbs gameplay)
- allows colorized and gradient chats
- reject list
- anti-spam/flood
- words restrictions
- and other minor features

what else? I have worked on this system very carefuly, I was always thinking about the best way to make it works, and I'm pretty sure that there is no faster way than the way/method I use in this system. This system also has several APIs that ofcourse will be helpful in-game.


but, there are 3 disadvantages on using this system which is a little hurt. you can read them inside the code. Maybe one I need to explain more is about double line bugs. You know if you entered a too-long-message the displayed text will be double lined. its something like this
Code:
-Single lined 12312312312312312312312312321123

-Double lined 12312312312312312312312312321123
123123123
this bug could hide the title or anything above since the max shown message is 16 on screen at the same time. But luckily, you could easily maintain the max entered chat length using this global (I guess it's a little awkward since you have to maintain it manually, so that's why I think I need to warn you about this)
private constant integer MAX_LENGTH = 73


meh, here is the code btw
JASS:
library UltimateChat initializer ini uses Table optional GradientText
    globals
        private                 string array    PLAYER_COLOR
        private                 string array    PLAYER_NAME
        
    /****************************************************************************************************/
    /*                                                                                                  */
    /*                              'Ultimate Chat System v1.5'                                         */
    /*                                                  *****                                           */
    /*                                               by Dalvengyr                                       */
    /*                                                                                                  */
    /* A smooth, full-featured, light-weight chat system that would improves your game performance and  */
    /* make it more elegant. Supports various fascinating features, they are all explained in the main  */
    /* forum. Now, what else do you want from a chat system?                                            */
    /*                                                                                                  */
    /* Check updates only at:                                                                           */
    /*      [url]www.hiveworkshop.com/forums/spells-569/ultimate-chat-system-v1-4-a-249369/[/url]                  */
    /*                                                                                                  */
    /* Requirements:                                                                                    */
    /*      - JNGP                                                                                      */
    /*      - Table by Bribe                                                                            */
    /*                                                                                                  */
    /* Optional:                                                                                        */
    /*      - GradientText                                                                              */
    /*                                                                                                  */
    /* Needed tools for install:                                                                        */
    /*      - winMPQ                                                                                    */
    /*      - Notepad                                                                                   */
    /*                                                                                                  */
    /* How to install: (follow all instructions below carefuly for your own safety)                     */
    /*      - Copy UCS folder at trigger editor into your map                                           */
    /*      - Use winMPQ, open your map and find war3mapMisc.txt then extract it                        */
    /*      - Open import manager of this demo map, export war3mapMisc.txt then open it using notepad   */
    /*      - Open war3mapMisc.txt of your map, copy all text there and paste them in war3mapMisc.txt   */
    /*        of this demo map. Then save it                                                            */
    /*      - Import that saved war3mapMisc.txt into your map                                           */
    /*      - Change the file path to war3mapMisc.txt (delete the "war3mapImported\")                   */
    /*      - Once you import war3mapMisc.txt you may only configure Gameplay Constants using notepad   */
    /*      - (Optional) You could use the same font with this demo map by exporting consola.ttf and    */
    /*        war3mapSkin.txt to your map with the same steps of exporting war3mapMisc.txt              */
    /*      - Once you import war3mapSkin.txt you may only configure Gameplay Interfaces using notepad  */
    /*                                                                                                  */
    /* API:                                                                                             */
    /*                                                                                                  */
    /* function AddRestrictedWord takes string s returns nothing                                        */
    /*                                                                                                  */
    /* function SetUCSTitle takes string s returns nothing                                              */
    /*                                                                                                  */
    /* function SetUCSHost takes player p returns nothing                                               */
    /*                                                                                                  */
    /* function GetUCSTitle takes nothing returns string                                                */
    /*                                                                                                  */
    /* function GetUCSHost takes player p returns nothing                                               */
    /*                                                                                                  */
    /* function OpenUCSChatWindow takes integer pn returns nothing                                      */
    /*                                                                                                  */
    /* function CloseUCSChatWindow takes integer pn returns nothing                                     */
    /*                                                                                                  */
    /* function GetUCSElapsedGameTime takes nothing returns string                                      */
    /*                                                                                                  */
    /* function GetUCSNickname takes integer pn returns string                                          */
    /*                                                                                                  */
    /* function SendUCSChatAll takes integer sender, string msg returns nothing                         */
    /*                                                                                                  */
    /* function SendUCSChatTeam takes integer sender, string msg returns nothing                        */
    /*                                                                                                  */
    /* function SendUCSChatSystem takes integer reciever, string msg returns nothing                    */
    /*                                                                                                  */
    /* function SendUCSChatPrivate takes integer sender, integer reciever, string msg returns nothing   */
    /*                                                                                                  */
    /* function TriggerRegisterUCSChatEvent takes trigger t, code cond, code act returns nothing        */
    /*                                                                                                  */
    /* function GetUCSSender takes nothing returns player                                               */
    /*                                                                                                  */
    /* function GetUCSReciever takes nothing returns player                                             */
    /*                                                                                                  */
    /* function GetUCSMessage takes nothing returns string                                              */
    /*                                                                                                  */
    /****************************************************************************************************/
    
    /****************************************************************************************************/
    /*                                                                                                  */
    /*          CONFIGURATIONS                                                                          */
    /*                                                                                                  */
    /****************************************************************************************************/
    
    /****************************************************************************************************/
    /* Interfaces                                                                                       */
    /****************************************************************************************************/
        // Title will be shown at the top of chat window
        private                 string          TITLE               = "UltimateChatSystem v1.5"
        // Prefix for private messages
        private     constant    string          PM_PREFIX           = "[|cff0000ffPrivate|r]"
        // Prefix for system messages
        private     constant    string          SM_PREFIX           = "[|cff0000ffSystem|r]"
        // Prefix for team messages
        private     constant    string          TM_PREFIX           = "[|cff0000ffTeam|r]"
        // Prefix for all messages
        private     constant    string          AM_PREFIX           = "[|cff0000ffAll|r]"
        // Will be added when host announce something
        private     constant    string          ANNOUNCEMENT        = "|cffffff00Announcement|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          EQUAL_SYMBOL        = ":"
        
    /****************************************************************************************************/
    /* Commands                                                                                         */
    /****************************************************************************************************/
        // Prefix to identity a command. Ex: -open
        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
        private     constant    string          CMD_UNBAN           = "unreject"
        // Another command for your personal needs. Ex: ^thetime
        private     constant    string          OTHER_CMD           = "^"
        
    /****************************************************************************************************/
    /* 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. Must be followed by target player's number
        private     constant    string          MSG_PRIVATE         = "pm"
        // To announce something. Only host has this authority
        private     constant    string          MSG_ANNOUNCEMENT    = "announce"
        
    /****************************************************************************************************/
    /* Options                                                                                          */
    /****************************************************************************************************/
        // Chat window size aka max messages that will be shown at screen
        private                 integer         WINDOW_SIZE         = 15
        // 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 saved
        private     constant    integer         MAX_SAVED           = 100000000
        // Maximum length of entered message
        private     constant    integer         MAX_LENGTH          = 73
        // Maximum length of each player name
        private     constant    integer         MAX_NICK_LENGTH     = 10
        // True to initialy open chat window for all players
        private     constant    boolean         INITIALY_OPEN       = false
        // 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_ENABLE       = true
        // Set the scroll rate
        private     constant    real            SCROLL_RATE         = .1
        // Delay for host to announce something
        private     constant    integer         ANNOUNCE_DELAY      = 30
        // Timer to check flooding
        private     constant    integer         FLOOD_CHECK_TIMER   = 5
        // Max message every FLOOD_CHECK_TIMER seconds or will be considered as flooding
        private     constant    integer         FLOOD_CHAT_MAX      = 5
        
    /****************************************************************************************************/
    endglobals
    static if DEBUG_MODE then
    globals
    
    /****************************************************************************************************/
    /* Debug Messages                                                                                   */
    /****************************************************************************************************/
        // Will be shown when player enters invalid command
        private     constant    string          DEBUG_MSG1          = "|CFFFF0000INVALID COMMAND|r"
        // Will be shown when player enters too long message
        private     constant    string          DEBUG_MSG2          = "|CFFFF0000MESSAGE OVERSIZED|r"
        // Will be shown when pm target is unidentified
        private     constant    string          DEBUG_MSG3          = "|CFFFF0000INVALID RECIPIENT|r"
        // Will be shown when pm target is unavailable
        private     constant    string          DEBUG_MSG4          = "|CFFFF0000RECIPIENT IS UNAVAILABLE|r"
        // Will be shown when not host player tries to announce something
        private     constant    string          DEBUG_MSG5          = "|CFFFF0000YOU DON'T HAVE THE AUTHORITY|r"
        // Will be shown when player floods
        private     constant    string          DEBUG_MSG6          = "|CFFFF0000DON'T FLOOD!|r"
        // Will be shown when host trying to announce something too often/before delay timer expired
        private     constant    string          DEBUG_MSG7          = "|CFFFF0000YOU CAN'T SEND ANNOUNCEMENT TOO OFTEN|r"
        // Will be shown when player sends pm successfuly
        private     constant    string          DEBUG_MSG8          = "|CFF00FF00PRIVATE MESSAGE HAS BEEN SENT|r"
        // Will be shown if message contains one of restricted words
        private     constant    string          DEBUG_MSG9          = "|CFFFF0000MESSAGE CONTAINS RESTRICTED WORD(S)|r"
        // Will be shown if reject/unreject target is invalid
        private     constant    string          DEBUG_MSG10         = "|CFFFF0000UNABLE TO REJECT/UNREJECT TARGET|r"
        // Will be shown when target successfuly added/removed to reject list
        private     constant    string          DEBUG_MSG11         = "|CFF00FF00TARGET HAS BEEN ADDED/REMOVED TO/FROM REJECT LIST|r"
        
    /****************************************************************************************************/
    endglobals
    endif
    
    /****************************************************************************************************/
    /* Player Colors                                                                                    */
    /****************************************************************************************************/
    private function setname 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                                                                   */
    /*                                                                                                  */
    /****************************************************************************************************/
    
    globals
        private                 boolean         SWEAR               = false
        private                 boolean array   OPEN
        private                 force array     REJECT_LIST
        private                 integer         ANNOUNCE_TIMER      = 0
        private                 integer         GAME_TIME           = 0
        private                 integer array   SCROLL_INT
        private                 integer array   SCROLL_DRCT
        private                 integer array   LAST_CHAT
        private                 integer array   LAST_PM_TARGET
        private                 integer array   FLOOD_CHAT_TOTAL
        private                 integer array   FLOOD_CHAT_TIMER
        private                 integer array   MAILTOTAL
        private                 player          HOST                = Player(15)
        public                  player          EVT_Reciever
        public                  player          EVT_Sender
        public                  real            EVT
        public                  string          EVT_Message
        private                 string          GAME_TIMES          = "00" + TIME_DEVIDER + "00"
        private                 timer           UNSWEAR_TIMER       = CreateTimer()
        private                 trigger         SCROLL              = CreateTrigger()
                                trigger         CHAT                = CreateTrigger()
        private                 Table array     MAILBOX[11]
    endglobals
    
    private function unswear takes nothing returns nothing
        set SWEAR = false
    endfunction
    
    private function recycle takes integer i returns nothing
        local integer i2 = 0
        
        loop
            set i2 = i2 + 1
            set MAILBOX[i].string[i2] = MAILBOX[i].string[i2 + 1]
            exitwhen i2 >= MAX_SAVED - 1
        endloop
    endfunction
    
    private function update takes integer i returns nothing
        local integer i2
        local integer ext
        local player p = Player(i)
        
        if GetLocalPlayer() == p then
            call ClearTextMessages()
        endif
        static if SHOW_TITLE then
            call DisplayTimedTextToPlayer(p, WINDOW_X, WINDOW_Y, 0.0, TITLE)
        endif
        if MAILTOTAL[i] < WINDOW_SIZE + SCROLL_INT[i] then
            set i2 = 0
            set ext = WINDOW_SIZE - MAILTOTAL[i] + SCROLL_INT[i]
            loop
                exitwhen i2 >= ext
                call DisplayTimedTextToPlayer(p, WINDOW_X, WINDOW_Y, 0.0, " ")
                set i2 = i2 + 1
            endloop
        endif
        set i2 = MAILTOTAL[i] - WINDOW_SIZE + 1 - SCROLL_INT[i]
        set ext = MAILTOTAL[i] - SCROLL_INT[i]
        loop
            exitwhen i2 > ext
            if MAILBOX[i].string[i2] != null then
                call DisplayTimedTextToPlayer(p, WINDOW_X, WINDOW_Y, 0.0, MAILBOX[i].string[i2])
            endif
            set i2 = i2 + 1
        endloop
    endfunction
    
    private function showDebug takes integer pn, string msg returns nothing
        if GetPlayerController(Player(pn)) == MAP_CONTROL_USER  then
            if MAILTOTAL[pn] >= MAX_SAVED then
                call recycle(pn)
            else
                set MAILTOTAL[pn] = MAILTOTAL[pn] + 1
            endif
            static if SHOW_TIME_TAG then
                set MAILBOX[pn].string[MAILTOTAL[pn]] = SM_PREFIX + " " + TIME_BRACKET1 + GAME_TIMES + TIME_BRACKET2 + " " + msg
            else
                set MAILBOX[pn].string[MAILTOTAL[pn]] = SM_PREFIX + " " + msg
            endif
            if OPEN[pn] then
                call update(pn)
            endif
        endif
    endfunction
    
    private function save takes integer i, string msg returns nothing
        set EVT_Reciever = Player(i)
        if GetPlayerController(EVT_Reciever) == MAP_CONTROL_USER  then
            if MAILTOTAL[i] >= MAX_SAVED then
                call recycle(i)
            else
                set MAILTOTAL[i] = MAILTOTAL[i] + 1
            endif
            set MAILBOX[i].string[MAILTOTAL[i]] = msg
            if OPEN[i] then
                call update(i)
            endif
        endif
        set EVT = 1.00
        set EVT = 0.00
        set EVT_Reciever = null
    endfunction
    
    private function process takes integer cat, integer pn, string msg returns nothing
        local integer i = 0
        local integer i2
        local integer t
        
        set EVT_Sender = Player(pn)
        set EVT_Message = msg
        static if LIBRARY_GradientText then
            set msg = Gradient(msg)
        endif
        if cat == 1 then
            static if SHOW_TIME_TAG then
                set msg = AM_PREFIX + " " + TIME_BRACKET1 + GAME_TIMES + TIME_BRACKET2 + " " + PLAYER_NAME[pn] + EQUAL_SYMBOL + " " + msg
            else
                set msg = AM_PREFIX + " " + PLAYER_NAME[pn] + EQUAL_SYMBOL + " " + msg
            endif
            loop
                exitwhen i > 11
                if not IsPlayerInForce(EVT_Sender, REJECT_LIST[i]) then
                    call save(i, msg)
                endif
                set i = i + 1
            endloop
        elseif cat == 2 then
            static if SHOW_TIME_TAG then
                set msg = PM_PREFIX + " " + TIME_BRACKET1 + GAME_TIMES + TIME_BRACKET2 + " " + PLAYER_NAME[pn] + EQUAL_SYMBOL + " " + msg
            else
                set msg = PM_PREFIX + " " + PLAYER_NAME[pn] + EQUAL_SYMBOL + " " + msg
            endif
            if LAST_PM_TARGET[pn] != pn and LAST_PM_TARGET[pn] >= 0 then
                if GetPlayerSlotState(Player(LAST_PM_TARGET[pn])) == PLAYER_SLOT_STATE_PLAYING then
                    if not IsPlayerInForce(EVT_Sender, REJECT_LIST[LAST_PM_TARGET[pn]]) then
                        call showDebug(pn, DEBUG_MSG8)
                        call save(LAST_PM_TARGET[pn], msg)
                    endif
                debug else
                    debug call showDebug(pn, DEBUG_MSG4)
                endif
            debug else
                debug call showDebug(pn, DEBUG_MSG3)
            endif
        elseif cat == 3 then
            static if SHOW_TIME_TAG then
                set msg = TM_PREFIX + " " + TIME_BRACKET1 + GAME_TIMES + TIME_BRACKET2 + " " + PLAYER_NAME[pn] + EQUAL_SYMBOL + " " + msg
            else
                set msg = TM_PREFIX + " " + PLAYER_NAME[pn] + EQUAL_SYMBOL + " " + msg
            endif
            loop
                exitwhen i > 11
                if not IsPlayerInForce(EVT_Sender, REJECT_LIST[i]) then
                    if IsPlayerAlly(EVT_Sender, Player(i)) then
                        call save(i, msg)
                    endif
                endif
                set i = i + 1
            endloop
        endif
        set EVT_Sender = null
        set EVT_Message = null
    endfunction
    
    private function chatEvent takes nothing returns boolean
        local string msg
        local string cmd
        local integer pn = GetPlayerId(GetTriggerPlayer())
        local integer len
        local integer len2
        local integer i = 0
        local integer i2
        local integer t
        local player p
        
        if GetEventPlayerChatStringMatched() != "" and not SWEAR then
            set SWEAR = true
            debug call showDebug(pn, DEBUG_MSG9)
            call TimerStart(UNSWEAR_TIMER, 0.01, false, function unswear)
        endif
        if not SWEAR then
            set msg = GetEventPlayerChatString()
            set cmd = SubString(msg, 0, 1)
            if cmd == CMD_PREFIX then
                set len = StringLength(CMD_PREFIX)
                if SubString(msg, len, len + StringLength(CMD_OPEN)) == CMD_OPEN then
                    set OPEN[pn] = true
                    call update(pn)
                elseif SubString(msg, len, len + StringLength(CMD_CLOSE)) == CMD_CLOSE then
                    set OPEN[pn] = false
                    if GetLocalPlayer() == GetTriggerPlayer() then
                        call ClearTextMessages()
                    endif
                elseif SubString(msg, len, len + StringLength(CMD_CLEAR)) == CMD_CLEAR then
                    set MAILTOTAL[pn] = 0
                    set SCROLL_INT[i] = 0
                    if OPEN[pn] then
                        call update(pn)
                    endif
                elseif SubString(msg, len, len + StringLength(CMD_BAN)) == CMD_BAN then
                    set t = S2I(SubString(msg, len + StringLength(CMD_BAN), len + StringLength(CMD_BAN) + 2)) - 1
                    if t != pn and t >= 0 then
                        debug call showDebug(pn, DEBUG_MSG11)
                        call ForceAddPlayer(REJECT_LIST[pn], Player(t))
                    debug else
                        debug call showDebug(pn, DEBUG_MSG10)
                    endif
                elseif SubString(msg, len, len + StringLength(CMD_UNBAN)) == CMD_UNBAN then
                    set t = S2I(SubString(msg, len + StringLength(CMD_UNBAN), len + StringLength(CMD_UNBAN) + 2)) - 1
                    if t != pn and t >= 0 then
                        debug call showDebug(pn, DEBUG_MSG11)
                        call ForceRemovePlayer(REJECT_LIST[pn], Player(t))
                    debug else
                        debug call showDebug(pn, DEBUG_MSG10)
                    endif
                debug else
                    debug call showDebug(pn, DEBUG_MSG1)
                endif
            elseif cmd == MSG_PREFIX then
                set len = StringLength(MSG_PREFIX)
                if StringLength(msg) - len <= MAX_LENGTH then
                    if SubString(msg, len, len + StringLength(MSG_ALL)) == MSG_ALL then
                        set FLOOD_CHAT_TIMER[pn] = FLOOD_CHECK_TIMER
                        set FLOOD_CHAT_TOTAL[pn] = FLOOD_CHAT_TOTAL[pn] + 1
                        set LAST_CHAT[pn] = 1
                        if FLOOD_CHAT_TOTAL[pn] <= FLOOD_CHAT_MAX then
                            call process(1, pn, SubString(msg, len + StringLength(MSG_ALL) + 1, StringLength(msg)))
                        debug else
                            debug call showDebug(pn, DEBUG_MSG6)
                        endif
                    elseif SubString(msg, len, len + StringLength(MSG_PRIVATE)) == MSG_PRIVATE then
                        set FLOOD_CHAT_TIMER[pn] = FLOOD_CHECK_TIMER
                        set FLOOD_CHAT_TOTAL[pn] = FLOOD_CHAT_TOTAL[pn] + 1
                        set LAST_CHAT[pn] = 2
                        if FLOOD_CHAT_TOTAL[pn] <= FLOOD_CHAT_MAX then
                            set len2 = StringLength(MSG_PRIVATE)
                            set LAST_PM_TARGET[pn] = S2I(SubString(msg, len + len2, len + len2 + 2)) - 1
                            call process(2, pn, SubString(msg, len + len2 + StringLength(I2S(LAST_PM_TARGET[pn])) + 1, StringLength(msg)))
                        debug else
                            debug call showDebug(pn, DEBUG_MSG6)
                        endif
                    elseif SubString(msg, len, len + StringLength(MSG_TEAM)) == MSG_TEAM then
                        set FLOOD_CHAT_TIMER[pn] = FLOOD_CHECK_TIMER
                        set FLOOD_CHAT_TOTAL[pn] = FLOOD_CHAT_TOTAL[pn] + 1
                        set LAST_CHAT[pn] = 3
                        if FLOOD_CHAT_TOTAL[pn] <= FLOOD_CHAT_MAX then
                            call process(3, pn, SubString(msg, len + StringLength(MSG_TEAM) + 1, StringLength(msg)))
                        debug else
                            debug call showDebug(pn, DEBUG_MSG6)
                        endif
                    elseif SubString(msg, len, len + StringLength(MSG_ANNOUNCEMENT)) == MSG_ANNOUNCEMENT then
                        if GetTriggerPlayer() == HOST then
                            if ANNOUNCE_TIMER == 0 then
                                set p = GetTriggerPlayer()
                                set ANNOUNCE_TIMER = ANNOUNCE_DELAY
                                static if LIBRARY_GradientText then
                                    set msg = Gradient(SubString(msg, len + StringLength(MSG_ANNOUNCEMENT) + 1, StringLength(msg)))
                                else
                                    set msg = SubString(msg, len + StringLength(MSG_ANNOUNCEMENT) + 1, StringLength(msg))
                                endif
                                static if SHOW_TIME_TAG then
                                    set msg = SM_PREFIX + " " + TIME_BRACKET1 + GAME_TIMES + TIME_BRACKET2 + " " + ANNOUNCEMENT + EQUAL_SYMBOL + " " + msg
                                else
                                    set msg = SM_PREFIX + " " + ANNOUNCEMENT + EQUAL_SYMBOL + " " + msg
                                endif
                                loop
                                    exitwhen i > 11
                                    if not IsPlayerInForce(p, REJECT_LIST[i]) then
                                        if MAILTOTAL[i] >= MAX_SAVED then
                                            call recycle(i)
                                        endif
                                        set MAILTOTAL[i] = MAILTOTAL[i] + 1
                                        set MAILBOX[i].string[MAILTOTAL[i]] = msg
                                        if OPEN[i] then
                                            call update(i)
                                        endif
                                    endif
                                    set i = i + 1
                                endloop
                            debug else
                                debug call showDebug(pn, DEBUG_MSG7)
                            endif
                        debug else
                            debug call showDebug(pn, DEBUG_MSG5)
                        endif
                    debug else
                        debug call showDebug(pn, DEBUG_MSG1)
                    endif
                debug else
                    debug call showDebug(pn, DEBUG_MSG2)
                endif
            else
                if SubString(msg, 0, StringLength(OTHER_CMD)) != OTHER_CMD then
                    if StringLength(msg) <= MAX_LENGTH then
                        set FLOOD_CHAT_TOTAL[pn] = FLOOD_CHAT_TOTAL[pn] + 1
                        set FLOOD_CHAT_TIMER[pn] = FLOOD_CHECK_TIMER
                        if FLOOD_CHAT_TOTAL[pn] <= FLOOD_CHAT_MAX then
                            static if LIBRARY_GradientText then
                                call process(LAST_CHAT[pn], pn, Gradient(msg))
                            else
                                call process(LAST_CHAT[pn], pn, msg)
                            endif
                        debug else
                            debug call showDebug(pn, DEBUG_MSG6)
                        endif
                    debug else
                        debug call showDebug(pn, DEBUG_MSG2)
                    endif
                endif
            endif
        endif
        return false
    endfunction
    
    private function time takes nothing returns nothing
        local string s1
        local string s2
        local integer i
        
        if ANNOUNCE_TIMER > 0 then
            set ANNOUNCE_TIMER = ANNOUNCE_TIMER - 1
        endif
        set i = 0
        loop
            exitwhen i > 11
            if FLOOD_CHAT_TIMER[i] > 0 then
                set FLOOD_CHAT_TIMER[i] = FLOOD_CHAT_TIMER[i] - 1
                if FLOOD_CHAT_TIMER[i] <= 0 then
                    set FLOOD_CHAT_TOTAL[i] = 0
                endif
            endif
            set i = i + 1
        endloop
        set GAME_TIME = GAME_TIME + 1
        set s1 = I2S(GAME_TIME / 60)
        set s2 = I2S(GAME_TIME - GAME_TIME / 60 * 60)
        if StringLength(s1) == 1 then
            set s1 = "0" + s1
        endif
        if StringLength(s2) == 1 then
            set s2 = "0" + s2
        endif
        set GAME_TIMES = 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 SCROLL_DRCT[i] > 0 then
                set c = c + SCROLL_DRCT[i]
                if SCROLL_DRCT[i] == 1 then
                    if SCROLL_INT[i] < MAILTOTAL[i] - 1 then
                        set SCROLL_INT[i] = SCROLL_INT[i] + 1
                    endif
                elseif SCROLL_DRCT[i] == 2 then
                    if SCROLL_INT[i] > 0 then
                        set SCROLL_INT[i] = SCROLL_INT[i] - 1
                    endif
                endif
                if OPEN[i] then
                    call update(i)
                endif
            endif
            set i = i + 1
        endloop
        if c == 0 then
            call DisableTrigger(SCROLL)
        endif
        return false
    endfunction
    
    private function scrollUp takes nothing returns boolean
        local integer i = GetPlayerId(GetTriggerPlayer())
        
        if SCROLL_DRCT[i] == 0 and OPEN[i] then
            set SCROLL_DRCT[i] = 1
        endif
        if not IsTriggerEnabled(SCROLL) then
            call EnableTrigger(SCROLL)
        endif
        return false
    endfunction
    
    private function scrollDown takes nothing returns boolean
        local integer i = GetPlayerId(GetTriggerPlayer())
        
        if SCROLL_DRCT[i] == 0 and OPEN[i] then
            set SCROLL_DRCT[i] = 2
        endif
        if not IsTriggerEnabled(SCROLL) then
            call EnableTrigger(SCROLL)
        endif
        return false
    endfunction
    
    private function scrollOff takes nothing returns nothing
        local integer i = GetPlayerId(GetTriggerPlayer())
        
        set SCROLL_DRCT[i] = 0
    endfunction
    
    private function ini takes nothing returns nothing
        local trigger t1 = CreateTrigger()
        local trigger t2 = CreateTrigger()
        local trigger t3 = CreateTrigger()
        local integer i = 0
        local player p
        
        call setname()
        loop
            exitwhen i > 11
            set p = Player(i)
            if GetPlayerController(p) == MAP_CONTROL_USER  then
                if SCROLL_ENABLE 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)
                endif
                static if not LIBRARY_ResWord then
                    call TriggerRegisterPlayerChatEvent(CHAT, p, "", false)
                endif
                set REJECT_LIST[i] = CreateForce()
                set SCROLL_DRCT[i] = 0
                set SCROLL_INT[i] = 0
                set MAILBOX[i] = Table.create()
                set MAILTOTAL[i] = 0
                set FLOOD_CHAT_TOTAL[i] = 0
                set FLOOD_CHAT_TIMER[i] = 0
                set LAST_CHAT[i] = 1
                if INITIALY_OPEN then
                    set OPEN[i] = true
                    call update(i)
                else
                    set OPEN[i] = false
                endif
            endif
            set PLAYER_NAME[i] = PLAYER_COLOR[i] + SubString(GetPlayerName(p), 0, MAX_NICK_LENGTH) + "|r"
            set i = i + 1
        endloop
        if SCROLL_ENABLE then
            call TriggerRegisterTimerEvent(SCROLL, SCROLL_RATE, true)
            call TriggerAddCondition(SCROLL, Condition(function scrollLoop))
            call TriggerAddCondition(t1, Condition(function scrollUp))
            call TriggerAddCondition(t2, Condition(function scrollDown))
            call TriggerAddAction(t3, function scrollOff)
            call DisableTrigger(SCROLL)
        else
            call DestroyTrigger(t1)
            call DestroyTrigger(t2)
            call DestroyTrigger(t3)
            set t1 = null
            set t2 = null
            set t3 = null
        endif
        call TriggerAddCondition(CHAT, Condition(function chatEvent))
        call TimerStart(CreateTimer(), 1, true, function time)
        if WINDOW_SIZE > 15 then
            set WINDOW_SIZE = 15
        endif
    endfunction
    
    function AddRestrictedWord takes string s returns nothing
        local integer i = 0
        
        loop
            exitwhen i > 11
            call TriggerRegisterPlayerChatEvent(CHAT, Player(i), s, false)
            set i = i + 1
        endloop
    endfunction
    
    function SetUCSTitle takes string s returns nothing
        set TITLE = s
    endfunction
    
    function SetUCSHost takes player p returns nothing
        set HOST = p
    endfunction
    
    function GetUCSTitle takes nothing returns string
        return TITLE
    endfunction
    
    function GetUCSHost takes nothing returns player
        return HOST
    endfunction
    
    function OpenUCSChatWindow takes integer pn returns nothing
        set OPEN[pn] = true
        call update(pn)
    endfunction
    
    function CloseUCSChatWindow takes integer pn returns nothing
        set OPEN[pn] = false
        if GetLocalPlayer() == Player(pn) then
            call ClearTextMessages()
        endif
    endfunction
    
    function GetUCSElapsedGameTime takes nothing returns string
        return GAME_TIMES
    endfunction
    
    function GetUCSNickname takes integer pn returns string
        return PLAYER_NAME[pn]
    endfunction
    
    function SendUCSChatAll takes integer sender, string msg returns nothing
        call process(1, sender, msg)
    endfunction
    
    function SendUCSChatPrivate takes integer sender, integer reciever, string msg returns nothing
        set LAST_PM_TARGET[sender] = reciever
        call process(2, sender, msg)
    endfunction
    
    function SendUCSChatTeam takes integer sender, string msg returns nothing
        call process(3, sender, msg)
    endfunction
    
    function SendUCSChatSystem takes integer reciever, string msg returns nothing
        call showDebug(reciever, msg)
    endfunction
    
    function TriggerRegisterUCSChatEvent takes trigger t, code cond, code act returns nothing
        call TriggerRegisterVariableEvent(t, "UltimateChat_EVT", EQUAL, 1.00)
        if cond != null then
            call TriggerAddCondition(t, Filter(cond))
        endif
        if act != null then
            call TriggerAddAction(t, act)
        endif
    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

if you want the demo map you can dl it right there :wink:

and also my new library called GradientText, it hasn't been approved yet so I need you guys to help me find anything's wrong or not optimized (I need it because this library is also contained in the chat system so this library must be approved first)
JASS:
library GradientText /* v1.0.9 */ uses HexString
    /*****************************************************************************************/
    /*                                                                                       */
    /*                                    'Gradient Text'                                    */
    /*                                             *****                                     */
    /*                                          by Dalvengyr                                 */
    /*                                                                                       */
    /* This library is used to converts inputed string into a degraded string based on given */
    /* or inputed color code. Dont be fooled by the result of this library. The result looks */
    /* simple but this library is actually doing a hard process. It makes the inputed string */
    /* become 11x sized plus 2(if you make gradient of it of course). For example you input  */
    /* 123, then the result will be |cff******1|cff******2|cff******3|r. Because of this I   */
    /* warn you not to use this in a complicated task. And also because of it and also limit */
    /* of wc3, you cant display too many chars just like if you use native DisplayText, you  */
    /* can only display max of 93 chars (in degraded version of course). Else, it is safe to */
    /* use this library. Enjoy.                                                              */
    /*                                                                                       */
    /* APIs                                                                                  */
    /* - function Gradient takes string s returns string                                     */
    /*                                                                                       */
    /* - function Gradient2 takes string s, string code1, string code2 returns string        */
    /*                                                                                       */
    /* - function UnparseColorCode takes string s returns string                             */
    /*                                                                                       */
    /* Remember that this library can only generate one gradation per FC                     */
    /*                                                                                       */
    /*****************************************************************************************/
    
    globals
    
        // This is for identifying a color code. Don't use "|c" !!
        // Ex. string = 0xFFAA00, identifier = 0x, color code = FFAA00
        
        public      constant        string     IDENTIFIER      = "0x"
        
        // This char will replace "|". Use "" to just delete it
        
        private     constant        string     REPLACER        = ""
        
        // If true, Aplha will also be attached on unparse
        // Ex. no alpha = 0xFF00FF, with alpha = 0xFFFF00FF
        
        private     constant        boolean    SHOW_ALPHA      = false
        
        // This message will be shown when user inputs invalid color code
        
        debug       constant        string     DEBUG_MSG       = "Invalid color code"
        
    endglobals
    
    private function gradation takes string s, string code1, string code2, integer len returns string
        local string res = ""
        local string R
        local string G
        local string B
        local string sub
        local integer r = HS2I(SubString(code1, 0, 2))
        local integer g = HS2I(SubString(code1, 2, 4))
        local integer b = HS2I(SubString(code1, 4, 6))
        local integer rd = (HS2I(SubString(code2, 0, 2)) - r) / (len - 1)
        local integer gd = (HS2I(SubString(code2, 2, 4)) - g) / (len - 1)
        local integer bd = (HS2I(SubString(code2, 4, 6)) - b) / (len - 1)
        local integer i = 0
        local boolean bool = code1 == code2
        
        loop
            exitwhen i > len - 1
            set sub = SubString(s, i, i + 1)
            if sub != " " then
                if sub != "|" then
                    if not bool then
                        set R = I2HS(r + rd * i, false)
                        if StringLength(R) == 1 then
                            set R = "0" + R
                        endif
                        set G = I2HS(g + gd * i, false)
                        if StringLength(G) == 1 then
                            set G = "0" + G
                        endif
                        set B = I2HS(b + bd * i, false)
                        if StringLength(B) == 1 then
                            set B = "0" + B
                        endif
                        set res = res + "|cff" + R + G + B + sub
                    else
                        set res = res + sub
                    endif
                else
                    set res = res + REPLACER
                endif
            else
                set res = res + " "
            endif
            set i = i + 1
        endloop
        if bool then
            set res = "|cff" + code1 + res
        endif
        return res
    endfunction

    function Gradient takes string s returns string
        local string code1 = ""
        local string code2 = ""
        local integer idl = StringLength(IDENTIFIER)
        local integer len = StringLength(s)
        local integer i = 0
        local integer dex1
        local integer dex2
        
        loop
            exitwhen i > len
            if SubString(s, i, i + idl) == IDENTIFIER then
                if code1 == "" then
                    set dex1 = i
                    set code1 = SubString(s, i + idl, i + idl + 6)
                    set s = SubString(s, 0, i) + SubString(s, i + idl + 6, len)
                    set len = len - 8
                else
                    set dex2 = i
                    set code2 = SubString(s, i + idl, i + idl + 6)
                    set s = SubString(s, 0, i) + SubString(s, i + idl + 6, len)
                    set len = len - 8
                    if HS2I(code1) >= 0 and HS2I(code2) >= 0 then
                        set s = SubString(s, 0, dex1) + gradation(SubString(s, dex1, dex2), code1, code2, dex2-dex1) + SubString(s, dex2, len)
                    debug else
                        debug call BJDebugMsg(DEBUG_MSG)
                    endif
                endif 
            endif
            set i = i + 1
        endloop
        if code1 != "" then
            if code2 == "" then
                if HS2I(code1) >= 0 then
                    set s = SubString(s, 0, dex1) + gradation(SubString(s, dex1, len), code1, code1, len-dex1) + "|r"
                debug else
                    debug call BJDebugMsg(DEBUG_MSG)
                endif
            else
                set s = s + "|r"
            endif
        endif
        return s
    endfunction

    function Gradient2 takes string s, string code1, string code2 returns string
        local integer len = StringLength(s)
        
        if HS2I(code1) >= 0 and HS2I(code2) >= 0 then
            set s = gradation(s, code1, code2, len) + "|r"
        debug else
            debug call BJDebugMsg(DEBUG_MSG)
        endif
        return s
    endfunction
    
    function UnparseColorCode takes string s returns string
        local integer len = StringLength(s)
        local integer idl = StringLength(IDENTIFIER)
        local integer i = 0
        local string sub
        
        loop
            exitwhen i > len
            set sub = SubString(s, i, i + 2)
            if sub == "|c" or sub == "|C" then
                static if SHOW_ALPHA then
                    set s = SubString(s, 0, i) + IDENTIFIER + SubString(s, i + 2, len)
                    set len = len + idl
                else
                    set s = SubString(s, 0, i) + IDENTIFIER + SubString(s, i + 4, len)
                    set len = len + idl - 2
                endif
            endif
            set i = i + 1
        endloop
        return s
    endfunction
endlibrary

Please, poll up wisely and give valid argument about your poll. because the poll is public.
 
Last edited:

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
If only you could block whispers,
yes, you could do it by, defaultly, entring this command -reject followed by target player's number. ex: -reject2 to block whisper from player 2
Any chance of seeing a GUI version? =)
maybe there is, but, I forgot how to code in GUI D:
 

Wrda

Spell Reviewer
Level 25
Joined
Nov 18, 2012
Messages
1,870
what's good about this system compared to default wc3 chat:
- you can send private message easiliy I don't think so, you need to type the command, which player, looks like more slower for me. I think its unnecessary.

- you can check chat history easier, as well as hiding, unhiding, and clearing them (no need to open window which disturbs gameplay) What about the scroll? Doesn't it screw up?

- allows colorized and gradient chats Useful
- reject list Useful
- anti-spam/flood Useful
- words restrictions Useful
- and other minor features okay... O_O

but, there are 3 disadvantages on using this system which is a little hurt. you can read them inside the code. Maybe one I need to explain more is about double line bugs. You know if you entered a too-long-message the displayed text will be double lined. its something like this
Code:
-Single lined 12312312312312312312312312321123

-Double lined 12312312312312312312312312321123
123123123
this bug could hide the title or anything above since the max shown message is 16 on screen at the same time. But luckily, you could easily maintain the max entered chat length using this global (I guess it's a little awkward since you have to maintain it manually, so that's why I think I need to warn you about this)
private constant integer MAX_LENGTH = 73That's bad, but maybe not a big problem, people usually don't write long sentences
Close to Wc3 chat :p
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Normal Chat
attachment.php


UCS
attachment.php


somebody got any argument about prefering normal chat than UCS? please, share here..

Your saying it blocks /w name?
wut? I was not saying that.. just -reject# (# is player number)
 

Attachments

  • ucs.jpg
    ucs.jpg
    329.4 KB · Views: 215
  • normal chat.jpg
    normal chat.jpg
    314.4 KB · Views: 225
Level 30
Joined
Nov 29, 2012
Messages
6,637
Observer is not actually that useless, it's a term use for those players only observing the game so for example if a player is observer, he will only watch the game and you can send message to these observer through the "Send to Observer". Just saying though but I really prefer your chat system more than the original. It's really an advance version of the original.
 
It might be a good system, but this thread seems useless for me.

People who need a chat system here on hive, will find it if they search for it. But this just seems for me like: "My system is very cool, so USE IT ! ! !"

Idk if it's needed to open more threads just to get more attention on your ressource, sorry.

But that's just my very subjective opinion, don't take it too personal. ;)
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
It might be a good system, but this thread seems useless for me.

People who need a chat system here on hive, will find it if they search for it. But this just seems for me like: "My system is very cool, so USE IT ! ! !"

Idk if it's needed to open more threads just to get more attention on your ressource, sorry.

But that's just my very subjective opinion, don't take it too personal. ;)
+1 vote
You've already got a thread or two regarding your chat system. Keep things related to it within them instead of spamming forum.
No offense though.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
but this thread seems useless for me.
it's not useless.. see? I always got more feedbacks here.. :)

"My system is very cool, so USE IT ! ! !"
absolutely not, I haven't got any review in the spell section, that's why I think I need to discuss here too. And actually, comparing ucs and wc3 chat is not the point of this thread, I want some helps to improve the code.. just that. dont worry I wont take it personal :)

Observer is not actually that useless, it's a term use for those players only observing the game so for example if a player is observer
and how to be ovserver? :p
thnks btw :D

- you can send private message easiliy I don't think so, you need to type the command, which player, looks like more slower for me. I think its unnecessary.
why? you just need to type *pm# once, after that you just need to type the message and the message will be automatically sent to the last recipient, the same thing happens for all and team message

- you can check chat history easier, as well as hiding, unhiding, and clearing them (no need to open window which disturbs gameplay) What about the scroll? Doesn't it screw up?
check the newest update, I have improved the scrolling where you could just hold the button to scroll up/down

UCS's chat takes kinda half of the screen to show the text, we can't see an area of the game properly.
that's right but you could smaller the fonts using war3mapMisc.txt :) I will add demo about this later..

I wouldn't send a private message, but a whisper "/w name", faster
how if my name is 10 characters long or more? :p

I have an idea to add glowing text feature.. but I need a font maker application, somebody know one? I need the free one :p
 
Status
Not open for further replies.
Top