Jump to content
Sign in to follow this  
blasturbator

Description.ext CTD

Recommended Posts

I'm getting a CTD when i try to save my mission with the following code in the description.ext:

class Extended_Init_EventHandlers {
class '''Man''' {
	if {!isPlayer} then {
		MyCode_init="_this call compile preprocessFileLineNumbers 'scripts\briefcaseintel.sqf'";
	};
};
};

The error says " ' encountered instead of { " but i can't see any such error, am i blind or?

Share this post


Link to post
Share on other sites

get rid of useage of extended EH, replace it with cfgfunctions and use preinit=1 to automatically run your code

Share this post


Link to post
Share on other sites
Maybe replace '''Man''' with "Man"?

Thanks for the try but that didnt work sadly :(

get rid of useage of extended EH, replace it with cfgfunctions and use preinit=1 to automatically run your code

I'm afraid i don't understand, you mean like this?

class cfgFunctions {
class '''Man''' {
    preInit=1;
	if {!isPlayer} then {
		MyCode_init="_this call compile preprocessFileLineNumbers 'scripts\briefcaseintel.sqf'";
	};
};
};

Edited by Blasturbator

Share this post


Link to post
Share on other sites

Not used this file much so not sure about the syntax, two things look possibly wrong though.

1. If {isplayer} should be if (isplayer) ?

2. Try "" for a double quote esccape sequence within a string?

Sent from my Spectrum 48K using Tapatalk

Share this post


Link to post
Share on other sites
I'm afraid i don't understand, you mean like this?

The wiki article:

https://community.bistudio.com/wiki/Functions_Library_%28Arma_3%29

class CfgFunctions
{
class someTag
{
	class someCategory
	{
		class my_fnc_briefcaseintel {
			file = "scripts\briefcaseintel.sqf";
			preInit = 1; // or postInit
		};
	};
};
};

File will be automatically called for all players.

Share this post


Link to post
Share on other sites

any function defined in cfgfunctions with the tag preinit=1 will automatically run before the mission.sqm is launched.

This will allow you to define any functions, global variables required for any code after. This works for both addons and missions.

XEH init eventhandlers were used to start code in addons for A2 to get around having to place a gamelogic in the mission.

The latest system cfgfunctions makes all this redundant

Share this post


Link to post
Share on other sites

Maybe i should explain what it is actually meant to do rather than just say it causes ctd's. It's supposed to add the script "briefcaseintel.sqf" to the init of every man that isn't a player.

The dev team of ALiVE referred it to me as the way to add inits to units spawned by ALiVE so i can assume that if i differ from that it might not work at all. So what i really need are fixes for that code in particular, not different ways to do it which may not even work.

edit: on re-reading this post sounds rather chastising, i didnt mean it to, i just wanted to let you know i wanted to fix it not change it :)

Edited by Blasturbator

Share this post


Link to post
Share on other sites
I'm getting a CTD when i try to save my mission with the following code in the description.ext:

class Extended_Init_EventHandlers {
class '''Man''' {
	if {!isPlayer} then {
		MyCode_init="_this call compile preprocessFileLineNumbers 'scripts\briefcaseintel.sqf'";
	};
};
};

The error says " ' encountered instead of { " but i can't see any such error, am i blind or?

even without knowing how extended event handlers accepts definitions, I know for a fact that you cannot declare a class with a stringed name.

You also cannot declare conditional statements inside a class definition (BIS classes don't support any sort of templating)

it should be:

class Extended_Init_EventHandlers {
class Man {
	MyCode_init="if (!isPlayer) then {_this call compile preprocessFileLineNumbers 'scripts\briefcaseintel.sqf';}";
};
};

Share this post


Link to post
Share on other sites

Well the code works, game stopped crashing. But it still isn't having the desired effect :(

Is there a way to loop the command? because of the way ALiVE handles units it despawns and respawns them a lot which is probably causing the issue.

Share this post


Link to post
Share on other sites
Maybe i should explain what it is actually meant to do rather than just say it causes ctd's. It's supposed to add the script "briefcaseintel.sqf" to the init of every man that isn't a player.

Sorry, misread. :(

Is there a way to loop the command? because of the way ALiVE handles units it despawns and respawns them a lot which is probably causing the issue.

What does briefcaseintel.sqf do? Have you considered running it through init.sqf or something, instead of Description.ext / a function?

if isServer then
{
[] [url="https://community.bistudio.com/wiki/spawn"]spawn[/url]
{
	while {TRUE} do
	{
		{ // forEach block start
			if (!isPlayer _x && !(_x [url="https://community.bistudio.com/wiki/getVariable"]getVariable[/url] ["intelVar", FALSE])) then
			{
				_x execVM "scripts\briefcaseintel.sqf";
				_x [url="https://community.bistudio.com/wiki/setVariable"]setVariable[/url] ["intelVar", TRUE];
			};
		} [url="https://community.bistudio.com/wiki/forEach"]forEach[/url] [url="https://community.bistudio.com/wiki/allUnits"]allUnits[/url];

		sleep 30; // loops through all the units every 30 seconds
	};
};
};

so many brackets

Edited by Magirot
Fixed a silly mistake! _this -> _x

Share this post


Link to post
Share on other sites

I tried something very similar to that before and it didnt seem to work, this is the one i used

[] spawn {
   while {true} do {
       {
           {
               if (!isPlayer) then {
                   _x call compile preprocessFileLineNumbers 'scripts\briefcaseintel.sqf';
                   _x setVariable ["UnitHasIntel", true, false];
               };
               sleep 0.1;
           }forEach allUnits _x;
           sleep 0.1;
       }forEach allUnits
   }; 
};  

Briefcaseintel spawns a briefcase and a trigger where the unit dies, i know it works because i tested it by putting it directly in a unit. Sadly i can't do that to units spawned by alive so i have to go about this the hard way.

Edited by Blasturbator

Share this post


Link to post
Share on other sites
isPlayer needs a parameter to check, I mean it has to be "isPlayer _x" or similar. Same thing is in your earlier snippet from Description.ext, actually. Anyway, the other forEach has no purpose there, and "allUnits _x" probably causes errors.

Share this post


Link to post
Share on other sites

Well i just tried yours and mine with the fixes you recommended and neither worked, not even for a unit not profiled by ALiVE.

Share this post


Link to post
Share on other sites

Weird, my code worked when I tried it. Are you sure it's not due to briefcaseintel.sqf trying to call the parameter from an array (_this select 0), or something like that?

Share this post


Link to post
Share on other sites

This is briefcaseintel.sqf:

if (isDedicated) exitWith {};

private["_obj", "_trigE"];
_obj = _this select 0;
_name = "intel";

waitUntil {!Alive _obj};

_intelCase = createVehicle ["Land_Suitcase_F", _obj modelToWorld [0,0,0]   ,[] , 0, "can_collide"];  
_intelCase setVehicleVarName _name;
call compile format["%1 =  _intelCase", _name];

	//	[[_intelCase,"<t color='#FF0000'>Gather Intel</t>"],"addactionMP", true, true] spawn BIS_fnc_MP;


       _trigE = createTrigger ["EmptyDetector",getPos _obj];
       _trigE setTriggerActivation ["WEST", "PRESENT", false];
       _trigE setTriggerArea [2, 2, 0, false];
       _trigE setTriggerStatements ["player in thislist","nul = [intel,thistrigger] execVM 'scripts\intelPickup.sqf' ", ""];  

there is a _this select 0 in there, I don't know why that would interfere though, it works fine if i call it in the init of a unit by hand. The script breaks if i don't use it too.

edit: So i took a moment to learn what select 0,1,2 etc actually does. I think i see the problem now xD

edit: yeah, no, i couldn't figure it out. I tried executing briefcaseintel with all the following:

 [_x] execVM "scripts\briefcaseintel.sqf";

 nul = [_x] execVM "scripts\briefcaseintel.sqf";

 [this] execVM "scripts\briefcaseintel.sqf";

 nul = [this] execVM "scripts\briefcaseintel.sqf";

 _x = [this] execVM "scripts\briefcaseintel.sqf";

My newfound understanding of selecting from arrays tells me that at least one of those MUST have executed the script on '_x' or 'this', yet no dice.

Edited by Blasturbator

Share this post


Link to post
Share on other sites
edit: So i took a moment to learn what select 0,1,2 etc actually does. I think i see the problem now xD

Yeah, either switch _this select 0 to _this in briefcaseintel.sqf, or _x to [_x] in the loop, and it should work. :)

Why do you terminate the script if the caller is a dedicated server, though? Currently it would require every player to run the allUnits loop. Was there a problem with the addAction?

Edit: Sorry, had the unrefreshed window open.

Did you have ececVM instead of execVM in your tests, like in those snippets?

Edited by Magirot

Share this post


Link to post
Share on other sites

ah lol no i didn't, that was just a typo when i copy pasted what i wrote in the reply :P

But yeah the script doesn't work without the '_this select 0' and using [_x] didn't work either ;-;

edit: didnt see the isDedicated, it was meant to be (isServer), that apparently was not the issue though.

Edited by Blasturbator

Share this post


Link to post
Share on other sites

You should try debugging it by temporarily adding hint "briefcaseintel.sqf executed"; at the very beginning, to make sure it's not hung on something else.

I can't tell why it doesn't work, but as said, the solution of executing it on all clients has some problems:

  1. Passing through allUnits is a somewhat heavy operation which shouldn't be done where it's not needed
  2. createVehicle is a global command, so it'll create a briefcase for every player running the script (10 players = 10 briefcases)
  3. Same thing with createTrigger, though the result isn't as bad (and you actually do have to execute the statements, area etc for every player), it eats a bit more performance.

I suggest the following chances:

  1. Put the loop under if isServer
  2. Instead of executing a script for every unit, add a onKilled event handler (as far as I know, it's lighter for the server than a waitUntil, which is basically a loop)
  3. Use it to add the addAction you were trying earlier

init.sqf or similar:

if isServer then
{
[] spawn
{
	while {TRUE} do
	{
		{ // forEach block start
			if (!isPlayer _x && !(_x getVariable ["unitHasIntel", FALSE])) then
			{
				_x addEventHandler ["Killed", {[_this select 0] execVM "scripts\briefcaseintel.sqf"}];
				_x setVariable ["unitHasIntel", TRUE];
			};
		} forEach allUnits;

		sleep 30; // loops through all the units every 30 seconds
	};
};
};

briefcaseintel.sqf:

hint "briefcaseintel.sqf executed"; // debug

private ["_obj","_intelCase"];
_obj = _this select 0;

_intelCase = createVehicle ["Land_Suitcase_F", _obj modelToWorld [0,0,0], [], 0, "can_collide"];  

// the last TRUE (isPersistent) might become a drag on the server if this is executed on many units,
// you might want to consider removing it even if JIP players cannot gather intelligence
// for units killed before them connecting to the server
[[_intelCase],"addactionMP", TRUE, TRUE] spawn BIS_fnc_MP;

addactionMP (still has to be defined to all players in init.sqf for example) could be something like this:

addactionMP = 
{
private "_briefcase";	
_briefcase = _this select 0;

_briefcase addAction [
	"<t color='#FF0000'>Gather Intel</t>", // action text
	{
		// what you want to execute, presumably at least
		_target = _this select 0;			
		deleteVehicle _target;
	},
	nil,  // no additional arguments passed
	10,   // priority
	TRUE, // show action in the middle of the screen when its available
	TRUE, // hide the action menu when the action is used
	"",   // shortcut key (none)

	// action executor cannot be in a vehicle and must be within 2m
	"vehicle _this == _this &&   _target distance _this < 2"
];
};

Probably full of wrong assumptions, please fix if necessary.

Edited by Magirot
fix for the addAction

Share this post


Link to post
Share on other sites

Well, i added isServer already once you pointed out it said isDedicated, that was an error due to me overlooking the first line. The eventhandler is probably a better idea but getting it working comes first i think, hey maybe the EH will fix whatever the problem is :P

addactionMP is defined elsewhere and is in fact from a previous attempt which involved an addaction instead of a trigger, i left it commented out but never removed it, that's gone now though.

So really i should just add the hint at various steps, could do 1/3, 2/3, 3/3 to find the problem i guess. And i'll try the eventhandler instead of the waituntil.

Edited by Blasturbator

Share this post


Link to post
Share on other sites
Well, i added isServer already once you pointed out it said isDedicated, that was an error due to me overlooking the first line.

If you just change the isDedicated to isServer it becomes even worse, because it's followed by

if (isServer) exitWith {};

So what it reads as is that the following script isn't executed if the caller is a dedicated/server. You probably wanted a "!"

if (!isServer) exitWith {}; // stuff after this only runs on the server

But: you should wrap the whole loop around isServer, because otherwise it'll will cycle pointlessly through allUnits on the player clients, just to execute scripts that deny the players running them on their first line.

Also, using a trigger will still involve using BIS_fnc_MP, because while createTrigger can and should only be executed on the server, the following commands (setTriggerActivation, setTriggerArea, setTriggerStatements) have to be executed on the player clients. So you'd have to define a function for that purpose in either case.

Share this post


Link to post
Share on other sites

Sorry i should have been more accurate with what i changed, i did indeed put if "isServer then {" instead of "if (isServer) exitWith {};" and i removed the line completely from briefcaseintel.sqf

I have only really used BIS_fnc_MP when creating addActions so i don't know how i'd implement that for a trigger :s But i'll sort that out after i get it working in singleplayer i guess.

this is the loop currently:

if isServer then {
[] spawn
{
	while {TRUE} do
	{
	hint format ["1/3"];
		{
			if (!isPlayer _x && (_x getVariable ["intelVar", FALSE])) then
			{
			hint format ["2/3"];

				_x addEventHandler ["Killed", {[_this select 0] execVM "scripts\briefcaseintel.sqf"}];
				_x setVariable ["intelVar", TRUE];
			};
		} forEach allUnits;

		sleep 10; // loops through all the units every 30 seconds
	};
};
};

and this is briefcaseintel.sqf currently:

private["_obj", "_trig"];
_obj = _this select 0;
_name = "intel";

hint format ["3/3];

_intelCase = createVehicle ["Land_Suitcase_F", _obj modelToWorld [0,0,0]   ,[] , 0, "can_collide"];  
_intelCase setVehicleVarName _name;
call compile format["%1 =  _intelCase", _name];

       _trig = createTrigger ["CaseTrigger",getPos _obj];
       _trig setTriggerActivation ["WEST", "PRESENT", false];
       _trig setTriggerArea [2, 2, 0, false];
       _trig setTriggerStatements ["player in thislist","nul = [intel,thistrigger] execVM 'scripts\intelPickup.sqf' ", ""];

I've noticed the hints dont reach 2/3 so it doesnt seem to make it past the if then in the loop

Share this post


Link to post
Share on other sites
Sorry i should have been more accurate with what i changed, i did indeed put if "isServer then {" instead of "if (isServer) exitWith {};" and i removed the line completely from briefcaseintel.sqf

I have only really used BIS_fnc_MP when creating addActions so i don't know how i'd implement that for a trigger :s But i'll sort that out after i get it working in singleplayer i guess.

Like this, for example:

definetriggerMP =
{
       _this setTriggerActivation ["WEST", "PRESENT", false];
       _this setTriggerArea [2, 2, 0, false];
       _this setTriggerStatements ["player in thislist","nul = [intel,thistrigger] execVM 'scripts\intelPickup.sqf' ", ""];
};

in briefcaseintel.sqf:

_trigE = createTrigger ["EmptyDetector", getPos _obj];
[_trigE, "definetriggerMP", true, true] spawn BIS_fnc_MP;

I've noticed the hints dont reach 2/3 so it doesnt seem to make it past the if then in the loop

That's because (_x getVariable ["intelVar", FALSE]) is missing ! before it - the purpose of the last FALSE is to define a default value if none is set. So it currently first checks if the variable exists -> it doesn't, so it sets it to FALSE -> checks if the variable is TRUE -> nope, next.

Share this post


Link to post
Share on other sites

That's because (_x getVariable ["intelVar", FALSE]) is missing ! before it - the purpose of the last FALSE is to define a default value if none is set. So it currently first checks if the variable exists -> it doesn't, so it sets it to FALSE -> checks if the variable is TRUE -> nope, next.

Derp >.< i need to stop typing things and start copy/pasting them.

Okay now it's stopping at 2/3. 3/3 should be showing when i kill something but it doesn't, so i guess that means the EH isn't being added to the unit.

Edited by Blasturbator

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
Sign in to follow this  

×