Beispiel #1
0
    /// <summary>
    /// Creates a newText scrollup effect
    /// </summary>
    /// <param id="tile">Tile where the effect will be created</param>
    /// <param id="duration">How long the effect will last</param>
    /// <param id="speed">How fast the newText will flow</param>
    /// <param id="newText">Text of the effect</param>
    public void CreateTextScrollUpEffect(IScriptTile tile, int duration, int speed, string text)
    {
      Tile tileCasted = (Tile)tile;

      float x = tileCasted.MapPosition.X;
      float y = tileCasted.MapPosition.Y - tileCasted.Elevation * MapBoard.ELEVATION_SCALING;
      Vector2 position = new Vector2(x, y).Round();

      GameEffect gEff = new ScrollTextEffect(text, position, duration, new Vector2(0, -1) * speed);
      gEff.Initialize(this, tileCasted);
      this.Effects.Add(gEff);
      SendData(Network.MakeServerMessage(MessageType.GameEffectCreate, gEff));
    }
Beispiel #2
0
    /// <summary>
    /// Carries out the order
    /// </summary>
    private void UpdateDoOrder()
    {
      GameEffect gEff = null;
      Building bldg = null;
      Tile tile = null;
      BuildingDb bldgEntry = null;
      switch (Order)
      {
        case GameObjectOrder.Idle:
          #region
          Logger.Log(string.Format("Unit #{0}:{1} finished move order", this.ObjectUID, this.Entry.Id), "Server update");

          if (!game.IsServer)
          {
            State = GameObjectState.Idle;
          }
          else
          {
            // Find position along traveling vector available for movement
            bool closeFound = false;
            if (NearestTile == null)
            {
              // Nearest Tile not yet updated
              return;
            }

            // If standing too close to other unit, move aside (if possible)
            foreach (var closeUnit in NearestTile.Units)
            {
              // Ignore self
              if (closeUnit == this) continue;
              // Ignore moving units
              if (closeUnit.State == GameObjectState.MovingToOrder) continue;
              // Check minimal distance
              if ((closeUnit.MapPosition - this.MapPosition).Length() < MIN_IDLE_DISTANCE)
              {
                Vector2 vector;
                // If the map positions aren't same, move in the same amount you are standing towards the other unit
                if (this.MapPosition != closeUnit.MapPosition)
                {
                  vector = this.MapPosition - closeUnit.MapPosition;
                  vector.Normalize();
                  OrderPosition = this.MapPosition + vector * DODGE_DISTANCE;
                }
                // If the position is same, come up with some vector
                else
                {
                  // Try to move in same amount you are standing from the origin position of the map
                  vector = this.MapPosition;
                  vector.Normalize();
                  if (NearestTile.Units.Any(q => (q.MapPosition - OrderPosition).Length() >= MOVEMENT_RANGE))
                  {
                    OrderPosition = this.MapPosition + vector * DODGE_DISTANCE;
                  }
                  // If the place is already occupied, try inverted vector and orthogonal vectors
                  else
                  {
                    Vector2 ort = new Vector2(-vector.Y, vector.X);
                    Queue<Vector2> attemptVector = new Queue<Vector2>();
                    attemptVector.Enqueue(ort); attemptVector.Enqueue(-vector);
                    attemptVector.Enqueue(-ort); attemptVector.Enqueue(vector);
                    Vector2 projectedPosition = default(Vector2);
                    while (attemptVector.Count > 0)
                    {
                      projectedPosition = this.MapPosition + attemptVector.Dequeue() * DODGE_DISTANCE;
                      if (NearestTile.Units.Any(q => (q.MapPosition - projectedPosition).Length() >= MOVEMENT_RANGE))
                        break;
                    }
                    // If everything else fails, use last failed
                    OrderPosition = projectedPosition;
                  }
                }

                State = GameObjectState.MovingToOrder;
                closeFound = true;
                game.SendData(Network.MakeServerMessage(MessageType.GameObjUpdate, this));
                break;
              }
            }
            // If there is no other unit, become idle
            if (!closeFound)
            {
              State = GameObjectState.Idle;
            }
            else
            {
              OrderTarget = null;
              OrderRange = MOVEMENT_RANGE;
            }
          }
          #endregion
          break;
        case GameObjectOrder.Attack:
          #region
          if (OrderTarget == null) return;

          if (OrderTarget == this)
          {
            CancelOrders(true);
            return;
          }

          // Animation effect
          TextureTileSet2D tex = new TextureTileSet2D(UI.Instance.GetTexture("combat"), 24, 1);
          Vector2 p = (Position + OrderTarget.Position) / 2;
          gEff = new AnimationEffect(tex, p + AlignmentOffset + Size / 2 - tex.FrameSize / 2, 24, 10, true);
          gEff.Initialize(game, NearestTile);
          this.game.Effects.Add(gEff);

          if (game.IsServer)
          {
            // Apply modifiers
            float amount = entry.AttackAmount;
            if (entry.Modifiers != null)
              for (int i = 0; i < entry.Modifiers.Length; i++)
                if (entry.Modifiers[i].Entry == OrderTarget.Entry)
                  amount *= entry.Modifiers[i].Mod;

            Logger.Log(string.Format("Unit #{0}:{1} attacking (-{2}) #{3}:{4} (before {5}/?)",
              this.ObjectUID, entry.Id, (int)amount, OrderTarget.ObjectUID, OrderTarget.Entry.Id,
              OrderTarget.Health), "Server update");

            // Apply damage
            OrderTarget.ReceiveDamage((int)amount);

            // Check whether target is alive
            if (OrderTarget.Health == 0)
            {
              CancelOrders(true);
              return;
            }
          }
          #endregion
          break;
        case GameObjectOrder.Construct:
          #region
          if (game.IsServer)
          {
            if (OrderTarget != null)
            {
              Debug.Assert(OrderTarget.GetEntityType == GameEntityType.Building);
              Logger.Log(string.Format("Unit #{0}:{1} constructing (+{2}) effect #{3}:{4} (before {5}/100)",
                this.ObjectUID, entry.Id, entry.ConstructAmount, OrderTarget.ObjectUID, OrderTarget.Entry.Id,
                ((Building)OrderTarget).Construction), "Server update");

              // Construct part of the building
              ((Building)OrderTarget).ConstructionProgress(entry.ConstructAmount);

            }
            else
            {
              Logger.Log(string.Format("Unit #{0}:{1} starting construction of {2}",
                this.ObjectUID, entry.Id, OrderEntry.Id), "Server update");
              tile = game.Map.GetTileFlat(OrderPosition);

              // Check whether building can be constructed at given position
              if (!Building.CanPlace(game.Map, tile) || Owner.Fow[tile.X, tile.Y] == 0)
              {
                Logger.Log(string.Format("Unit #{0}:{1} construction of {2} aborted - unable to place",
                  this.ObjectUID, entry.Id, OrderEntry.Id), "Server update");
                CancelOrders(true);
                return;
              }

              bldgEntry = (BuildingDb)OrderEntry;

              // Check whether building can be built more than once
              if (bldgEntry.OnlyOneAllowed && Owner.Buildings.Any(q => q.Entry == bldgEntry))
              {
                ScrollUpMessage("Only one such building allowed at a time", 100, true);
                CancelOrders(true);
                return;
              }

              if (bldgEntry.UnlockedBy != null)
              {
                bldg = Owner.Buildings.FirstOrDefault(q => q.Entry == bldgEntry.UnlockedBy);
                if (bldg == null || !bldg.Constructed)
                {
                  ScrollUpMessage("Building unavailable", 100, true);
                  CancelOrders(true);
                  return;
                }
              }

              // Check whether player canCast enough resources
              if (bldgEntry.Cost != null)
              {
                foreach (var costEntry in bldgEntry.Cost)
                {
                  if (Owner.ResourceStockpiles[costEntry.Entry] < costEntry.Amount)
                  {
                    ScrollUpMessage("Not enough resources", 100, true);
                    CancelOrders(true);
                    return;
                  }
                }
              }

              // Place new building
              bldg = new Building();
              bldg.Initialize(bldgEntry, game, Owner, tile);
              bldg.InitializeGraphics();
              game.SendData(Network.MakeServerMessage(MessageType.GameObjCreate, bldg));

              // Deduct resources from the player
              if (bldgEntry.Cost != null)
                foreach (var costEntry in bldgEntry.Cost)
                  Owner.ResourceStockpiles[costEntry.Entry] -= costEntry.Amount;

              // Set target for this unit (so it will automatically construct the building)
              OrderTarget = bldg;
              OrderEntry = null;

              game.SendData(Network.MakeServerMessage(MessageType.PlayerUpdate, Owner));
              game.SendData(Network.MakeServerMessage(MessageType.GameObjUpdate, this));
            }
          }
          #endregion
          break;
        case GameObjectOrder.Spell:
          #region
          EffectDb effect = (EffectDb)OrderEntry;
          if (game.IsServer)
          {
            // Check whether spell can be cast
            if (effect.UnlockedBy != null)
            {
              bldg = Owner.Buildings.FirstOrDefault(q => q.Entry == effect.UnlockedBy);
              if (bldg == null || !bldg.Constructed)
              {
                CancelOrders(true);
                return;
              }
            }

            Logger.Log(string.Format("Unit #{0}:{1} casting {2}", this.ObjectUID, entry.Id, OrderEntry.Id), "Server update");
            switch (effect.Spell.Target)
            {
              case SpellEntry.TargetType.Tile:
                tile = game.Map.GetTileFlat(OrderPosition);
                gEff = new GameEffect(effect, this, tile);
                gEff.Initialize(game, tile);
                this.game.Effects.Add(gEff);
                break;
              case SpellEntry.TargetType.GameEntity:
                Debug.Assert(OrderTarget != null);
                gEff = new GameEffect(effect, this, OrderTarget);
                gEff.Initialize(game, OrderTarget.NearestTile);
                this.game.Effects.Add(gEff);
                break;
              default:
                throw new Exception("Undefined spell type");
            }
            game.SendData(Network.MakeServerMessage(MessageType.GameEffectCreate, gEff));
          }
          if (!effect.AutoRepeat)
          {
            State = GameObjectState.Idle;
          }
          #endregion
          break;
        case GameObjectOrder.Gather:
          #region
          if (OrderTarget.GetEntityType == GameEntityType.Building)
          {
            Debug.Assert(carryType != null);

            if (carryAmount > 0)
            {
              ScrollUpMessage(string.Format("Returned {0} of {1}", carryAmount, carryType.Name), 50);
            }

            if (game.IsServer)
            {
              // First zoneFound only transfers carried resources and sets order delay, second time around unit moves back to resource
              if (carryAmount > 0)
              {
                Debug.Assert(((BuildingDb)OrderTarget.Entry).ResourceCenter);

                Logger.Log(string.Format("Unit #{0}:{1} returned +{2} of {3} (before {4}) to #{5}:{6}",
                  this.ObjectUID, this.Entry.Id, carryAmount, carryType.Id, Owner.ResourceStockpiles[carryType],
                  OrderTarget.ObjectUID, OrderTarget.Entry.Id), "Server update");

                // Give resources to player
                Owner.ResourceStockpiles[carryType] += carryAmount;
                carryAmount = 0;
                OrderTimeout = GATHER_RETURN_DELAY;

                game.SendData(Network.MakeServerMessage(MessageType.GameObjUpdate, this));
                game.SendData(Network.MakeServerMessage(MessageType.PlayerUpdate, Owner));
              }
              else
              {
                if (lastGatheredResource.Amount == 0)
                {
                  CancelOrders(true);
                  return;
                }
                // Head towards resource
                Debug.Assert(lastGatheredResource != null);
                OrderTarget = lastGatheredResource;
                OrderRange = entry.GatherRange;
                OrderTimeout = entry.GatherSpeed;

                game.SendData(Network.MakeServerMessage(MessageType.GameObjUpdate, this));
              }
            }
          }
          else if (OrderTarget.GetEntityType == GameEntityType.Resource)
          {
            Debug.Assert(carryAmount == 0 || carryType == (ResourceDb)OrderTarget.Entry);
            Resource res = (Resource)OrderTarget;

            if (res.Cooldown > 0) break;

            if (game.IsServer)
            {

              if (carryAmount == 0)
              {
                carryType = (ResourceDb)res.Entry;
              }

              if (res.Amount == 0)
              {
                CancelOrders(true);
                return;
              }

              int take = res.Take(entry.GatherAmount);

              Logger.Log(string.Format("Unit #{0}:{1} gathered +{2} of {3} (before {4}) from #{5}:{6}",
                this.ObjectUID, this.Entry.Id, take, carryType.Id, carryAmount,
                OrderTarget.ObjectUID, OrderTarget.Entry.Id), "Server update");

              carryAmount += take;

              game.SendData(Network.MakeServerMessage(MessageType.GameObjUpdate, res));
              ScrollUpMessage(string.Format("Gathered {0} of {1}", take, OrderTarget.Entry.Name), 30, true);
            }
          }
          else
          {
            CancelOrders(true);
          }

          #endregion
          break;
        case GameObjectOrder.Train:
          #region
          if (game.IsServer)
          {
            bldg = (Building)OrderTarget;
            // If the building is already training, wait
            if (bldg.Spawner != null && bldg.Spawner.Active) break;
            bldgEntry = (BuildingDb)bldg.Entry;

            bool noEntry = true;
            BuildingDb.TrainEntry trainEntry = default(BuildingDb.TrainEntry);
            if (bldgEntry.Trains != null)
            {
              foreach (var iterTrainEntry in bldgEntry.Trains)
              {
                if (iterTrainEntry.TrainFrom == this.entry)
                {
                  noEntry = false;
                  trainEntry = iterTrainEntry;
                  break;
                }
              }
            }

            if (noEntry)
            {
              ScrollUpMessage("Unable to train this unit in this building", 100, true);
              CancelOrders(true);
              return;
            }

            // Check whether player canCast enough resources
            if (trainEntry.Cost != null)
            {
              foreach (var costEntry in trainEntry.Cost)
              {
                if (Owner.ResourceStockpiles[costEntry.Entry] < costEntry.Amount)
                {
                  ScrollUpMessage("Not enough resources", 100, true);
                  CancelOrders(true);
                  return;
                }
              }
            }

            Logger.Log(string.Format("Unit #{0}:{1} start training in #{2}:{3} towards {4}",
              this.ObjectUID, this.Entry.Id, OrderTarget.ObjectUID, OrderTarget.Entry.Id, bldgEntry.Id), "Server update");

            // Initialize spawning of the new unit
            bldg.StartUnitSpawner(trainEntry.TrainTo, trainEntry.Speed);

            // Deduct resources from the player
            if (trainEntry.Cost != null)
              foreach (var costEntry in trainEntry.Cost)
                Owner.ResourceStockpiles[costEntry.Entry] -= costEntry.Amount;
            game.SendData(Network.MakeServerMessage(MessageType.PlayerUpdate, Owner));

            // Info newText
            gEff = new ScrollTextEffect("Training", Position, 50, new Vector2(0, -1));
            gEff.Initialize(game, bldg.NearestTile);
            this.game.Effects.Add(gEff);
            game.SendData(Network.MakeServerMessage(MessageType.GameEffectCreate, gEff));

            // Kill the unit
            Kill(true);
            return;
          }
          #endregion
          break;
      }
    }
Beispiel #3
0
    /// <summary>
    /// Gives unit an order with specified parameters
    /// </summary>
    /// <param id="order">New game object order</param>
    /// <param id="orderParam">Order's EntryDb parameter</param>
    /// <param id="targetTile">Tracked tile at the moment of giving order</param>
    /// <param id="targetGameObject">Tracked game object at the moment of giving order</param>
    /// <returns>Returns true if the order was successfully applied to the game object</returns>
    public override bool SetOrder(GameObjectOrder order, EntryDb orderParam, Tile targetTile, GameObject targetGameObject)
    {
      if (this.game.IsServer) Debug.Fail("Server isn't supposed to call this routine");

      if (!base.SetOrder(order, orderParam, targetTile, targetGameObject))
      {
        game.SendData(Network.MakeClientMessage(MessageType.GameObjUpdate, this));
        return false;
      }

      if (!CanDoOrder(order))
      {
        GameEffect ge = new ScrollTextEffect("Unit cannot attack", Position, 50, new Vector2(0, -1f));
        ge.Initialize(game, NearestTile);
        this.game.Effects.Add(ge);

        CancelOrders(true);
        return false;
      }

      BuildingDb bldgEntry;

      switch (order)
      {
        case GameObjectOrder.Idle:
          #region
          if (targetTile == null) return false;
          OrderTarget = null;
          OrderRange = MOVEMENT_RANGE;
          OrderPosition = targetTile.MapPosition + new Vector2(MapBoard.TILE_XSPACING, MapBoard.TILE_YSPACING) / 2;
          #endregion
          break;
        case GameObjectOrder.Attack:
          #region
          if (targetGameObject == null) return false; // Hit something
          if (targetGameObject == this) return false; // Don't hit yourself
          OrderTarget = targetGameObject;
          OrderRange = entry.AttackRange;
          OrderTimeout = entry.AttackSpeed;
          #endregion
          break;
        case GameObjectOrder.Construct:
          #region
          OrderRange = entry.ConstructRange;
          OrderTimeout = entry.ConstructSpeed;

          if (targetGameObject != null && targetGameObject.GetEntityType == GameEntityType.Building)
          {
            OrderTarget = targetGameObject;
            OrderEntry = null;
          }
          else if (targetGameObject == null || targetGameObject.GetEntityType == GameEntityType.Unit)
          {
            if (orderParam == null) return false;
            bldgEntry = (BuildingDb)orderParam;
            if (bldgEntry.OnlyOneAllowed && Owner.Buildings.Any(q => q.Entry == orderParam))
            {
              ScrollUpMessage("Only one such building allowed at a time", 50, false);
              CancelOrders(true);
              return false;
            }
            if (bldgEntry.UnlockedBy != null)
            {
              Building bldg = Owner.Buildings.FirstOrDefault(q => q.Entry == bldgEntry.UnlockedBy);
              if (bldg == null || !bldg.Constructed)
              {
                ScrollUpMessage("Building unavailable", 100, true);
                CancelOrders(true);
                return false;
              }
            }

            OrderTarget = null;
            OrderEntry = (BuildingDb)orderParam;
            OrderPosition = targetTile.MapPosition + new Vector2(MapBoard.TILE_XSPACING, MapBoard.TILE_YSPACING) / 2;
          }
          #endregion
          break;
        case GameObjectOrder.Spell:
          #region

          EffectDb effect = (EffectDb)orderParam;

          if (effect.UnlockedBy != null)
          {
            Building bldg = Owner.Buildings.FirstOrDefault(q => q.Entry == effect.UnlockedBy);
            if (bldg == null || !bldg.Constructed)
            {
              ScrollUpMessage("Spell unavailable", 100, true);
              CancelOrders(true);
              return false;
            }
          }

          OrderEntry = effect;
          OrderRange = effect.CastRange;
          OrderTimeout = effect.Cooldown;
          switch (effect.Spell.Target)
          {
            case SpellEntry.TargetType.Tile:
              if (targetTile == null) return false;
              OrderRange = effect.CastRange;
              OrderPosition = targetTile.MapPosition + new Vector2(MapBoard.TILE_XSPACING, MapBoard.TILE_YSPACING) / 2;
              break;
            case SpellEntry.TargetType.GameEntity:
              if (targetGameObject == null) return false;
              OrderTarget = targetGameObject;
              break;
          }
          #endregion
          break;
        case GameObjectOrder.Gather:
          #region
          if (targetGameObject == null) return false;
          OrderTarget = targetGameObject;
          if (targetGameObject.GetEntityType == GameEntityType.Resource)
          {
            lastGatheredResource = (Resource)targetGameObject;
          }
          else if (targetTile != null && targetTile.Resource != null)
          {
            lastGatheredResource = targetTile.Resource;
          }
          else
          {
            CancelOrders(true);
            return false;
          }
          OrderRange = entry.GatherRange;
          OrderTimeout = entry.GatherSpeed;
          #endregion
          break;
        case GameObjectOrder.Train:
          #region
          if (targetGameObject == null) return false;
          if (targetGameObject.GetEntityType != GameEntityType.Building) return false;
          bldgEntry = (BuildingDb)((Building)targetGameObject).Entry;
          if (bldgEntry.Trains == null) return false;
          if (bldgEntry.Trains.All(p=>p.TrainFrom != this.Entry)) return false;

          OrderTarget = targetGameObject;
          OrderRange = MOVEMENT_RANGE;
          OrderTimeout = TRAIN_QUEUE_CHECK_TIMEOUT;
          #endregion
          break;
        default:
          break;
      }
      State = GameObjectState.MovingToOrder;
      this.Order = order;
      game.SendData(Network.MakeClientMessage(MessageType.GameObjUpdate, this));
      return true;
    }
Beispiel #4
0
 /// <summary>
 /// Creates a new instance of the GameEffect class using the serialized data
 /// </summary>
 /// <param id="line">String array containing the serialized data</param>
 /// <param id="position">Current position in the array</param>
 /// <param id="context">Context of the serialized data, game where this INetworkSerializable object is in</param>
 /// <returns>GameEffect created using the provided serialized data</returns>
 public static GameEffect Create(string[] line, ref int position, WildmenGame context)
 {
   GameEffect e = null;
   EffectTypes et = (EffectTypes)int.Parse(line[position++]);
   switch (et)
   {
     case EffectTypes.Scripted:
       e = new GameEffect();
       break;
     case EffectTypes.UnitDeath:
       e = new UnitDeathEffect();
       break;
     case EffectTypes.ScrollText:
       e = new ScrollTextEffect();
       break;
     case EffectTypes.Animation:
       e = new AnimationEffect();
       break;
     case EffectTypes.Spawner:
       e = new SpawnerEffect();
       break;
     default:
       throw new Exception("Unknown effect");
   }
   e.game = context;
   e.Deserialize(MessageType.GameEffectCreate, line, ref position, context);
   return e;
 }
Beispiel #5
0
 /// <summary>
 /// Creates a scroll-up message in the current game at the game object's position, initializes it and adds to the list of active game effects
 /// </summary>
 /// <param id="text">Text of the scroll-up message</param>
 /// <param id="length">Duration of the message</param>
 /// <param id="announce">Should the message be available for all players?</param>
 /// <returns>Game effect representing the scroll-up message effect</returns>
 protected GameEffect ScrollUpMessage(string text, int length, bool announce = false)
 {
   GameEffect gEff = new ScrollTextEffect(text, Position, length, new Vector2(0, -1));
   gEff.Initialize(game, NearestTile);
   this.game.Effects.Add(gEff);
   if (announce)
     game.SendData(Network.MakeServerMessage(MessageType.GameEffectCreate, gEff));
   return gEff;
 }
Beispiel #6
0
    /// <summary>
    /// Kills the building
    /// </summary>
    /// <param id="noMessage">Should the kill be announced</param>
    public void Kill(bool noMessage = false)
    {
      Health = 0;
      game.SendData(Network.MakeServerMessage(MessageType.GameObjKill, this));

      if (!noMessage)
      {
        GameEffect ge = new ScrollTextEffect("Destroyed", Position + MapBoard.TILE_SIZE / 2, 20, new Vector2(0, -1));
        ge.Initialize(game, NearestTile);
        this.game.Effects.Add(ge);
        game.SendData(Network.MakeServerMessage(MessageType.GameEffectCreate, ge));
      }

      Dispose();
    }
Beispiel #7
0
    /// <summary>
    /// Completes the construction of this building
    /// </summary>
    /// <param name="announce">Whether a scroll-up message should be created</param>
    public void Completed(bool announce = true)
    {
      Logger.Log(string.Format("Building #{0} completed", this.ObjectUID), "Server update");

      Construction = entry.ConstructionAmount;
      if (entry.Spawns != null)
      {
        UnitSpawnQueue = new Dictionary<int, int>();
        foreach (var item in entry.Spawns)
        {
          if (item.Speed != -1)
          {
            if (UnitSpawnQueue.ContainsKey(item.Entry.UnitGroup)) throw new Exception();
            UnitSpawnQueue.Add(item.Entry.UnitGroup, item.Capacity);
          }
        }
      }

      Owner.BuildingFinished(this);

      if (announce)
      {
        GameEffect ge = new ScrollTextEffect("Completed", Position + MapBoard.TILE_SIZE / 2, 200, new Vector2(0, -.5f));
        ge.Initialize(game, NearestTile);
        this.game.Effects.Add(ge);
        game.SendData(Network.MakeServerMessage(MessageType.GameEffectCreate, ge));
      }
    }
Beispiel #8
0
    // ORDER EXECUTION

    /// <summary>
    /// Gives order to currently selected units
    /// </summary>
    private void ExecuteOrder()
    {
      foreach (var gObj in selectedObjects)
      {
        if (gObj.GetEntityType != GameEntityType.Unit) break;
        Unit unit = (Unit)gObj;
        switch (inGameState)
        {
          case InGameStateEnum.DragSelecting:
            break;
          case InGameStateEnum.Movement:
            unit.SetOrder(GameObjectOrder.Idle, null, mouseoverTile, mouseoverGameObject);
            break;
          case InGameStateEnum.Attack:
            #region
            if (mouseoverGameObject != null)
            {
              unit.SetOrder(GameObjectOrder.Attack, null, mouseoverTile, mouseoverGameObject);
            }
            else if (mouseoverTile != null)
            {
              Vector2 position = mouseoverTile.MapPosition - new Vector2(0, (float)mouseoverTile.Elevation * MapBoard.ELEVATION_SCALING) + MapBoard.TILE_SIZE / 2;
              GameEffect ge = new ScrollTextEffect("No target to attack", position, 50, new Vector2(0, -1f));
              ge.Initialize(game, mouseoverTile);
              this.game.Effects.Add(ge);
            }
            #endregion
            break;
          case InGameStateEnum.Spell:
            unit.SetOrder(GameObjectOrder.Spell, Db.Instance.Effects.OrderBy(p => p.Value.Tier).ElementAt(entryIdx).Value, mouseoverTile, mouseoverGameObject);
            break;
          case InGameStateEnum.BuildingPlacement:
            #region
            if (mouseoverTile != null)
            {
              Building mouseoverBuilding = mouseoverTile.Building;
              if (mouseoverBuilding == null)
              {
                if (Building.CanPlace(game.Map, mouseoverTile) && controllingPlayer.Fow[mouseoverTile.X, mouseoverTile.Y] != 0)
                {
                  unit.SetOrder(GameObjectOrder.Construct, Db.Instance.Buildings.OrderBy(p => p.Value.Tier).ElementAt(entryIdx).Value, mouseoverTile, null);
                }
                else if (controllingPlayer.Fow[mouseoverTile.X, mouseoverTile.Y] == 0)
                {
                  Vector2 position = mouseoverTile.MapPosition - new Vector2(0, (float)mouseoverTile.Elevation * MapBoard.ELEVATION_SCALING) + MapBoard.TILE_SIZE / 2;
                  GameEffect ge = new ScrollTextEffect("Unknown terrain", position, 50, new Vector2(0, -1f));
                  ge.Initialize(game, mouseoverTile);
                  this.game.Effects.Add(ge);
                }
                else
                {
                  Vector2 position = mouseoverTile.MapPosition - new Vector2(0, (float)mouseoverTile.Elevation * MapBoard.ELEVATION_SCALING) + MapBoard.TILE_SIZE / 2;
                  GameEffect ge = new ScrollTextEffect("Unable to build here", position, 50, new Vector2(0, -1f));
                  ge.Initialize(game, mouseoverTile);
                  this.game.Effects.Add(ge);
                }
              }
              else
              {
                unit.SetOrder(GameObjectOrder.Construct, null, mouseoverTile, mouseoverBuilding);
              }
            }
            #endregion
            break;
          case InGameStateEnum.Building:
            if (mouseoverGameObject == null) break;
            unit.SetOrder(GameObjectOrder.Construct, null, mouseoverTile, mouseoverGameObject);
            break;
          case InGameStateEnum.Gather:
            if (mouseoverGameObject == null) break;
            unit.SetOrder(GameObjectOrder.Gather, null, mouseoverTile, mouseoverGameObject);
            break;
          case InGameStateEnum.Train:
            if (mouseoverGameObject == null) break;
            unit.SetOrder(GameObjectOrder.Train, null, mouseoverTile, mouseoverGameObject);
            break;
          case InGameStateEnum.DefaultSelected:
            break;
          default:
            System.Diagnostics.Debug.Fail("Invalid order");
            break;
        }
      }
      autoCursor = true;
    }