// Magic Spell: Bridge of Light
//  by Pteromys of Melon Island... http://melonisland.net
// Usage: Hold down attack to charge up a spell.  A glow
//   will show the bridge's extent.  Release to create a
//   bridge.
// Tips:
//   The longer the spell charges, the longer the bridge. A
//     more experienced wizard will be able to create
//     longer bridges.
//   The last bridge created can be cut down by aiming a
//     spell at its base end.  A flame will appear on it to
//     show that it will be destroyed.
//   Bridges are sustained by magic and can be destroyed by
//     disenchants.  Long bridges drain significant amounts
//     of mana.
//   It is impossible to sustain more than one bridge at a
//     time.  Only the last bridge created will be kept,
//     while previous bridges will count down 5 seconds
//     before expiring.
//   You can still sustain a bridge if the spellbook is put
//     away, but not if it is dropped from your hands.
//
// Guide to object states:
//  0  Spellbook
//  1  Bridge segment falling into position
//  2  Bridge segment of the last bridge created
//  3  Bridge segment counting down to expiration
//  4  Bridge segment about to vanish
//  5+ Bridge segment just spawned
// Content variable usage:
//  As spellbook, records the charge.
//  As bridge segment, records float height.
// Known issues:
//  You can't drive mounts over the bridge.
//  Going "trigger happy" and casting hundreds of bridges
//    in quick succession has a small chance of crashing
//    the game.
//

IfSpawned
  IfStateIs0				// Spellbook
    tmpargument = 0
    SetState
    KeepAction
  Else					// Energy Beam
    // Bridge segment
    MakeNameUnknown
    NotAnItem
    MakeCrushValid

    tmpargument = 0			// Make it invisible while it's falling
    SetLight

    SetTargetToOwner
    tmpargument = targetz + 16
    SetContent				// Store the original z position.
    tmpx = selfx
    tmpy = selfy
    tmpargument = 0
    SetXY				// Store the original xy position

    GetState				// More bridge segments?
    tmpx = tmpargument
    tmpy = 5
    IfXIsMoreThanY
      tmpx = selfx
      tmpy = selfy
      tmpturn = selfturn
      tmpdistance = 64
      Compass
      tmpdistance = selfz + 100
      SpawnCharacterXYZ
        GetState
        tmpargument = tmpargument - 1	// Child will spawn more
        SetChildState
        EnchantChild
    Else
      tmpargument = 2			// Make the last segment glow
      tmpdistance = 1
      SpawnAttachedParticle

    GetContent				// Very clever, IMHO, test to find if it's the first segment
    tmpx = selfz - tmpargument		// First thing was spawned 100 above the owner, so dist must be near
    tmpy = 120				// Tolerance of 20
    IfXIsLessThanY
      SetTargetToOwner			// Tell the spellmaster (the spellbook, actually) "I'm here"
        SetTargetToTargetLeftHand
          tmpargument = [BRDG]
          IfTargetHasSpecialID
            tmpargument = selfindex < 24	// CreateOrder seems funky. Did it by hand instead.
            OrderTarget
      SetTargetToOwner
        SetTargetToTargetRightHand
          tmpargument = [BRDG]
          IfTargetHasSpecialID
            tmpargument = selfindex < 24
            OrderTarget
      tmpargument = 2			// Make the first segment glow
      tmpdistance = 1
      SpawnAttachedParticle

      tmpx = 1
      tmpy = 1
      tmpargument = 1
      SetXY				// Remember that it's the first segment
    Else
      tmpx = 1
      tmpy = 0
      tmpargument = 1
      SetXY				// Remember that it's not the first segment
    tmpargument = 1
    SetState
    tmpargument = 100			// Wait before incompletion kill.
    SetTime

IfChanged
  // It's a spell in hand
  tmpargument = 0
  SetState
  KeepAction

//Bridge segment event handling
IfStateIs0
  GetState //nop
Else
  IfStateIs1
    IfTimeOut				// If incomplete, then kill from this point forward.
      UndoEnchant
      tmpargument = 5
      SetTime
      tmpargument = 4
      SetState
  IfStateIs2
    tmpx = rand & 65535
    tmpy = 1024
    IfXIsLessThanY
      tmpx = selfx
      tmpy = selfy
      tmpdistance = selfz
      tmpargument = 3
      SpawnExactParticle
    tmpx = selflife
    tmpy = 512
    IfXIsLessThanY			// If disenchanted
      UndoEnchant
      tmpx = selfx
      tmpy = selfy
      tmpdistance = selfz
      tmpargument = 1
      SpawnExactParticle
      tmpargument = 5
      SetTime
      tmpargument = 4
      SetState
    tmpargument = 0
    IfOrdered
      tmpx = selforder
      tmpy = 3349
      IfXIsEqualToY
        SetTargetToSelf
        SetOwnerToTarget
        EnchantTarget
        tmpargument = 1
    tmpx = selflife
    tmpy = 768
    IfXIsEqualToY
      tmpargument = 1
    tmpx = tmpargument
    tmpy = 1
    IfXIsEqualToY
      SetTargetToSelf
      SetOwnerToTarget
      EnchantChild
      tmpargument = 100
      SetTime
      tmpargument = 3
      SetState
  IfStateIs3
    tmpx = rand & 65535
    tmpy = 1024
    IfXIsLessThanY
      tmpx = selfx
      tmpy = selfy
      tmpdistance = selfz
      tmpargument = 3
      SpawnExactParticle
    tmpx = selflife
    tmpy = 768
    IfXIsLessThanY			// If disenchanted
      UndoEnchant
      tmpx = selfx
      tmpy = selfy
      tmpdistance = selfz
      tmpargument = 1
      SpawnExactParticle
      tmpargument = 5
      SetTime
      tmpargument = 4
      SetState
    IfTimeOut
      tmpargument = 1
      ChangeArmor

      tmpargument = 1
      GetXY
      IfXIsEqualToY
        tmpargument = 4
        SendMessageNear
      tmpargument = 4
      SetState
      tmpargument = 150
      SetTime
  IfStateIs4
    tmpx = rand & 65535
    tmpy = 1024
    IfXIsLessThanY
      tmpx = selfx
      tmpy = selfy
      tmpdistance = selfz
      tmpargument = 5
      SpawnExactParticle
    IfTimeOut
      tmpargument = 1
      GetXY
      IfXIsEqualToY
        tmpargument = 1
        tmpdistance = 11025
        PlaySound
        tmpargument = 5
        SendMessageNear
      DisaffirmCharacter
      SetTargetToSelf
      DisenchantTarget

      tmpargument = ACTIONKA
      DoActionOverride
      tmpargument = 100			// So I don't call this part again
      SetTime

  IfCrushed				// Doors can truncate the bridge
    tmpargument = 1
    tmpdistance = 11025
    PlaySound
    tmpargument = 7
    SendMessageNear
    tmpargument = 5
    SetTime
    tmpargument = 4
    SetState
    UndoEnchant

  tmpargument = 0
  GetXY			// set x,y to original
  tmpdistance = tmpy	// original y
  tmpy = selfx		// current x
  IfXIsEqualToY		// compare current to orig
    tmpy = tmpdistance	// original y
    tmpx = selfy	// current y
    IfXIsEqualToY	// compare current to orig
      GetState //nop
    Else
      GetXY
      Teleport
  Else
    GetXY
    Teleport

  GetContent		//stay at height
  tmpx = tmpargument
  tmpy = selfz
  IfXIsMoreThanY
    IfStateIs1
      tmpargument = ACTIONMJ
      DoActionOverride
      KeepAction
      tmpargument = 127
      SetLight
      tmpargument = 2
      SetState
    SetTargetToSelf
    tmpargument = 1 - targetspeedz
    tmpargument = tmpargument < 1 + tmpargument < 3 + tmpargument < 2 //long-way multiply by 100
    AccelerateUp

// Spell AI
IfStateIs0
  // Listen for child - fixed 3 Sep. 2004
  IfOrdered
    TranslateOrder
    tmpargument = [BRDG]
    IfTargetHasSpecialID
      SetOldTarget
    Else
      SetTargetToOldTarget
  // Remove the charge
  IfTakenOut
    tmpargument = 0
    SetContent
    SetTargetToWhoeverIsHolding
      IfTargetIsAPlayer
        tmpargument = 1
        IfNameIsKnown
          tmpargument = 2
        SendMessageNear
    SetTargetToOldTarget
  // Allow it to be used
  IfUsed
    SetTargetToWhoeverIsHolding
    SetOwnerToTarget
    tmpargument = [WMAG]
    IfTargetHasSkillID
      GetContent
      tmpx = tmpargument
      tmpy = 4056			// Max charge
      IfXIsLessThanY
        tmpy = targetmanaflow
        IfXIsLessThanY
          tmpx = 4
          tmpargument = tmpx
          CostTargetMana
            GetContent
            tmpargument = tmpargument + 8
            SetContent

      tmpargument = 0
      SetTargetToOldTarget		// Restore first-child from old target slot
      IfFacingTarget
        SetTargetToWhoeverIsHolding
        IfTargetIsOldTarget
          GetState //nop
        Else
          SetTargetToOldTarget
          tmpx = targetdistance
          tmpy = 100
          IfXIsMoreThanY
            tmpy = 700
            IfXIsLessThanY
              IfTimeOut
                tmpx = targetx
                tmpy = targety
                tmpdistance = targetz
                tmpargument = 1
                SpawnExactParticle
                tmpargument = 2
                SetTime
              tmpargument = 1
      tmpx = tmpargument
      tmpy = 0
      IfXIsEqualToY			// If failed to find bridge to cut
        IfTimeOut
          SetTargetToOwner
          GetContent
          tmpdistance = tmpargument > 2 + 128 //tmpargument > 8 + 2 < 6
          tmpturn = targetturn
          tmpx = targetx
          tmpy = targety
          Compass
          tmpdistance = targetz
          tmpargument = 0
          SpawnExactParticle
          tmpargument = 2
          SetTime
    SetTargetToOldTarget
  Else
    GetContent
    tmpx = tmpargument
    tmpy = 255
    IfXIsMoreThanY
      tmpargument = 0
      IfFacingTarget			// If I'm facing the old bridge's first segment
        SetTargetToWhoeverIsHolding
        IfTargetIsOldTarget
          GetState //nop
        Else
          SetTargetToOldTarget
          tmpx = targetdistance
          tmpy = 100
          IfXIsMoreThanY		// If the spellmaster is at a safe distance
            tmpy = 700
            IfXIsLessThanY		// If we're not *too* far
              UndoEnchant			// Cut the bridge!
              SetTargetToWhoeverIsHolding
              tmpargument = 6
              SendMessageNear

              GetContent
              tmpargument = tmpargument - 256 > 1
              PumpTarget
              tmpargument = 1
      tmpx = tmpargument		// If I could not find a bridge to cut...
      tmpy = 0
      IfXIsEqualToY
        SetTargetToOldTarget
        tmpargument = [BRDG]
        IfTargetHasSpecialID
          tmpargument = 3349		// Arbitrary order number to disconnect link to bridge (hex D15)
          OrderTarget
          UnsparkleIcon
        SetTargetToWhoeverIsHolding
        SetOwnerToTarget
        tmpargument = ACTIONZA
        CorrectActionForHand
        TargetDoAction
        tmpx = targetx
        tmpy = targety
        tmpturn = targetturn
        tmpdistance = 60
        Compass
        tmpdistance = targetz + 100
        SpawnCharacterXYZ			// Make the first bridge segment
          // Set starting state
          GetContent
          tmpargument = tmpargument > 8 + 6	// (d5) Child will spawn more
          SetChildState
          EnchantChild
            tmpargument = YELLOW
            SparkleIcon

          // Identify stuff
          MakeNameKnown

          // Cast sound
          tmpargument = 0
          PlaySound

          tmpargument = 3
          SendMessageNear
        Else
          // Tried to cast in a wall?
          tmpargument = 0
          SendMessageNear
    Else
      tmpy = 0
      IfXIsMoreThanY			// If it was actually pumped at all
        // Didn't pump it enough
        tmpargument = 0
        SendMessageNear
    tmpargument = 0
    SetContent

  // Return to spellbook, Do last!
  IfDropped
    SetTargetToOldTarget
    tmpargument = [BRDG]
    IfTargetHasSpecialID
      tmpargument = 3349
      OrderTarget
      UnsparkleIcon
    tmpargument = 0
    SetContent
    BecomeSpellbook
    DisaffirmCharacter
    tmpargument = ACTIONJB
    DoAction
    KeepAction

End
