//Firehopper monster by Pteromys
//  Designed to be deadly annoying. Due to all the cool moves
//    it is capable of, it would be very difficult to make
//    the Firehopper into a playable character...
//    You're welcome to try, though.
//  Stuff used:
//    Timer - check for enemies and attacks at intervals
//    State - records the state of jumps
//      0 = wander			3 = falling on first
//      1 = no jumps			4 = rising on second
//      2 = rising on first jump	5 = falling on second
//    Cont  - secondary timer for cool moves
//    x0    - records state of slam attacks
//  Functions
//    Spawning - initialize
//    Draw a blip and decrement the timer
//    Avoid the lava
//    Jump over other obstacles
//    Look for enemies, see if attack is feasible
//      Attacks: Basic thrust      Charge
//               Flares            Slam down
//    Dodge attacks or just jump around
//    Handle getting hurt
//    Make sure human players (oddly enough, found by looking
//      for idsz [HUMA]) aren't left out
//    Handle death and killing
//    Check and handle jump codes

IfSpawned
  tmpargument = 0
  SetState			// Jump record
  SetContent			// Secondary timer
  tmpx = 0			// Slam attack status
  tmpy = 0
  SetXY
  //AddStat
  //JoinEvilTeam
  SetTargetToSelf

//Draw a blip
IfOrdered
  tmpargument = selforder
  ChangeArmor
tmpx = selfx
tmpy = selfy
tmpargument = selfaccel - 55 - 14 //accels vary with skin
ShowBlipXY

// Content is used as a secondary timer
tmpargument = 0
IfContentIs
  GetContent //nop
Else
  GetContent
  tmpargument = tmpargument - 1
  SetContent

// Hop above the lava
GetWaterLevel
tmpy = tmpargument + 51600
tmpx = selfz < 2 + selfz < 1 //Long-way multiply by 10
IfXIsLessThanY
  tmpargument = ACTIONJA
  DoAction
  tmpargument = 0
  tmpdistance = rand & 4095 + 8000
  PlaySound
  tmpargument = 3800
  AccelerateUp
  IfStateIsOdd				// If falling jumpcode, do not count jump.
    tmpargument = 1
    IfStateIsNot
      GetState
      tmpargument = tmpargument - 1
      SetState

// Jump obstacles and bodies
IfBumped
  SetTargetToWhoeverBumped
  tmpx = 0
  tmpy = 1
  IfTargetIsAlive
    IfTargetIsAPlatform
      tmpx = 1
    Else
      IfFacingTarget
        IfTargetIsOnHatedTeam
          tmpturn = rand & 2
          tmpargument = ACTIONTA + tmpturn
          DoAction
            tmpargument = 0
            tmpdistance = tmpturn < 1 + 1
            SpawnAttachedParticle
  Else
    tmpx = 1
  IfXIsEqualToY
    SetTargetToSelf			// Jumping instructions
    tmpx = targetspeedz
    tmpy = 3
    IfXIsLessThanY
      GetState
      tmpx = tmpargument
      tmpy = 4
      IfXIsLessThanY			// Do not allow more than 2 jumps
        tmpy = 1
        IfXIsEqualToY
          tmpargument = 2
          SetState
        Else
          tmpargument = 4
          SetState
        tmpargument = 1800
        AccelerateUp

        tmpargument = ACTIONJA
        DoAction
        tmpargument = 0
        tmpdistance = rand & 4095 + 8000
        PlaySound
    //SetTargetToOldTarget
  SetTargetToOldTarget


// Attack or no?
IfTimeOut
  SetTargetToNearestEnemy
    SetOldTarget
    IfStateIs0
      tmpargument = 1
      SetState
      SetTurnModeToWatchTarget
  Else
    SetTargetToOldTarget

  IfStateIs0
    tmpx = selfspawnx
    tmpy = selfspawny
    tmpturn = rand & 65535
    tmpdistance = rand & 511
    Compass
  Else
    tmpx = targetdistance
    tmpy = 140
    IfXIsLessThanY				// Thrust if in range
      tmpx = targetz
      tmpy = selfz - 40
      IfXIsMoreThanY				// Is enemy high enough to be hit?
        tmpy = selfz + 40
        IfXIsLessThanY				// Is it low enough to be hit?
          tmpturn = rand & 2
          tmpargument = ACTIONTA + tmpturn
          DoAction
            tmpargument = 0
            tmpdistance = tmpturn < 1 + 1
            SpawnAttachedParticle
        Else					// The enemy is above... thrust upwards.
          tmpargument = ACTIONBA
          DoAction
            tmpargument = 0
            tmpdistance = 1
            SpawnAttachedParticle
            tmpdistance = 5
            SpawnAttachedParticle
        tmpdistance = 0 - 120
      Else
        tmpy = selfz - 80
        IfXIsLessThanY				// The enemy is below... prepare a slam attack.
          tmpargument = 0
          GetXY
          tmpy = 0
          IfXIsEqualToY				// No slam attack already in progress
            SetTargetToSelf			// Leap up to get ready to slam
            tmpx = targetspeedz
            tmpy = 5
            IfXIsLessThanY
              tmpargument = 4
              SetState
              tmpargument = 2400
              AccelerateUp
              tmpargument = ACTIONJA
              DoAction

              tmpargument = 0
              tmpdistance = rand & 4095 + 8000
              PlaySound
              tmpargument = 6
              tmpdistance = 1
              SpawnAttachedParticle
              tmpdistance = 5
              SpawnAttachedParticle

              tmpargument = 0			// Modify slam code (x0)
              GetXY
              tmpx = 1
              SetXY
            SetTargetToOldTarget
        tmpdistance = 0
    Else					// Too far away for an ordinary thrust attack...
      tmpy = 450
      IfXIsLessThanY				// Close enough for a charge?
        tmpx = targetz
        tmpy = selfz - 40
        IfXIsMoreThanY				// Is enemy high enough to be hit?
          tmpy = selfz + 40
          IfXIsLessThanY				// Is it low enough to be hit?
            tmpx = rand & 65535
            tmpy = 8192
            IfXIsLessThanY				// Charge sparingly; the tranch is hard enough to beat.
              tmpargument = ACTIONBC
              DoAction
                tmpargument = 0
                tmpdistance = 1
                SpawnAttachedParticle
                tmpdistance = 5
                SpawnAttachedParticle
                tmpx = 0
                tmpy = 0
                tmpturn = targetturnto
                tmpdistance = 18
                Compass
                SetTargetToSelf
                AccelerateTarget
                SetTargetToOldTarget
      tmpdistance = 100
    tmpx = targetx
    tmpy = targety
    tmpturn = targetturnto
    Compass
  ClearWaypoints
  AddWaypoint
  tmpargument = rand & 15 + 15
  SetTime

//React to attacking target... or just randomly jump to show off
tmpargument = 0
tmpx = rand & 65535
tmpy = 1024
IfXIsLessThanY
  tmpargument = 1
IfTargetIsAttacking
  tmpargument = 1
tmpx = tmpargument
tmpy = 1
IfXIsEqualToY
  tmpargument = 0
  IfStateIsNot
    tmpx = targetdistance
    tmpy = 350
    IfXIsLessThanY
      tmpargument = 0					// If secondary timer hasn't run out, don't dodge.
      IfContentIs
        tmpargument = 3
        tmpturn = selfturn - targetturn			// Don't always dodge attacks that don't face...
        tmpx = tmpturn
        tmpy = 24768
        IfXIsMoreThanY
          tmpy = 40768
          IfXIsLessThanY
            tmpargument = 4
        tmpx = tmpargument
        tmpy = rand & 3
        IfXIsMoreThanY
          tmpturn = targetturnto
          tmpdistance = 18
          tmpx = targetz - selfz
          tmpy = 120
          IfXIsMoreThanY					// Attack from high above... roll under.
            tmpdistance = 18
          Else
            tmpy = 70
            IfXIsMoreThanY				// Attack from above, not wise to roll under... roll aside.
              tmpturn = tmpturn + 32768
              tmpturn = rand & 16384 - 8192 + tmpturn & 65535	//flips around, +/- 8192
            Else
              tmpy = 20
              IfXIsMoreThanY				// Attack from modest height, can't jump over... jump aside.
                tmpturn = tmpturn + 32768
                tmpturn = rand & 16384 - 8192 + tmpturn & 65535
              Else					// Attack on level or from below... jump over.
                tmpdistance = 12

              SetTargetToSelf				// Jumping instructions
              tmpx = targetspeedz
              tmpy = 3
              IfXIsLessThanY
                GetState
                tmpx = tmpargument
                tmpy = 4
                IfXIsLessThanY			// Do not allow more than 2 jumps
                  tmpy = 1
                  IfXIsEqualToY
                    tmpargument = 2
                    SetState
                  Else
                    tmpargument = 4
                    SetState
                  tmpargument = 1800
                  AccelerateUp
              SetTargetToOldTarget

          tmpx = 0
          tmpy = 0
          Compass
          SetTargetToSelf
          AccelerateTarget
          SetTargetToOldTarget

          tmpargument = ACTIONEA
          tmpx = tmpturn + 8192 & 65535
          tmpy = 16384
          IfXIsLessThanY
            tmpargument = ACTIONJA
          Else
            tmpy = 32768
            IfXIsLessThanY
              tmpargument = ACTIONEB
            Else
              tmpy = 49152
              IfXIsLessThanY
                tmpargument = ACTIONHA
          DoAction
          tmpargument = 0
          tmpdistance = rand & 4095 + 8000
          PlaySound
          tmpargument = 40		//Cool dodge moves allowed only per 40 ticks
          SetContent
    Else				//Throw fireballs
      tmpy = 450
      IfXIsLessThanY
        SetTargetToSelf
        tmpargument = 256
        CostTargetMana
          tmpturn = rand & 2
          tmpargument = ACTIONTA + tmpturn
          DoAction
            tmpargument = 1
            tmpdistance = tmpturn < 1 + 1
            tmpx = 0
            tmpy = 0
            SpawnParticle
            SpawnParticle
            SpawnParticle
            SpawnParticle
            SpawnParticle
        SetTargetToOldTarget
      Else				//Rush to catch up
        tmpargument = ACTIONBC
        DoAction
          tmpargument = 0
          tmpdistance = 1
          SpawnAttachedParticle
          tmpdistance = 5
          SpawnAttachedParticle
          tmpx = 0
          tmpy = 0
          tmpturn = targetturnto
          tmpdistance = 18
          Compass
          SetTargetToSelf
          AccelerateTarget
          SetTargetToOldTarget

IfAttacked
  SetTargetToWhoeverAttacked
  IfTargetIsOnHatedTeam
    SetOldTarget
    IfStateIs0
      tmpargument = 1
      SetState
      SetTurnModeToWatchTarget
  Else
    SetTargetToOldTarget
  tmpargument = 4
  tmpdistance = rand & 4095 + 9000
  PlaySound
  tmpargument = ACTIONHA
  DoActionOverride

  //Ice is painful
  GetDamageType
  tmpx = tmpargument
  tmpy = DAMAGEICE
  IfXIsEqualToY
    tmpargument = 0 - 512
    SetTargetToSelf
    GiveLifeToTarget
    SetTargetToOldTarget

  //recoil
  IfHitFromFront
    tmpdistance = 0 - 16
  Else					// Jump into the air if not hit from front
    tmpargument = 0
    IfStateIsNot
      SetTargetToSelf			// Jumping instructions
      tmpx = targetspeedz
      tmpy = 3
      IfXIsLessThanY
        GetState
        tmpx = tmpargument
        tmpy = 4
        IfXIsLessThanY			// Do not allow more than 2 jumps
          tmpy = 1
          IfXIsEqualToY
            tmpargument = 2
            SetState
          Else
            tmpargument = 4
            SetState
          tmpargument = 1800
          AccelerateUp
      SetTargetToOldTarget
    tmpdistance = 8
  tmpturn = selfturn
  tmpx = 0
  tmpy = 0
  Compass
  SetTargetToSelf
  AccelerateTarget
  SetTargetToOldTarget

// Keep the players in the fray; battles tend to run away!
tmpargument = [HUMA]
tmpdistance = BLAHENEMIES
SetTargetToWideBlahID
  tmpx = targetdistance
  tmpy = 200
  IfXIsMoreThanY
    tmpx = targetx
    tmpy = targety
    ClearWaypoints
    AddWaypoint
  SetTargetToOldTarget
Else
  tmpx = 32 < 7 - selfx
  tmpy = 32 < 7 - selfy
  tmpdistance = xydistance
  tmpturn = 400
  IfDistanceIsMoreThanTurn
    tmpx = 32 < 7
    tmpy = 32 < 7
    ClearWaypoints
    AddWaypoint

// Dealing with death...
IfKilled
  tmpargument = 0
  SendMessageNear
  tmpargument = 5
  tmpargument = 4
  tmpx = selfx
  tmpy = selfy
  tmpdistance = selfz
  SpawnExactParticle
  GoPoof
IfTargetKilled
  tmpargument = 0
  SetState
  SetTurnModeToWatch

// End-of-script jump-code checking
tmpargument = 0
IfStateIsNot			// Idles don't need to check jumps
  SetTargetToSelf
  tmpx = targetspeedz
  tmpy = 0 - 1
  IfStateIsOdd			// If falling and landed, reset to no-jump.
    IfXIsMoreThanY		// If hit ground
      tmpargument = 1
      SetState

      tmpargument = 0		// If slam code set, do a kapow!
      GetXY
      tmpy = 2
      IfXIsEqualToY
        tmpx = selfx
        tmpy = selfy
        tmpdistance = selfz
        tmpargument = 3
        SpawnExactParticle
        tmpargument = 0
        GetXY
        tmpx = 0
        SetXY
  Else				// If in air and falling, increment jump code.
    tmpy = 0 - 5
    IfXIsLessThanY
      GetState
      tmpargument = tmpargument + 1
      SetState

      tmpargument = 0		// If slam code set, go down!
      GetXY
      tmpy = 1
      IfXIsEqualToY
        tmpargument = ACTIONBB
        DoActionOverride
        tmpargument = 0 - 1000
        AccelerateUp
        tmpargument = 2
        tmpdistance = rand & 4095 + 8000
        PlaySound

        tmpargument = 0
        GetXY
        tmpx = 2
        SetXY
  SetTargetToOldTarget

//DebugMessage

End
