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>

Image:Exos-simples-1.jpg

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>