Jump to content
lxets

Creating a basic kill feed

Recommended Posts

Hi, I've been trying to create a kill feed script aiming for it to look/behave something like it does on games like BF4 for example - http://i.gyazo.com/e743a53ce660b50a5e8544b3c699fd21.mp4
 

Ive seen it done on a couple of arma missions, notably KOTH, and also one of KK's videos.
http://i.gyazo.com/5ba4024f0b19ff9ff72ebdbdfaddd2c6.mp4

https://www.youtube.com/watch?v=4Dnz2qFz7QQ

 

I have a pretty decent understanding of dialog, I know how to display all the information I need, however I don't really understand how to make the most recent kills show up and push the previous kill downwards like it does on the examples above when someone gets multiple kills. Hopefully that makes sense, I would really appreciate any advice/examples of how I should go about doing this. Thanks.

  • Like 1

Share this post


Link to post
Share on other sites

Well at the end of the day it's all just maths.

Here's how I'd do it:

You have 5 text boxes on the screen. For simpleness let's just say the top of the killfeed will be box 1 and the bottom will be box 5.

When someone dies you'd do the following:

Check text value for box 1 to 5. Fill in text on lowest empty position. If all positions are filled then cascade the text downwards and fill in the top position with the new text.

As for animating it you could do a sleep or something? Every X milliseconds move it a little bit further down... But I haven't done any GUI animating myself so I dunno.

Share this post


Link to post
Share on other sites

This any use ?

tlq_killTicker = { 

	_this addMPEventHandler ['MPKilled',{

		_unit = _this select 0;
		_killer = _this select 1;

		_newKill = [_unit,_killer];

		if (count tlq_killArray > 100) then {tlq_killArray = []};

		tlq_killArray set [count tlq_killArray,_newKill call tlq_parseKill];

		[] spawn tlq_killList;
		if (player == _killer) then {_newKill spawn tlq_killPopUp};


	}
	];
	
};



tlq_parseKill = {
	
	_line = "";
	_killerName = "";
	_victimName = "";
	_killerString = "";
	_victimString = "";
	_killerColor = "#99D5FF";
	_victimColor = "#99D5FF";


	_victim = _this select 0;
	_killer = _this select 1;

	if (!(isplayer _killer)) then {
		_killerName = getText (configFile >> "CfgVehicles" >> format["%1",typeOf _killer] >> "Displayname");
		if(vehicle _killer != _killer) then {_killerName = getText (configFile >> "CfgVehicles" >> format["%1 crew",typeof vehicle _killer] >> "Displayname")};
		}else{_killerName = name _killer};

	if (!(isplayer _victim)) then {
		_victimName = getText (configFile >> "CfgVehicles" >> format["%1",typeOf _victim] >> "Displayname");
		if(vehicle _victim != _victim) then {_victimName = getText (configFile >> "CfgVehicles" >> format["%1 crew",typeof vehicle _victim] >> "Displayname")};
		}else{_victimName = name _victim};

	if ((_killer==player) or (_killer == vehicle player)) then
		{
		_killerColor = "#ffff00"; //yellow
		}
		else
		{
		_killerColor = side group _killer call BIS_fnc_sideColor;

			_r = _killerColor select 0;
			_g = _killerColor select 1;
			_b = _killerColor select 2;

		_killerColor = [_r+0.1,_g+0.1,_b+0.1];

		_killerColor = _killerColor call BIS_fnc_colorRGBtoHTML;

		};

	if (_victim==player) then
		{
		_victimColor = "#ffff00"; //yellow
		}
		else
		{
		_victimColor = side group _victim call BIS_fnc_sideColor;

			_r = _victimColor select 0;
			_g = _victimColor select 1;
			_b = _victimColor select 2;

		_victimColor = [_r+0.1,_g+0.1,_b+0.1];
		
		_victimColor = _victimColor call BIS_fnc_colorRGBtoHTML;
		
		};

	_killerString = format["<t color='%1'>%2</t>",_killerColor ,_killerName];
	_victimString = format["<t color='%1'>%2</t>",_victimColor,_victimName];

	//the line which shows the final formatted kill
	_line = switch(true) do {
		case(_killer == _victim): {format ["%1 killed themselves",_killerString]};
		case(isNull _killer): {format ["Bad luck for %1",_victimString]};
		default {format ["%1 killed %2",_killerString,_victimString]};
	};

	_line;
	
};


tlq_killPopUp = {

	_victim = _this select 0;
	_killer = _this select 1;


	_victimName = "";	
	_victimString = "";
	_victimColor = "#99D5FF";


	if (!(isplayer _victim)) then {
		_victimName = getText (configFile >> "CfgVehicles" >> format["%1",typeOf _victim] >> "Displayname");
	if(vehicle _victim != _victim) then {_victimName = getText (configFile >> "CfgVehicles" >> format["%1 crew",typeof vehicle _victim] >> "Displayname")};
		}else{_victimName = name _victim};

	_victimColor = (side group _victim call BIS_fnc_sideColor) call BIS_fnc_colorRGBtoHTML;

	_victimString = format["<t color='%1'>%2</t>",_victimColor,_victimName];

	_line = if ((_killer == player) and (_victim == player)) then {
		"<t size='0.5'>You killed yourself</t>";
	} else {
		format ["<t size='0.5'>You killed %1</t>",_victimString];
	};	

 	[_line,0,0.8,2,0,0,7017] spawn bis_fnc_dynamicText;

};



tlq_killList = {
	

	//flush kills and  show most recent
	if (time - tlq_killTime > 37) then {
		tlq_displayedKills = [];
	};


	tlq_displayedKills set [count tlq_displayedKills, tlq_killArray select (count tlq_killArray - 1)];



	_tickerText = "";


	_c = 0;
	for "_i" from (count tlq_displayedKills) to 0 step -1 do{

		_c = _c + 1;
	
		_tickerText = format ["%1<br />%2",tlq_displayedKills select _i,_tickerText];

		if (_c > 8) exitWith{};

	};

	hintsilent parsetext _tickerText;

	//["<t size='0.4' align='right'>" + _tickerText + "</t>",safeZoneX,safeZoneY,10,0,0,7016] call bis_fnc_dynamicText;


	tlq_killTime = time;

};



//declare global variables

tlq_killArray = [];
tlq_displayedKills = [];
tlq_killTime = 0;

//start kill registration for player
if (!isNull player) then {
	player spawn tlq_killTicker;
};

if (isServer) then {
	//ai
	{
		if (!(isPlayer _x)) then {
			_x spawn tlq_killTicker};
	} forEach allUnits;
};
  • Like 1

Share this post


Link to post
Share on other sites

Yea I found this recently aswell, the message in the middle of the screen from the tlq_killPopUp section is pretty much what im aiming for, but on multiple lines if you get more than 1 kill as this removes the previous message rather than creating a new one under it. 

Share this post


Link to post
Share on other sites

This is a very complicated dialog, but you've gotten me interested. I've wanted to make a kill feed of some kind for a while but I haven't gotten around to it. The idea is very simple, rather than trying to work with set controls exported from the GUI Editor, I suggest trying out dynamically created controls with the ctrlCreate command. I'm going to keep looking into it and try to make something a little better, but this code should get you started on the right path (paste in init.sqf):

sleep 1;
 
disableSerialization;
 
_display = findDisplay 46;
_ctrl1 = _display ctrlCreate ["RscText", 1];
_ctrl2 = _display ctrlCreate ["RscText", 2];
 
_ctrl1 ctrlSetPosition [0.5, 0.7, 0.2, 0.1];
_ctrl1 ctrlSetText "Test1";
 
_ctrl1 ctrlCommit 0;
 
sleep 0.5;
 
_ctrl1 ctrlSetPosition [0.5, 0.725, 0.2, 0.1];
_ctrl2 ctrlSetText "Test2";
 
_ctrl1 ctrlCommit 0.25;

Share this post


Link to post
Share on other sites

So I guess it wasn't as complicated as I thought it might be, because I'm done.

 

This simple system works by keeping a global list of controls, then through a "Killed" event handler it will move existing controls down and create a new control. This simple system also fades out the created controls and deletes them (confirmed by watching the global list shrink).

 

To start off, you'll need 2 variables: One to keep track of all created controls, and another to keep assigning unused control numbers (controls cannot be created with an idc of an existing control, all idc's must be unique). Place something like this in init.sqf:

activeControls = [];
control = 2000;
Now you need to create your event handler. To keep things easy to edit, I recommend that the only thing that your event handler contains is a script call using execVM (to make yourself really look like you know what you're doing, compile your script using the Functions Library and just do a function call instead of a script). You'll probably end up with something that looks like this:
this addEventHandler ["Killed",
{
	[control, _this select 0] execVM "kill_feed.sqf";
}];
Now what? I guess you need to actually write the script that your event handler calls. You'll need to access the global list of controls and move every active control down just a little bit. You'll then need to create another control for the most recent event, set it's text and color, and fade it out over the course of a few seconds. Oh yeah and you'll also need to spawn another thread that will handle deletion of the control you just created. After you created the control, don't forget to add it to the global list (and also increment your idc number). When it's all said and done I think you'll have something that looks like this:
disableSerialization;

{
	_ctrl = (findDisplay 46) displayCtrl _x;
	
	_pos = ctrlPosition _ctrl;
	_pos set [1, (_pos select 1) + 0.025];
	
	_ctrl ctrlSetPosition _pos;
	
	_ctrl ctrlCommit 0.25;
}forEach activeControls;

UISleep 0.25;

_ctrl = (findDisplay 46) ctrlCreate ["RscText", _this select 0];

_ctrl ctrlSetPosition [0.45, 0.7, 0.4, 0.1];
_ctrl ctrlSetTextColor [1, 0, 0, 1];

_ctrl ctrlSetText ("You killed a " + (getText(configFile >> "CfgVehicles" >> typeOf (_this select 1) >> "displayName")));

_ctrl ctrlCommit 0;

_ctrl ctrlSetFade 1;
_ctrl ctrlCommit 10;

0 = (_this select 0) spawn
{
	disableSerialization;
	_ctrl = (findDisplay 46) displayCtrl _this;
	
	UISleep 10;
	
	ctrlDelete _ctrl;
	activeControls = activeControls - [_this];	
};

activeControls = [_this select 0] + activeControls;
control = control + 1;

Hope that helps

  • Like 1

Share this post


Link to post
Share on other sites

Thanks very much for that, really helped. Have it working and i'm currently using it to show unit killed,reward for the unit + distance bonus.  :)

a272219ba9395e928be5c5eef1085e4c.jpg

Share this post


Link to post
Share on other sites

I'm glad I could help, honestly I thought that was going to be a lot harder to do that it was.

 

This idea could be expanded upon to create another feed in the top corner as a kind of global kill feed that all players will see.

 

Also, I'm pretty sure chat works exactly the same way as this system, except that the older messages move up instead of down.

Share this post


Link to post
Share on other sites

That script could be optimized a bit. binary addition with arrays is silly when you have commands like pushBack and set

This is very true, it has been several months since I've written any code that is worth posting

Share this post


Link to post
Share on other sites

I like this one posted by kaysio Which line dictates how long it stays on screen for?

Share this post


Link to post
Share on other sites

where can i start if i want to mod simple ui like hitmarkers and killfeeds

i am new to this if anyone can help me where to start learning modding like these things 

 

Share this post


Link to post
Share on other sites

I managed to create simple kill feed, but need some queue.

 

 

  • Like 1

Share this post


Link to post
Share on other sites

I came up with these, from what I scrapped on this thread;

 

 

thanks for the thread, I will be updating this with a github link soon, this game needs a perfect killfeed mod for both MP and SP gameplays.

Share this post


Link to post
Share on other sites

Hello, please can someone show me where to put dreadedentity's EH script for it to work with DAC (Dynamic AI Creator) created groups? Right now it only works on players and zeus placed units using a sleep 10; script timer.

On 8/7/2015 at 4:49 PM, dreadedentity said:

this addEventHandler ["Killed", { [control, _this select 0] execVM "kill_feed.sqf"; }];

 

  • Like 1

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×