OSP Kit MP [WB] Colored Faction Chat

Users who are viewing this thread

MadocComadrin

Water-Borne Annelid
Count
This is a customizable kit you can use to add a colored team chat to your mod. It currently uses 5 colors, but they can be expanded easily. Feel free to use it or modify it however you please without permission (Some credit would be nice, but it's not necessary  :mrgreen:).

About the fix, if my theory was correct, the reason the faction chat was bugging out in PW Mod was due to a high number of mission_template triggers and scripts running simultaneously as well as Low Framerate client-side. Hopefully this update will fix all that, or at least make the message repeat once or twice instead of not showing up at all.

Also, the look of the chat box has been fixed to look almost exactly as the native chats (off by a few pixels). Plus, I've changed it so the text above the box is the same color as your color (thanks to Lazslo et al for the inspiration). Finally, expect to no longer need to click on the chat box after the 1.128 patch (thanks to Vorne for the inside info).

Well, lets get on to the good stuff

header_common
Put these anywhere in header_common.
Code:
fac_red                                       = 0
fac_white                                     = 1
fac_blue                                      = 2
fac_green                                     = 3
fac_gold                                      = 4
fac_max_fac                                   = 5
Add these to the list of multiplayer events (note: if you have defined other events, make sure you adjust the numbers accordingly).
Code:
#server
multiplayer_event_new_fac_chat                = 113
#client
multiplayer_event_display_fac_chat            = 114
multiplayer_event_fac_chat_successful         = 115


module_presentations
Add this presentation anywhere. If you add more colors, make sure you tweak this script accordingly (there is a comment to tell you where you'll need to update).
Code:
("send_faction_message",prsntf_manual_end_only, 0,[
    (ti_on_presentation_load,
       [
	    (set_fixed_point_multiplier, 1000),
        (init_position, pos1),
        (str_store_string, s1, "@Send message to current faction:"),
        (create_text_overlay, reg1, s1,tf_with_outline),
		(overlay_set_color, reg1, 0xFFFFFFFF), #DEFAULT OVERLAY COLORY
		
		#Color factions are related to the hex code for overlay color. IF YOU ADD MORE COLORS UPDATE THIS!
		(multiplayer_get_my_player, ":player_no"),
		(call_script,"script_get_player_color_faction", ":player_no"),
        (try_begin),
           (eq,reg0, fac_red),
           (overlay_set_color, reg1, 0xFF0000),
        (else_try),
           (eq,reg0, fac_white),
           (overlay_set_color, reg1, 0x000000),
        (else_try),
           (eq,reg0, fac_blue),
           (overlay_set_color, reg1, 0x0000FF),
        (else_try),
           (eq,reg0, fac_green),
           (overlay_set_color, reg1, 0x00FF00),
        (else_try),
           (eq,reg0, fac_gold),
           (overlay_set_color, reg1, 0xFFF500),
        (try_end),
		
        (position_set_x, pos1, 200),
        (position_set_y, pos1, 530),
        (overlay_set_position, reg1, pos1),
        (overlay_set_text, reg1, s1),
        (position_set_x, pos1, 1000),
        (position_set_y, pos1, 1000),
        (overlay_set_size, reg1, pos1),

        (create_simple_text_box_overlay, "$g_presentation_obj_fac_message", tf_center_justify),
        (position_set_x, pos1, 200),
        (position_set_y, pos1, 500),
        (overlay_set_position, "$g_presentation_obj_fac_message", pos1),
        (position_set_x, pos1, 600),
        (position_set_y, pos1, 1000),
        (overlay_set_size, "$g_presentation_obj_fac_message", pos1),
        (overlay_obtain_focus, "$g_presentation_obj_fac_message"),
      
        (assign, "$g_waiting_to_send_fac_chat", 1),
        (str_clear, s0),
        (overlay_set_text, "$g_presentation_obj_fac_message", s0),
        (assign,"$g_waiting_for_confirmation_to_terminate", 1),
        (presentation_set_duration, 999999),
      ]),

      (ti_on_presentation_event_state_change,
              [(store_trigger_param_1, ":object"),
              (try_begin),
                  (eq,":object", "$g_presentation_obj_fac_message"),
              (try_end),
              (try_begin),
                  (neq,"$g_waiting_to_send_fac_chat",1),
				  (assign, "$RepeatChatUntilSucess", 1),
				  (str_store_string_reg, s67, s0),
                  (multiplayer_send_string_to_server, multiplayer_event_new_fac_chat, s0),
                  (assign, "$g_waiting_for_confirmation_to_terminate", 0),
                  (presentation_set_duration, 0),
              (try_end),
        ]),

       (ti_on_presentation_run,
           [(store_trigger_param_1, ":cur_time"),
           (try_begin),
                 (key_clicked, key_escape),
                 (assign, "$g_waiting_for_confirmation_to_terminate", 0),
                 (presentation_set_duration, 0),
                 (assign, "$g_waiting_to_send_fac_chat", 0),
           (else_try),
                  (key_clicked, key_enter),
                  (assign, "$g_waiting_to_send_fac_chat", 0),
           (try_end),
        ]),
    ]),


module_mission_templates
Add these triggers in whatever gamemodes you need faction chat in.
Code:
(0.5, 0, 0, [],
       [
         (try_begin),
         (eq, "$RepeatChatUntilSucess", 1),
		 (multiplayer_send_string_to_server, multiplayer_event_new_fac_chat, s67),
         (try_end),         
       ]),
(Note: you can change the key used to access the chat in this trigger)
Code:
(0, 0.05, 0, [
             (eq, "$g_waiting_for_confirmation_to_terminate", 0),
             (multiplayer_get_my_player, ":player_no"),
             (player_is_active, ":player_no"),
             (key_clicked, key_u),
       ],
       [
           (start_presentation, "prsnt_send_faction_message"),     
       ]),


module_mission_scripts
Add this script to the bottom of the scripts (before the bracket). This is the script where you'll want to add in the conditions that determine to which faction a player belongs (eg. PW Mod uses armors or hats). You can also add more colors here.
Code:
  #####################################
  #get_player_faction
  #input:  arg1=player id
  #output: reg0=player's color faction, returns -1 if no faction.
  #####################################
  ("get_player_color_faction",
    [
     (store_script_param_1, ":player_no"),
     (player_get_agent_id, ":agent_no", ":player_no"),
          (assign, reg0, -1),
      (try_begin), #RED
      #INSERT CONDITIONS HERE
        (assign, reg0, fac_red),
     (else_try), #WHITE
       #INSERT CONDITIONS HERE
       (assign, reg0, fac_white),
     (else_try), #BLUE
		#INSERT CONDITIONS HERE
       (assign, reg0, fac_blue),
     (else_try), #GREEN
		#INSERT CONDITIONS HERE
		(assign, reg0, fac_green),
     (else_try), #GOLD
       #INSERT CONDITIONS HERE
       (assign, reg0, fac_gold),
     (try_end),
  ]),

Next look for the script, game_receive_network_message and add these to their respective spots.

Add this to the server events
Code:
	(else_try),
		(eq, ":event_type", multiplayer_event_new_fac_chat),
		(try_begin), ###Get sender players color
			(str_store_player_username, s1,":player_no"),
			(str_store_string, s4, "@[{s1}] {s0}"),
			(server_add_message_to_log, s4),
			(call_script, "script_get_player_color_faction", ":player_no"),
			(assign, ":player_fac", reg0),
       
			(get_max_players, ":players"), #Get destination players' color based on color faction
                        (try_for_range, ":dest_player_no", 1, ":players"),
				(try_begin),
					(player_is_active, ":dest_player_no"),
					(call_script, "script_get_player_color_faction", ":dest_player_no"),
					(eq, reg0, ":player_fac"),
					(multiplayer_send_string_to_player, ":dest_player_no", multiplayer_event_display_fac_chat, s4),
				(try_end),
			(try_end),
			(multiplayer_send_message_to_player, ":player_no", multiplayer_event_fac_chat_successful),
		(try_end),

Add these two to the client events.
If you add more colors, make sure you tweak this script accordingly (there is a comment to tell you where you'll need to update).
Code:
(else_try),
          (eq, ":event_type", multiplayer_event_display_fac_chat),
          (multiplayer_get_my_player, ":player_no"),
			(assign, reg0, fac_gold), ###DEFAULT COLOR
			(call_script, "script_get_player_color_faction", ":player_no"),
        
			#Color factions are related to the hex code for color displayed. IF YOU ADD MORE COLORS, UPDATE THIS!!!
			(try_begin),
				(eq,reg0, fac_red),
				(display_message, s0, 0xFF0000),
			(else_try),
				(eq,reg0, fac_white),
				(display_message, s0, 0x000000),
			(else_try),
				(eq,reg0, fac_blue),
				(display_message, s0, 0x0000FF),
			(else_try),
				(eq,reg0, fac_green),
				(display_message, s0, 0x00FF00),
			(else_try),
				(eq,reg0, fac_gold),
				(display_message, s0, 0xFFF500),
			(try_end),
Code:
(else_try),
		  (eq, ":event_type", multiplayer_event_fac_chat_successful),
		  (assign, "$RepeatChatUntilSucess", 0),

Confused? Don't worry, this is what the entire game_receive_network_message script should look like.
http://gk-server.us/game_receive_network_message.txt


Okay, that's all folks! If there are any problems or questions (or praise) let me know
 
In-game it looks pretty much like the normal chat, except the message is displayed in a certain color and only to certain people based on a set of conditions that you can customize. For example, in PW the factions are based on what armor you are wearing. Also, Laszlo made a slight modification that I like and will include when I add a fix for dropped chats (and maybe a fix for needing to click on the chat box, if M&B has the right operations).
 
Excellent! This was something that we sorely needed. Also, you wouldn't happen to have any ideas for fixing the the message-not-appearing bug? Or at least any ideas where the problem lies?
 
Not really, sorry. I've tested that sort of feature many times for the poll and admin mod, with a local server and clients, and I remember it working consistently; so I would guess that the problem is related to how the network code works when heavily loaded - though it may turn out to be a bug in the added scripts after all. For the next week or so I'm on holiday without a M&B install, so I can't test anything.
 
I like the date you update  :grin:

Surely there must be a better solution then keep sending the message to the server until you get the response back, I can imagine that with some lag it might be shown twice or thrice to some clients without connection issues at those frames?
 
Until I know exactly what the problem is (or the devs fix something behind the scenes), it's better than the message not appearing at all. Also, when I tested it with low framerate, only rarely did the message show more than once. Besides, if low frame-rate plus connection problems make the messages appear to often, the trigger can be set to fire at a slower interval.
 
Hmm, i'd say check every half second 0.5 if the message was properly send (500 ping) in stead of 0.05 (50 ping).
And I do think it is not a fixable thing, I did some research in the network code.

Basically the problem is player numbers. Players have to get updates about actions of other players (walk, stand, block,swing,shoot, so on.)

Each player is sending data to the server, in my tests this is around 2-3 Kilo Bytes per second (depends on actions of player more movement,swings is more data).
If you had 20 players that would mean the server is sending to each player: 3 * 20 = 60 Kilo Bytes p/s which is horrid. That is just impossible for the server to handle to each player.
The hard coded limit for upload bandwidth from server to player is 45 Kilo Bytes p/s so that would mean 20 players is already impossible?

Well no, what these developers did, like many others is a prioritizing system. People that are far away from you usually get you not the normal 60 updates per second about their actions.
No! the server is sending you maybe twice a second a update, basically it smartly limits the data your really getting.
For instance in a duel with another player your getting the full information about this player because he is so close to you.

Now to cut back to this bug, the server is also discarding receiving packets if he can't handle it. (both bandwidth and CPU limited).
For a player action like a bit of walking this is no big deal, in the next frame this will probably be corrected by another packet that IS handled.
Now sending a command to the server like a normal chat message is prioritized as a important part of the packet.
So it is usually handled (although i also sometimes get problems with normal chat.)
Your own messages are just not important enough for the server to handle if it is to busy handling other more important requests like blocks and swings and is just discarding your packet.

Not much we can do about this aswell, it is all hard coded in the server. Plus i rather have proper fighting without lag (server prioritizing that) then the stupid spam :grin:.

Maybe we should ask the devs to make a parameter for the receive network message to specify if it is a high priority packet or something?
 
Gaah, I can't believe I made that typo  :oops: Anyway it's now 0.5 instead of 0.05.

That illuminates most of the problem; however, I do notice problems with the faction chat even with small player numbers (4-5). That means that there is another factor or I'm just unlucky  :mad:. Anyway, this should bring the faction chat up to a more usable level. The idea was to eliminate some of the clutter from the global chat, so considering that faction-chat messages aren't sent to every player and people aren't repeating themselves in global chat, they're should be a net reduction in traffic both up and down.

Edit: The faction chat should no-longer need to be clicked on to use it!!! 1.130 ONLY!!!
 
Vincenzo said:
Yes but now the letter you use to open the chat is sometimes printed in the chat window  :eek:
:lol: I figured something stupid would go wrong, considering I didn't test it. Anyway, a small amount of fire-delay should fix that.

Edit: there we go. That should be good.
 
So does this still work?  I'm getting errors in module_scripts.py and I'm too new to scripting to figure this out on my own.  Any help or confirmation that this works would be a great help.

WARNING: Local variable never used: agent_no, at: get_player_color_faction

Seems like a simple fix but im still a nubian :wink:.  I tried simply removing agent_no but got same error only "player_no" instead. 

PART I - at end of module_scripts.py (before last bracket of course)
  #####################################
  #get_player_faction
  #input:  arg1=player id
  #output: reg0=player's color faction, returns -1 if no faction.
  #####################################
  ("get_player_color_faction",
    [
    (store_script_param_1, ":player_no"),
    (player_get_agent_id, ":agent_no", ":player_no"),        ## here -
      (assign, reg0, -1),
      (try_begin), #RED
      (assign, reg0, fac_red),
    (else_try), #WHITE
      #INSERT CONDITIONS HERE
      (assign, reg0, fac_white),
    (else_try), #BLUE
#INSERT CONDITIONS HERE
      (assign, reg0, fac_blue),
    (else_try), #GREEN
#INSERT CONDITIONS HERE
(assign, reg0, fac_green),
    (else_try), #GOLD
      #INSERT CONDITIONS HERE
      (assign, reg0, fac_gold),
    (try_end),
  ]),

\/      \/      \/ 

OK yes, you pointed me in the right direction Madoc.  It seems to be working now... thanks alot for posting this script!!  Respect and thanks to all modders/scripters! :grin:
 
Sorry for the late reply.

The color faction chat kit is modular--you can adapt it to whatever you want. In that script where it's giving errors, there are currently no conditions--what determines who receives/sends what color chat is up to you, just replace the "#INSERT CONDITIONS HERE" comments with the desired code. The agent_no was stored just to make your lif easier if you needed it when coding your conditions.
 
Back
Top Bottom