Home   Help Search Login Register  

Author Topic: missing men during civilian spawn and cull scripts.  (Read 1123 times)

0 Members and 2 Guests are viewing this topic.

Offline ceeb

  • Members
  • *
  • I'm a llama!
missing men during civilian spawn and cull scripts.
« on: 15 Jan 2006, 05:43:52 »
hi all,

  i'm trying to create a series of scripts to simulate a civilian (+ rebel) population on an island. rather than having them all alive at once, the populations of each town are kept in one global array. when the player gets close to a town, it spawns the population. When the player leaves the area, the civs are counted then deleted, and the global array updated. this ain't no DAC, but i'm enjoying myself...

 the problem i'm having is that not all the civs spawn correctly. about 1 in 5 times, 1 or 2 don't appear. so if you go near a town, then leave and come back enough times, the population disappears. the createUnit script is trying to make the correct number, they just don't appear. i assumed it was due to creating new units too close to other objects, and have made a proximity loop, but this doesn't help (testing it on the intro map has the same problem). i've also slowed the spawn scripts right down, but that doesn't help either.

 does anybody have any tips on creating several groups of units within an area, quickly and accurately? i didn't know how to set the side of a created unit, so i'm using a civilian (dummyCiv) on a far away island to create each group, then removing him from the group. i'm sure this isn't the best way to do things...

 also, i plan to give these civilians some tasks to do once they spawn, such as wander around. if possible, i want only one script running to control each towns population. what is the best way to move multiple spawned groups (ie not on the map in the mission editor) without lag?



here is an overview of my scripts :
 
-playerMonitor.sqs
checks player position. if close to town, exec spawnTown.sqs. if far from spawned town, exec cullTown.sqs


-townSpawn.sqs
----------------------------------------------------------------------------------------------
_placeObject = _this select 0
_placeArrayElement = _this select 1
_placeCivs = placeCivsArray select _placeArrayElement
_placeRebels = placeRebelArray select _placeArrayElement

player globalChat format ["population is %1 civs, %2 rebels",_placeCivs,_placeRebels]

#spawnLoop
_randomNum = [1,4] call randomInt
[_placeObject,_randomNum,civArray] exec "spawnUnitArray2.sqs"
_placeCivs = _placeCivs - _randomNum
~5
if (_placeCivs > 4) then {goto "spawnLoop"}
~1
[_placeObject,_placeCivs,civArray] exec "spawnUnitArray2.sqs"
-------------------------------------------------------------------------------------------------------

- spawnUnitArray2.sqs
(upside down for efficiency = good??? i've adjusted the delays and spacing between each new unit without any luck. )
-------------------------------------------------------------------------------------------------------
goto "init"

#checkloop
_createPos = _objectPos
_randTheta = [360] call randomPlus
_randRange = [100] call randomPlus
_createPos = [(_createPos select 0) + _randRange * (cos _randTheta), (_createPos select 1) + _randRange * (sin _randTheta), _createPos select 2]
_nearObj = nearestObject [_createPos select 0,_createPos select 1,_createPos select 2]
hint format ["nearestObject = %1",_nearObj]
dummyLogic setPos _createPos
player globalChat format ["distance is %1", (_nearObj distance dummyLogic)]
if (_nearObj distance dummyLogic < 10) then {player globalchat "too close"; goto "checkLoop"}
~0.1

#placeLoop
;~0.2
_unitArray select ([_unitArrayCount] call randomPlus) createUnit [_createPos,_tempGroup]
_createPos = [(_createPos select 0) + 1, (_createPos select 1) + 1, _createPos select 2]
_tempLoop = _tempLoop + 1
if (_tempLoop < _numberToMake) then {goto "placeLoop"}
~0.2
[dummyCiv] join grpNull
~0.2
group dummyCiv setGroupID ["Alpha","GroupColor1"]
;hint "spawnUnitArray.sqs exiting"
exit

#init
;hint "spawnUnitArray.sqs running"
_objectPos =  getPos (_this select 0)
_createPos = _objectPos
_randTheta = [360] call randomPlus
_randRange = [50] call randomPlus
_createPos = [(_createPos select 0) + _randRange * (cos _randTheta), (_createPos select 1) + _randRange * (sin _randTheta), _createPos select 2]
_numberToMake = _this select 1
_unitArray = _this select 2
_unitArrayCount = count _unitArray
_tempLoop = 0
_tempGroup = group dummyCiv
player globalChat format ["number to make = %1",_numberToMake]
~0.1
goto "checkLoop"
-------------------------------------------------------------------------------------------------------


thanks guys!!! : )
« Last Edit: 15 Jan 2006, 05:49:53 by ceeb »

Offline THobson

  • OFPEC Patron
  • Former Staff
  • ****
Re:missing men during civilian spawn and cull scripts.
« Reply #1 on: 15 Jan 2006, 11:17:11 »
I have not analysed the scripts in detail - but I have had a quick lool and offer the following thoughts:

There is a limit of 12 units per group and there is a limit of 63 groups per side, remember a unit on its own constitutes a group.  Bearing those in mind I think you need to look carefully at the following bit of code with some of my thoughts inserted:

#placeLoop
;~0.2
_unitArray select ([_unitArrayCount] call randomPlus) createUnit [_createPos,_tempGroup]

Will _tempGroup ever try to go beyong 12 units in the line above?  If later you are going to get them to joing grpNull why not do that now to keep the size of _tempGroup down?

_createPos = [(_createPos select 0) + 1, (_createPos select 1) + 1, _createPos select 2]
_tempLoop = _tempLoop + 1
if (_tempLoop < _numberToMake) then {goto "placeLoop"}
~0.2
[dummyCiv] join grpNull

dummyCiv is the name of a group right?  (It should be: you set _tempGroup = to it in the init piece of code).  In which case I don't know what this line will do.  You may be right but the construct I would use is:
{[_x] join grpNull} forEach units dummyCiv
In any event will this ever result in there being more that 63 groups of civis?


~0.2
group dummyCiv setGroupID ["Alpha","GroupColor1"]
;hint "spawnUnitArray.sqs exiting"
exit

If you try to exceed 12 units per group or 63 groups you will not get a warning, but strange things will happen.

Offline Terox

  • Former Staff
  • ****
  • Follow the Sappers!
    • zeus-community.net
Re:missing men during civilian spawn and cull scripts.
« Reply #2 on: 15 Jan 2006, 12:28:11 »
the better solution to this is to use BN880's excellent CoCai on demand system

This basically allows you to place units, with waypoints on the map where you want them

The system then removes them from the map and places them in stasis, until X condition is met

X condition can be a
1) boolean
2) a distance measurement to the nearest enemy unit
(This distance condition even takes into consideration any waypoints that the group may have)

Implementation is fairly easy, basically copy the coc_ad folder into your mission directory, create a trigger that encompasses the entire map

and place a line in the init field of each group leader who's group you want placed in stasis.


It takes into account any vehicle the unit was in, his weapons etc, the height the unit was at, eg if in a building,
such entries in the init field of a unit such as disableai "move" are not kept automatically by the system, however there is a way of initiating that code during the "respawn" of the unit

This is the best way to get the max number of units/groups on the map, yet preserve that ever important fps
There is a readme included in the folder and imho is an absolutely excellent system to use

One note
From my experience, using booleans is more cpu efficient that using the distance condition.

although the distance condition can be tied in with the viewdistance

eg

INIT.sqs
tx_vd = 1200
?(local server): tx_vd = tx_vd * 0.88
setviewdistance tx_vd


and the init field of the group leader would look like the following
[this,{_d<tx_vd}]call loadfile "CoC_AD\addgroup.sqf"

an example of using a boolean in the group leaders init field

[this,{txB_B},true]call loadfile""CoC_AD\addgroup.sqf"

where txB_B is a boolean, initiated by a trigger condition, west (enemy) present , triggered once and then deleting the trigger



The link

http://s92713009.onlinehome.us/OFP/CoC_ADrev36.zip (ftp://http://s92713009.onlinehome.us/OFP/CoC_ADrev36.zip)
« Last Edit: 15 Jan 2006, 12:33:10 by Terox »
Zeus ARMA2 server IP = 77.74.193.124 :2302
Teamspeak IP = 77.74.193.123

Offline ceeb

  • Members
  • *
  • I'm a llama!
Re:missing men during civilian spawn and cull scripts.
« Reply #3 on: 15 Jan 2006, 13:53:03 »
I have not analysed the scripts in detail - but I have had a quick lool and offer the following thoughts:

There is a limit of 12 units per group and there is a limit of 63 groups per side, remember a unit on its own constitutes a group.  Bearing those in mind I think you need to look carefully at the following bit of code with some of my thoughts inserted:

#placeLoop
;~0.2
_unitArray select ([_unitArrayCount] call randomPlus) createUnit [_createPos,_tempGroup]

Will _tempGroup ever try to go beyong 12 units in the line above?  If later you are going to get them to joing grpNull why not do that now to keep the size of _tempGroup down?

_createPos = [(_createPos select 0) + 1, (_createPos select 1) + 1, _createPos select 2]
_tempLoop = _tempLoop + 1
if (_tempLoop < _numberToMake) then {goto "placeLoop"}
~0.2
[dummyCiv] join grpNull

dummyCiv is the name of a group right?  (It should be: you set _tempGroup = to it in the init piece of code).  In which case I don't know what this line will do.  You may be right but the construct I would use is:
{[_x] join grpNull} forEach units dummyCiv
In any event will this ever result in there being more that 63 groups of civis?


~0.2
group dummyCiv setGroupID ["Alpha","GroupColor1"]
;hint "spawnUnitArray.sqs exiting"
exit

If you try to exceed 12 units per group or 63 groups you will not get a warning, but strange things will happen.

 hey thobson. i loved your abandoned armies mission, it is the main reason i've become interested in scripting : )

 the populations of each town are only 5-20, made of groups of 1-4 people. i'm expecting there to maximum of 3 towns alive at once. i will have to put some effort into creating checks against the limits of the engine. please note this is my first script beyond making the ai appear to launch a flare and making a truck blow up near the enemy.

dummyCiv is the name of a civilian standing on an small island (out of the way). i create the new units in his group to ensure sure their side = civ, even if spawning a "SoldierGMG". is there an easier way without a custom .cpp? _tempGroup refers to the newly created group in the placeLoop :

set _tempGroup to refer to the dummy's Group (Alpha Black)
create several units in _tempGroup
remove dummy from _tempGroup
set dummys group to Alpha Black (ofp automatically assigns a free group name to _tempGroup)

this gives the newly created group the first available name (Bravo Black, etc). i originally used two arrays [alpha,bravo....] and [groupColor1,groupColor2...] to give the new group a random group name, but discovered ofp can rename the group for me. i'm assuming a group needs to have a name??  could the missing civs become lost in this name juggling?

 terox,
   thanks for the info. CoCai sounds like a powerful system. i've also looked into DAC, but couldn't understand the scripts well enough to see how it works. however, i'm doing this to learn about scripting and for my own amusement. i'm a beginner and although what i'm doing has been done far better by someone else, it seems to make more sense to learn the basics myself rather than just pluging in someone else's system.
« Last Edit: 15 Jan 2006, 14:04:33 by ceeb »

Offline THobson

  • OFPEC Patron
  • Former Staff
  • ****
Re:missing men during civilian spawn and cull scripts.
« Reply #4 on: 15 Jan 2006, 14:24:28 »
I am glad you liked my mission, and am pleased it inspired you to do some scripting.

What might also be easy is to have a group of civis on an off shore island and then just setPos them to the relevant twon when the player is near it.

Offline ceeb

  • Members
  • *
  • I'm a llama!
Re:missing men during civilian spawn and cull scripts.
« Reply #5 on: 15 Jan 2006, 15:53:54 »
 that would work, but is too simple. the population arrays i use update if some civs move from town to town, or die, or unfortunately fail to spawn... the long term goal is some kind of insurgancy style mission.

but, back to the problem at hand. the online reference states :
"If you use createUnit to create too many units at once, they may stand frozen in place for a while regardless of commands.  Put a delay between createUnit commands; try ~1 for starters."

i've tested it with ~2 between createUnit loops, and ensured that only one spawnArray runs at once, with no luck. i've also "pre-loaded" one of each of the civilian types. are there any other known circumstances that cause the createUnit command to fail to work?

thanks again, i'm off to bed : )

Offline ceeb

  • Members
  • *
  • I'm a llama!
Re:missing men during civilian spawn and cull scripts.
« Reply #6 on: 16 Jan 2006, 05:29:46 »
 i've solved the problem, spawnArray was trying to create a unit without a type once in every ~14 loops.  i'm surprised it didn't return an error : (

_unitArray select ([_unitArrayCount] call randomPlus) createUnit [_createPos,_tempGroup]

should have been

_unitArray select ([_unitArrayCount - 1] call randomPlus) createUnit [_createPos,_tempGroup]



 cheers : )
« Last Edit: 16 Jan 2006, 05:33:46 by ceeb »