Solutions to NDF advanced exercises
From AOW HT Wiki
Contents |
Exercise 1
- With GROUPE_SEMANTIQUE
The units are defined in the files in the following directory : <GameDirectory>\AOW\DataLight\TypeWarriorLazy\Unites\
The Marine SPF is defined in the following file : <GameDirectory>\AOW\DataLight\TypeWarriorLazy\Unites\TF\Marine SPF\AoW_TF_MSPF.ndf
The main part of the file is the template TypeWarriorAow_TF_MarineSPF. You can see it immediately because it is "exported" and therefore accessible from other files.
The caracteristics of the unit are defined through the parameter AOW_TF_MARINE_SPF_SEMANTIQUE (Nom_Parametre_Semantique = AOW_TF_MARINE_SPF_SEMANTIQUE) which description is divised into two files :
<GameDirectory>\datalight\DefaultNDF\Unites\ParametreSemantiques\_zAoW_XX_ParametresSemantiquesUnites_DoNotEdit.ndf
and <GameDirectory>\datalight\DefaultNDF\Unites\ParametreSemantiques\zAoW_TF_ParametresSemantiquesUnites.ndf.
The characteristic which interests us is MOUVEMENT which represents mainly the speed of the unit.
So in order to increase the speed of the MSPF, you just have to find the GROUPE_SEMANTIQUE AOW_TF_MARINE_SPF_SEMANTIQUE and modify the value MOUVEMENT = 1100
- With Cheatcode
The cheatchodes are defined here : <GameDirectory>\datalight\effet\EffetIA\AoWCheatCode.ndf. The cheatcode that we will add looks like the 'duckhunt' one. Add :
<ndf>('supermspf', $/DefaultConst/IsMSPFAcceleratedValue := TConditionNot :
SubCondition = $/DefaultConst/IsMSPFAccelerated
),
</ndf>
That is a global variable that indicates if the MSPF unit is accelerated or not.
You have to declare it in <GameDirectory>\datalight\DefaultNDF\System\RessourceList.ndf :
<ndf>export IsMSPFAcceleratedValue is TEugBBoolean( Value = false ) export IsMSPFAccelerated is TAccesseurBooleanFromEUGBObject ( EUGBObject = IsMSPFAcceleratedValue )</ndf>
After that, you have to use this variable were the speed of the MSPF is defined.
TypeWarriorAow_TF_MarineSPF is a Template_TypeWarrior_Infanterie which is defined here : <GameDirectory>\AOW\DataLight\TypeWarrior\_Common\Unites\AOW\AoW_Infanterie.ndf
In that template, search MouvementParSeconde = <Nom_Parametre_Semantique>.MOUVEMENT and replace it by
<ndf>MouvementParSeconde = TAccesseurRealTestIfTrueOrFalse :
Condition = <IsAccelerated>
AccesseurRealIfTrue = 2 * <Nom_Parametre_Semantique>.MOUVEMENT
AccesseurRealIfFalse = <Nom_Parametre_Semantique>.MOUVEMENT
</ndf>
The template parameter <IsAccelerated> has to be add in the parameters of Template_TypeWarrior_Infanterie (just after AdditionalDataBlockList = [],, you add IsAccelerated = False. So by default the units will not be accelerated.
Finally, go back in TypeWarriorAow_TF_MarineSPF and add IsAccelerated = $/DefaultConst/IsMSPFAccelerated to make him accelerated if the cheatcode is active.
Tips : to save your time, you should add this cheatcode :
<ndf>
('units', SEQ with
[
TemplateSpawnUniteDuJoueurAuCentre(TYPE_WARRIOR_AS_STRING = 'TypeWarrior/TypeWarriorAoW_CS_ArmorFactory'),
TemplateSpawnUniteDuJoueurAuCentre(TYPE_WARRIOR_AS_STRING = 'TypeWarrior/TypeWarrior_AoW_CS_BTR80'),
TemplateSpawnUniteDuJoueurAuCentre(TYPE_WARRIOR_AS_STRING = 'TypeWarrior/TypeWarrior_AoW_US_Abrams'),
TemplateSpawnUniteDuJoueurAuCentre(TYPE_WARRIOR_AS_STRING = 'TypeWarrior/TypeWarriorAow_TF_MarineSPF'),
TemplateSpawnUniteDuJoueurAuCentre(TYPE_WARRIOR_AS_STRING = 'TypeWarrior/TypeWarrior_AoW_US_RPG'),
TemplateSpawnUniteDuJoueurAuCentre(TYPE_WARRIOR_AS_STRING = 'TypeWarrior/TypeWarrior_Aow_CS_Soldier')
]
),
</ndf>
It will spawn the different units you need in theses exercises.
And do not forget you can spawn the bases of CS, US and TFT with the shortcut CTRL+F1, CTRL+F2 and CTRL+F3
Exercise 2
- With GROUPE_SEMANTIQUE
Alter the rate of fire with GROUPE_SEMANTIQUE is the same as in exercise 1. The javelin is named TypeWarrior_AoW_US_RPG in <GameDirectory>\AOW\DataLight\TypeWarriorLazy\Unites\US\RPG\AoW_US_RPG.ndf
Its GROUPE_SEMANTIQUE is AoW_US_RPG_SEMANTIQUE_GRAPHIC. So in <GameDirectory>\datalight\DefaultNDF\Unites\ParametreSemantiques\_zAoW_XX_ParametresSemantiquesUnites_DoNotEdit.ndf alter DUREE_TIR of AOW_US_RPG_SEMANTIQUE and the rate of fire will be altered
- With Cheatcode
First we add a cheatcode like in exercise 1 :
<ndf>
('superjavelin', $/DefaultConst/IsJavelinFireAcceleratedValue := TConditionNot :
SubCondition = $/DefaultConst/IsJavelinFireAccelerated
),</ndf>
And declare the variable :
<ndf> export IsJavelinFireAcceleratedValue is TEugBBoolean( Value = false ) export IsJavelinFireAccelerated is TAccesseurBooleanFromEUGBObject ( EUGBObject = IsJavelinFireAcceleratedValue ) </ndf>
After that, we can alter directly the rate of fire of the RPG in AoW_US_RPG.ndf. Replace DUREE_RECHARGE_TIR with :
<ndf> TAccesseurRealTestIfTrueOrFalse : Condition = $/DefaultConst/IsJavelinFireAccelerated AccesseurRealIfTrue = 0.5 * AOW_US_RPG_SEMANTIQUE.DUREE_TIR AccesseurRealIfFalse = AOW_US_RPG_SEMANTIQUE.DUREE_TIR} </ndf>
If you want, you can also improve the speed of animations : see the ACCESSEUR_DUREE_EN_SECONDE.
Exercise 3
Additional Property
Fist, we must add an additional property to the typewarrior : ObjectString_GenerationNumber
This will represent the generation number of the domino. When it's 20, it doesn't create new domino anymore
In <GameDirectory>\DataLight\DefaultNDF\System\ObjectConst.ndf add :
<ndf>export ObjectString_GenerationNumber is TEUGBString : Value = 'NumeroGeneration' </ndf>
We set this additionnal property to 1 for the first domino :
<ndf>
Test is SEQ :
VarLocaleList = [ locUnite is TemplateVariableLocaleUnitBalise() ]
with
[
TEffetCreateWarrior :
AccesseurPositionPlancher = DefaultConst/AccesseurPositionPlancher_PickedPoint
TypeWarriorAsString = '$/TypeWarrior/effettest/TypeWarriorDomino'
AccesseurCamp = DefaultConst/AccesseurCampDuJoueur
VariableLocaleCible = locUnite
,
TEffetSetIntegerAdditionalProperty :
PropertyName = $/DefaultConst/ObjectString_GenerationNumber
AccesseurUnitBalise = locUnite
Value = 1
]
</ndf>
When we will create another domino, we will increment this value by 1 :
<ndf>
SEQ with
[
TEffetCreateWarrior :
AccesseurPositionPlancher = locPosition
TypeWarriorAsString = '$/TypeWarrior/effettest/TypeWarriorDomino'
AccesseurCamp = DefaultConst/AccesseurCampDuJoueur
VariableLocaleCible = locUnite
,
TEffetSetIntegerAdditionalProperty :
PropertyName = $/DefaultConst/ObjectString_GenerationNumber
AccesseurUnitBalise = locUnite
AccesseurValue = TAccesseurIntegerAdd :
IntegerList = [
1,
TAccesseurIntegerFromAdditionalProperty :
AccesseurUnitBalise = $/DefaultConst/SelfUnitBalise
PropertyName = $/DefaultConst/ObjectString_GenerationNumber
]
]
</ndf>
Unit State Machine Descriptor
We create two states :
SubUnitStateDescriptorList = [USD_Reproduction, USD_Suicide]
The first one will wait during 1 second, and then create another domino and go to the other state.
<ndf>
USD_Reproduction is TUnitStateDescriptor :
MyName = 'USD_Reproduction'
EffetDescriptor = TWaitPrecis :
DureeEnSecondes = 1
EffetDescriptorBeforeEnd = SEQ with
[
EffectCreateAnotherWarrior
,
TEffetUnitStateMachine_ChangeFatherUnitDecision :
Niveau = 1
NewUnitDecision = TUnitDecisionConstante :
MyName = 'UD_Suicide'
UnitStateDescriptor = USD_Suicide
]
</ndf>
The second state will wait during 3 seconds, and then kill itself.
<ndf>
USD_Suicide is TUnitStateDescriptor :
MyName = 'USD_Suicide'
EffetDescriptor = TWaitPrecis :
DureeEnSecondes = 3
EffetDescriptorBeforeEnd = TEffetKillUnitBalise :
AccesseurUnitBalise = $/DefaultConst/SelfUnitBalise
AccesseurCampResponsableDeLaMort = DefaultConst/AccesseurCampDuJoueur
AccesseurUnitBaliseResponsableDeLaMort = $/DefaultConst/SelfUnitBalise
AcceptUnitBaliseNil = True
</ndf>
Code
<ndf>
Test is SEQ :
VarLocaleList = [ locUnite is TemplateVariableLocaleUnitBalise() ]
with
[
TEffetCreateWarrior :
AccesseurPositionPlancher = DefaultConst/AccesseurPositionPlancher_PickedPoint
TypeWarriorAsString = '$/TypeWarrior/effettest/TypeWarriorDomino'
AccesseurCamp = DefaultConst/AccesseurCampDuJoueur
VariableLocaleCible = locUnite
,
TEffetSetIntegerAdditionalProperty :
PropertyName = $/DefaultConst/ObjectString_GenerationNumber
AccesseurUnitBalise = locUnite
Value = 1
]
//------------------------------------------------------------------------------
EffectCreateAnotherWarrior is SEQ :
VarLocaleList = [
locPosition is TemplateVariableLocalePositionPlancher(),
locShiftX is TemplateVariableLocaleReal(),
locShiftY is TemplateVariableLocaleReal(),
locUnite is TemplateVariableLocaleUnitBalise()
]
with
[
locShiftX := 0,
locShiftY := 0,
RandomShift is TEffetRunEffetFromIndex :
AccesseurInteger_Index = TAccesseurIntegerRandom :
ValueMin = 0
Range = 4
EffetList = [
locShiftX := -400,
locShiftX := 400,
locShiftY := 400,
locShiftY := -400
]
,
ShiftPosition is locPosition := TAccesseurPositionPlancher_Decalage :
AccesseurRealDecalageX = locShiftX
AccesseurRealDecalageY = locShiftY
AccesseurPositionPlancher = TAccesseurPositionPlancher_SelfFromUnitBalise :
AccesseurUnitBalise = $/DefaultConst/SelfUnitBalise
,
TestIfLastGeneration is TEffetTestIfTrueOrFalse :
Condition = TAccesseurBooleanComparatorReal :
AccesseurReal1 = TAccesseurIntegerFromAdditionalProperty :
AccesseurUnitBalise = $/DefaultConst/SelfUnitBalise
PropertyName = $/DefaultConst/ObjectString_GenerationNumber
Value2 = 10
Can1BeEgalA2 = True
EffetIfFalse = SEQ with
[
TEffetCreateWarrior :
AccesseurPositionPlancher = locPosition
TypeWarriorAsString = '$/TypeWarrior/effettest/TypeWarriorDomino'
AccesseurCamp = DefaultConst/AccesseurCampDuJoueur
VariableLocaleCible = locUnite
,
TEffetSetIntegerAdditionalProperty :
PropertyName = $/DefaultConst/ObjectString_GenerationNumber
AccesseurUnitBalise = locUnite
AccesseurValue = TAccesseurIntegerAdd :
IntegerList = [
1,
TAccesseurIntegerFromAdditionalProperty :
AccesseurUnitBalise = $/DefaultConst/SelfUnitBalise
PropertyName = $/DefaultConst/ObjectString_GenerationNumber
]
]
]
//------------------------------------------------------------------------------
TypeWarriorDomino is TTypeWarrior :
SoldatCarac = TSoldatCarac :
PV = 1
Detectable = False
Blessable = True
Visualisable = True
Selectionnable = False
DoNotMirror = True
EffectReproductionBeforeEnd is SEQ with
[
EffectCreateAnotherWarrior
,
TEffetUnitStateMachine_ChangeFatherUnitDecision :
Niveau = 1
NewUnitDecision = TUnitDecisionConstante :
MyName = 'UD_Suicide'
UnitStateDescriptor = USD_Suicide
]
USD_Reproduction is TUnitStateDescriptor :
MyName = 'USD_Reproduction'
EffetDescriptor = TWaitPrecis :
DureeEnSecondes = 1
EffetDescriptorBeforeEnd = EffectReproductionBeforeEnd
USD_Suicide is TUnitStateDescriptor :
MyName = 'USD_Suicide'
EffetDescriptor = TWaitPrecis :
DureeEnSecondes = 3
EffetDescriptorBeforeEnd = TEffetKillUnitBalise :
AccesseurUnitBalise = $/DefaultConst/SelfUnitBalise
AccesseurCampResponsableDeLaMort = DefaultConst/AccesseurCampDuJoueur
AccesseurUnitBaliseResponsableDeLaMort = $/DefaultConst/SelfUnitBalise
AcceptUnitBaliseNil = True
UnitStateMachineDescriptor = USMD is TUnitStateMachineDescriptor :
MainUnitStateDescriptor = MUSD is TUnitStateDescriptor :
EffetDescriptor = Animation is SEQ with
[
TScaleModificator :
ScaleX = 20
ScaleY = 20
ScaleZ = 20
,
EffetRepeatAnim :
MODEL_ASE = 'Data\XFiles3\Util\PointInterrogation'
PERIODE_EN_SECONDE = 2
]
MyName = 'MUSD_Domino'
SubUnitStateDescriptorList = [USD_Reproduction, USD_Suicide]
UnitDecision = TUnitDecisionConstante :
MyName = 'UD_Reproduction'
UnitStateDescriptor = USD_Reproduction
WarriorKreator = WarriorKreator/WarriorKreatorMarine
AdditionalPropertyList = [
TAdditionalPropertyInteger :
MinValue = 1
MaxValue = 10
PropertyName = $/DefaultConst/ObjectString_GenerationNumber
Value = 1
]
</ndf>
Exercise 4
Add an upgrade to the BTR-80 (Consortium light tank) in order to make him shoot at ennemi aircrafts
The BTR-80 is TypeWarrior_AoW_CS_BTR80, defined in <GameDirectory>\AOW\DataLight\TypeWarriorLazy\Unites\CS\AoW_CS_BTR80\AoW_CS_BTR80.ndf.
Add a MAIN_EFFET_DESCRIPTOR that changes its scanner. The scanner of a unit represents what he is able to target and shoot.
<ndf>
MAIN_EFFET_DESCRIPTOR = SEQ with
[
TEffetDescriptorSortilegeChangeScannerDescriptor :
ScannerDescriptor = $/TypeWarrior/TemplateScannerDescriptorFromDataBlockAoW :
AltitudeDeVision = AOW_TF_BUGGY_MISSILE_SEMANTIQUE.ALTITUDE_VISION
ScannerAnalysor = $/DefaultConst/ScannerAnalysorAntiAvionSoldatChar
CaracGroup = 'Upgrade_AA'
]
</ndf>
We must also define the missile characteristics (we take the TF Buggy example) :
<ndf>
AdditionalDataBlockList = [ TDataBlock :
BlockModule = 'ParamsUnit'
BlockObject = 'AOW_TF_BUGGY_MISSILE_SEMANTIQUE'
CaracGroup = 'Upgrade_AA'
]
</ndf>
Now the BTR-80 is able to shoot at aircrafts. But if you try the mod, you see that the missile does not follow the aircraft.
In EffetTirBTR80 replaceUnitIACategoryList = $/DefaultConst/IACategoryList_VehiculeSolby :
<ndf>
UnitIACategoryList = $/DefaultConst/IACategoryList_VehiculeSol
+
$/DefaultConst/IACategoryList_Helicoptere_Avion
</ndf>
Add a button in the action cube (use the AA buggy upgrade icone)
First we will create a ressource : a global variable that will indicate if the upgrade has already been done.
In <GameDirectory>\datalight\DefaultNDF\System\RessourceList.ndf, add :
<ndf> export Ressource_CS_UpgradeBTR80AACapacity is TRessourceConstruction : ClefAccess = 'CS_UpgradeBTR80AACapacity' Nom = '|Upgrade BTR80 AA Capacity' </ndf>
Next we have to wait our upgrade is done to let the BTR_80 fire on aircraft, so replace the MAIN_EFFET_DESCRIPTOR by
<ndf>
MAIN_EFFET_DESCRIPTOR = SEQ with
[
Template_WaitForGlobalUpgrade :
UPGRADE_RESSOURCE = $/DefaultConst/Ressource_CS_UpgradeBTR80AACapacity
,
TEffetDescriptorSortilegeChangeScannerDescriptor :
ScannerDescriptor = $/TypeWarrior/TemplateScannerDescriptorFromDataBlockAoW :
AltitudeDeVision = AOW_TF_BUGGY_MISSILE_SEMANTIQUE.ALTITUDE_VISION
ScannerAnalysor = $/DefaultConst/ScannerAnalysorAntiAvionSoldatChar
CaracGroup = 'Upgrade_AA'
]
</ndf>
Now we can add a button in the Armor Factory to purchase this upgrade : In <GameDirectory>\AOW\DataLight\TypeWarriorLazy\Bases\CS\Aow_CS_ArmorFactory\AoW_CS_ArmorFactory.ndf In COMPETENCE_LIST_AFTER_CONSTRUCTION :
Remove : CompetenceConstruireUpgradeTunguskaExtendedAARadar/CompetenceConstruire (otherwise there is not enough place for our upgrade)
And add : CompetenceConstruire_Upgrade_BTR80AACapacity/CompetenceConstruire
This has to be defined in <GameDirectory>\AOW\DataLight\TypeWarrior\_Common\SpecialAptitude\Competence_CS.ndf. Add :
<ndf> CompetenceConstruire_Upgrade_BTR80AACapacity is TemplateCompetenceConstruire_UpgradeInWarp : ICONE_X = AoW_CUBEACTION_DIM.COLONNE_2 ICONE_Y = AoW_CUBEACTION_DIM.LIGNE_3 Texture = $/DefaultConst/AOW_STANDARD.PATH_ICONES + 'Competence\TF\TF_Upgrade_Buggy_AA.tga' TYPE_WARRIOR_TO_CREATE_AS_STRING = 'TypeWarrior/TypeWarrior_AoW_CS_Upgrade_BTR80AACapacity' ParametreSemantiqueHint_Bouton = AOW_TF_UPGRADE_BUGGY_AA_CAPACITY_SEMANTIQUE_HINT PROPERTY_NAME = $/DefaultConst/ObjectString_AoW_CS_Upgrade_BTR80AACapacity </ndf>
As you see, you have to create a property_name : $/DefaultConst/ObjectString_AoW_CS_Upgrade_BTR80AACapacity, and a typewarrior : TypeWarrior_AoW_CS_Upgrade_BTR80AACapacity
The property_name :
In <GameDirectory>\AOW\DataLight\TypeWarrior\_Common\Unites\UnitBaliseCamp.ndf add (next to the others upgrades) :
<ndf> Template_AdditionalProperty_Upgrade : PropertyName = $/DefaultConst/ObjectString_AoW_CS_Upgrade_BTR80AACapacity </ndf>
And in <GameDirectory>\datalight\DefaultNDF\System\_AdditionalProperties_ObjectString.ndf, add :
<ndf> export ObjectString_AoW_CS_Upgrade_BTR80AACapacity is TEUGBString ( Value = 'AoW_CS_Upgrade_BTR80AACapacity' ) </ndf>
The TypeWarrior :
In AOW_CS_ArmorFactory.ndf (at the end of the file) :
<ndf> export TypeWarrior_AoW_CS_Upgrade_Fake_BTR80AACapacity is TemplateTypeWarriorUpgradeFakeTechno : Classement = 'AOW/Factions/TaskForce/Utils/FakeUpgrade/$TF_Upgrade_BuggyAACapacity' Nom_Parametre_Semantique = AOW_CS_UPGRADE_BTR80_AA_CAPACITY_SEMANTIQUE ADDITIONAL_PROPERTY_DU_CAMP = $/DefaultConst/ObjectString_AoW_CS_Upgrade_BTR80AACapacity UPGRADE_RESSOURCE = $/DefaultConst/Ressource_CS_UpgradeBTR80AACapacity export TypeWarrior_AoW_CS_Upgrade_BTR80AACapacity is Template_TypeWarrior_Upgrade_GlobalCampNeMeurtJamaisEtNeSAnnuleJamais : Nom_Parametre_Semantique = AOW_CS_UPGRADE_BTR80_AA_CAPACITY_SEMANTIQUE Nom_Parametre_Semantique_Hint = AOW_TF_UPGRADE_BUGGY_AA_CAPACITY_SEMANTIQUE_HINT ADDITIONAL_PROPERTY_DU_CAMP = $/DefaultConst/ObjectString_AoW_CS_Upgrade_BTR80AACapacity </ndf>
and in <GameDirectory>\AOW\datalight\TypeWarrior\_Common\_ChargementRetardeBases.ndf :
<ndf>
Chargement_TypeWarrior_Aow_CS_ArmorFactory is TemplateChargement_TWAOW :
TWNameList = STRINGLIST
[
(...)
'TypeWarrior_AoW_CS_Upgrade_Fake_BTR80AACapacity',
'TypeWarrior_AoW_CS_Upgrade_BTR80AACapacity',
]
</ndf>
And finally, the AOW_CS_UPGRADE_BTR80_AA_CAPACITY_SEMANTIQUE :
<GameDirectory>\datalight\DefaultNDF\Unites\ParametreSemantiques\zAoW_CS_ParametresSemantiquesUpgrades.ndf
<ndf>
GROUPE_SEMANTIQUE AOW_CS_UPGRADE_BTR80_AA_CAPACITY_SEMANTIQUE
Multiplicateur_DistanceAir = 1.5
CoutTechno = DefaultConst/EnsembleRessourceVide
ApportTechno = TEnsembleRessource :
ElementRessourceListe =
[
TElementRessource ( RessourceGroup = $/defaultconst/Ressource_CS_UpgradeBTR80AACapacity QuantiteRessource = 1 )
]
end
</ndf>
and : <GameDirectory>\datalight\DefaultNDF\Unites\ParametreSemantiques\_zAoW_XX_ParametresSemantiquesUpgrades_DoNotEdit.ndf
<ndf> GROUPE_SEMANTIQUE AOW_CS_UPGRADE_BTR80_AA_CAPACITY_SEMANTIQUE TEMPS_PRODUCTION = 30 COUT = 1500 end </ndf>
Unlock this upgrade via a Cheatcode
This functionnality is much more simple. Fist add a cheatcode like in exercises 1 and 2
In AOWCheatCode.ndf :
<ndf>
('superbtr80', $/DefaultConst/IsBTR80AAunlockedValue := TConditionNot( SubCondition = $/DefaultConst/IsBTR80AAunlocked ) ),
</ndf>
And in RessourceList.ndf :
<ndf> export IsBTR80AAunlockedValue is TEugBBoolean( Value = false ) export IsBTR80AAunlocked is TAccesseurBooleanFromEUGBObject ( EUGBObject = IsBTR80AAunlockedValue ) </ndf>
And in your CompetenceConstruire_Upgrade_BTR80AACapacity in Competence_CS.ndf, just add :
<ndf>ACCESSEUR_IS_AVAILABLE = $/DefaultConst/IsBTR80AAunlocked</ndf>
Exercise 5
First let's set a new additionnal property for the stealth.
In <GameDirectory>\AOW\DataLight\TypeWarrior\_Common\SpecialAptitude\properties.ndf add :
<ndf> export AdditionalProperty_LastUseStealth is TAdditionalPropertyDate : PropertyName = $/DefaultConst/ObjectStringDateLastUseStealth MustMirror = True </ndf>
In the file <GameDirectory>\datalight\DefaultNDF\System\ObjectConst.ndf :
<ndf> export ObjectStringDateLastUseStealth is TEUGBString : Value = 'DateLastUseStealth' </ndf>
Add the additionnalproperty to the TypeWarrior_Aow_CS_Soldier : Replace
<ndf>AdditionalPropertyList = AdditionalPropertyList_SoldatBlessableSecourableUpgradable</ndf>
by
<ndf>AdditionalPropertyList = AdditionalPropertyList_SoldatBlessableSecourableUpgradable
+ [ AdditionalProperty_LastUseStealth ]
</ndf>
At the top of the file, to replace
<ndf>const
MODEL_ASE_PATH_AK74 = 'Data\XFiles3\AoW\Infanterie\AoW_CS_RegularSoldier\AOW_CS_RegularSoldier_'
MODEL_ASE_PATH_MM1 = 'Data\XFiles3\AoW\Infanterie\AoW_CS_MortarSoldier\AOW_CS_MortarSoldier_'
MODEL_ASE_PATH_RPG7 = 'Data\XFiles3\AoW\Infanterie\AoW_CS_RPGSoldier\AOW_CS_RPGSoldier_'
end</ndf>
by
const MODEL_ASE_PATH_AK74 = 'Data\XFiles3\AoW\Infanterie\AoW_CS_RegularSoldier\AOW_CS_RegularSoldier_' MODEL_ASE_PATH_MM1 = 'Data\XFiles3\AoW\Infanterie\AoW_CS_MortarSoldier\AOW_CS_MortarSoldier_' MODEL_ASE_PATH_RPG7 = 'Data\XFiles3\AoW\Infanterie\AoW_CS_RPGSoldier\AOW_CS_RPGSoldier_' STEALTH_DURATION = 10 STEALTH_RELOAD_DURATION = 15 end
</pre>
Let's place our icon in the cube action and link it with the stealth action :
<ndf>
CS_AK74_Stealth is TemplateCompetenceActionInstantaneeEffetAvecChronographe :
ICONE_X = AoW_CUBEACTION_DIM.COLONNE_2
ICONE_Y = AoW_CUBEACTION_DIM.LIGNE_3
Texture = $/DefaultConst/AOW_STANDARD.PATH_ICONES + 'Competence\US\US_Upgrade_ReactiveArmor.tga'
Caption = ''
HINT = ''
ACCESSEUR_IS_ENABLE = TAccesseurBooleanIsAdditionalPropertyDateDepasseeDepuisAuMoins :
AccesseurUnitBalise = $/DefaultConst/AccesseurUnitBaliseFromUnitBalise
PropertyName = $/DefaultConst/ObjectStringDateLastUseStealth
AccesseurTempsEcoule = TAccesseurRealConstante :
Value = STEALTH_RELOAD_DURATION
Effet = TNewEffetDescriptorSurCible :
AccesseurUnitBaliseList = AccesseurUnitBaliseList_FromContextForCompetence
Effet = CS_AK74_UseStealth
ACCESSEUR_REAL_PROGRESSION = Template_MeilleurAvancementFromSelectionEntre0Et1 :
TypeWarriorConcerneAsString = 'TypeWarrior/TypeWarrior_Aow_CS_Soldier'
AdditionalPropertyString = $/DefaultConst/ObjectStringDateLastUseStealth
RealTempsDelai = STEALTH_RELOAD_DURATION
</ndf>
Let's define our stealth action :
<ndf>
CS_AK74_UseStealth is SEQ with
[
TEffetResetDateAdditionalProperty :
AccesseurUnitBalise = $/DefaultConst/SelfUnitBalise
PropertyName = $/DefaultConst/ObjectStringDateLastUseStealth
,
TEffetFireAndForgetSurCible :
AccesseurUnitBalise = $/DefaultConst/SelfUnitBalise
Effet = COMPET with
[
TWaitPrecis :
DureeEnSecondes = STEALTH_DURATION
,
Template_UniteStealth :
Aggressif = False
CONDITION_SUP = $/DefaultConst/ConditionAlwaysTrue
,
AffichageChrono is SEQ :
Support = TGraphicCaracTextBox :
Material = $/m3d/Shader/MaterialLegacy_AlphaDetail_NoZClipping
TranslateX = -40
TranslateY = -35
SizeX = 20
Sizey = 20
Pure2D = True
Caption = ''
calqueLevel = 1
Font = $/Default3D/AOW_Font_EurostileExtendedBold_14
R = 100
G = 255
B = 255
A = 255
TextFormatProperties = $/Default3D/StandardTextFormatPropertiesCenter
with
[
TTextBoxModificator :
DureeEnSecondes = 10000000
AccesseurString = TAccesseurStringFromReal :
AccesseurReal = TAccesseurRealSub :
RealList = [
STEALTH_DURATION,
TAccesseurRealSub :
RealList = [
TAccesseurDateEnSecondes(),
TAccesseurDateFromAdditionalProperty :
AccesseurUnitBalise = $/DefaultConst/SelfUnitBalise
PropertyName = $/DefaultConst/ObjectStringDateLastUseStealth
]
]
NbDigit = 3
UseExtended = True
EveryTurn = True
]
]
]
</ndf>
Now, add the skill to your AK74 soldier (named CS_AK74_MUSD).
Replace :
<ndf>COMPETENCE_LIST = AoW_CompetenceListStandardSoldatCaptureur</ndf>
by :
<ndf>
COMPETENCE_LIST = AoW_CompetenceListStandardSoldatCaptureur
+
[ CS_AK74_Stealth/CompetenceActionInstantanee ]
</ndf>
