Home   Help Search Login Register  

Author Topic: Some tips for addon scripter & mission designer  (Read 9107 times)

0 Members and 1 Guest are viewing this topic.

Offline rom

  • Members
  • *
  • . . .
Re:Some tips for addon scripter & mission designer
« Reply #45 on: 26 Apr 2003, 20:16:45 »
That's really strange that this is crashing your PC.
When I'm trying to createUnit something with an empty group then it just doesn't create the unit. Also joining a unit to grpNull doesn't give me problems either.
(Clients: Windows XP, OFP:Resistance v. 1.91; Server: Win2k Server, OFP dedicated v. 1.91. Also no problems in SP and player server)

From what I've know so far is that joining a Unit to grpNull puts the Unit in the next available (new) group. This is the only way of creating new groups with scripting that I know of.
You can't name the Gamelogic in its init field because "this" is different on clients and server and using it will give you errors. So you need this grouping trick to delete the Gamelogic again.

Perhaps your _obj wasn't in a group at the beginning?
Units created with createVehicle don't have a group for example. Take the player as _obj for example to make sure _obj has a valid group.

Offline WizzyWig

  • Members
  • *
  • Mod Maker
    • Oblivion Promotions
Re:Some tips for addon scripter & mission designer
« Reply #46 on: 26 Apr 2003, 20:31:50 »
uiox please can you send out demo download so we can c persisley how to install this as it looks like some people are haveing trubal with it thanks

Code: [Select]
JUST FOR YOU UIOX
Code: [Select]
uiox peut s'il vous plaît vous envoyez le chargement de modèle de demonstration si nous pouvons persisley de c comment installer ceci comme il a l'air de quelques gens ont trubal remercie avec cela

Rubble_Maker

  • Guest
Re:Some tips for addon scripter & mission designer
« Reply #47 on: 26 Apr 2003, 21:48:36 »
Well I had like 4 crashes when playing with that code, after the fourth one my CMOS settings had gone lost, so I'm going to be a bit more careful with that createUnit thingy now ;)

I'm using Win98 and ofp1.91 in SP.

"From what I've know so far is that joining a Unit to grpNull puts the Unit in the next available (new) group. This is the only way of creating new groups with scripting that I know of"

Yes I've seen that; when I join the created unit into GrpNull, it becomes Bravo Black #1 or something, whereas before it was Alpha.

"Units created with createVehicle don't have a group for example"

Yes that was probably my fault, I used createVehicle to make one gamelogic which then I wanted to use to make further game logics. That was when the crashes happened. I also tried using the player to do that, but it destroyed his group, i.e. after I called createUnit to drop a new unit into his group and removed it again, my group members were no longer available.

I hope there's a better way to use your trick, because messing with the player's group is not a very nice way. Maybe just tell the addon user to make one game logic that I use as reference.

btw. when I createUnit a game logic, and then join it into the player's group and then join it with GrpNull, is it assigned its own group?


Offline rom

  • Members
  • *
  • . . .
Re:Some tips for addon scripter & mission designer
« Reply #48 on: 26 Apr 2003, 22:30:43 »
No need to play with grpNull when you createUnit the Gamelogic into the players group, just delete it from the group again:

Code: [Select]
_playerGroup = group player
_playerGroupArray = units _playerGroup
"Logic" createUnit [[0,0,0], _playerGroup,"[engineobj] exec ""globalEngine.sqs""",0.5,"PRIVATE"]
_newPlayerGroupArray = units (group player)
_Logic = (_newPlayerGroupArray - _playerGroupArray) select 0
deleteVehicle _logic

But for your question:
Yes, I think that joining the Gamelogic to grpNull (after you createUnit it into the player group) will put it into a new group.
But first you have to name the Gamelogic with the array method before you can do anything with it.

Rubble_Maker

  • Guest
Re:Some tips for addon scripter & mission designer
« Reply #49 on: 27 Apr 2003, 00:03:27 »
thx I try that code ASAP!

what do you mean with "array method"?

Rubble_Maker

  • Guest
Re:Some tips for addon scripter & mission designer
« Reply #50 on: 27 Apr 2003, 13:56:23 »
rom, the code you posted works fine, but when I create more than 1 gamelogic, it crashes again! Here's the code I use:

_playerGroup = group player
_playerGroupArray = units _playerGroup
"Logic" createUnit [[0,0,0], _playerGroup,"",0.5,"PRIVATE"]
"Logic" createUnit [[0,0,0], _playerGroup,"",0.5,"PRIVATE"]
"Logic" createUnit [[0,0,0], _playerGroup,"",0.5,"PRIVATE"]
"Logic" createUnit [[0,0,0], _playerGroup,"",0.5,"PRIVATE"]
"Logic" createUnit [[0,0,0], _playerGroup,"",0.5,"PRIVATE"]
"Logic" createUnit [[0,0,0], _playerGroup,"",0.5,"PRIVATE"]
"Logic" createUnit [[0,0,0], _playerGroup,"",0.5,"PRIVATE"]
hint format ["%1",(group player)]
exit

This is not aceptable, because when you have many scripts running simultaneously, it can happen that the player group receives more than one gamelogic at a time (because just before one script removes the logic, another script creates another logic).

Offline Dinger

  • Contributing Member
  • **
  • where's the ultra-theoretical mega-scripting forum
Re:Some tips for addon scripter & mission designer
« Reply #51 on: 28 Apr 2003, 03:33:01 »
a beta of bn880's MP services is due out _very_ soon.
I'll also put out a little function I wrote (really, it's graffiti compared to his calligraphy) called "PublicArray".  So check the chainofcommand in the next couple of days.
Dinger/Cfit

Offline uiox

  • Contributing Member
  • **
Re:Some tips for addon scripter & mission designer
« Reply #52 on: 28 Apr 2003, 21:31:47 »
Array, we want in opfec to see the tip.

We are in OFPEC, you know?

Editing Center....

Advertisement Center

It's OFPAC....

Offline Dinger

  • Contributing Member
  • **
  • where's the ultra-theoretical mega-scripting forum
Re:Some tips for addon scripter & mission designer
« Reply #53 on: 29 Apr 2003, 06:27:07 »
I can't publish bn880's stuff uiox, and i haven't updated my stuff to make sure it still works.  Here's my scribblings, for what it's worth.  In a few days, the code that makes it work will be available.


init.sqs lines
Code: [Select]
@rNClientsReady
[] exec "publicArray\PublicArrayInit.sqs"

PublicArrayInit.sqs
Code: [Select]
;dinger@raf303.org
_publicarrays = ["Test1", "Test2", "Test3"]

?rNisServer == rNisServer:goto "NetworkInitRunning"
;insert variable initialized function
call preprocessFile "string\string.sqf"
call preprocessFile "numSystem\numSys.sqf"
call preProcessFile "Network\COMM_HEADER.sqf";

_connectTimeout = 10;
rNClientsReady = false;
_connectTimeout call loadFile "Network\initializeNetwork.sqf";

#NetworkInitRunning
_timeout = _time + 60

@(rNClientsReady || _time > _timeout)
?_Time > _Timeout: player sidechat "CoC_PublicArrayInit Error: failed to initialize network"; exit
if !ecool function ehre then {rPublicArrays = rPublicArrays + _publicarrays} else {rPublicArrays = +_publicarrays}





rPublicArrays = ["Test1", "Test2", "test3"]
;rPublicArrays = the names of the arrays to share

rNPA_PollInterval = .1
;set higher interval for lower urgency/traffic and higher overall performance, lower interval for high traffic/urgency

rNPA_Terminate = False
;set to TRUE to shut down polling

;rNPA_cc# = server/client channel (0 = master update) = time hack
;rNPA_ci# = server/client index = index to rPublicArrays
;rNPA_ind# = index reference from rPublicArrays -> nPAs
;rNPA_tim# = time hack for rPublicArrays updates
;rNPA_cp# = port opened to client
;rNPAA-rNPA9 = ports

;checkandload libraries
fPublicArray = preprocessfile "publicArray\fPublicArray.sqf"
?LIBNUMSYS > 0:goto "LoadPALib"
call loadfile "numSys\numSys.sqf"
#LoadPALIb
?LIBARRAYCNV > 0:goto "Initialize"
call preprocessfile "arrayConversions\arrayConversions.sqf"

#Initialize
rPublicArrayCount = count rPublicArrays
rPublicArrayPorts = []
_rPortStackDepth = 36
;nb This system is good only for 36 channels
;if you want more, we can add 36 to index, and go double-digit
rPublicArrayStem = "rNPa"
_i = 0

#BuildStack
_currentPort = rPublicArrayStem + (_i call fDecToAlpha)
call format ["%1 = time", _currentPort]
rPublicArrayPorts = rPublicArrayPorts + [_currentPort]
_i = _i + 1
?_i < _rPortStackDepth: goto "BuildStack"

#BuildIndices
_i = 0
{call format ["rNPA_ind%1 = -1; rNPA_tim = -1", (_i call fDecToAlpha)]; _i = _i + 1} ForEach rPublicArrays

;debug
player sidechat format ["%1", rPublicArrayPorts]

;start server
?local server:[] exec "publicArray\Server.sqs"

;start client
?player == player:[] exec "publicArray\Client.sqs"
exit


PublicArray.sqs
Code: [Select]
;dinger@raf303.org

_channel = rNClientChannel call fDecToAlpha
_push = format ["rNPA_cc%1", _channel]
_pushi = format ["rNPA_ci%1", _channel]
_tune = format ["rNPA_cp%1", _channel]

#Top
?count rPublicArrayOut == 0:exit
_arrayIndex = rPublicArrayOut select 0
call format ["%1 = time; %2 = _arrayIndex", _push, _pushi]
call {PublicVariable _pushi; PublicVariable _push}
player sidechat "Pushi = "+_pushi + "  _push = " + _push
_timeout = time + 10

#WaitForServer
?(call format ["%1 == (-1 * (_arrayIndex+5))", _pushi]):goto "FFE"
~rNPA_PollInterval
?time < _timeout: goto "WaitForServer"
player sidechat "PublicArray.sqs server timeout"
?!rNPA_Terminate:goto "Top"
exit

#FFE
;call format ["%1 = 0
_stemName = format ["rNPA%1", (call _tune) call fDecToAlpha]
_transmitArray = [call (rPublicArrays select _arrayIndex), _stemName] call fArrayToVar
{publicvariable _x} foreach _transmitArray
player sidechat format ["DEBUG - XMIT: %1: %2/Stem: %3, pushi: %4 = %5", (rPUblicArrays select _arrayIndex), _transmitArray, _stemname, _Pushi, call _pushi]

_timeout = time + 20
#WaitForAck
~rNPA_PollInterval
?time > _timeout:goto "TimeOut"
?(call format ["((%1 < -4) or (%1 > -1))", _pushi]):goto "WaitforAck"
?(call format ["%1 == -1", _pushi]):rPublicArrayOut set [0, -666]; rPublicArrayOut = rPublicArrayOut - [-666];goto "Top"

#TimeOut
player sidechat format ["PublicArray.sqs: NoAck (pushi: %1 = %2)", _pushi, call _pushi]
?!rNPA_Terminate:goto "Top"
exit

server.sqs
Code: [Select]
;dinger@raf303.org

;initialize clientchannels
_clients = (count rNClientList)
_i = 0
{call format ["rNPA_cc%1 = -1; rNPA_ci%1 = -1", (_i call fDecToAlpha)]; _i = _i + 1} ForEach rNClientList

rPublicArrayPortCurrent = 0
rPublicArrayPortsOpen = []

#RequestScan
_i = 0
#RequestScanLoop
_Channel = Format ["rNPA_cc%1", (_i call fDecToAlpha)]
? (call (_channel + " != -1")):player sidechat format ["Opening Channel %1", _channel]; call format [{%1 = -1; [_i] exec "PublicArray\ServerOpen.sqs"}, _channel]
_i = _i + 1
?_i < _clients: goto "RequestScanLoop"
~rNPA_PollInterval
?!rNPA_Terminate:goto "RequestScan"
exit

ServerOpen.sqs
Code: [Select]
;dinger@raf303.org
_channel = ((_this select 0) call fDecToAlpha)
_indexVar = format ["rNPA_ci%1", _channel]
_portVar = format ["rNPA_cp%1", _channel]
_index = call _indexVar
_ia = _index call fDecToAlpha
_port = 0
call format ["_port = %1; rPublicArrayPortsOpen = rPublicArrayPortsOpen + [%1]", rPublicArrayPortCurrent]
call {while {rPublicArrayPortCurrent in rPublicArrayPortsOpen} do {rPublicArrayPOrtCurrent = rPublicArrayPortCurrent + 1; if (rPublicArrayPortCurrent >= count rPublicArrayPorts) then {rPublicArrayPOrtCurrent = 0;}}}
_portIndexName = format [rPublicArrayStem + "%1_", _port call fDecToAlpha]
call (_portIndexNAme + " = nil")
call format ["%1 = _port", _portVar]
call (_indexVar + { = -1 * (_index+5)})
call {PublicVariable _portVar; PublicVariable _indexVar}
player sidechat format ["SO.sqs: Portvar: %1:%2, _port %3, IndxVar: %4,%5, _portIndexName %6", _portvar, call _portvar, _port, _indexvar, call _indexvar, _portIndexName]


_timeout = _time + 30
player sidechat "SO.sqs: Waiting for Xmission"
#WaitForTransmission
?(call _portIndexName) == (call _portIndexName):goto "TransmissionReceived"
?_time > _TimeOut:goto "TimeOut"
~rNPA_PollInterval
goto "WaitForTransmission"

#TransmissionReceived
player sidechat "SO.sqs: Xmission received"
call (_indexVar + { = -1})

_arrayIndex = format ["rNPA_ind%1", _ia]
_arrayTimeIndex = format ["rNPA_tim%1", _ia]
;player sidechat format ["aI = %1, ATI = %2, IV:%3 = %4, Ind = %5, IA = %6", _ArrayIndex, _ArrayTimeIndex, _IndexVAr, call _indexVar, _index, _ia]
_portAuthentication = _portIndexName + "_tim"
call (_portAuthentication + "=time")
call (_arrayIndex + " = _port")
call (_arrayTimeIndex + "= time")
rNPA_hack = time

call {publicvariable _arrayindex; publicvariable _arrayTimeIndex; publicVariable _portauthentication, publicvariable "RNPA_hack", publicvariable _indexVar}
goto "end"

#TimeOut
player sidechat "SO.sqs TimeOut"
call (_indexVar + { = -2})
publicvariable _indexVar
;wait for client to finish transmission or disconnect
~60

#end
rPublicArrayPortsOpen = rPublicArrayPortsOpen - [_port]
exit

Client.sqs
Code: [Select]
;dinger@raf303.org
_i = 0
fReceiveArray = preprocessfile "publicArray\fReceiveArray.sqf"
rPublicArrayOut = []
rPublicArrayIndex = []

{rPublicArrayIndex = rPublicArrayIndex + [-1]} ForEach rPublicArrays
{call format ["rNPA_ind%1", _i call fDecToAlpha]; _i = _i + 1} ForEach rPublicArrays
_hack = -1
rNPA_ccA = _hack
~(random 1)
player sidechat "ClientProcessRunning"

#MonitorLoop
?rNPA_hack != _hack: rNPA_hack = _hack; call fReceiveArray; player sidechat "hack"
~rNPA_PollInterval
?!rNPA_Terminate:goto "MonitorLoop"
exit


ArrayVar.sqf
Code: [Select]
/*
Array conversion sublibrary
Dinger March 6, 2003.
www.thechainofcommand.net
*/
If (local server) then {CoCArrayWidget = "Logic" createvehicle [-10000,-10000,0]; CoCArrayNullWidget = "Logic" createvehicle [-900,900,0]; PublicVariable "CoCArrayWidget"; PublicVariable "CoCArrayNullWidget"};
fVarToArray = preprocessfile {fVarToArray.sqf};
fArrayToVar = preprocessfile {fArrayToVar.sqf};
LIBARRAYVAR = 1

fPublicArray.sqf
Code: [Select]
private ["_array", "_arrayname", "_i"];
_arrayname = _this;
_i = 0;
if (!(_arrayname in rPublicArrays)) then {hintc format ["ERROR: ARRAY %1 NOT IN PUBLIC ARRAY LIST", _arrayname]}
   else
   {While {(rPublicArrays select _i) != _arrayname} do
   {_i = _i + 1}};
if (count rPublicArrayOut > 0) then
   {rPublicArrayOut = rPublicArrayOut + [_arrayname]}
   else
   {
   rPublicArrayOut = +[_i];
   [] exec "PublicArray\PublicArray.sqs";
   };
;


Code: [Select]
private ["_i", "_ind", "_ia", "_tim", "_channel", "_stemname"];
_i = 0;
while {_i < rPublicArrayCount} do
   {
   _ia = (_i call fDecToAlpha);
   _tim = format ["rNPA_tim%1", _ia];
      if (call format ["rNPA_tim%1 > (rPublicArrayIndex select _i)", _ia]) then
      {
      _ind = (call format ["rNPA_ind%1", _ia]) call fDecToAlpha;
      _stemname = format [{%1%2}, rPublicArrayStem, _ind];
      player sidechat format ["Receiving: %1 = %2", _stemname, call _stemname];
      call format [{%1 = +((_stemname) call fVarToArray)}, (rPublicArrays select _i)];
      rPublicArrayIndex set [_i, (call format ["rNPA_tim%1", _ia])];
      player sidechat format ["DEBUG - REC: %1 : %2", rPublicArrays select _i, call (rPublicArrays select _i)];
      };
   _i = _i + 1;
   };
;
Dinger/Cfit

Offline Dinger

  • Contributing Member
  • **
  • where's the ultra-theoretical mega-scripting forum
Re:Some tips for addon scripter & mission designer
« Reply #54 on: 29 Apr 2003, 06:31:55 »
Missed a library.
arrayConversions.sqf
Code: [Select]
/*
Array conversion sublibrary
Dinger March 6, 2003.
www.thechainofcommand.net
*/
If (local server) then {CoCArrayWidget = "Logic" createvehicle [-10000,-10000,0]; CoCArrayNullWidget = "Logic" createvehicle [-900,900,0]; PublicVariable "CoCArrayWidget"; PublicVariable "CoCArrayNullWidget"};
fVarToArray = preprocessfile {arrayConversions\fVarToArray.sqf};
fArrayToVar = preprocessfile {arrayConversions\fArrayToVar.sqf};
LIBARRAYCNV = 1;

ArrayToVar.sqf
Code: [Select]
/*
PURPOSE: Convert a multidimensional array of Booleans, Floats or Units into a sequentially numbered group of individual variables.
HISTORY:    CoC Dinger 03/06/2003
INPUTS:   _array: Multidimensional array of booleans, floats or units.
      _stemname: base name for metavariables (to be inflected with numerical series)
RETURNS:    one-dimensional array of strings, containing the names of content and index variables describing the array.
ALGORITHM:  
END ALGORITHM
CALL EXAMPLES:
 
   _array = [True, player, [32, leader group player], 5]
   _stemname = "rNVp1"
   [_array, _stemname] call fArrayToVar -> ["rNVp1A", "rNVp1B", "rNVp1C", "rNVp1C_", "rNVp1C_A", "rNVp1C_B", "rNVp1C_", "rNVp1D", "rNVp1_"]
*/
private ["_stemname", "_array", "_element","_output", "_i", "_elementname", "_indexname"];

_array = _this select 0;
_stemname = _this select 1;
_indexname = format ["%1_", _stemname];
_output = [];
_i = 0;

while {_i < count _array} do
    {
   _element = _array select _i;
   _elementname = _stemname + (_i call fDecToAlpha);
   if (_element in [_element]) then
      {
      call (_elementname + {= _element});
      _output = _output + [_elementname];
      }
   else
      {
      if (format ["%1", _element] == "scalar bool array string 0xfcfffef") then
         {
         call (_elementname + {= CoCArrayNullWidget});
         _output = _output + [_elementname]
         }
      else
         {
         call (_elementname + {= CoCArrayWidget;});
         _output = _output + [_elementname] + ([_element, (_elementname + "_")] call fArrayToVar);
         };
      };      
   _i = _i + 1;
   };

call (_indexname + "= _i");
_output = _output + [_indexname];
_output

VarToArray.sqf
Code: [Select]
/*
PURPOSE: Convert a sequentially numbered group of content and index variables into an array
HISTORY:    CoC Dinger 03/05/2003
INPUTS:   _stemname: base name for metavariables.
RETURNS:    multidimensional-dimensional array; destroys content and index variables on local machine
ALGORITHM:  Really, I stole this header from Bn880
END ALGORITHM
CALL EXAMPLES:
 
   _stemname = "rNVp1"
   _stemname call fVarToArray -> [True, Player, [32, leader group player], 5]


*/
 private ["_stemname", "_array", "_element","_output", "_i", "_elementname", "_indexname", "_index"];
_stemname = _this;
_indexname = _this + "_";
_index = call _indexname;
_output = [];
_i = 0;

while {_i < _index} do
   {
   _elementname = _stemname + (_i call fDecToAlpha);
   _element = call _elementname;

   if (_element in [CoCArrayWidget, CoCArrayNullWidget]) then
      {
      _output = _output + [((_elementname + "_") call fVarToArray)]}
   else
      {_output = _output + [call _elementname]};

   call (_elementname + "= nil");
   _i = _i + 1;
   };
call (_indexname + "= nil");
_output
Dinger/Cfit

Offline uiox

  • Contributing Member
  • **
Re:Some tips for addon scripter & mission designer
« Reply #55 on: 29 Apr 2003, 11:29:16 »
When I say tip, it's not your code, it's nice to publish it, but the method you apply. MP scripters has different problem sometime and need adapt or build new code.

Teote

  • Guest
Re:Some tips for addon scripter & mission designer
« Reply #56 on: 02 May 2003, 03:43:59 »
Can someone please explain to me what ?(local server) does?

I've herd this before:

If you want your script to be run on a local computer then use:
?(local server):

or if the script is to be only run on the server then have the following line at the start of the script:

?!(local Server): exit

but doesnt ?!(local server): exit translate into, if not on local computer exit. If that is correct wouldnt ?(local server):  be the same as ?!(local server): exit when you are trying to run a command on a server? ???

I don't know if that made any sence to anyone but to me these 2 if statements counterdict eachother and would not let a script be run on a server.

Offline Dinger

  • Contributing Member
  • **
  • where's the ultra-theoretical mega-scripting forum
Re:Some tips for addon scripter & mission designer
« Reply #57 on: 02 May 2003, 10:03:08 »
uiox: yes, I understand that; but I tried my best to explain what I was doing in tips before.  But I'll wager a bottle of 10-year-old calvados there's nothing less ambiguous than a bunch of code.  Hmmm. forget the wager.  I'll buy regardless, and we can argue it out.  (I would have said 25-yr-old, but I'm a poor student)

Teote: the solution to your problems lies in this: server is not a reserved variable.  In a mission, you can put a line:
server = "MyLeftGnut"
and it won't give you any trouble.

But many MP scripts require that you place in your mission a gamelogic, and that you give it the name "server".
In MP, each computer keeps track of some part of the game.  Basically, each client keeps track of all the units in the client's group, and the server takes care of all the other units.  Thus, all gamelogics established at the beginning of a mission are taken care of on the server.
local (unit) returns a boolean on whether the unit is being taken care of by the particular computer.  so for units that are placed at the beginning of a mission and are not in a player's group, local (unit) will only return TRUE on the server.

Therefore, if you place a gamelogic called "server" in a mission, <local server> will only be true on the server.  That's how you figure out what the server is.
Dinger/Cfit

Offline Terox

  • Former Staff
  • ****
  • Follow the Sappers!
    • zeus-community.net
Re:Some tips for addon scripter & mission designer
« Reply #58 on: 02 May 2003, 23:33:06 »
forgive my ignorance, ive read through all the posts on this thread
I understand the difference between all the variable types, server side scripting etc

I dont understand what this thread is all about

Are you trying to get all clients to process the same data that the server is processing , with the end aim to reduce desync or something on those lines
I am lost a bit
Would prefer a brief explanation in laymans terms

Thanks ;D
« Last Edit: 02 May 2003, 23:35:44 by Terox »
Zeus ARMA2 server IP = 77.74.193.124 :2302
Teamspeak IP = 77.74.193.123

Teote

  • Guest
Re:Some tips for addon scripter & mission designer
« Reply #59 on: 03 May 2003, 01:56:34 »
Dinger thank you that makes more sence and I think I understand it.

So does the server take care of all the collisions from all of the entities and does each computer take care of ever entity?
« Last Edit: 03 May 2003, 01:58:53 by Teote »