/* * TubeCarrier.cs * Authors: Mike Dapiran * Copyright (c) 2007-2008 Cornell University This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ using System.Collections.Generic; using ColonySim.Structures; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; namespace ColonySim { class TubeCarrier : Carrier { private int mCurrentDistance; bool mTowardsResource; ResourceCode mAssociatedResource; public bool TowardsResource { get { return mTowardsResource; } set { mTowardsResource = value; } } public bool InitialTowardsResource { get { return mInitialTowardsResource; } set { mInitialTowardsResource = value; } } public ResourceCode AssociatedResource { get { return mAssociatedResource; } set { mAssociatedResource = value; } } bool mInitialTowardsResource; public TubeCarrier(bool GotoResource, ResourceCode pAssociatedResource, ContentManager pContent, string pModelName, string pTextureName, Grid pGridReference) : base(pContent, pModelName, pTextureName, pGridReference) { mAssociatedResource = pAssociatedResource; mInitialTowardsResource = GotoResource; mTowardsResource = mInitialTowardsResource; } public void UpdateDirection() { if (GridPosition.X < GridReference.GridBounds.Left || GridPosition.X > GridReference.GridBounds.Right || GridPosition.Y < GridReference.GridBounds.Top || GridPosition.Y > GridReference.GridBounds.Bottom) { // Purge this carrier Destroy(); return; } else { Dictionary neighbors = GridReference.GetNeighborsForRoad(GridPosition); if (mInitialTowardsResource) { if (GridReference.GridContents(GridPosition).mDistanceFromResource[(int)mAssociatedResource] == 0 && Util.Random.Bool()) { Destroy(); return; } } else { foreach (Structure s in neighbors.Values) { if (!(s is TransportStructure || s is MiningPlant) && Util.Random.NextDouble() <= .2) { Destroy(); return; } } } neighbors = GridReference.GetNeighborsForRoad(GridPosition, typeof(Tube)); if (neighbors.Count == 0) { Destroy(); return; } else { mTowardsResource = mInitialTowardsResource; List possibleDirections = new List(); foreach (Directions d in neighbors.Keys) { if (mTowardsResource && neighbors[d].mDistanceFromResource[(int)mAssociatedResource] < mCurrentDistance) { possibleDirections.Add(d); } else if (!mTowardsResource && neighbors[d].mDistanceFromResource[(int)mAssociatedResource] > mCurrentDistance) { possibleDirections.Add(d); } } if (possibleDirections.Count == 0) { foreach (Directions d in neighbors.Keys) { possibleDirections.Add(d); } } Direction = possibleDirections[Util.Random.Next(0, possibleDirections.Count)]; } } } public override bool UpdatePosition() { if (!base.UpdatePosition()) return false; // If we've moved outside the bounds of the grid, destroy us Structure contents = GridReference.GridContents(GridPosition); if (GridPosition.X < GridReference.GridBounds.Left || GridPosition.X > GridReference.GridBounds.Right || GridPosition.Y < GridReference.GridBounds.Top || GridPosition.Y > GridReference.GridBounds.Bottom) { // Purge this carrier Destroy(); return false; } else { if (mInitialTowardsResource) { if (contents.mDistanceFromResource[(int)mAssociatedResource] == 1 && Util.Random.Bool()) { Destroy(); return false; } } else { Dictionary neighborsTemp = GridReference.GetNeighborsForRoad(GridPosition); foreach (Structure s in neighborsTemp.Values) { if (!(s is TransportStructure || s is MiningPlant) && Util.Random.NextDouble() <= .2) { Destroy(); return false; } } } Dictionary neighbors; if (contents is RoadTubeCrossing) { neighbors = GridReference.GetNeighborsForIntersection(GridPosition, typeof(Tube)); } else { neighbors = GridReference.GetNeighborsForRoad(GridPosition, typeof(Tube)); Dictionary temp = GridReference.GetNeighborsForRoad(GridPosition, typeof(RoadTubeCrossing)); foreach (Directions d in temp.Keys) { if (GridReference.GetNeighborsForIntersection(temp[d].GridPosition, typeof(Tube)).ContainsValue(contents)) { neighbors.Add(d, temp[d]); } } } if (neighbors.Count == 0) { Destroy(); return false; } else if (neighbors.Count == 1) { Dictionary.KeyCollection.Enumerator temp = neighbors.Keys.GetEnumerator(); temp.MoveNext(); Direction = temp.Current; mTowardsResource = !mTowardsResource; if (bumps >= 4) { Destroy(); return false; } bumps++; } else if (neighbors.Count == 2) { foreach (Directions d in neighbors.Keys) { if (d != Opposite(Direction)) { Direction = d; return false; } } } else { mTowardsResource = mInitialTowardsResource; List possibleDirections = new List(); foreach (Directions d in neighbors.Keys) { if (mTowardsResource && neighbors[d].mDistanceFromResource[(int)mAssociatedResource] < mCurrentDistance) { possibleDirections.Add(d); } else if (!mTowardsResource && neighbors[d].mDistanceFromResource[(int)mAssociatedResource] > mCurrentDistance) { possibleDirections.Add(d); } } if (possibleDirections.Count == 0) { foreach (Directions d in neighbors.Keys) { if(d != Opposite(Direction)) possibleDirections.Add(d); } } Direction = possibleDirections[Util.Random.Next(0, possibleDirections.Count)]; } } return true; } } }