/*
 * Called every frame to update the link's state
 */
void TemporalClass::Update() {
  if ( this->Victim && this->Victim->TemporalTargettingMe == this && this->PrevTemporal ) {
    // special bug workaround? doesn't normally happen
    this->Victim->TemporalTargettingMe = 0;
    this->Victim->IsBeingWarpedOut = 0;
    this->Detach();
  }
  else {
    if ( this->OwnerUnit && this->OwnerUnit->OpenTopped && this->Victim ) {
      dwXYZ *xyzVictim = this->Victim->GetCoords();
      dwXYZ *xyzSource = this->OwnerUnit->GetCoords();
      if ( FloatToInt(float_sqrt(XYZ_Distance(xyzVictim, xyzSource))) > Rules->OpenToppedWarpDistance * 256 ) // 256 leptons / cell
        this->LetGo();
    }
    TemporalClass *nextNode = this->NextTemporal;
    int helperDamage = 0;
    if ( nextNode )
      helperDamage = nextNode->GetWarpPerStep(1);
    int weaponSlot = this->OwnerUnit->SelectWeapon(NULL); // NULL = no target, which returns primary
    WeaponTypeClass *weapon = this->OwnerUnit->GetWeapon(this->OwnerUnit, weaponSlot);
    int oldWarp = this->WarpRemaining;
    int warpStep = weapon->WeaponType->Damage;
    this->WarpPerStep = warpStep;
    int remainWarp = oldWarp - (helperDmg + warpStep);
    this->WarpRemaining = remainWarp;
    if ( remainWarp <= 0 ) {
      if ( this->Victim ) {
        new AnimClass(
          Rules->WarpAway,   // AnimType 
          this->Victim->pos, // Coords
          0, 
          1,                 // RepeatTimes
          sizeof(AnimClass),
          0,                 // ForceZAdjust
          0);
      }
      else {
        this->Victim = NULL;
        this->NextTemporal = NULL;
        this->PrevTemporal = NULL;
        this->SourceSW = NULL;
        this->field_38 = NULL;
        if ( this->OwnerUnit )
          this->OwnerUnit->AssumeMissionComplete(0, 1);
      }
      if ( this->Victim ) { // Bye bye 
        if ( this->OwnerUnit->vt->GetType()->Trainable ) {
          int victimCost = this->Victim->GetType()->GetActualCost(this->Victim->OwningPlayer);
          int ownerCost  = this->OwnerUnit->GetType()->GetActualCost(this->OwnerUnit->OwningPlayer);
          this->OwnerUnit->Experience->Add(ownerCost, victimCost);
        }
        if ( this->Victim->What_Am_I() == IS_BUILDING ) {
          if ( this->Victim ) {
            if ( this->Victim->GetOccupierCount() > 0 )
              this->Victim->EvictOccupiers(NULL); // evict all
            if ( !MutexRadioCommands ) { // MutexRadioCommands is a global lock that screws up a lot of stuff
              while ( this->Victim->Passengers.first ) {
                TechnoClass *passenger = this->Victim->Passengers->EjectFirstPassenger();
                if ( passenger )
                  passenger->~TechnoClass(1); // destructor - delete object
              }
            }
          }
          if ( this->SourceSW ) {
            this->SourceSW->UpdateTimerState(0);
            this->SourceSW = NULL;
          }
          if ( this->Victim->Bunker ) {
            BuildingClass *Bunker;
            if ( this->Victim )
              Bunker = this->Victim;
            else
              Bunker = NULL;
            Bunker->UnloadBunker(); // orders any vehicles inside to move out to surrounding area
          }
          if ( this->Victim->SlaveManager )
            this->Victim->SlaveManager->ReleaseSlaves(this->OwnerUnit, NULL); // (Killer, forcedNewHouse)
          this->Victim->DestroyedBy(this->OwnerUnit);
          this->Victim->AnnounceDestruction(this->OwnerUnit);
          this->Victim->UnInit();
          this->Victim->OwningPlayer->RecheckTechLevels = 1;
        }
        else {
          BuildingClass *BunkerX;
          if ( this->Victim->Bunker ) {
            if ( this->Victim->Bunker )
              BunkerX = this->Victim->Bunker;
            else
              BunkerX = NULL;
            BunkerX->ClearBunker(); // orders bunker walls to go down
          }
          if ( this->Victim->SlaveManager )
            this->Victim->SlaveManager->ReleaseSlaves(this->OwnerUnit, this->OwningPlayer);
          this->Victim->DestroyedBy(this->OwnerUnit);
          this->Victim->AnnounceDestruction(this->OwnerUnit);
          this->Victim->UnInit();
        }
        if ( this->OwnerUnit )
          this->OwnerUnit->AssumeMissionComplete(0, 1);
      }
      this->Victim = NULL;
      this->NextTemporal = NULL;
      this->PrevTemporal = NULL;
      this->SourceSW = NULL;
      this->field_38 = NULL;
      if ( this->OwnerUnit )
        this->OwnerUnit->AssumeMissionComplete(0, 1);
    }
  }
}