Jump to content
Rydygier

HETMAN - Artificial Leader

Recommended Posts

HAL avoids messing with low-level AI

 

It could be made an optional feature, toggleable by a variable?

 

 

 

 I wonder, If I would be able to grasp and implement anyhow effective self-learning algorithms (currently no idea, how) and some kind of "passive military advisor" module, but such things, if possible, are rather for Hetman 2

 

 

Sounds really very complicated. Perhaps a simpler method as just those two extra types plus the default would be more than enough options for a long long time. At least for me. Whatever you decide to do I wish you good luck in your coding endeavours.

 

 

 

As for each single shot in the salvo spread - IIRC in A3 it's handled by some vanilla, internal calculations and I can't adjust that (I did in A2's Fire At Will, FFE ancestor).

 

Too bad, especially the mortars tend to fire all the rounds within a very small area, wasting the potential of the rounds. And often looking a little silly.

 

 

 

 

Targeting time however is hard to ommit, as it's not just artificial delay, this time is used to calculate real movement vector of the target, the shorter this time, the less accurate prediction, so shortening this targeting delay may have a harsh price. 

 

How fast or often are current know targets given to the mortars to fire upon?

Share this post


Link to post
Share on other sites

Well, known enemies are considered as possible targets (and if accepted, fire missions right away sent to available/free batteries) each HAL's cycle, so at least this delay may be reduced by reducing whole HAL's cycle comm delay:

 

 

RydHQ_CommDelay = 1 - this is the multiplier of the pause between the end of one cycle and the start of a new one for the given Leader. I advise caution with values smaller than 1; the flow of information can possibly be significantly perturbed by low values. Values higher than 1 are for realism fans who would like the delivery of orders to take as much time as it would in reality. 

 

The length of the pause itself:

 

_delay = ((count _friends) * 5) + (round (((10 + (count _friends))/(0.5 + (_HQ getVariable ["RydHQ_Reflex",0.5]))) * (_HQ getVariable ["RydHQ_CommDelay",1])));

 

So for default commDelay and average (0.5) reflex, with 12 groups under control this will give 60 + 22 seconds. Note, commdelay and reflex may affect only the "22" part. "60" is independent, only based on groups count (5 seconds per each). It's IIRC because of added in the one of last versions time spread for displaying the comm messages between Leader issuing orders and subsequent groups, to spread them evenly through the cycle instead of having one, simulatanous series of orders in one second and nothing rest of the time. SOmething like that. Of course this line may be edited (line 1075, HAC_fnc2.sqf)

Share this post


Link to post
Share on other sites

Is there a way to activate HETMAN via trigger?

I'm using the mod version.

 

 

Thank you.

Share this post


Link to post
Share on other sites

Script version - yes. Mod version - no. Mod version starts automatically when scenario is loaded. But after HAL init is started, after sleep equal to RydHQ_Wait (15 seconds by default), before anything else, it also awaits till there's LeaderHQ variable defined. So you can make a workaround for mod version: prepare everything, but do not name intended A side leader as LeaderHQ, but for example LeaderHQX (or anything you like). Then in the trigger's act field: 

 

LeaderHQ = LeaderHQX;

 

If I'm not mistaken, this should do the trick - HAL will run further up to 1 second after activation of the trigger.  

Share this post


Link to post
Share on other sites

Hello Rydygier!

 

Could you explain this commands meaning a bit better?

 

 

//only, if at least 6 groups will be closest to given objective, that objective become a perimeter point

RydHQ_DefendObjectives = 6;

 

Or

 

RydHQ_DefendObjectives = 4 – In “DEFEND†mode this variable controls, how many groups should have already taken objective as closest, to consider it as additional defense perimeter. If set to 0, only Leader’s position is considered as perimeter center/reference point. This variable allows to avoid situations, when alone group or too few of them are defending given perimeter;

 

 

 

And also, what is a defense center?

 

 

And, should this be added to the PDF guide:

 

RydHQ_Taken = [RydHQ_Obj1,RydHQ_Obj2,RydHQ_Obj3,RydHQ_Obj4];//required along with NObj after last updates to make all objectives "taken"

 

Share this post


Link to post
Share on other sites

Defense center - position of the Leader or positions of already taken objectives. RydHQ_Taken as you see with NObj is optional only, it controls, which objectives are considered taken (thus may become a defensive perimeter center), but it's not required for defensive stance to work. 

 

DefendObjectives - when defensive stance is activated, script checks for each of potential defensive centers around taken objectives, for how many groups this center is the closest one. If at least that much, as set with DefendObjectives - defensive perimeter will be set around this center using those groups. Otherwise - center will be not defended, and groups will be used to defend primary center - around the Leader instead. 

Share this post


Link to post
Share on other sites

Is there a way to make captured objectives defense centers regardless if there are troops or not?

Also, is there a way to make leaders position not a defense center?

Also, can reserves be sent closer to last objective without moving the leader ?

Share this post


Link to post
Share on other sites
"Is there a way to make captured objectives defense centers regardless if there are troops or not?"

 

RydHQ_DefendObjectives = 1; is best, you can do here, I think. If no groups near, then nothing changes for that spot, center or not. 

 

"Also, is there a way to make leaders position not a defense center?"

 

Technically no. Can't check right now, but probably the only way is to make all the defending groups closer to one of taken objectives than to the Leader. Or placing the Leader exactly on the one of the taken objectives which makes his center covering with that objective's center. 

 

"Also, can reserves be sent closer to last objective without moving the leader ?"

 

Most likely only via direct HAL's code edition. 

Share this post


Link to post
Share on other sites


23:59:07 Error in expression <["RydHQ_LZ",false]) then {deleteVehicle _lz};

if ((isPlayer (leader _GDV)) and >

23:59:07 Error position: <_lz};

if ((isPlayer (leader _GDV)) and >

23:59:07 Error Undefined variable in expression: _lz

Share this post


Link to post
Share on other sites

Any tips on getting the leaders to move around more? I tried enabling relocation, but they didn't move a muscle for over an hour.

Share this post


Link to post
Share on other sites

Shortly, because it's late: if you wish to make Leader to move somewhere - feel free to make him - assign him a waypoint or use on him some script, that will make him moving. The only thing, HAL should try here is to make Leader go towards lately taken objective, if proper config variable is set (but this should be turned off, if Big Boss mode is applied. BB moves Leaders on its own rules).There's also:

 

Quote

RydHQ_GetHQInside = false –  if true, and Leader’s group relocating is active, HAL will try to find some position inside random enterable building in 100 meters radius around relocation waypoint and will send Leader’s group there. Works only, if there is no vehicle assigned to that group;

 

I didn't tested HAL long time, so till I finally get free mind to review and update it I can only hope, relocating stuff still works. Besides that - indeed, HAL doesn't really touches Leader unit. 

 

But what exactly mean "move around"? Some random movements here and there? If so - why HAL should do this with Leader unit?

Share this post


Link to post
Share on other sites
3 hours ago, Rydygier said:

Shortly, because it's late: if you wish to make Leader to move somewhere - feel free to make him - assign him a waypoint or use on him some script, that will make him moving. The only thing, HAL should try here is to make Leader go towards lately taken objective, if proper config variable is set (but this should be turned off, if Big Boss mode is applied. BB moves Leaders on its own rules).There's also:

 

 

I didn't tested HAL long time, so till I finally get free mind to review and update it I can only hope, relocating stuff still works. Besides that - indeed, HAL doesn't really touches Leader unit. 

 

But what exactly mean "move around"? Some random movements here and there? If so - why HAL should do this with Leader unit?

 

Normally the leaders are used to command squads, giving them the role of the platoon leader. But to help encourage stealth for the player and save performance, I've divided the squads into smaller fireteams, and I'm using the leaders to fill the position of squad leader, who should follow his units. This is also true of platoon leaders, but to a lesser extent. I'll try some follow waypoints, though.

 

As to how well HAL is working these days, I'm having trouble with several of the config variables, BB seems to be completely messed up, and I'm getting a lot of error messages. I hope you get the chance to work on it, because I use it in most of my missions now.

Share this post


Link to post
Share on other sites

Well, each game update may break something, but before you assume, HAL is broken, be sure, all is OK your end, for example run fully vanilla Arma and test, if same errors occur for the provided demo missions. If no - it's pobably a good news, because in such case you likely don't need to wait, till I update the HAL, just review your mission setup. If same errors occur for provided demos - let me know, if you wish to speed up fixing, when I get time for it. In such case specifics are welcome - best, exact RPT logs with mentioned errors. Same, if your bugs occur in the specific circumstancies, that demo mission doesn't reproduce, thus bugs not occur in the demo. RPT logs are very important to determine, what's wrong exactly, othewise I'm searching blindly across the whole code, which is very extensive, complex and I may even miss, what troubles some players, that didn't reported encountered bugs. Also vanilla repro mission is a great help.

 

Also, when you do some fancy stuff with the groups, not sure, how exactly you divide them into fireteams, be advised, HAL anyway thinks in groups, and each is treated as a whole, independent being. Also Leader's group is assumed to be a separate, whole and independent.

 

About moving the Leader - as said, feel free, to make him move, as you wish, just remember, many things in HAL are calculated in relation to current Leader position (treated as HQ position, a heart of the army), so repositioning the Leader may have various impact on how battle is conducted, where some groups are sent etc. 

Share this post


Link to post
Share on other sites

Thank you for producing this fantastic mod. Im working on a mission using the CUP units, does anybody have the RHQ arrays for the CUP mod?

 

Thanks

 

Mack

Share this post


Link to post
Share on other sites

Let me start by saying this is an amazing mod sir.  Paired with a good squad-level AI, this provides an amazingly immersive experience with barely any setup.

 

That said, I feel this could benefit from some expanded documentation.  Specifically, set up custom factions can be confusing in some circumstances.  I've been working on slamming together something for Operation Trebuchet, a halo mod, but ran into trouble with some of the more exotic units.  It definitely helps to know what each class is supposed to be, but maybe expand on how Hetman treats different classes, what it does differently for a group containing a type of unit?

 

Insurrections have a jury rigged "APC," an ugly metal box crudely welded onto a stolen warthog.  And I'm not sure on whether it would be a car or light armored.  The APC is completely unarmed.  It's passengers are well protected, a thick steel box with no windows encasing them.  But the driver and front passenger lack the same protection, no doors or windows, and wide open glass windshield.  I'm running it through trial and error, and you can't be expected to have documentation for every last weird vehicle, so instead knowing what HETMAN does with different classes would be ideal, and we can determine for ourselves if that behavior suits the exotic unit.  Does classing it as light armor assume it is armed and treat it as infantry support after unloading, or does light armor simply tell HETMAN that the passengers are more likely to survive being shot at?  Would light armor conflict with unarmed cargo?  Again, it's not that I'm expecting you to cover every last weird ass situation a class type might encounter, this is just an example.  Just asking for some documentation on how being in different class types modifies HETMAN's decision making.  What does he do with snipers, with cars, with light armor that he doesn't do with any other classtype.  Give us the tools to figure it out ourselves.

 

Thanks for an amazing mod.

  • Like 1

Share this post


Link to post
Share on other sites

OK, fair point. In some free time I'll try to answer in this post in more comprehensive manner, for know just quick info - it's primarily about prioritizing, who Hetman will send against who/with what task. So, if the class of the hostile vehicle was defined as one of armored, Hetman will choose primarily units of classes known for their good anti armor effectiveness to engage it (amongst available). AT infantry, MBT, gunship.... If the mission is to make some recon - best to use units least likely to be spotted by enemy. Etc. Of course there are also unique missions for some specific classes, like fire missions for artillery, transport missions for the cargo or sniper missions. 

Share this post


Link to post
Share on other sites
5 minutes ago, Rydygier said:

OK, fair point. In some free time I'll try to answer in this post in more comprehensive manner, for know just quick info - it's primarily about prioritizing, who Hetman will send against who/with what task. So, if the class of the hostile vehicle was defined as one of armored, Hetman will choose primarily units of classes known for their good anti armor effectiveness. AT infantry, MBT, gunship.... If the mission is to make some recon - best to use units least likely to be spotted by enemy. Etc. Of course there are also unique missions for some specific classes, like fire missions for artillery, transport missions for the cargo or sniper missions. 

Excellent news!  I think I see.  The APC isn't really enough of a threat to warrant being reinforced with AT units, well placed shots can take out the driver before he reaches his destination, and it's unarmed... who knows.  I'll toss it in the cars pile and see what happens.  Half the fun of modding is smashing two different mods together and having them react in hilariously unexpected way, yeah?

Share this post


Link to post
Share on other sites

:) Indeed. 

 

Realized, that answering your question may be more difficult I thougth. Thing is, how exactly unit of given class will behave in given mission is determined by pieces of the code spread across whole script often in not obvious and complex manner (how wide flanking before attack, kind of waypoints assigned, movement manner etc. details). To explain the thing thoroughly I would need basically read and explain to you big part of the Hetman code line by line, where many thing are conditional and many things depends on many other factors. However apart from the info given already in the manual and apart from what's intuitional, here is some data:

 

	switch (_kind) do
		{
		case ("Recon") : 
			{
			_pool = [[_SnipersG,0.5,"SNP"],[_NCrewInfG,0.5,"INF"]]
			};

		case ("ATInf") : 
			{
			_pool = [[_SnipersG,0.5,"SNP"],[_air,2,"AIR"],[_NCrewInfG,0.5,"INF"]]
			};

		case ("Inf") : 
			{
			_pool = [[_LArmorG,1,"ARM"],[_HArmorG,1,"ARM"],[_SnipersG,0.5,"SNP"],[_cars,1,"INF"],[_air,2,"AIR"],[_NCrewInfG,0.5,"INF"]]
			};

		case ("Armor") : 
			{
			_pool = [[_air,2,"AIR"],[_HArmorG,1,"ARM"],[_LArmorATG,1,"ARM"],[_ATInfG,0.5,"INF"]]
			};

		case ("Cars") : 
			{
			_pool = [[_LArmorG,1,"ARM"],[_cars,1,"INF"],[_HArmorG,1,"ARM"],[_air,2,"AIR"],[_NCrewInfG,0.5,"INF"]]
			};

		case ("Art") : 
			{
			_pool = [[_air,2,"AIR"],[_LArmorG,1,"ARM"],[_cars,1,"INF"],[_HArmorG,1,"ARM"],[_NCrewInfG,0.5,"INF"]]
			};

		case ("Air") : 
			{
			_pool = [[_air,2,"AIR"],[_AAInfG,0.5,"INF"]]
			};

		case ("Static") : 
			{
			_pool = [[_air,2,"AIR"],[_LArmorG,1,"ARM"],[_SnipersG,0.5,"SNP"],[_cars,1,"INF"],[_HArmorG,1,"ARM"],[_NCrewInfG,0.5,"INF"]]
			};
		};

 

It's part of "Dispatcher" function. Each "case" tells, what kind of threat was detected. What you have in the "_pool" arrays, is basically priority list - who should be sent against given threat in what order of availability.

 

So for example first - if detected a threat of "recon" kind. First you have: [_SnipersG,0.5,"SNP"]. So at first Hetman checks, if there's available sniper team (a group consisting sniper unit, preferably 1-2 men max). Number is a multiplier of search radius. It's multiplied by 10000 meters (10 km). So in this case, it will pick the group for attack task only, if it's not farther, than 5000 meters from the threat position (cosidered too far to use against given target otherwise). Last value ("SNP") is tactical pattern detrmining details like how many groups of that kind should be sent at max against hostile group, if terrain at the target position is friendly enough for that unit, presence of what known enemy at the expected route should make Hetman reconsider sending someone else instead (eg aerial unit may not be sent after all, if AA weaponry presence is known at the route, but it's fuzzy logic, statistical, not deterministic, depending on Leader's presonality (tendency to take risks in this case, it's day or night, overcast value etc.)). 

 

So, anyway, what that tells you? It tells, against groups (consisting units of given kind), that you categorized as "recon", Hetman will consider as most effective in the first place groups, you categorized as snipers. Have that in mind during categorization. And so forth. Second in anti-recon array is "_NCrewInfG" - that states for general, any non-crew infantry. 

 

An obvious assumption: a group is able to engage given opponent, means it is equipped qith proper weaponry/armament. In case of unarmed units/vehicles, put them in the one of "NC" RHQ categories, if fits, or just take groups consisiting such vehicles into RydHQ_NoAttack or RydHQ_CargoOnly or whatever special array you see fit best. If not, and if you, for example, put unarmed unit into "snipers" RHQ, that unarmed unit may be sent against recon threat. 

 

As said - in general it's intuitive. So snipers means easy-to-hide long range good accuracy anti personnel troops preferably with good spotting capability. Recon - hard to detect units with good spotting capability. Cars - vehicles of no noticeable armor capability (say, vulnerable below 0.5 cal). Cargo - vehicles able to carry some passengers. Statics - vehicles unable to move. Arty - vehicles able to perform non-direct long range fire missions using Arma's own artillery engine/handler - compatibile with it, if it actually should perform such missions, not just be treated as able to do so... OR to be precise, any units, you would like to be treated as such. Still, with mentioned in the manual exceptions, better to avoid categorizing foot mobiles as vehicles and vice versa. 

 

Any doubts - ask. :)

Share this post


Link to post
Share on other sites
On ‎1‎/‎29‎/‎2017 at 8:51 PM, Mack. said:

Thank you for producing this fantastic mod. Im working on a mission using the CUP units, does anybody have the RHQ arrays for the CUP mod?

 

Thanks

 

Mack

I go through and create personal unit mods like a kid and candy. So I created this little script I've been using on personal missions. Maybe it will be useful to you and others. I put this in my init.sqf of any mission I'm playing or just goofing around with. So rather than going through and finding all the classes or a post with classes I wrote this to go into any HAL type mission I like playing through with different mods loaded. Hope this helps
 

Spoiler




_cfgVehicles = configfile >> "cfgvehicles";
_cfgfactions = configfile >> "CfgFactionClasses";

RYD_WS_Inf_class = [];
RYD_WS_recon_class = [];
RYD_WS_FO_class = [];
RYD_WS_snipers_class = [];
RYD_WS_ATinf_class = [];
RYD_WS_AAinf_class = [];
RYD_WS_Art_class = [];
RYD_WS_HArmor_class = [];
RYD_WS_MArmor_class = [];
RYD_WS_LArmor_class = [];
RYD_WS_LArmorAT_class = [];
RYD_WS_Cars_class = [];
RYD_WS_Cargo_class = [];
RYD_WS_NCCargo_class = [];
RYD_WS_Crew_class = [];
RYD_WS_rep = [];
RYD_WS_med = [];
RYD_WS_fuel = [];
RYD_WS_ammo = [];
RYD_WS_Other_class = [];
RYD_WS_Support_class = [];
RYD_WS_Air_class = [];
RYD_WS_BAir_class = [];
RYD_WS_RAir_class = [];
RYD_WS_Naval_class = [];
RYD_WS_Static_class = [];
RYD_WS_StaticAA_class = [];
RYD_WS_StaticAT_class = [];
for "_c" from 0 to (count _cfgVehicles - 1) do {
	_current = _cfgVehicles select _c;
	if (isClass _current) then {
		_currentClass = configname _current;
		//hint str [_currentClass,_current]; sleep 1;
		if ((getNumber (_current >> 'scope') >= 1) && (getNumber (_current >> 'side') != 3) && _currentClass isKindOf "Man") then {
			//hint str (getNumber (_current >> 'camouflage')); sleep .03; getText (_current >> 'vehicleClass') in ['men','Men','infantry',"Man"]
			RYD_WS_Inf_class pushBack _currentClass;
			if ((getText (_current >> 'DisplayName')) find 'Crew' >= 0 ||
					(getText (_current >> 'DisplayName')) find 'Pilot' >= 0 ) then {
				RYD_WS_Crew_class pushBack _currentClass;
			};
			if ((getText (_current >> 'editorSubcategory') in ["EdSubcat_Personnel_SpecialForces"]) &&
					((getText (_current >> 'DisplayName')) find 'Diver' == -1)) then { //getText (_currentClass >> 'vehicleClass') (_currentClass isKindOf "MenSniper" || _currentClass isKindOf "MenRecon")
				RYD_WS_recon_class pushBack _currentClass;
			};
			if ((getText (_current >> 'DisplayName')) find 'Officer' >= 0 ||
					(getText (_current >> 'DisplayName')) find 'Commmander' >= 0 ||
						(getText (_current >> 'DisplayName')) find 'General' >= 0 ||
							(getText (_current >> 'DisplayName')) find 'Colonel' >= 0 ||
								(getText (_current >> 'DisplayName')) find 'Major' >= 0 ||
									(getText (_current >> 'DisplayName')) find 'Captain' >= 0 ||
										(getText (_current >> 'DisplayName')) find 'Lieutenant' >= 0 ||
											(getText (_current >> 'DisplayName')) find 'Squad Leader' >= 0 ||
												(getText (_current >> 'DisplayName')) find 'Sargeant' >= 0 ||
													(getText (_current >> 'DisplayName')) find 'Sergeant' >= 0 ||
														(getText (_current >> 'DisplayName')) find 'Team Leader' >= 0 ||
															(getText (_current >> 'DisplayName')) find 'Watcher' >= 0 ||
																(getText (_current >> 'DisplayName')) find 'Corporal' >= 0 ||
																	(getText (_current >> 'DisplayName')) find 'JTAC' >= 0) then {
				RYD_WS_FO_class pushBack _currentClass;
			};
			if ((getText (_current >> 'DisplayName')) find 'Marksman' >= 0 ||
					(getText (_current >> 'DisplayName')) find 'Sharpshooter' >= 0 ||
						(getText (_current >> 'DisplayName')) find 'Sniper' >= 0 ) then {
				RYD_WS_snipers_class pushBack _currentClass;
			};
			if (((getText (_current >> 'DisplayName')) find 'AT' >= 0||
					(getText (_current >> 'DisplayName')) find 'Javelin' >= 0 ||
						(getText (_current >> 'DisplayName')) find 'RPG' >= 0 ||
							(getText (_current >> 'DisplayName')) find 'RShG' >= 0 ||
								(getText (_current >> 'DisplayName')) find 'Hireling' >= 0 ||
									(getText (_current >> 'DisplayName')) find 'Tow' >= 0) &&
										((getText (_current >> 'DisplayName')) find 'Asst' == -1)) then {
				RYD_WS_ATinf_class pushBack _currentClass;
			};
			if ((getText (_current >> 'DisplayName')) find 'AA' >= 0 && (getText (_current >> 'DisplayName')) find 'Asst' == -1) then {
				RYD_WS_AAinf_class pushBack _currentClass;
			};
		};
		if ((getNumber (_current >> 'scope') > 1) && (getNumber (_current >> 'side') != 3) && _currentClass isKindOf "LandVehicle") then {
			_bbuarty = [(configfile >> "CfgVehicles" >> _currentClass),"availableForSupportTypes",0] call BIS_fnc_returnConfigEntry;
			if (_bbuarty find  "Artillery" > -1) then {
				RYD_WS_Art_class pushBack _currentClass;
			};
			if (getNumber (_current >> 'armor') >= 600 && !(_currentClass in RYD_WS_Art_class)) then {
				RYD_WS_HArmor_class pushBack _currentClass;
			};
			if (getNumber (_current >> 'armor') >= 300 && getNumber (_current >> 'armor') < 600 && !(_currentClass in RYD_WS_Art_class)) then {
				RYD_WS_MArmor_class pushBack _currentClass;
			};
			if (getNumber (_current >> 'armor') > 200 && getNumber (_current >> 'armor') < 300 && !(_currentClass in RYD_WS_Art_class)) then {
				RYD_WS_LArmor_class pushBack _currentClass;
			};
			if (getNumber (_current >> 'armor') < 600 && _currentClass find 'cannon' >= 0 && !(_currentClass in RYD_WS_Art_class)) then {
				RYD_WS_LArmorAT_class pushBack _currentClass;
			};
			if (getNumber (_current >> 'armor') > 70 && getNumber (_current >> 'armor') <= 200 && !(_currentClass in RYD_WS_Art_class)) then {
				RYD_WS_Cars_class pushBack _currentClass;
			};
		};
		if ((getNumber (_current >> 'scope') > 1) && (getNumber (_current >> 'side') != 3) && _currentClass isKindOf "Air") then {
			RYD_WS_Air_class pushBack _currentClass;
			if (((getText (_current >> 'DisplayName')) find 'CAS' >= 0 ||
					(getText (_current >> 'DisplayName')) find 'Armed' >= 0 ||
						_currentClass find 'Attack' >= 0 ||
							_currentClass find 'AA' >= 0 ||
								_currentClass find 'armed' >= 0) && _currentClass find 'unarmed' == -1) then {
				RYD_WS_BAir_class pushBack _currentClass;
			};
			if (_currentClass find 'UAV' >= 0 && _currentClass find 'CAS' == -1 && !(_currentClass in RYD_WS_BAir_class)) then {
				RYD_WS_RAir_class pushBack _currentClass;
			};
		};
		if ((getNumber (_current >> 'scope') > 1) && (getNumber (_current >> 'side') <= 2) && _currentClass isKindOf "StaticWeapon") then {
			RYD_WS_Static_class pushBack _currentClass;
			if (_currentClass find 'AA' >= 0) then {
				RYD_WS_StaticAA_class pushBack _currentClass;
			};
			if (_currentClass find 'AT' >= 0) then {
				RYD_WS_StaticAT_class pushBack _currentClass;
			};
		};
		if ((getNumber (_current >> 'scope') > 1) && (getNumber (_current >> 'side') <= 2) && _currentClass isKindOf "Ship") then {
			RYD_WS_Naval_class pushBack _currentClass;
		};
		if ((getNumber (_current >> 'scope') > 1) && getNumber (_current >> 'transportSoldier') >= 2 && !(_currentClass in RYD_WS_Art_class)) then {
			RYD_WS_Cargo_class pushBack _currentClass;
			RYD_WS_NCCargo_class pushBack _currentClass;
		};
		if (((getText (_current >> 'DisplayName')) find 'repair' >= 0 ) || ((getText (_current >> 'DisplayName')) find 'Repair' >= 0 )) then {
			RYD_WS_rep pushBack _currentClass;
		};
		if (((getNumber (_current >> 'scope') > 1) && (getNumber (_current >> 'side') != 3)) &&
				(((getText (_current >> 'DisplayName')) find 'Medical' >= 0 ) ||
					((getText (_current >> 'DisplayName')) find 'Medevac' >= 0)) &&
						((_currentClass isKindOf "LandVehicle") || (_currentClass isKindOf "Air"))) then {
			RYD_WS_med pushBack _currentClass;
		};
		if (((getNumber (_current >> 'scope') > 1) && (getNumber (_current >> 'side') != 3)) &&
				(((getText (_current >> 'DisplayName')) find 'fuel' >= 0 ) ||
				 	((getText (_current >> 'DisplayName')) find 'Fuel' >= 0 )) &&
						((_currentClass isKindOf "LandVehicle") || (_currentClass isKindOf "Air"))) then {
			RYD_WS_fuel pushBack _currentClass;
		};
		if (((getNumber (_current >> 'scope') > 1) && (getNumber (_current >> 'side') != 3)) &&
				(((getText (_current >> 'DisplayName')) find 'Ammo' >= 0 ) ||
				 	((getText (_current >> 'DisplayName')) find 'ammo' >= 0 )) &&
						((_currentClass isKindOf "LandVehicle") || (_currentClass isKindOf "Air"))) then {
			RYD_WS_ammo pushBack _currentClass;
		};
		if (((getNumber (_current >> 'scope') > 1) && (getNumber (_current >> 'side') != 3)) &&
				(((getText (_current >> 'DisplayName')) find 'Ammo' >= 0 ) ||
					 ((getText (_current >> 'DisplayName')) find 'fuel' >= 0 ) ||
					 	((getText (_current >> 'DisplayName')) find 'Fuel' >= 0 ) ||
						 	((getText (_current >> 'DisplayName')) find 'Medical' >= 0 ) ||
								((getText (_current >> 'DisplayName')) find 'Medevac' >= 0) ||
									 	((getText (_current >> 'DisplayName')) find 'ammo' >= 0 )) &&
											((_currentClass isKindOf "LandVehicle") || (_currentClass isKindOf "Air"))) then {
			RYD_WS_Support_class pushBack _currentClass;
		};


	};

};
RYD_WS_NCAir_class = RYD_WS_Air_class - RYD_WS_BAir_class;

RYD_WS_AllClasses = RYD_WS_Inf_class + RYD_WS_Art_class + RYD_WS_HArmor_class + RYD_WS_MArmor_class + RYD_WS_LArmor_class + RYD_WS_Cars_class + RYD_WS_Air_class + RYD_WS_Naval_class + RYD_WS_Static_class + RYD_WS_Support_class + RYD_WS_Other_class;

 

 

  • Like 1

Share this post


Link to post
Share on other sites

That's cool, in fact, Hetman even includes similar auto-categorize code, just likely will differ in some conditions. Still, for units with exotic configs (SF stuff likely may be such kind) it may produce not always desired outcome. If not - RHQ arrays filled by hand are the backup. Then this:

 

RydHQ_RHQAutoFill = true – shared by all Leaders. Switch for automatic RHQ set construction based on units’ config. May be used instead or together with manual RHQ setting. May be not 100% reliable for units configured in exotic way;

 

Should be rather disabled. 

 

For reference/comparison:

 

Spoiler

RYD_PresentRHQ = 
	{
	private ["_allVehs","_allUnits","_vehClass","_wpClass","_magClass","_ammoClass","_addedU","_addedV","_veh","_vehClass2","_weapons","_hasLaserD","_wpClass2","_type","_mags",
	"_isDriver","_turrets","_mainT","_isArmed","_isAA","_isAT","_weaps","_trt","_wps","_wp","_muzzles","_ammo","_ammoC","_dam","_isCargo"];
	
	RYD_WS_AllClasses = RYD_WS_Inf_class + RYD_WS_Art_class + RYD_WS_HArmor_class + RYD_WS_MArmor_class + RYD_WS_LArmor_class + RYD_WS_Cars_class + RYD_WS_Air_class + RYD_WS_Naval_class + RYD_WS_Static_class + RYD_WS_Support_class + RYD_WS_Other_class;
	//RYD_WS_AllClasses = [];
		
	_allVehs = [];
	
		{
		if ((side _x) in [west,east,resistance]) then
			{
			_vh = toLower (typeOf _x);
			if not (_vh in RYD_WS_AllClasses) then
				{
				RYD_WS_AllClasses pushBack _vh;
				_allVehs pushBack _x
				}
			}
		}
	foreach vehicles;	
	
	_allUnits = [];
	
		{
		if ((side _x) in [west,east,resistance]) then
			{
			_vh = toLower (typeOf _x);
			if not (_vh in RYD_WS_AllClasses) then
				{
				RYD_WS_AllClasses pushBack _vh;
				_allUnits pushBack _x
				}
			}
		}
	foreach allUnits;
	
	_vehClass = configFile >> "CfgVehicles";
	_wpClass = configFile >> "CfgWeapons";
	_magClass = configFile >> "CfgMagazines";
	_ammoClass = configFile >> "CfgAmmo";
	
	_addedU = [];
	_addedV = [];
	
		{
		_veh = toLower (typeOf _x);
		if not (_veh in _addedU) then
			{
			_addedU pushBack _veh;
			RHQ_Inf pushBack _veh;
			
			_vehClass2 = _vehClass >> _veh;

			if ((getNumber (_vehClass2 >> "camouflage")) < 1) then
				{				
				if ((toLower (getText (_vehClass2 >> "textSingular"))) isEqualTo "sniper") then
					{
					RHQ_Snipers pushBack _veh
					}
				else
					{
					_weapons = getArray (_vehClass2 >> "weapons");
					
					RHQ_Recon pushBack _veh;
					
					_hasLaserD = false;
					
						{
						_wpClass = configFile >> "CfgWeapons" >> _x;
						_type = getNumber (_wpClass >> "type");
						
						if (_type == 4096) then
							{
							_cursor = toLower (getText (_wpClass >> "cursor"));
							if (_cursor in ["","emptycursor"]) then 
								{
								_cursor = toLower (getText (_wpClass >> "cursorAim"))
								};

							if (_cursor isEqualTo "laserdesignator") exitWith {_hasLaserD = true}
							};
							
						if (_hasLaserD) exitWith {}
						}
					foreach _weapons;
					
					if (_hasLaserD) then
						{
						RHQ_FO pushBack _veh
						}					
					}
				};
			
			_wps = getArray (_vehClass2 >> "Weapons");

			if ((count _wps) > 1) then
				{
				_isAT = false;
				_isAA = false;
				
					{
					_sWeapon = _x;
					_mgs = configfile >> "CfgWeapons" >> _sWeapon >> "magazines";
					if (isArray _mgs) then
						{
						_mgs = getArray _mgs;

						if ((count _mgs) > 0) then
							{
							_mag = _mgs select 0;
							_ammo = getText (configfile >> "CfgMagazines" >> _mag >> "ammo");
							_ammoC = configfile >> "CfgAmmo" >> _ammo;
							
							_isAA = ((getNumber (_ammoC >> "airLock")) > 1) or {((getNumber (_ammoC >> "airLock")) > 0) and {((getNumber (_ammoC >> "irLock")) > 0)}};
							
							if not (_isAA) then
								{
								_isAT = ((((getNumber (_ammoC >> "irLock")) + (getNumber (_ammoC >> "laserLock"))) > 0) and {((getNumber (_ammoC >> "airLock")) < 2)})
								};
							
							if (not (_isAT) and {not (_isAA)}) then
								{
								
									{
									_ammo = getText (configfile >> "CfgMagazines" >> _x >> "ammo");
									_ammoC = configfile >> "CfgAmmo" >> _ammo;
									_actHit = getNumber (_ammoC >> "hit");

									if (_actHit > 150) exitWith {_isAT = true}
									}
								foreach _mgs
								};
							
							if (_isAT) then 
								{
								RHQ_ATInf pushBack _veh
								};
								
							if (_isAA) then  
								{
								RHQ_AAInf pushBack _veh
								};
							}
						};
						
					if ((_isAT) or {(_isAA)}) exitWith {}
					}
				foreach _wps
				}
			}	
		}
	foreach _allUnits;

	_flareMags = ["Laserbatteries","60Rnd_CMFlareMagazine","120Rnd_CMFlareMagazine","240Rnd_CMFlareMagazine","60Rnd_CMFlare_Chaff_Magazine","120Rnd_CMFlare_Chaff_Magazine","240Rnd_CMFlare_Chaff_Magazine","192Rnd_CMFlare_Chaff_Magazine","168Rnd_CMFlare_Chaff_Magazine","300Rnd_CMFlare_Chaff_Magazine"];
	
		{
		_veh = toLower (typeOf _x);
		_vehO = _x;
		if not (_veh in _addedV) then
			{
			_addedV pushBack _veh;
			
			_vehClass2 = _vehClass >> _veh;

			_isDriver = (getNumber (_vehClass2 >> "hasDriver")) > 0;

			_turrets = _vehClass2 >> "Turrets";
			_cT = count _turrets;
			_tMags = [];
			
			if (_cT > 0) then
				{
				for "_i" from 0 to (_cT - 1) do 
					{
					_trt = _turrets select _i;
					if (isClass _trt) then
						{
						_trt = configName _trt;
						_mgT = _vehClass2 >> "Turrets" >> _trt >> "magazines";
						if (isArray _mgT) then
							{
							_tMags = _tMags + (getArray _mgT)
							}
						}
					}
				};

			_mainT = _turrets >> "MainTurret";
			_isMainT = isClass _mainT;
			
			_isAmmoS = (getNumber (_vehClass2 >> "transportAmmo")) > 0;
			_isFuelS = (getNumber (_vehClass2 >> "transportFuel")) > 0;
			_isRepS = (getNumber (_vehClass2 >> "transportRepair")) > 0;
			_isMedS = (getNumber (_vehClass2 >> "attendant")) > 0;
			_mags = getArray (_vehClass2 >> "magazines") + _tMags;			
			_isArmed = (count (_mags - _flareMags)) > 0;
			_isCargo = ((getNumber (_vehClass2 >> "transportSoldier")) > 0) and {((getNumber (_vehClass2 >> "transportAmmo")) + (getNumber (_vehClass2 >> "transportFuel")) + (getNumber (_vehClass2 >> "transportRepair")) + (getNumber (_vehClass2 >> "attendant"))) < 1};
			_isArty = (getNumber (_vehClass2 >> "artilleryScanner")) > 0;
						
			_type = "inf";

			_base = _veh;
			
			while {not (_base in ["air","ship","tank","car","wheeled_apc_f","ugv_01_base_f"])} do
				{
				_base = inheritsFrom (_vehClass >> _base);
				if not (isClass _base) exitWith {};
				_base = toLower (configName _base);
				if (_base in ["allvehicles","all"]) exitWith {};
				};			
			
			if not (_base isEqualTo "ugv_01_base_f") then
				{
				if (_base in ["air","ship","tank","car","wheeled_apc_f"]) then
					{
					_type = _base
					};
				};
				
			if (_isArty) then
				{
				RHQ_Art pushBack _veh;
				
				_prim = "";
				_rare = "";
				_sec = "";
				_smoke = "";
				_illum = "";

				if (_isArmed) then
					{
					_mags = magazines _vehO;
					
					if (_isMainT) then
						{
						_mags = _mags + ((getArray (_mainT >> "magazines")) - _mags)
						};
						
					_maxHit = 10;
					
						{
						_ammo = getText (configfile >> "CfgMagazines" >> _x >> "ammo");
						_ammoC = configfile >> "CfgAmmo" >> _ammo;
						
						_actHit = getNumber (_ammoC >> "indirectHitRange");
						_subM = toLower (getText (_ammoC >> "submunitionAmmo"));
												
						if (_actHit <= 10) then
							{
							if not (_subM isEqualTo "") then
								{
								_ammoC = configfile >> "CfgAmmo" >> _subM;
								_actHit = getNumber (_ammoC >> "indirectHitRange")
								}
							};
						
						if ((_actHit > _maxHit) and {_actHit < 100}) then
							{
							_maxHit = _actHit;
							_prim = _x
							}
						}
					foreach _mags;
					
					_mags = _mags - [_prim];
					_mags0 = +_mags;
					_illumChosen = false;
					_smokeChosen = false;
					_rareChosen = false;
					_secChosen = false;
					
						{
						_ammo = getText (configfile >> "CfgMagazines" >> _x >> "ammo");
						_ammoC = configfile >> "CfgAmmo" >> _ammo;
						
						_hit = getNumber (_ammoC >> "indirectHit");
						_lc = _ammoC >> "lightColor";
						_sim = toLower (getText (_ammoC >> "simulation"));
						_subM = toLower (getText (_ammoC >> "submunitionAmmo"));
						
						if (_hit <= 10) then
							{
							if not (_subM isEqualTo "") then
								{
								_ammoC = configfile >> "CfgAmmo" >> _subM;
								_hit = getNumber (_ammoC >> "indirectHit")
								}
							};

						switch (true) do
							{
							case ((isArray _lc) and {not (_illumChosen)}) : 
								{
								_illum = _x;
								_mags = _mags - [_x];
								_illumChosen = true
								};
								
							case ((_hit <= 10) and {(_subM isEqualTo "smokeshellarty") and {not (_smokeChosen)}}) : 
								{
								_smoke = _x;
								_mags = _mags - [_x];
								_smokeChosen = true
								};
								
							case ((_sim isEqualTo "shotsubmunitions") and {not (_rareChosen)}) : 
								{
								_rare = _x;
								_mags = _mags - [_x];
								_rareChosen = true
								};
								
							case ((_hit > 10) and {not ((_secChosen) or {(_rare == _x)})})  : 
								{
								_sec = _x;
								_mags = _mags - [_x];
								_secChosen = true
								}
							}
						}
					foreach _mags0;
					
					if (_sec isEqualTo "") then
						{
						_maxHit = 10;
						
							{
							_ammo = getText (configfile >> "CfgMagazines" >> _x >> "ammo");
							_ammoC = configfile >> "CfgAmmo" >> _ammo;
							_subAmmo = _ammoC >> "subMunitionAmmo";
							
							if not (_subAmmo isEqualTo "") then
								{
								_ammoC = configfile >> "CfgAmmo" >> _subAmmo
								};
								
							_actHit = getNumber (_ammoC >> "indirectHit");
							
							if (_actHit > _maxHit) then
								{
								_maxHit = _actHit;
								_sec = _x
								}
							}
						foreach _mags;
						}
					};
					
				_arr = [_prim,_rare,_sec,_smoke,_illum];
				if (({_x isEqualTo ""} count _arr) < 5) then
					{
					RydHQ_Add_OtherArty pushBack [[_veh],_arr]
					}
				};
			
			if (_isDriver) then
				{
				switch (_type) do
					{
					case ("car") : {RHQ_Cars pushBack _veh};	
					case ("tank") : {RHQ_HArmor pushBack _veh};	
					case ("wheeled_apc_f") : {RHQ_LArmor pushBack _veh};
					case ("air") : 
						{
						RHQ_Air pushBack _veh;

						if not (_isArmed) then
							{
							RHQ_NCAir pushBack _veh;
							};
							
						_isUAV = (getNumber (_vehClass2 >> "Uav")) > 0;
						
						if not (_isUAV) then
							{
							_isUAV = (toLower (getText (_vehClass2 >> "crew"))) in ["b_uav_ai","i_uav_ai","o_uav_ai"];
							};
							
						if (_isUAV) then
							{
							RHQ_RAir pushBack _veh
							}
						};
						
					case ("ship") : {RHQ_Naval pushBack _veh};			
					};
					
				if (_isCargo) then 
					{
					RHQ_Cargo pushBack _veh;
					if not (_isArmed) then
						{
						RHQ_NCCargo pushBack _veh;
						}
					};
										
				RHQ_HArmor = RHQ_HArmor - RHQ_Art;
				
				if (_isArmed) then
					{
					_mags = magazines _vehO;
					
					if (_isMainT) then
						{
						_mags = _mags + ((getArray (_mainT >> "magazines")) - _mags)
						};
					
						{
						_ammo = getText (configfile >> "CfgMagazines" >> _x >> "ammo");
						_ammoC = configfile >> "CfgAmmo" >> _ammo;
						
						_isAA = (getNumber (_ammoC >> "airLock")) > 1;
						_isAT = ((((getNumber (_ammoC >> "irLock")) + (getNumber (_ammoC >> "laserLock"))) > 0) and {((getNumber (_ammoC >> "airLock")) < 2)});
						
						if ((_isAA) and {not (_type isEqualTo "air")}) then {RHQ_AAInf pushBack _veh};
						if (_isAT) then 
							{
							if (_type isEqualTo "wheeled_apc_f") then
								{
								RHQ_LArmorAT pushBack _veh
								}
							else
								{
								if (_type isEqualTo "car") then
									{
									RHQ_ATInf pushBack _veh
									}
								}
							};
							
						if ((_isAA) or {(_isAT)}) exitWith {}
						}
					foreach _mags
					}
				}
			else
				{
				if (_isArmed) then
					{
					RHQ_Static pushBack _veh;
					
					_mags = magazines _vehO;
					
					if (_isMainT) then
						{
						_mags = _mags + ((getArray (_mainT >> "magazines")) - _mags)
						};
					
						{
						_ammo = getText (configfile >> "CfgMagazines" >> _x >> "ammo");
						_ammoC = configfile >> "CfgAmmo" >> _ammo;
						
						_isAA = (getNumber (_ammoC >> "airLock")) > 1;
						_isAT = ((((getNumber (_ammoC >> "irLock")) + (getNumber (_ammoC >> "laserLock"))) > 0) and {((getNumber (_ammoC >> "airLock")) < 2)});
						
						if (_isAA) then {RHQ_StaticAA pushBack _veh};
						if (_isAT) then {RHQ_StaticAT pushBack _veh};
							
						if ((_isAA) or {(_isAT)}) exitWith {}
						}
					foreach _mags
					}
				};
				
			if (_isAmmoS) then 
				{
				if not (_veh in RHQ_Ammo) then
					{
					RHQ_Ammo pushBack _veh
					};				

				if not (_veh in RHQ_Support) then
					{
					RHQ_Support pushBack _veh
					}
				};
				
			if (_isFuelS) then 
				{				
				if not (_veh in RHQ_Fuel) then
					{
					RHQ_Fuel pushBack _veh
					};					
				
				if not (_veh in RHQ_Support) then
					{
					RHQ_Support pushBack _veh
					}
				};
				
			if (_isRepS) then 
				{				
				if not (_veh in RHQ_Rep) then
					{
					RHQ_Rep pushBack _veh
					};					
				
				if not (_veh in RHQ_Support) then
					{
					RHQ_Support pushBack _veh
					}
				};
				
			if (_isMedS) then 
				{				
				if not (_veh in RHQ_Med) then
					{
					RHQ_Med pushBack _veh
					};	
				
				if not (_veh in RHQ_Support) then
					{
					RHQ_Support pushBack _veh
					}
				};
				
			if (_type in ["air","tank","wheeled_apc_f"]) then
				{
				_crew = _vehClass >> _veh >> "crew";
				
				if (isText _crew) then
					{
					_crew = toLower (getText _crew);

					if not (_crew in (RYD_WS_Crew_class + RHQ_Crew)) then
						{
						RHQ_Crew pushBack _crew;
						}
					}
				}
			};			
		}
	foreach _allVehs;
	
	RHQ_Inf = RHQ_Inf - ["b_uav_ai","i_uav_ai","o_uav_ai"];
	RHQ_Crew = RHQ_Crew - ["b_uav_ai","i_uav_ai","o_uav_ai"];
	
	true
	};

 

 

  • Like 2

Share this post


Link to post
Share on other sites

Cool beans didn't notice the auto file feature. lol Guess I got to busy learning the config commands I didn't look hard enough. Thanks. :)

Share this post


Link to post
Share on other sites

Thanks mikey74 and Rydygier.

 

The auto filler works quite well however some units are behaving strangely (artillery and some helicopters) I'm guessing due to the configs.

 

I have previously written simple scripts however my scripting knowledge is very basic hence my enthusiasm for HETMAN as I only have to place units, a few triggers and tweak some variables to make a complete dynamic war.

 

With regards to the autofilers above ( both mikey74's and Rydygier's) is it possible to output the contents of the arrays for the autofilled units to a text file?

 

That way the RHQ arrays are automatically built and I can see exactly how HETMAN is seeing the units and simply correct any misfiled units.

 

I hope the above makes sense and thanks again.

 

 

Mack

 

 

Share this post


Link to post
Share on other sites

Thanks for the info, it will definitely come in handy.  Configuring some units has been a pain.  If you get a chance, do you think you could update the online manual with some of this?  The one on Google Drive?  Keep it somewhere easy to find instead of buried in a forum, yeah?  Also, I have a faint idea of what Forward Observers are supposed to be, but just to check, are they supposed to be spotters for artillery of some sort, or are they spotters for snipers?  OPTRE pairs snipers with a single forward observer in it's groups, so I'm not sure.

 

If you don't mind me suggesting, might I recommend a new class for heavily armored aircraft?  I ask because of OPTRE's pelicans, they can and will soak up several shots from AA rockets before failing, and the passengers will likely said shots.  I wouldn't ask just for one unique unit, but I've also heard several Russian made helicopters have similar reputations for resisting AA fire, and it'd be interesting to see what HETMAN would do if it knew an armed cargo helicopter could afford to take a few hits from rockets.

Share this post


Link to post
Share on other sites

Well, there is this:

 

RydHQ_RHQCheck = false – common to all Leaders. If set as true, at HAL init will be displayed report about class names of any combat unit on map, that are not included in the RHQ set (see 7.1). More detailed report will be saved in RPT file;

 

It's not exactly, what you want, but the code run here is this:

 

Spoiler

RYD_RHQCheck = 
	{
	private ["_type","_noInTotal","_noInAdditional","_noInBasic","_civF","_total","_basicrhq","_Additionalrhq","_Inf","_Art","_HArmor","_LArmor","_Cars","_Air","_Naval","_Static","_Other","_specFor",
		"_recon","_FO","_snipers","_ATInf","_AAInf","_LArmorAT","_NCAir","_StaticAA","_StaticAT","_Cargo","_NCCargo","_Crew","_MArmor","_BAir","_RAir","_ammo","_fuel","_med","_rep"];

	_specFor = RHQ_SpecFor + RYD_WS_specFor_class - RHQs_SpecFor;

	_recon = RHQ_Recon + RYD_WS_recon_class - RHQs_Recon;
		
	_FO = RHQ_FO + RYD_WS_FO_class - RHQs_FO;
		
	_snipers = RHQ_Snipers + RYD_WS_snipers_class - RHQs_Snipers;
		
	_ATinf = RHQ_ATInf + RYD_WS_ATinf_class - RHQs_ATInf;
		
	_AAinf = RHQ_AAInf + RYD_WS_AAinf_class - RHQs_AAInf;

	_Inf = RHQ_Inf + RYD_WS_Inf_class - RHQs_Inf;
		
	_Art = RHQ_Art + RYD_WS_Art_class - RHQs_Art;
		
	_HArmor = RHQ_HArmor + RYD_WS_HArmor_class - RHQs_HArmor;
		
	_MArmor = RHQ_MArmor + RYD_WS_MArmor_class - RHQs_MArmor;

	_LArmor = RHQ_LArmor + RYD_WS_LArmor_class - RHQs_LArmor;
		
	_LArmorAT = RHQ_LArmorAT + RYD_WS_LArmorAT_class - RHQs_LArmorAT;

	_Cars = RHQ_Cars + RYD_WS_Cars_class - RHQs_Cars;
		
	_Air = RHQ_Air + RYD_WS_Air_class - RHQs_Air;
		
	_BAir = RHQ_BAir + RYD_WS_BAir_class - RHQs_BAir;
		
	_RAir = RHQ_RAir + RYD_WS_RAir_class - RHQs_RAir;
		
	_NCAir = RHQ_NCAir + RYD_WS_NCAir_class - RHQs_NCAir;

	_Naval = RHQ_Naval + RYD_WS_Naval_class - RHQs_Naval;

	_Static = RHQ_Static + RYD_WS_Static_class - RHQs_Static;
		
	_StaticAA = RHQ_StaticAA + RYD_WS_StaticAA_class - RHQs_StaticAA;
		
	_StaticAT = RHQ_StaticAT + RYD_WS_StaticAT_class - RHQs_StaticAT;
		
	_Support = RHQ_Support + RYD_WS_Support_class - RHQs_Support;
		
	_Cargo = RHQ_Cargo + RYD_WS_Cargo_class - RHQs_Cargo;
		
	_NCCargo = RHQ_NCCargo + RYD_WS_NCCargo_class - RHQs_NCCargo;
		
	_Crew = RHQ_Crew + RYD_WS_Crew_class - RHQs_Crew;
		
	_Other = RHQ_Other + RYD_WS_Other_class;

	_ammo = RHQ_Ammo + RYD_WS_ammo - RHQs_Ammo;

	_fuel = RHQ_Fuel + RYD_WS_fuel - RHQs_Fuel;

	_med = RHQ_Med + RYD_WS_med - RHQs_Med;

	_rep = RHQ_Rep + RYD_WS_rep - RHQs_Rep;
		
	_civF = ["CIV_F","CIV","CIV_RU","BIS_TK_CIV","BIS_CIV_special"];

	_basicrhq = _Inf + _Art + _HArmor + _LArmor + _Cars + _Air + _Naval + _Static;

	_Additionalrhq = _Other + _specFor + _recon + _FO + _snipers + _ATInf + _AAInf + _LArmorAT + _NCAir + _StaticAA + _StaticAT + _Cargo + _NCCargo + _Crew + _MArmor + _BAir + _RAir + _ammo + _fuel + _med + _rep;

	_total = _basicrhq + _Additionalrhq;

	_noInBasic = [];
	_noInAdditional = [];
	_noInTotal = [];

		{
		if not ((faction _x) in _civF) then
			{
			_type = toLower (typeOf _x);
			if not ((_type in _basicrhq) or (_type in _noInBasic)) then {_noInBasic pushBack _type};
			if not ((_type in _Additionalrhq) or (_type in _noInAdditional)) then {_noInAdditional pushBack _type};
			if not ((_type in _total) or (_type in _noInTotal)) then {_noInTotal pushBack _type};
			}
		}
	foreach (AllUnits + Vehicles);

	diag_log "-------------------------------------------------------------------------";
	diag_log "-----------------------------RHQCHECK REPORT-----------------------------";
	diag_log "-------------------------------------------------------------------------";
	diag_log "Types not added to basic RHQ:";

		{
		diag_log format ["%1",_x];
		}
	foreach _noInBasic;

	diag_log "-------------------------------------------------------------------------";
	diag_log "Types not added to exact RHQ (not all must be):";

		{
		diag_log format ["%1",_x];
		}
	foreach _noInAdditional;

	diag_log "-------------------------------------------------------------------------";
	diag_log "Types not added anywhere:";

		{
		diag_log format ["%1",_x];
		}
	foreach _noInTotal;
	diag_log "-------------------------------------------------------------------------";
	diag_log "-------------------------END OF RHQCHECK REPORT--------------------------";
	diag_log "-------------------------------------------------------------------------";

	"RHQ CHECK" hintC format ["Forgotten classes: %1\nClasses not present in basic categories: %2\n(see RPT file for detailed forgotten classes list)",count _noInTotal,count _noInBasic];
	};

and should be fairly easy to change it so it will list also every category internal array content into RPT. Just below hintC line add some new lines for each category looking simpliest like this:

 


diag_log "RYD_WS_specFor_class:"

		{
		diag_log format ["%1",_x];
		}
	foreach RYD_WS_specFor_class;
	
diag_log "";
diag_log "RYD_WS_recon_class:"

		{
		diag_log format ["%1",_x];
		}
	foreach RYD_WS_recon_class;
	
diag_log "";

//etc. for every array

 

 

The function is located in HAC_fnc.sqf, lines from 4866. Then run a scenario with Hetman control over every single unit and vehicle, that you want to have in your RHQ and RHQCheck set as true. 

  • Like 1

Share this post


Link to post
Share on other sites
Quote

Thanks for the info, it will definitely come in handy.  Configuring some units has been a pain.  If you get a chance, do you think you could update the online manual with some of this?  The one on Google Drive?  Keep it somewhere easy to find instead of buried in a forum, yeah?

 

In the future I plan to update whole HAL, then it may happen. Not sure, when it will be. 

 

Quote

If you don't mind me suggesting, might I recommend a new class for heavily armored aircraft?

 

That would require not so simple changes across the code, I mean as soon I figure out, what should differ common aircraft and armored aircraft as for usage on the battlefield. Perhaps bigger tolerance on the hostile AA presence in the target area... Don't know, no promises. 

 

FO category IIRC (yep, I easily could forgot something) has in fact no unique role in Hetman. These are just second choice recon units. Artillery can be called in fact by every single soldier (Call For Fire philosophy), so here it's just about the advantage, fancy optics, they usually carry, give FO units as for spotting potential targets for artillery (every known enemy group is potential target) during recon missions. Also FO groups behave a bit differently on recon missions - tend more to take elevated positions and stay longer there. 

 

 

 

 

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

×