Jump to content
Mr H.

BIS_fnc_dynamic test character cap?

Recommended Posts

So, I'm making a credits script which spawns movie-like credits rolling on the screen. The script works fine but I'm using bis_fnc_dynamictext to create the text, and there seems to be a limit to the length of the text you can use. My initial idea was to rewrite a very similar function only changing the length cap. Trouble is I don't understand what's limiting the length of the text in the original function. Any clues? Here's the code to the fnc:

/*
	File: credits.sqf
	Author: Karel Moricky

	Description:
	Dynamic opening credits

	Parameter(s):
	_this select 0: Text
	_this select 1: (Optional) X coordinates
	_this select 2: (Optional) Y coordinates
	_this select 3: (Optional) Duration
	_this select 4: (Optional) Fadein time
	_this select 5: (Optional) Delta Y
	_this select 6: (Optional) Resource layer
*/
disableserialization;

_text = _this select 0;
_x = if (count _this > 1) then {_this select 1} else {-1};
_y = if (count _this > 2) then {_this select 2} else {-1};
_w = -1;
_h = -1;
_delay = if (count _this > 3) then {_this select 3} else {4};
_fade = if (count _this > 4) then {_this select 4} else {1};
_moveY = if (count _this > 5) then {_this select 5} else {0};
_layer = if (count _this > 6) then {_this select 6} else {[] call bis_fnc_rscLayer};
if (_delay < 0) then {_delay = 4};
if (_fade < 0) then {_fade = 1};

//--- Width and Height
if (typename _x == typename []) then {
	_array = _x;
	_x = _array select 0;
	_w = _array select 1;
};
if (typename _y == typename []) then {
	_array = _y;
	_y = _array select 0;
	_h = _array select 1;
};

_layer cutrsc ["rscDynamicText","plain"];

_display = uinamespace getvariable "BIS_dynamicText";
_control = _display displayctrl 9999;
_control ctrlsetfade 1;
_control ctrlcommit 0;
_pos = ctrlposition _control;
if (_x != -1) then {_pos set [0,_x]};
if (_y != -1) then {_pos set [1,_y]};
if (_w != -1) then {_pos set [2,_w]};
if (_h != -1) then {_pos set [3,_h]};
_control ctrlsetposition _pos;

if (typeName _text == typeName "") then
{
	_control ctrlsetstructuredtext parseText _text;
}
else
{
	_control ctrlsetstructuredtext _text;
};
_control ctrlcommit 0;

_control ctrlsetfade 0;
_control ctrlcommit _fade;
waituntil {ctrlcommitted _control};

if (_moveY != 0) then {
	_y = _pos select 1;
	_pos set [1,_y + _moveY];
	_control ctrlsetposition _pos;
	_control ctrlcommit _delay;
};

//if (_layer != 789) exitwith {};

_spawn = missionnamespace getvariable format ["bis_dynamicText_spawn_%1",_layer];
if (!isnil "_spawn") then  {terminate _spawn};
_spawn = [_control,_delay,_fade,_moveY,_layer] spawn {
	disableserialization;
	_control = _this select 0;
	_delay = _this select 1;
	_fade = _this select 2;
	_moveY = _this select 3;
	_layer = _this select 4;

	if (_moveY != 0) then {waituntil {ctrlcommitted _control}} else {sleep _delay};

	_control ctrlsetfade 1;
	_control ctrlcommit 1;
	waituntil {ctrlcommitted _control};

	_layer cuttext ["","plain"];
};
missionnamespace setvariable [format ["bis_dynamicText_spawn_%1",_layer],_spawn];
waituntil {scriptdone _spawn};

 

Share this post


Link to post
Share on other sites

So my test was finally succesful: The 6th parameter is really important when it comes to displaying more lines. If it is too low then the text just won't move any further. Here is my test code:

_text = "Line<br />";
for "_i" from 0 to 1000 do {
	_text = _text +format ["Line %1<br />",_i];
};
[
	_text,
	-1,
	0 * safezoneH + safezoneY,
	4,
	1,
	-100,
	789
] execVM "test.sqf";

test.sqf is just a little modification of the BIS function to display some parameters with systemchat, therefore not important.

 

When using -1 instead of -100 then the lines will go down to line 39 and then stop and fade out. Changing this param to -100 it displays all 1000 lines (really fast btw, bc of duration = 4). That's it.

 

~~~Own request~~~

 

I am now elaborating further on this to find the correct speed for the text to scroll through but I need to count the lines to find the correct deltaY param. The text should disappear from the screen completely. This is what I have in mind:

_text = "Line<br/>";
for "_i" from 0 to 100 do {
	_text = _text +format ["Line %1<br/>",_i];
};
// _text will later on be the input text
_tCount = count _text;
_duration = _tCount/20;
_lineHeight = 0.0607143;
//count the lines and find _deltaY
_deltaY = count /*lines, how?*/;
[
	_text,
	-1,
	0 * safezoneH + safezoneY,
	_duration,
	1,
	_deltaY,
	789
] spawn BIS_fnc_dynamicText;

 

  • Like 2

Share this post


Link to post
Share on other sites

I gather you haven't found a solution yet? I agree that it seems the size of the display layer plays a role in this, I've given up on this and done things differently but if you find a working solution let me know!

Share this post


Link to post
Share on other sites

Can you post the text and how you call the function here? Maybe that will clear things up. Otherwise I said that I found a solution for the cap which is the 6th parameter: deltaY. This tells the function how far the text should be scrolled down. The length of the text isn't limited by either the max cap of characters a control can hold (I let my script run to 20k or sth before aborting bc of lag) and neither the size of the control which is 10000 (on line is roughly 0.06) therefore plenty enough.

 

Here is the script I came up with:

/*
	Author: Terra
	Description:
	 Create a credit screen

	Params:
	 0: Credit text - STRING
*/
params ["_text"];
_lineHeight = 0.0607143;
_screenLines = 24;
_screenHeight = _screenLines *_lineHeight;
_br = ["<br/>","<br />"];

_manipulate = _text;
_manipulate = _manipulate splitString "<>";
_lineCount = {_x find "br/" != -1 OR _x find "br /" != -1} count _manipulate;

_startPos = (0 * safezoneH + safezoneY)+_screenHeight;
_duration = _lineCount/2;
_deltaY = (-_lineCount*_lineHeight) -_screenHeight;
[
	_text,
	-1,
	_startPos,
	_duration,
	1,
	_deltaY,
	402
] spawn BIS_fnc_dynamicText;

This one is unoptimised in regards to other screen sizes. I only took my own screen into account (1920:1080) and I have no idea how it will behave with other resolutions or settings.

Share this post


Link to post
Share on other sites

the text is generated by a script, it has a variable size depending on how many players participate in the mission. Disclaimer: not all of the code is mine, I've taken skippy's roster script as a base for this. Here's a video of the script in action: https://www.twitch.tv/videos/178329712

_duree = _this select 0;

_includeAI 	= 1;//0->only players, 1->both AI and players, 2->playable units only (includes player and some AI)
_rank 		= true;//true->display unit's rank		false->hide unit's rank
_role 		= true;//true->display unit's role		false->hide unit's role
_strRank 		= "";//will contain unit's rank
_strRole 		= "";//will contain unit's role
_strGrp 		= "";//will contain unit's group name
_strColorGrp 	= "";//will contain unit's group color
_strFinal 		= "";//will contain final string to be displayed
_oldGrp 		= grpNull;//group of last checked unit
_newGrp 		= grpNull;//group of current unit
_unitsArr 		= [];//will contain all units that have to be processed


switch(_includeAI) do {
	case 0:{//only players
		{
			if(isPlayer _x) then {
				_unitsArr = _unitsArr + [_x];
			};
		}forEach allUnits;
	};
	case 1:{//both AI and players
		_unitsArr = allUnits;
	};
	case 2:{//only playable units
		if(isMultiplayer) then {
			_unitsArr = playableUnits;
		} else {
			_unitsArr = switchableUnits;
		};
	};
	default{
		_unitsArr = allUnits;
	};
};

{//forEach
	if(side _x == side player) then {
		_newGrp = group _x;
		_strGrp = "";
		
		if(_rank) then {
			switch(rankID _x) do {
				case 0:{
					_strRank = "Simple soldat ";
				};
				case 1:{
					_strRank = "Caporal ";
				};
				case 2:{
					_strRank = "Sergent ";
				};
				case 3:{
					_strRank = "Lieutenant ";
				};
				case 4:{
					_strRank = "Capitaine ";
				};
				case 5:{
					_strRank = "Major ";
				};
				case 6:{
					_strRank = "Colonel ";
				};
				default{
					_strRank = "Simple soldat ";
				};
			};
		};

		if(_role) then {
			_strRole = " - " + getText(configFile >> "CfgVehicles" >> typeOf(_x) >> "displayName");
		};
		
		if((_x getVariable "displayName") != "") then {
			_strRole = " - " +(_x getVariable "displayName");
		};

		if(_newGrp != _oldGrp) then {
			_strGrp = "£";
			
			if((_this find ("Color"+str(side _x)))>-1) then {
				if(count _this > ((_this find ("Color"+str(side _x))) + 1)) then {
					_strColorGrp = _this select ((_this find ("Color"+str(side _x))) + 1);
				} else {
					hint "Skippy-Roster - Missing Param";
					_strColorGrp = "";
				};
			} else {
				switch (side _x) do {
					case EAST:{
						_strColorGrp = "'#990000'";
					};
					case WEST:{
						_strColorGrp = "'#0066CC'";
					};
					case RESISTANCE:{
						_strColorGrp = "'#339900'";
					};
					case CIVILIAN:{
						_strColorGrp = "'#990099'";
					};
				};
			};
			
			if(((group _x) getVariable "color") != "") then {
				_strColorGrp = (group _x) getVariable "color";
			};
		};


		_strFinal =   _strFinal +_strGrp + _strRank + name _x + _strRole + "<br/>" ;

		_oldGrp = group _x;
	};
}forEach _unitsArr;

_title = _this select 1;
_makername = _this select 2;
_thanks = _this select 3;
_extratext =  _this select 4; //if(_extratext == objNull) then { _extratext = "";};
_year = _this select 5;

_strprecredit ="<t font = 'PuristaMedium'>" + "C'était: <br/>" + _title +"<br/>" + "Une mission proposée par:<br/>" + _makername +"<br/>" + "Entièrement réalisée pour Arma III <br/>" + "Une production Team TGV<br/>" + "Avec les mods: <br/> CBA 3 <br/> Ace 3 <br/> Acre 2 <br/> RHS Escalation <br/> Project Opfor <br/> Cup Terrains <br/> Cup Terrains core<br/><br/> Remerciements:<br/>" + "<br/>"  + _thanks +"<br/>" + "<br/>" + _extratext + "<br/>" + "Avec dans leurs rôles respectifs:<br/>" + "</t>";

_strpostcredit ="<t font = 'PuristaMedium'>" + "<br/><br/><br/>" + "© " + _makername + "<br/>" + _year + "</t>" + "<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>";
//_strFinal = _strprecredit + _strFinal + _strpostcredit;

test = _strfinal splitstring "£";
//copytoclipboard _test;
part1 = [_strprecredit,-1,-1,_duree ,-1, -1] spawn BIS_fnc_dynamicText;
waituntil {scriptdone part1};
sleep 1;
part2 = [] spawn {{["<t font = 'PuristaMedium'><t size = '1'>" + _x + "</t>",-1, -1,1 ,2, 0] spawn BIS_fnc_dynamicText; sleep 5;} forEach test;};
waituntil {scriptdone part2};
part3 = [_strpostcredit,-1,-1,_duree ,-1, -1] spawn BIS_fnc_dynamicText;
waituntil {scriptdone part3};

//[_strFinal,-1,-1,_duree ,-1] spawn BIS_fnc_dynamicText; // trouver le cap et réécrire la fonction
/*
    Number: X coordinates (optional)

    Number: Y coordinates (optional)

    Number: Duration (Optional)

    Number: FadeIn time (Optional)

    Number: Delta Y, Text will move up or down depending on value (Optional)

    Number: Resource layer (Optional)
*/

 

Share this post


Link to post
Share on other sites

as you will notice I split the generated text into several parts as a solution, there are parts of the original roster script I have deactivated but I haven't bothered to clean it so sorry if it's a bit messy.

Share this post


Link to post
Share on other sites

What is your first param when executing this script?

Share this post


Link to post
Share on other sites

It defines the duration of pre/post credits.

Share this post


Link to post
Share on other sites

Sorry wrong way of thinking by me. What I wanted to know is what your deltaY parameter is.

[_strFinal,-1,-1,_duree ,-1] spawn BIS_fnc_dynamicText;

With these params the text won't scroll down entirely. Change the last one to a higher number than -1 so the entire text can scroll through. The longer the text the higher (lower) the number has to be. Positive numbers will mean that the text will scroll down while a negative number scrolls up. Default value is 0 with no scrolling at all. -1 only scrolls (as I stated) to line 39 before fading out which is your "length limitation" problem.

[_strFinal,-1,-1,_duree ,-100] spawn BIS_fnc_dynamicText;

This will scroll through your entire text but the script will run offscreen too. If you want to find the correct value then you'll have to test a bit.

Share this post


Link to post
Share on other sites

I have tried that by using the controlTextHeight command (I think it was that one)  to determine the text height and set it as the correct height, that is becaus I wan't this script to be reusable and depending on missions and Player attendency, there is no way to know how long the text is going to be. It didn't work for me but maybe I did something wrong.

Share this post


Link to post
Share on other sites

Okay here is a script to create a credit screen. The cutRsc is taken from the BI function.

/*
	Author: Terra

	Description:
	Credit screen

	Parameter(s):
	0: Structured text (STRING)
	1 (optional): Speed multiplier, determines how fast the text will scroll through (NUMBER)
		Default: 1

	Example:
	_text = "";
	for "_i" from 1 to 10 do {
		_text = _text +format ["Line %1<br/>",_i];
	};
	[_text] call TER_fnc_credits;
*/
disableserialization;
params [
	"_text",
	["_speedMultiplier",1]
];

// Create cutRsc
"TER_creditsLayer" cutrsc ["rscDynamicText","BLACK FADED",5];
_display = uinamespace getvariable "BIS_dynamicText";
_control = _display displayctrl 9999;
_control ctrlSetStructuredText parseText "Line 0";
_oneLine = ctrlTextHeight _control;
// Set text and position
_text = parseText format ["<t align='center'>%1</t>",_text];
_control ctrlSetStructuredText _text;
_tHeight = ctrlTextHeight _control;
_control ctrlSetPosition [
	0 * safezoneW + safezoneX,
	(1 * safezoneH + safezoneY)+(3*_oneLine),
	1 * safezoneW,
	_tHeight
];
_control ctrlCommit 0;
// Move control
_control ctrlSetPosition [
	0 * safezoneW + safezoneX,
	-_tHeight + (0 * safezoneH + safezoneY)-(3*_oneLine),
	1 * safezoneW,
	_tHeight
];
_addSleep = safeZoneH/_oneLine;
_commitTime = ((_tHeight/_oneLine)+_addSleep)/_speedMultiplier;
_control ctrlCommit _commitTime;
waitUntil {ctrlCommitted _control};
"TER_creditsLayer" cuttext ["","plain"];

 

  • 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

×