Solutions to NDF exercises
From AOW HT Wiki
Contents |
Exercise 1
<ndf>
// Exercise 1
Test is SEQ :
VarLocaleList = [ locInteger is TemplateVariableLocaleInteger() ]
with
[
locInteger := 1,
Boucle is TEffetRepeatSequentiel :
NbFois = 6
Effet = Appel is SEQ with
[
TEffetEugDebugWin32 :
AccesseurAffichage = TAccesseurStringFromInteger :
AccesseurInteger = locInteger
,
locInteger := locInteger * (-1)
]
]
</ndf>
Exercise 2
<ndf>
Test is SEQ :
VarLocaleList = [ locString is TemplateVariableLocaleString() ]
with
[
locString := '',
Loop is TEffetRepeatSequentiel :
NbFois = 4
Effet = Appel is SEQ with
[
locString := TAccesseurStringFormat :
AccesseurCaption = '%1+1'
ParameterList = [locString]
,
TEffetEugDebugWin32 :
AccesseurAffichage = locString
]
]
</ndf>
Exercise 3
<ndf>
Template TemplateTest [ StringValue = '1',
Iteration = 4 ] is SEQ :
VarLocaleList = [ locString is TemplateVariableLocaleString() ]
with
[
locString := ''
,
Loop is TEffetRepeatSequentiel :
NbFois = <Iteration>
Effet = SEQ with
[
locString := TAccesseurStringFormat :
AccesseurCaption = '%1+%2'
ParameterList = [locString, <StringValue>]
,
TEffetEugDebugWin32 :
AccesseurAffichage = locString
]
]
Test is SEQ with
[
MyObject1 is TemplateTest :
StringValue = '1'
Iteration = 4
,
MyObject2 is TemplateTest :
StringValue = 'y'
Iteration = 3
]
</ndf>
Exercise 5
<ndf>
MyTemplate is SEQ :
VarLocaleList = [ locInteger is TemplateVariableLocaleInteger() ]
with
[
locInteger := 1
,
Loop is TEffetRepeatSequentiel :
NbFois = 6
Effet = Display is SEQ with
[
TEffetEugDebugWin32 :
AccesseurAffichage = TAccesseurStringFromInteger :
AccesseurInteger = locInteger
,
locInteger := locInteger * -1
,
TWaitPrecis :
DureeEnSecondes = 1
]
]
Test is SIMU with
[
MyTemplate,
MyTemplate
]
</ndf>
Exercise 6
<ndf>
// Exercise 6
Template TemplateAddCharacterNTimes [ StringToModify,
Character,
NTimes ] is TEffetRepeatSequentiel :
NbFoisAccesseur = <NTimes>
Effet = <StringToModify> := TAccesseurStringFormat :
AccesseurCaption = '%1%2'
ParameterList = [
<StringToModify>,
<Character>
]
Test is SEQ :
VarLocaleList = [ locStringLine is TemplateVariableLocaleString(),
locLineNumber is TemplateVariableLocaleInteger(),
locSequenceNumber is TemplateVariableLocaleInteger() ]
with
[
locStringLine := '',
locLineNumber := 0,
locSequenceNumber := 2,
TEffetRepeatSequentiel :
NbFois = 7
Effet = DisplayOneLine is SEQ with
[
locLineNumber := locLineNumber + 1
,
TestIfNextSequence is TEffetTestIfTrueOrFalse :
Condition = TAccesseurBooleanComparatorReal :
AccesseurReal1 = locLineNumber
Value2 = 5
Can1BeEgalA2 = True
EffetIfTrue = SEQ with
[
locLineNumber := 1,
locSequenceNumber := locSequenceNumber + 1
]
,
LineBegining is locStringLine := TAccesseurStringFormat :
AccesseurCaption = '%1_'
ParameterList = [
TAccesseurStringFromInteger :
AccesseurInteger = locLineNumber
]
,
AddFirstCharacterSequence is TemplateAddCharacterNTimes :
StringToModify = locStringLine
Character = '1'
NTimes = locLineNumber
,
AddSecondCharacterSequence is TemplateAddCharacterNTimes :
StringToModify = locStringLine
Character = TAccesseurStringFromInteger :
AccesseurInteger = locSequenceNumber
NTimes = 5 - locLineNumber
,
DisplayLine is TEffetEugDebugWin32 :
AccesseurAffichage = locStringLine
]
]
</ndf>
Exercise 7
Tips
- How to kill the warrior a the end of the path?
The exercise suggests us to use TAccesseurRealFromPositionPlancher_Distance2DEnCase, TAccesseurPositionPlancher_SelfFromUnitBalise, TAccesseurBooleanComparatorReal etc. apparently, we will have to deal with computations of distances.
We also know that walking along a rectangular path brings the warrior at its initial position at the end of the path. Thus, testing if the walk is completed is equivalent to testing if the distance between its actual position and its initial position is less than a given threshold.
In order to avoid to kill the warrior immediatly(because the distance between his position and the initial position is surely less than the established threshold), we can wait a certain amount of time in order to let enough distance between the warrior and the initial point before applying the distance test.
- How to make sure that the code doesn't crash if the warrior is killed before the path is completed?
We know that killing the warrior destroys its UnitBalise, hence applying a test on a previously destroyed UnitBalise will make the code crash. In order to avoid that, we can test if the UnitBalise still exists before applying the distance test.
Code
<ndf>
const
Offset = 1600
SquareThreshold = 0.95
end
Template TemplateWalkToPosition [
_X = 0,
_Y = 0
] is SEQ with
[
TEffetDonnerUnOrdre :
AccesseurUnitBalisePorteur = locAccesseurUnitBalise
IsMove = true
AccesseurPositionPlancherCible = TAccesseurPositionPlancher_Decalage :
AccesseurRealDecalageX = <_X>
AccesseurRealDecalageY = <_Y>
AccesseurPositionPlancher = locAccesseurPositionAtStart
AddAtEnd = true
]
Test is SEQ :
VarLocaleList =
[
locAccesseurUnitBalise is TemplateVariableLocaleUnitBalise(),
locAccesseurPositionAtStart is TemplateVariableLocalePositionPlancher(),
]
with
[
locAccesseurPositionAtStart := TAccesseurPositionPlancher_PickedPoint(),
CreateOurWarrior is TEffetCreateWarrior :
TypeWarriorAsString = '$/typewarrior/TypeWarrior_Aow_US_Marine'
AccesseurCamp = $/DefaultConst/AccesseurCampDuJoueur
AccesseurPositionPlancher = locAccesseurPositionAtStart
VariableLocaleCible = locAccesseurUnitBalise
,
TemplateWalkToPosition :
_X = Offset
_Y = 0
,
TemplateWalkToPosition :
_X = Offset
_Y = Offset
,
TemplateWalkToPosition :
_X = 0
_Y = Offset
,
TemplateWalkToPosition :
_X = 0
_Y = 0
,
Duel is COMPET with
[
TestIfKilled is TEffetWaitCondition :
_EveryTurn = true
Condition = TAccesseurBooleanObjectIsNil :
AccesseurObject = locAccesseurUnitBalise
,
WaitForSquareCompletedThenKill is SEQ with
[
TWaitPrecis :
DureeEnSecondes = 1
,
WaitForSquareCompleted is TEffetWaitCondition :
_EveryTurn = true
Condition = TAccesseurBooleanComparatorReal :
AccesseurReal1 = TAccesseurRealFromPositionPlancher_Distance2DEnCase :
AcceptInvalid = True
ValueIfInvalid = 0
AccesseurPositionPlancher1 = locAccesseurPositionAtStart
AccesseurPositionPlancher2 = TAccesseurPositionPlancher_SelfFromUnitBalise :
AccesseurUnitBalise = locAccesseurUnitBalise
AccesseurReal2 = SquareThreshold
Can1BeStrictementPlusPetitQue2 = true
,
KillWarrior is TEffetKillUnitBalise :
AccesseurUnitBalise = locAccesseurUnitBalise
AccesseurCampResponsableDeLaMort = $/DefaultConst/AccesseurCampNil
AccesseurUnitBaliseResponsableDeLaMort = locAccesseurUnitBalise
]
]
]
</ndf>
Exercise 8
<ndf>
// Exercise 8
Effect1 is TEffetEugDebug :
AccesseurAffichage = 'effect 1'
Effect2 is TEffetEugDebug :
AccesseurAffichage = 'effect 2'
Effect3 is TEffetEugDebug :
AccesseurAffichage = 'effect 3'
Template TemplateEffetsSequentiels [ List,
Boolean,
TypeWarrior ] is SEQ with
[
if EqualListeVide(<List>) then
Effect1
else
if Equal(arg1 = <Boolean> arg2 = True) then
Effect2
else
if SamePointer :
arg1 = <TypeWarrior>
arg2 = $/typewarrior/TypeWarrior_AoW_US_Marine
then
Effect3
end
end
end
]
Test is SEQ with
[
Test1 is TemplateEffetsSequentiels :
List = []
Boolean = True
TypeWarrior = $/typewarrior/TypeWarrior_AoW_US_Marine
,
Test2 is TemplateEffetsSequentiels :
List = [1]
Boolean = True
TypeWarrior = $/typewarrior/TypeWarrior_AoW_US_Marine
,
Test3 is TemplateEffetsSequentiels :
List = [1]
Boolean = false
TypeWarrior = $/typewarrior/TypeWarrior_AoW_US_Marine
]
</ndf>
Exercise 9
Explanations
- We have to find the code that defines our warrior (for our case we chose the TypeWarrior AOW_US_marine which which NDF file can be found at AOW\DataLight\TypeWarriorLazy\Unites\US\Marine\AoW_US_Marine.ndf) and copy it in our own code.
- As we would like to change the graphical aspect of our soldier by providing it a graphical effect (an Interrogation point that spins above its head), and at the same time we know that our soldier's type is Template_TypeWarrior_Infanterie which prototype has a field EffetGraphique(Graphical effect), we can therefore redefine this field in order to make our interrogation point appear accordind to what is stated in the exercise.
- In order to achieve that, we can write a Graphical Effect that could look like:
<ndf>
// Exercise 9
SpinAndWait is TEffetRepeatSequentiel :
NbFois = 0
Effet = SpinAndWait is SEQ with
[
ActionRotate is SEQ :
Support = TGraphicCaracModel3D :
ModelAse = 'Data\XFiles3\Util\PointInterrogation'
TranslateZ = 220
with
[
TOrientationModificator :
DureeEnSecondes = 1
VitesseAngulaire = 360
],
TWaitPrecis :
DureeEnSecondes = 3
]
</ndf>
- Then assign this new graphical effect to the field EffetGraphique of the TypeWarrior TypeWarrior_Aow_US_Marine as following:
<ndf> EffetGraphique = ActionRotate is SpinAndWait </ndf>
- As we have redifined the properties of the TypeWarrior TypeWarrior_Aow_US_Marine, it would be relevant to rename this TypeWarrior to a new one(for example TypeWarrior_Aow_US_Marine2)
Code
In m
<ndf>
//-----------------------------------------------------------------------------
const
MODEL_ASE_PATH = 'Data\XFiles3\AoW\Infanterie\Aow_US_Marine\AOW_US_marine_'
MODEL_ASE_PATH_M203 = 'AOW_ADDON\Res3D\UnitesInfanterie\Infanterie_US\US_M203\US_M203_'
end
.
.
.
EffetGraphique = ActionRotate is SpinAndWait
//-----------------------------------------------------------------------------
SpinAndWait is TEffetRepeatSequentiel :
NbFois = 0
Effet = SpinAndWait is SEQ with
[
ActionRotate is SEQ :
Support = TGraphicCaracModel3D :
ModelAse = 'Data\XFiles3\Util\PointInterrogation'
TranslateZ = 220
with
[
TOrientationModificator :
DureeEnSecondes = 1
VitesseAngulaire = 360
],
TWaitPrecis :
DureeEnSecondes = 3
]
test is SEQ :
VarLocaleList = [locAccesseurUnitBalise is TemplateVariableLocaleUnitBalise()]
with
[
TEffetCreateWarrior :
TypeWarriorAsString = '$/TypeWarrior/effettest/TypeWarrior_Aow_US_Marine2'
AccesseurCamp = $/DefaultConst/AccesseurCampDuJoueur
AccesseurPositionPlancher = TAccesseurPositionPlancher_PickedPoint()
VariableLocaleCible = locAccesseurUnitBalise
]
</ndf>

