/* * Hub.cs * Authors: Bradley R. Blankenship * 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; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework; namespace ColonySim.Structures { /// /// Represents a Hub in the Tube system for the Colony project. /// abstract class Hub : Structure { #region Fields // Enumeration of the directions public enum Directions { Positive_Y, Positive_X, Negative_Y, Negative_X } // A list of the input carriers to distribute protected List mInputCarriers; // The array of tubes Tube[] mTubes = new Tube[4]; // The flow through the tubes float[] mFlows = new float[4]; #endregion #region Properties /// /// Allows access to the array of Tubes. /// protected Tube[] Tubes { get { return mTubes; } } /// /// Allows access to the array of flows. /// protected float[] Flows { get { return mFlows; } } #endregion #region Constructs /// /// Base constructor /// /// The Content Manager /// The model name /// The texture name public Hub(ContentManager pContent, string pModelName, string pTextureName) : base(pContent, pModelName, pTextureName) { // Create the lists mInputCarriers = new List(); } #endregion #region Behavior /// /// Tick along for the turn. /// public override void Tick() { // Distribute the carriers DistributeCarriers(); // Clear the current input carriers mInputCarriers.Clear(); } /// /// Distributes the current Carriers into new Carriers, based /// on what's needed. /// public void DistributeCarriers() { // The tubes to output to Dictionary outputs = new Dictionary(); // Get the output tubes for(int i = 0; i < Tubes.Length; i++) { // Go through and get the tube at the coordinate Tube tube = Tubes[i]; // Make sure it isn't null if( tube != null && mFlows[i] > 0 ) { // See if it is facing the right way to be an output tube, and it's not null if ((tube.GridPosition.X < this.GridPosition.X && tube.Running == Tube.Runnings.Negative_X) || (tube.GridPosition.X > this.GridPosition.X && tube.Running == Tube.Runnings.Positive_X) || (tube.GridPosition.Y < this.GridPosition.Y && tube.Running == Tube.Runnings.Negative_Y) || (tube.GridPosition.Y > this.GridPosition.Y && tube.Running == Tube.Runnings.Positive_Y)) { // Add the tube outputs.Add(tube, Flows[i]); } } } // Take the current carriers and split them as needed foreach (Carrier carrier in mInputCarriers) { // Add a new carrier for each output tube foreach (Tube tube in outputs.Keys) { // Create a new carrier with the same graphics as the previous Carrier newCarrier = new Carrier(this.Content, carrier.ModelPath, carrier.TexturePath); // Get the resource of the old carrier Resource resource = carrier.Resource.Clone(); resource.Amount = (int)(resource.Amount * outputs[tube]); // Now set the values of the carrier to match that of the old carrier newCarrier.Resource = resource; newCarrier.NumberOfTurns = carrier.NumberOfTurns; newCarrier.TransformationMatrix = Matrix.CreateTranslation(tube.TransformationMatrix.Translation); newCarrier.GridPosition = tube.GridPosition; newCarrier.DrawOrder = tube.DrawOrder - 1; // Call the tube to accept it tube.ReceiveCarrier(newCarrier); // Add the new carrier to the output list GridReference.AddCarrier(newCarrier); } } } /// /// Receive the given Carrier. /// /// The carrier to receive. /// Whether we received the carrier or not public override bool ReceiveCarrier(Carrier pCarrier) { // Add the carrier to our list of Carriers mInputCarriers.Add(pCarrier); // Dispose of the Carrier pCarrier.Dispose(); // Add the carrier to our list of carriers return base.ReceiveCarrier(pCarrier); } #endregion #region Utility /// /// Add the given tube and flow amount to the Hub. /// /// The tube to add /// The direction to add it on public void AddTube(Tube pTube, Directions pDirection) { // Add the tube mTubes[(int)pDirection] = pTube; mFlows[(int)pDirection] = 1.0f; } public bool TubeExists(Directions pDirection) { return mTubes[(int)pDirection] != null; } /// /// Return the flow of at the given index. /// /// The direction to look. /// The flow for that direction. public float GetFlow(Directions pDirection) { return mFlows[(int)pDirection]; } /// /// Sets the flow for a given direction. /// /// The flow amount. /// The direction of flow. public void SetFlow(float pFlow, Directions pDirection) { // Set the flow mFlows[(int)pDirection] = pFlow; } /// /// Removes the given tube from the list. /// /// The tube to remove. public void RemoveTube(Tube tube) { // Go through and find the tube for (int i = 0; i < mTubes.Length; i++) { // If it is the same tube if (tube == mTubes[i]) { // Set the tube to null mTubes[i] = null; mFlows[i] = 0.0f; } } } #endregion } }