• 🏆 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 Chat System v1.1

  • Like
Reactions: LuizBills
Description: This system can be used as a replacement messaging system for RPG, AOS, ORPG or any basic map. Customization is included in the script, however I'll also post some explanations here ; ). When I was working on a map with a friend, I found myself lacking a chat system that had what I wanted, so I decided to make my own. I believe the script matches JPAG requirements, if you find a mistake please tell me, I'll fix it but I checked over it and fixed what I found. The system will take the original system and change it to be more controllable and flexible for developers. This alternative allows players to change their name and text color. I really needed a new Chat System for my ORPG game in development and so I created this. This new chat system is like the blizzard chat system, however it allows the map to get a more customized feel, taking away from the game being as WC3. Many maps out there have name change systems and color change systems, and this system will give you both in one package. I feel like it's more of an aesthetic system, but in map development, looks are also important ^.^
Along with the ability to completely disable sections of the script, you can have your map set up pretty much any way you want it. I'm most likely going to fix this script up big time to make it so you can pick which text you want as your PERSONAL default, however I'm not certain about making them able to use outside commands, as I've disabled the main Blizzard chat display. I'll be tweaking it for a little while and seeing what I can do, along with checking here for feedback on what people actually want in a custom chat system. Chat and social connection in a game is very important and I felt this system would be a fitting addition to THW.

Note: Some are asking about it (Bribe) and yes, one of my friends that was helping me with this script died during the process. I won't go into details but I just felt this was something that I could do for him in memory.

Configuration: To set up your own map to comply with this system, simple copy and paste the code into an empty trigger base (doesn't matter what you name it) and remember to change Advanced -> Game Interface -> all the chat boxes (first 5 fields) to 240 spaces. (Suggestion): Make 24 spaces in a word document or other typing application and simply copy it and paste it 10 times.

Changing the set messTime = 10. value to any other value (other than negative, will cause crashes) will set the amount of time that messages will display on the screen.

Current problems being looked into:
  • Currently all messages are displayed in Chat Log unless typed in observers chat. This is being looked into now.
    *Solution*. The only solution is to use observers chat. It is recommended to send players a message saying this at or near the beginning of gameplay or I will add it in if a mod or users say it would be best to do so. Apologies, some things cant be worked around.

Changing one of these lines
JASS:
            set privOn = true
            set allOn = true
            set allyOn = true
            set colOn = true
            set nameOn = true
to false will cause the function to be not able to be used by players. If enough people want me to create it, I can create another section of the system that will allow the "host" player to activate or inactivate any functions because these values are global they can be modified anywhere.

Adding colors is as simple as adding another value to the colName index (count ascending not randomly), and the corresponding WC3 color code to the cCol index. and changing the colorCount integer to correspond with the new max number of color indexes.


There are more slight modifications throughout the coding, if you care to change them, feel free ; ), however remember if you change the commands, you must make sure that they comply with the substrings, and they have checks to ensure that players cannot find a hole in the coding or glitch it. If you need modifications, please contact me if you can't do it. Please give credit to me if the system is used, not exactly sure if anyone else wants the credit, some are only credited for assisting concepts which helped me, but I feel need to accredit them originally.

Coding listed below:

JASS:
library CSV2 initializer Init
     /* Very effective and customizable system. It efficiently uses minimal string creations, other than those
    repeated I.E. Colors, real names along with substrings to check for commands.
    
    Map Config Needed: Make sure to set Advanced > Game Interface > first five fields (Chat fields) to exactly 240
    spaces. Also you will need JNPG to compile this script.
    
    Credits (Scripter) to:
    khamarr3524: 95% of the work done, with critiquing from others listed below. 5% to Sean, R.I.P.
    
    Credits (From thehiveworkshop.com) to:
    TheMaker: For assisting me in portions of the script along with helping me understand initializers.
    Troll - Brain: For assisting me in portions of the script and debugging along with initializers.
    Magtheridon96: For supportive feedback and assisting me in portions of the script along with understaind initializers.
    Dr Super Good: For helping me understand substring clauses and assisting me in portions of the script.
    PurgeandFire111: For helping me understand substring clauses.
    
    Credits (From friends) to:
    Stygian_Shadow: For testing the script.
    RoxasHikari: For testing the script.
    Suppressed: For testing the script.
    Kavudragon: For testing the script.
    Aradicator: For testing the script.
    Fluffysaur: For testing the script.
    Sean: Helping with the script layout, dedication to him, may he rest in peace.
     */ 


    globals
        private string array cCol
        private string array colName
        string array custName
        private integer array pCol
        private real messTime
        force playForce = CreateForce()
        private boolean allies = false
        private boolean all = false
        private boolean priv = false
        private boolean sCol = false
        private boolean cName = false
        public boolean privOn
        public boolean allOn
        public boolean allyOn
        public boolean colOn
        constant integer colorCount = 18
        public boolean nameOn
        constant string errorOn = "|c00ff3300You cannot use this function.|r"
        private integer whoPrivate
        private player sendPlayer = null
        private string message = ""
    endglobals

    scope Start

        function DoMapSetup takes nothing returns nothing
            local integer i = 0
            local player p
            loop
                set p = Player(i)
                if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER then
                    call ForceAddPlayer(playForce, p)
                    set custName[i] = GetPlayerName(p)
                endif
                set i = i + 1
                exitwhen i > 11
            endloop
            set p = null
//Set this to a real integer for time to display messages. Negative values cause crashes.
            set messTime = 10.
//Here you can specify what you want to be enabled. Setting True means it will be active. False will be inactive.
//By creating a trigger series or library, (probably will be made by me and posted), you can let the play in
//"host slot select these options on start of map ;). Otherwise you can just use set <variable> = true/false
            set privOn = true
            set allOn = true
            set allyOn = true
            set colOn = true
            set nameOn = true
//-----------------------------------------------------------------
            set cCol[0] = "|c00ff0000"
            set cCol[1] = "|c000000ff"
            set cCol[2] = "|c0000ffff"
            set cCol[3] = "|c00660099"
            set cCol[4] = "|c00ffff00"
            set cCol[5] = "|c00ff9900"
            set cCol[6] = "|c0033ff00"
            set cCol[7] = "|c00ff00ff"
            set cCol[8] = "|c00999999"
            set cCol[9] = "|c009999ff"
            set cCol[10] = "|c00006600"
            set cCol[11] = "|c00330000"
            set cCol[12] = "|c00000000"
            set cCol[13] = "|c00990000"
            set cCol[14] = "|c00999900"
            set cCol[15] = "|cffffffff"
            set cCol[16] = "|c00999999"
            set cCol[17] = "|c0033ff00"
            set cCol[18] = "|c00ff33ff"
 //------------------------------------------------
//Add any colors here that you want. Remember if you add colors to change colorCount in the globals and add the
//wc3 color code to correspond to the index and name here in the cCols.
            set colName[0] = "Red"
            set colName[1] = "Blue"
            set colName[2] = "Teal"
            set colName[3] = "Purple"
            set colName[4] = "Yellow"
            set colName[5] = "Orange"
            set colName[6] = "Lgreen"
            set colName[7] = "Pink"
            set colName[8] = "Gray"
            set colName[9] = "Lblue"
            set colName[10] = "Green"
            set colName[11] = "Brown"
            set colName[12] = "Black"
            set colName[13] = "Maroon"
            set colName[14] = "Gold"
            set colName[15] = "White"
            set colName[16] = "Silver"
            set colName[17] = "Lime"
            set colName[18] = "Fuchsia"
        endfunction

        struct Text extends array
            
            private static method textAll takes nothing returns nothing
                local player p = sendPlayer
                local integer pNum = GetPlayerId( p )
                local integer i = 0
                local player recP
                if allOn then
                    call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, messTime, (cCol[pNum] + "(All): " + custName[pNum] + ":|r " + cCol[pCol[pNum]] + message + "|r" ) )
                    set message = null
                    set sendPlayer = null
                    set p = null
                    set recP = null
                    return
                endif
                call DisplayTimedTextToPlayer(p, 0, 0, 10, errorOn)
                set p = null
                set recP = null
            endmethod
        
            private static method textPrivate takes nothing returns nothing
                local player p = sendPlayer
                local integer pNum = GetPlayerId( p )
                local player recP = Player( whoPrivate )
                if privOn then
                    if custName[whoPrivate] == null then
                        call DisplayTimedTextToPlayer(p, 0, 0, messTime, "That player isn't in the game.")
                        set message = null
                        set sendPlayer = null                        
                        set p = null
                        set recP = null
                        return
                    endif
                    call DisplayTimedTextToPlayer( recP, 0, 0, messTime, ( cCol[pNum] + "(Private): " + custName[pNum] + ":|r " + cCol[pCol[pNum]] + message + "|r") )
                    call DisplayTimedTextToPlayer(p, 0, 0, messTime, ( cCol[GetPlayerId(recP)] + "(Private): " + custName[GetPlayerId(recP)] + ":|r " + cCol[pCol[pNum]] + message + "|r" ) )
                    set message = null
                    set sendPlayer = null
                    set p = null
                    set recP = null
                    return
                endif
                call DisplayTimedTextToPlayer(p, 0, 0, messTime, errorOn)
                set message = null
                set sendPlayer = null
                set p = null
                set recP = null
            endmethod
    
            private static method textAllies takes nothing returns nothing
                local player p = sendPlayer
                local integer pNum = GetPlayerId( p )
                local integer i = 0
                local player recP
                if allyOn then
                    loop
                        set recP = Player( i )
                        if IsPlayerInForce( recP, playForce ) and IsPlayerAlly( recP, p ) then
                            call DisplayTimedTextToPlayer( recP, 0, 0, messTime, ( cCol[pNum] + "(Allies): " + custName[pNum] + ":|r " + cCol[pCol[pNum]] + message + "|r" ) )
                        endif
                        set i = i + 1
                        exitwhen i > 11
                    endloop
                    set message = null
                    set sendPlayer = null
                    set p = null
                    set recP = null
                    return
                endif
                call DisplayTimedTextToPlayer(p, 0, 0, messTime, errorOn)
                set message = null
                set sendPlayer = null
                set p = null
                set recP = null
            endmethod
            
            private static method name takes nothing returns nothing
                local player p = sendPlayer
                local integer pNum = GetPlayerId(p)
                if nameOn then
                    if message == "" or message == " " or StringLength(message) > 15 then
                        call DisplayTimedTextToPlayer(p, 0, 0, messTime, "You must enter a valid name.")
                        set p = null
                        set message = null
                        set sendPlayer = null
                        return
                    endif
                    set custName[pNum] = message
                    call DisplayTimedTextToPlayer(p, 0, 0, messTime, "|c00ff3300Your name is now: " + custName[pNum] + "|r")
                    set message = null
                    set sendPlayer = null
                    set p = null
                    return
                endif
                call DisplayTimedTextToPlayer(p, 0, 0, messTime, errorOn)
                set message = null
                set sendPlayer = null
                set p = null
            endmethod
            
            private static method color takes nothing returns nothing
                local player p = sendPlayer
                local integer pNum = GetPlayerId(p)
                local integer i = 0
                if colOn then
                    loop
                        if StringCase(message, false) == StringCase(colName[i], false) then
                            set pCol[pNum] = i
                            call DisplayTimedTextToPlayer(p, 0, 0, messTime, "|c00ff3300Your color is now:|r " + colName[i])
                            return
                        endif
                        set i = i + 1
                        exitwhen i > colorCount
                    endloop
                    call DisplayTimedTextToPlayer(p, 0, 0, messTime, "|c00ff3300Please type an available color.|r")
                    return
                endif
                call DisplayTimedTextToPlayer(p, 0, 0, messTime, errorOn)
                set p = null
                set message = null
                set sendPlayer = null
            endmethod
    
            static method sendMessage takes nothing returns nothing
                if allies then
                    call thistype.textAllies( )
                    set allies = false
                elseif all then
                    call thistype.textAll( )
                    set all = false
                elseif priv then
                    call thistype.textPrivate( )
                    set priv = false
                elseif cName then
                    call thistype.name()
                    set cName = false
                elseif sCol then
                    call thistype.color()
                    set sCol = false
                endif
            endmethod
        endstruct
    endscope
    
    private function ConvertText takes nothing returns nothing
        local string origString = GetEventPlayerChatString( )
        local string codeString = SubString( origString, 0, 4 )
        local integer end = StringLength( origString )
        local integer isAlly = 0
        set sendPlayer = GetTriggerPlayer( )
        if codeString == "-pm " then
            set priv = true
            set whoPrivate = (S2I( SubString( origString, 4, 6 ) ) - 1 )
            if whoPrivate < 0 or whoPrivate > 11 then
                call DisplayTimedTextToPlayer( sendPlayer, 0, 0, messTime, "You must enter a digit 1-12.")
                set priv = false
                set origString = null
                set codeString = null
                return
            endif
            set message = SubString( origString, 6, end )
            call Text.sendMessage( )
            set origString = null
            set codeString = null
            return
        endif
            set isAlly = isAlly + 1
        if codeString == "-all" then
            set all = true
            set message = SubString ( origString, 4, end )
            if SubString(message, 0, 1) == " " then
                set message = SubString(message, 1, StringLength(message))
            endif
            call Text.sendMessage( )
            set origString = null
            set codeString = null
            return
        else
            set isAlly = isAlly + 1
        endif
        set codeString = SubString(origString, 0, 7)
        if codeString == "-color " then
            set sCol = true
            set message = SubString(origString, 7, end)
            call Text.sendMessage()
            set origString = null
            set codeString = null
            return
        elseif codeString == "-cname " then
            set cName = true
            set message = SubString(origString, 7, 18)
            call Text.sendMessage()
            set origString = null
            set codeString = null
            return
        elseif isAlly == 2 then
            set allies = true
        endif
        set message = SubString( origString, 0, end )
        call Text.sendMessage( )
        set origString = null
        set codeString = null
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger( )
        local integer i = 0
        local player p
        call DoMapSetup()
        loop
            if GetPlayerSlotState( Player( i ) ) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController( Player( i ) ) == MAP_CONTROL_USER then
                call TriggerRegisterPlayerChatEvent( t, Player(i), "", false)
                set pCol[i] = 15 //if you want this to be changed to their color. Swap it with the next line.
                //set pCol[i] = [i]
            endif
            set i = i + 1
            exitwhen i > 11
        endloop
        call TriggerAddAction( t, function ConvertText )
        set t = null
        set p = null
    endfunction
endlibrary

scope PlayerLeaves initializer init
    private function Leaver takes nothing returns nothing
        local player p = GetTriggerPlayer()
        call ForceRemovePlayer(playForce, p)
        set custName[GetPlayerId(p)] = null
        call SetPlayerName(p, "Left the Game!")
        set p = null
    endfunction
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        loop
            call TriggerRegisterPlayerEvent(t, Player(i), EVENT_PLAYER_LEAVE)
            set i = i + 1
            exitwhen i > 11
        endloop
        call TriggerAddAction(t, function Leaver)
        set t = null
    endfunction
endscope


v1.0: Release
v1.1: Added 3 new colors, system message have special color.


Keywords:
Warcraft 3, vjass Chat system, custom chat system, chat, chat system, vjass, system, custom, message
Contents

vJass Chat System (Map)

Reviews
Update 26 April 2012 Bribe: Approved 3/5. Another chat system for vJass joins the fray. 6th Apr 2012 Bribe: In "sendMessage" method, instead of spamming "return" use the "elseif" keyword. You are leaking handle ID's. Sean: Helping with the...

Moderator

M

Moderator

Update 26 April 2012
Bribe: Approved 3/5. Another chat system for vJass joins the fray.

6th Apr 2012
Bribe: In "sendMessage" method, instead of spamming "return" use the "elseif" keyword.

You are leaking handle ID's.

JASS:
Sean: Helping with the script layout, @dedication to him, may he rest in peace@.

Someone died to write this script for you?

Spawner trigger -

This doesn't compile and run properly for me: public constant effect array landing[11]. Arrays cannot be constant, ever.

The following lines:

JASS:
//Instead of this:
        local trigger t = CreateTrigger()
        call rects()
        call TriggerRegisterTimerEvent(t, .05, false)
        call TriggerAddAction(t, function spawn.start)
        set t = null
//Do this:
 call rects()
 call TimerStart(CreateTimer(), 0.5, false, function spawn.start)
 
  • All the globals should be private or private constant so users can't use them outside the system and because they're taking up namespace
  • The global boolean private should be changed because it might cause errors with the parser o-o (change the name to priv or something)
  • ==true is incredibly redundant everywhere
  • To display a message to all players, you would do this: call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, DURATION, MESSAGE)
  • Whenever you call DisplayText functions multiple times inside a function, you could optimize that function by using a local string and instead of displaying the message, you would that local to: set s = s + message + "\n", then you would call DisplayTimedTextToPlayer at the end of the function.
  • You don't need to check if a player is playing or not to display text. You won't lose performance at all. In fact, by not caring, you would be gaining performance.
  • In your name static method, the 15 should be configurable.

edit
And who's Sean? :eek:
 
khamarr3524 said:
Description: This system can be used for RPG, AOS, ORPG or any basic map. Customization is included in the script, however I'll also post some explanations here ; ). When I was working on a map with a friend, I found myself lacking a chat system that had what I wanted, so I decided to make my own. I believe the script matches JPAG requirements, if you find a mistake please tell me, I'll fix it but I checked over it and fixed what I found.

where is the description of what this system does?
 
Level 9
Joined
Apr 23, 2011
Messages
460
  • All the globals should be private or private constant so users can't use them outside the system and because they're taking up namespace
  • The global boolean private should be changed because it might cause errors with the parser o-o (change the name to priv or something)
  • ==true is incredibly redundant everywhere
  • To display a message to all players, you would do this: call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, DURATION, MESSAGE)
  • Whenever you call DisplayText functions multiple times inside a function, you could optimize that function by using a local string and instead of displaying the message, you would that local to: set s = s + message + "\n", then you would call DisplayTimedTextToPlayer at the end of the function.
  • You don't need to check if a player is playing or not to display text. You won't lose performance at all. In fact, by not caring, you would be gaining performance.
  • In your name static method, the 15 should be configurable.

edit
And who's Sean? :eek:

1. Will fix SOME globals. As stated in the configuration, the functions listed with On in them should be left touchable to players because they can configure them throughout the game. Also some globals are used outside the library and therefore cannot be wrapped as private, otherwise they wouldn't work properly.

2. I thought I did this, but I must have been wrong :p Thank you. Fixed.

3. I don't understand? In configuration for whatever reason, if default values are not given, the functions dont register values properly.

4. Fixed. Thanks, I was unaware of this. I've heard to avoid GetLocalPlayer() for desyncs but I guess if it's all, doesn't affect it at all :p

5. If you read the scripting more clearly, you would notice some slight differences in the only location in which this occurs are present, this is why I cannot simplify it more.

6. Originally when working with the coding, displaying text to a non-playing player seemed bad because it would create an excess string declaration that cannot be "trash collected". Or am I wrong? And I don't really see where this is, other than when I add players to playForce.

7. Fixed :p

Also, Sean is more of a personal friend, he hung himself last weekend and we were working on this together, I felt it fitting to include him as a very important contributor.
 
Level 9
Joined
Apr 23, 2011
Messages
460
Apologies, I mean to edit >.<. Anyways I understand now, I haven't been very direct in explaining it, I'll post a revised description now. It's more of a "non-Blizzard" way of displaying in-game messages. I'll post more in original post.


EDIT: I understand Magtheridon96 now, all "redundant" == true comparisons are resolved. I was unaware of this o.o Thank you.
 
Last edited:
if whoPrivate != 0 and whoPrivate != 1 and whoPrivate != 2 and whoPrivate != 3 and whoPrivate != 4 and whoPrivate != 5 and whoPrivate != 6 and whoPrivate != 7 and whoPrivate != 8 and whoPrivate != 9 and whoPrivate != 10 and whoPrivate != 11 then

Why not check if it's less than 0 or greater than 11? ._.
 
Level 9
Joined
Apr 23, 2011
Messages
460
@Magtheridon o.o I'm sorry, i didn't do that system set, I should have picked up on it, but I'll fix it now thanks.

@shadowvs Messages are displayed only to players in the game and who are users due to the conditions set in place in the addition of players to the force playForce.

Edit: Map is currently not updated however script is. Apologies.

Edit: Map is now updated. A solution to the PM problem has been found.
 
Last edited:
Top