Jump to content
Sign in to follow this  
CarlGustaffa

Weird MP problem, marker moved, but not object.

Recommended Posts

Going crazy about a bug here, time to check with the experts and maybe some fresh eyes. Posting the whole script in spoiler, although it won't work on it's own. Problematic part is highlighted. And naturally it's working without problems in singleplayer.

// by Xeno
#include "x_setup.sqf"
private ["_oldpos","_exitj","_ari_num","_position","_str","_score","_control","_rank","_man_type","_pos_at","_no","_number","_vocal","_vocalarray","_vocaltype","_ari_target","_ariavailstr","_firstsecondstr","_arti_markername","_XD_display","_GridStringToPosition","_input"];

disableSerialization;
_ToGrid8 = {
private ["_pos","_posx","_posy","_array","_tmp","_str"];
_pos = _this;
_str = format ["%1",mapGridPosition _pos];
_posx = toArray format ["%1", round (((_pos select 0) % 100) / 11)] select 0;
_posy = toArray format ["%1", round (((_pos select 1) % 100) / 11)] select 0;
_array = toArray _str;
_tmp = [];
{_tmp set [count _tmp, _x]} forEach [_array select 0, _array select 1, _array select 2, _posx, _array select 3, _array select 4, _array select 5, _posy];
_str = toString _tmp;
_tmp = nil;
_posx = nil;
_posy = nil;
_str
};

_GridStringToPosition = {
private ["_input","_res","_exit","_tocheck"];
_input = _this select 0;
_res = [];
if !(typeName _input in ["STRING"]) exitWith {if(d_debug_mode) then {hintSilent "_StringToGrid: Not a string, code error!"}; _res = "Bad grid data due to code error!"; _res};
if (count toArray _input != 6 && count toArray _input != 8) exitWith {if(d_debug_mode) then {hintSilent "_StringToGrid: String not of correct size"}; _res = "Bad grid data"; _res};
_exit = false;
for "_i" from 0 to (count toArray _input) - 1 do {
	_tocheck = (toArray _input) select _i;
	if !(_tocheck in [48,49,50,51,52,53,54,55,56,57]) exitWith {_exit = true};
};
if (_exit) exitWith {if (d_debug_mode) then {hintSilent "_StringToGrid: String contained non numerals"}; _res = "Bad grid data"; _res};
if (count toArray _input == 6) then {
	_res = [
		10000 * (parseNumber toString [toArray _input select 0]) +
		1000 * (parseNumber toString [toArray _input select 1]) +
		100 * (parseNumber toString [toArray _input select 2]) + 50,
		10000 * (parseNumber toString [toArray _input select 3]) +
		1000 * (parseNumber toString [toArray _input select 4]) +
		100 * (parseNumber toString [toArray _input select 5]) + 50
	];
} else {
	_res = [
		10000 * (parseNumber toString [toArray _input select 0]) +
		1000 * (parseNumber toString [toArray _input select 1]) +
		100 * (parseNumber toString [toArray _input select 2]) +
		10 * (parseNumber toString [toArray _input select 3]) + 5,
		10000 * (parseNumber toString [toArray _input select 4]) +
		1000 * (parseNumber toString [toArray _input select 5]) +
		100 * (parseNumber toString [toArray _input select 6]) +
		10 * (parseNumber toString [toArray _input select 7]) + 5
	];
};
_res
};

_ari_num = (_this select 3) select 0;
_ari_target = (_this select 3) select 1;
_ariavailstr = switch (_ari_num) do {
case 1: {"ari_available"};
case 2: {"ari2_available"};
};
_firstsecondstr = switch (_ari_num) do {
case 1: {"Anvil"};
case 2: {"Mohican"};
};
_arti_markername = switch (_ari_num) do {
case 1: {"arti_target"};
case 2: {"arti_target2"};
}; 

if (!(X_JIPH getVariable _ariavailstr)) exitWith {
#ifndef _TT__
_str = _firstsecondstr + " currently not available...";
#else
_str = "Artillery currently not available...";
#endif
_str call XfHQChat;
};

_exitj = false;
if (d_with_ranked) then {
_score = score player;
if (_score < (d_ranked_a select 2)) exitWith {
	(format ["You don't have enough points to call an artillery strike. You need %2 points for a strike, your current score is %1", _score,(d_ranked_a select 2)]) call XfHQChat;
	_exitj = true;
};
};

if (_exitj) exitWith {};

["arti1_marker_1",position player,"ELLIPSE","ColorYellow",[d_ArtiOperatorMaxDist,d_ArtiOperatorMaxDist],"",0,"","FDiagonal", (if(d_nightfilter) then {0.2} else {1})] call XfCreateMarkerLocal;

d_ari_fire = false;
d_ari_type = "";
d_ari_salvos = 1;
_oldpos = position _ari_target;
_ok = createDialog "XD_ArtilleryDialog";
_XD_display = __uiGetVar(D_ARTI_DISP);
if (d_with_ranked) then {
_rank = rank player;
if (_rank in ["PRIVATE","CORPORAL"]) then {
	_control = _XD_display displayCtrl 11007;
	_control ctrlShow false;
	_control = _XD_display displayCtrl 11008;
	_control ctrlShow false;
} else {
	if (_rank in ["SERGEANT","LIEUTENANT"]) then {
		_control = _XD_display displayCtrl 11008;
		_control ctrlShow false;
	};
};
};

setMousePosition [0.5,0.5];
_control = _XD_display displayCtrl 11020;
_control ctrlSetText "6/8 digit grid";

D_ARTI_HELPER = switch (_ari_num) do {
case 1: {D_AriTarget};
case 2: {D_AriTarget2};
};
D_ARTI_MARKER_HELPER = _arti_markername;

[color="SeaGreen"]//onMapSingleClick "D_ARTI_HELPER setpos _pos;D_ARTI_MARKER_HELPER setMarkerPos _pos"; //Used to work just fine[/color]

waitUntil {d_ari_fire || !dialog || !alive player};
[color="Blue"]deleteMarkerLocal "arti1_marker_1";[/color] //Fix not related to original problem
_control = _XD_display displayCtrl 11020;
_input = ctrlText _control;
_position = [_input] call _GridStringToPosition;
if (typeName _position == "STRING") exitWith {"Firesupport canceled." call XfHQChat;};
_input = toArray _input;
[color="Blue"]_position set [2,0];[/color] //Attempted fix, but doesn't do much
sleep 0.678;
D_ARTI_HELPER setpos _position;
D_ARTI_MARKER_HELPER setMarkerPos _position;

#define __restore _ari_target setpos _oldpos; _arti_markername setMarkerPos _oldpos;
#define __speaker if(_ari_num == 1) then {d_hq_logic_en3} else {d_hq_logic_en4}

[color="Red"][s]//deleteMarkerLocal "arti1_marker_1"; //Moved up, stupid bug, but not the cause of this problem.[/s][/color]
if (!alive player) exitWith {if (dialog) then {closeDialog 0}};
//if (d_ari_type != "") then {
if (d_ari_fire) then {
if (typeName _position == "STRING") exitWith {_position call XfHQChat; __restore};

[b][color="Red"]	D_ARTI_HELPER = switch (_ari_num) do {
	case 1: {D_AriTarget};
	case 2: {D_AriTarget2};
};
D_ARTI_MARKER_HELPER = _arti_markername;
D_ARTI_HELPER setPos _position;
D_ARTI_MARKER_HELPER setMarkerPos _position;
//BEGIN DEBUG!!!
_s = format ["_ari_num: %1",_ari_num]; hint _s; diag_log _s;
_s = format ["typeName _position: %1",typeName _position]; hint _s; diag_log _s;
_s = format ["D_ARTI_HELPER: %1",D_ARTI_HELPER]; hint _s; diag_log _s;
_s = format ["D_ARTI_MARKER_HELPER: %1",D_ARTI_MARKER_HELPER]; hint _s; diag_log _s;
_s = format ["_position: %1",_position]; hint _s; diag_log _s;
_s = format ["getPos D_ARTI_HELPER: %1",getPos D_ARTI_HELPER]; hint _s; diag_log _s;
_s = format ["getMarkerPos D_ARTI_MARKER_HELPER: %1",getMarkerPos D_ARTI_MARKER_HELPER]; hint _s; diag_log _s;
// END DEBUG
[/color][/b]//BEGIN Possible exits
if (d_ari_type == "") exitWith {"Bad mission parameters given." call XfHQChat; __restore};
if (!(X_JIPH getVariable _ariavailstr)) exitWith {"Somebody else allready executed an artillery strike, artillery currently not available..." call XfHQChat};
if (player distance [position _ari_target select 0,position _ari_target select 1,0] > d_ArtiOperatorMaxDist) exitWith {
	(format ["You are too far away from your selected target, no line of sight !!! Get within %1 meters.).", d_ArtiOperatorMaxDist]) call XfHQChat;
	__restore
};
_no = objNull;
if (d_arti_check_for_friendlies == 0) then {
	if (d_ari_type == "he" || d_ari_type == "dpicm" || d_ari_type == "wp") then {
		_man_type = switch (d_own_side) do {
			case "WEST": {"SoldierWB"};
			case "EAST": {"SoldierEB"};
			case "GUER": {"SoldierGB"};
		};
		_pos_at = [position _ari_target select 0,position _ari_target select 1,0];
		_no = nearestObject [_pos_at, _man_type];
	};
};
if (!isNull _no) exitWith {
	"Friendlies near target. Aborting strike..." call XfHQChat;
	__restore
};
//END Possible Exits
if (d_with_ranked) then {
	if ((d_ranked_a select 2) > 0) then {["d_pas", [player, (d_ranked_a select 2) * -1]] call XNetCallEvent};
};
//	["d_say", [player,"Funk"]] call XNetCallEvent; //Disabled for now, interferes with kbTell system.
#ifndef __TT__
//	player kbTell [d_kb_logic1,d_kb_topic_side_arti,"ArtilleryRequest",["1","",d_ari_type,[]],["2","",str(d_ari_salvos),[]],["3","",str(getPosASL _ari_target select 1),[]],["4","",str(getPosASL _ari_target select 0),[]],true];
//	player kbTell [d_kb_logic1,d_kb_topic_side_arti,"ArtilleryRequest",["1","",d_ari_type,[]],["2","",str(d_ari_salvos),[]],["3","",mapGridPosition getPosASL _ari_target,[]],true];
//	player kbTell [d_kb_logic1,d_kb_topic_side_arti,"ArtilleryRequest",["1","",d_ari_type,[]],["2","",str(d_ari_salvos),[]],["3","",if (count _input == 8) then {_position call _ToGrid8} else {mapGridPosition getPosASL _ari_target},[]],true];
// WILD ATTEMPT

_vocalarray = ["pause","pause","pause","grid"];
for "_i" from 0 to (count _input) - 1 do {
	_number = parseNumber (format ["%1",toString [_input select _i]]);
	_vocal = switch _number do {
		case 0: {"zero2"};
		case 1: {"one2"};
		case 2: {"two2"};
		case 3: {"three2"};
		case 4: {"four2"};
		case 5: {"five2"};
		case 6: {"six2"};
		case 7: {"seven2"};
		case 8: {"eight2"};
		case 9: {"nine2"};
		default {"zero2"};
	};
	_vocalarray set [_i+4, _vocal];
};
//	player globalChat format ["%1",_vocalarray];
_vocaltype = switch d_ari_type do {
	case "he": {["RequestingImmediateArtillerySuppressionHighExplosiveHowCopyQ"]};
	case "wp": {["RequestingImmediateCoverWithWilliePeteOver"]};
	case "smoke": {["AdjustFireAtTheTargetLocationOver","pause","pause","WithAnImmediateArtillerySuppressionRequestSmokeOver"]}; //Smoke is missing, so this is workaround
	case "flare": {["RequestingContinuousIlluminationAtTheTargetLocationHowCopyQ"]};
	case "sadarm": {["WeNeedAGuidedAntiArmorStrikeOver"]};
	case "copperhead": {["WeNeedLaserGuidedOrdnanceOver"]};
	case "dpicm": {["RequestingFireSupportFireForEffectOver"]};
	default {[]};
};
player kbTell [__speaker,d_kb_topic_side_arti,"ArtilleryRequest",
	["Team","",_firstsecondstr,[_firstsecondstr]],
	["Type","",d_ari_type,_vocaltype],
	["Rounds","",str(d_ari_salvos),[]],
	["Location","",if (count _input == 8) then {_position call _ToGrid8} else {mapGridPosition getPosASL _ari_target},_vocalarray],
	true
];

#else
_topicside = switch (_ari_num) do {
	case 1: {"HQ_ART_W"};
	case 2: {"HQ_ART_E"};
};
_logic = switch (_ari_num) do {
	case 1: {d_hq_logic_en1};
	case 2: {d_hq_logic_ru1};
};
//	player kbTell [_logic,_topicside,"ArtilleryRequest",["1","",d_ari_type,[]],["2","",str(d_ari_salvos),[]],["3","",str(getPosASL _ari_target select 1),[]],["4","",str(getPosASL _ari_target select 0),[]],true];
//	player kbTell [_logic,_topicside,"ArtilleryRequest",["1","",d_ari_type,[]],["2","",str(d_ari_salvos),[]],["3","",mapGridPosition getPosASL _ari_target,[]],true];
player kbTell [__speaker,_topicside,"ArtilleryRequest",["1","",d_ari_type,[]],["2","",str(d_ari_salvos),[]],["3","",if(count _input == 8) then {_position call _ToGrid8} else {mapGridPosition getPosASL _ari_target},[]],true];
#endif
sleep 3;
["ari_type", [d_ari_type,d_ari_salvos,player,_ari_target,_ariavailstr,_ari_num]] call XNetCallEvent;
} else {
//	format ["Firesupport canceled. %1",if (typeName _position == "STRING") then {_position + "."} else {"Bad mission parameters."}] call XfHQChat;
"Firesupport canceled." call XfHQChat;
__restore
};

The problem is that the marker is moved, but the HeliH object remains at its original position. I just can't for the life of me figure out where I'm going wrong here.

The output from the diag_log as follows:

"_ari_num: 1"

"typeName _position: ARRAY"

"D_ARTI_HELPER: 1bb91080# 438988: empty.p3d REMOTE"

"D_ARTI_MARKER_HELPER: arti_target"

"_position: [8150,2250]"

"getPos D_ARTI_HELPER: [0,0,0]"

"getMarkerPos D_ARTI_MARKER_HELPER: [8150,2250,0]"

If I use "D_ARTI_HELPER setPos getPos player" from within stra_debug, then it moves. I've ran it through squint, no significant errors shown there.

Edited by CarlGustaffa

Share this post


Link to post
Share on other sites

"_position: [8150,2250]"

Are you sure setpos takes 2D position? You might need to add Z-value.

Share this post


Link to post
Share on other sites

Tried inserting:

_input = toArray _input;

_position set [2,0];

sleep 0.678;

But no go. Output is now:

"_ari_num: 1"

"typeName _position: ARRAY"

"D_ARTI_HELPER: 1bcf3700# 438988: empty.p3d REMOTE"

"D_ARTI_MARKER_HELPER: arti_target"

"_position: [8150,2250,0]"

"getPos D_ARTI_HELPER: [0,0,0]"

"getMarkerPos D_ARTI_MARKER_HELPER: [8150,2250,0]"

Share this post


Link to post
Share on other sites

Sound like a locality issue, is the object local to the setPos? from what i recall setPos is sensitive to the locality. Try to run the setPos command wherever the object is local.

Share this post


Link to post
Share on other sites

I don't think so. I've now highlighted a commented but earlier version that used to work, in green. Earlier onMapSingleClick was used without any problems moving the same object. And, I'm able to access and move it locally using the debug dialog.

I've tried setting up my own server locally, and I've tried connecting without the debug tool, thinking maybe it was a cheat prevention thing or something. I've noticed that somehow I can't "player allowDamage false" anymore, which was useful for testing.

Also I have that "sleep 0.678;" which should be good enough for any lag induced problems, especially on local dedi.

Share this post


Link to post
Share on other sites

Not to hijack your thread or anything, i'm just extremely curious to know where people get those sleep numbers from. Why not 0.500 or 0.750. I believe in domination the side missions or something also has those "kind" of numbers.

Share this post


Link to post
Share on other sites

I'm just following Xenos Domination footsteps :p But I assume it is/was to prevent loops occuring at regular intervals causing hickups. Consider ten heavy scripts running each with sleep 1.567. In perfect conditions that would be a hickup every 1.567 seconds. If you randomize the sleeps they have less chance of causing a script restart at the same time. I believe.

Anyway, I just tried skipping D_ARTI_HELPER completely and accessing _ari_target = (_this select 3) select 1; directly instead. But still it's a no go. Note that _ari_target is setPos'ed elsewhere in the script as well, which haven't been a problem before. Not quite sure what the deal is about D_ARTI_HELPER at all actually.

Share this post


Link to post
Share on other sites
where people get those sleep numbers from

IMHO the intention here is (or was at some point) that not every script or loop is clocked the same, so that the workload distributes better over time.

Let's say you have all your scripts/loops clocked to sleep 0.5 seconds each iteration and let's assume that these scripts are started right after another:

[start Scripts] . . . . . s1 s2 s3 s4 . . . . . s1 s2 s3 s4 . . . . .
t0              t1        t2          t3        t4          t5

The scripts start at t0, pause from t1 to t2 and execute the next iteration from t2 to t3 and so on... What you get is an interval of two phases, one in which not much is running and one in which all the scripts execute the next iteration.

Now if these scripts all had a different clock or sleep-time, this picture would be much more random, which equals a better distribution for raising numbers of scripts running.

Personally I like to write something like the following to get my magic numbers:

_delay = 2 + (random 1);

to get a slightly randomized clock for fsm delay-loops for example.

Share this post


Link to post
Share on other sites

I'm beginning to think this script isn't the source of the problem. I've done a lot of changes, including trying to base everything in this script around the marker instead and move the object in the server script. I've also replaced the __restore macro with a hint that doesn't kick in (as expected and hoped for when parameters are correct).

So while running on server I constantly hint out the position of the object, and it turns out that it's position is actually updated. But just a second later there is something else going on elsewhere that moves it back to [0,0,0]. Just need to figure out where that can be... :confused:

Edit, no that was just the result of an earlier attempt that went a little bad. Using original script also failed until I took away the bad stuff in x_arifire (server side didn't have a marker - DOH, wtf was I thinking...). So with that fixed and getting back my bad script with the disabled __restore macro, position is no longer reset. So the problem is a __restore in a place where it doesn't belong. Narrowing it down at least...

Edit2, back to where I began... I thought... Except now it suddenly works... Problem solved, I hope...

Edited by CarlGustaffa

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  

×