Example #1
0
void System::LoadObject(const DataNode &node, Set<Planet> &planets, int parent)
{
	int index = objects.size();
	objects.push_back(StellarObject());
	StellarObject &object = objects.back();
	object.parent = parent;
	
	bool isAdded = (node.Token(0) == "add");
	if(node.Size() >= 2 + isAdded)
	{
		Planet *planet = planets.Get(node.Token(1 + isAdded));
		object.planet = planet;
		planet->SetSystem(this);
	}
	
	for(const DataNode &child : node)
	{
		if(child.Token(0) == "sprite" && child.Size() >= 2)
		{
			object.LoadSprite(child);
			object.isStar = !child.Token(1).compare(0, 5, "star/");
			if(!object.isStar)
			{
				object.isStation = !child.Token(1).compare(0, 14, "planet/station");
				object.isMoon = (!object.isStation && parent >= 0 && !objects[parent].IsStar());
			}
		}
		else if(child.Token(0) == "distance" && child.Size() >= 2)
			object.distance = child.Value(1);
		else if(child.Token(0) == "period" && child.Size() >= 2)
			object.speed = 360. / child.Value(1);
		else if(child.Token(0) == "offset" && child.Size() >= 2)
			object.offset = child.Value(1);
		else if(child.Token(0) == "object")
			LoadObject(child, planets, index);
		else
			child.PrintTrace("Skipping unrecognized attribute:");
	}
}
Example #2
0
// Load a system's description.
void System::Load(const DataNode &node, Set<Planet> &planets)
{
    if(node.Size() < 2)
        return;
    name = node.Token(1);

    // If this is truly a change and not just being called by Load(), these sets
    // of objects will be entirely replaced by any new ones, rather than adding
    // the new ones on to the end of the list:
    bool resetLinks = !links.empty();
    bool resetAsteroids = !asteroids.empty();
    bool resetFleets = !fleets.empty();
    bool resetObjects = !objects.empty();

    for(const DataNode &child : node)
    {
        if(child.Token(0) == "pos" && child.Size() >= 3)
            position.Set(child.Value(1), child.Value(2));
        else if(child.Token(0) == "government" && child.Size() >= 2)
            government = GameData::Governments().Get(child.Token(1));
        else if(child.Token(0) == "link")
        {
            if(resetLinks)
            {
                resetLinks = false;
                links.clear();
            }
            if(child.Size() >= 2)
                links.push_back(GameData::Systems().Get(child.Token(1)));
        }
        else if(child.Token(0) == "habitable" && child.Size() >= 2)
            habitable = child.Value(1);
        else if(child.Token(0) == "asteroids")
        {
            if(resetAsteroids)
            {
                resetAsteroids = false;
                asteroids.clear();
            }
            if(child.Size() >= 4)
                asteroids.emplace_back(child.Token(1), child.Value(2), child.Value(3));
        }
        else if(child.Token(0) == "trade" && child.Size() >= 3)
            trade[child.Token(1)].SetBase(child.Value(2));
        else if(child.Token(0) == "fleet")
        {
            if(resetFleets)
            {
                resetFleets = false;
                fleets.clear();
            }
            if(child.Size() >= 3)
                fleets.emplace_back(GameData::Fleets().Get(child.Token(1)), child.Value(2));
        }
        else if(child.Token(0) == "object")
        {
            if(resetObjects)
            {
                for(StellarObject &object : objects)
                    if(object.GetPlanet())
                    {
                        Planet *planet = planets.Get(object.GetPlanet()->Name());
                        planet->RemoveSystem(this);
                    }
                resetObjects = false;
                objects.clear();
            }
            LoadObject(child, planets);
        }
        else
            child.PrintTrace("Skipping unrecognized attribute:");
    }

    // Set planet messages based on what zone they are in.
    for(StellarObject &object : objects)
    {
        if(object.message || object.planet)
            continue;

        const StellarObject *root = &object;
        while(root->parent >= 0)
            root = &objects[root->parent];

        static const string STAR = "You cannot land on a star!";
        static const string HOTPLANET = "This planet is too hot to land on.";
        static const string COLDPLANET = "This planet is too cold to land on.";
        static const string UNINHABITEDPLANET = "This planet is uninhabited.";
        static const string HOTMOON = "This moon is too hot to land on.";
        static const string COLDMOON = "This moon is too cold to land on.";
        static const string UNINHABITEDMOON = "This moon is uninhabited.";
        static const string STATION = "This station cannot be docked with.";

        double fraction = root->distance / habitable;
        if(object.IsStar())
            object.message = &STAR;
        else if (object.IsStation())
            object.message = &STATION;
        else if (object.IsMoon())
        {
            if(fraction < .5)
                object.message = &HOTMOON;
            else if(fraction >= 2.)
                object.message = &COLDMOON;
            else
                object.message = &UNINHABITEDMOON;
        }
        else
        {
            if(fraction < .5)
                object.message = &HOTPLANET;
            else if(fraction >= 2.)
                object.message = &COLDPLANET;
            else
                object.message = &UNINHABITEDPLANET;
        }
    }
}
Example #3
0
// Load a system's description.
void System::Load(const DataNode &node, Set<Planet> &planets)
{
	if(node.Size() < 2)
		return;
	name = node.Token(1);
	
	// For the following keys, if this data node defines a new value for that
	// key, the old values should be cleared (unless using the "add" keyword).
	set<string> shouldOverwrite = {"asteroids", "attributes", "fleet", "link", "object"};
	
	for(const DataNode &child : node)
	{
		// Check for the "add" or "remove" keyword.
		bool add = (child.Token(0) == "add");
		bool remove = (child.Token(0) == "remove");
		if((add || remove) && child.Size() < 2)
		{
			child.PrintTrace("Skipping " + child.Token(0) + " with no key given:");
			continue;
		}
		
		// Get the key and value (if any).
		const string &key = child.Token((add || remove) ? 1 : 0);
		int valueIndex = (add || remove) ? 2 : 1;
		bool hasValue = (child.Size() > valueIndex);
		const string &value = child.Token(hasValue ? valueIndex : 0);
		
		// Check for conditions that require clearing this key's current value.
		// "remove <key>" means to clear the key's previous contents.
		// "remove <key> <value>" means to remove just that value from the key.
		bool removeAll = (remove && !hasValue);
		// If this is the first entry for the given key, and we are not in "add"
		// or "remove" mode, its previous value should be cleared.
		bool overwriteAll = (!add && !remove && shouldOverwrite.count(key));
		overwriteAll |= (!add && !remove && key == "minables" && shouldOverwrite.count("asteroids"));
		// Clear the data of the given type.
		if(removeAll || overwriteAll)
		{
			// Clear the data of the given type.
			if(key == "government")
				government = nullptr;
			else if(key == "music")
				music.clear();
			else if(key == "attributes")
				attributes.clear();
			else if(key == "link")
				links.clear();
			else if(key == "asteroids" || key == "minables")
				asteroids.clear();
			else if(key == "haze")
				haze = nullptr;
			else if(key == "trade")
				trade.clear();
			else if(key == "fleet")
				fleets.clear();
			else if(key == "object")
			{
				// Make sure any planets that were linked to this system know
				// that they are no longer here.
				for(StellarObject &object : objects)
					if(object.GetPlanet())
						planets.Get(object.GetPlanet()->TrueName())->RemoveSystem(this);
				
				objects.clear();
			}
			
			// If not in "overwrite" mode, move on to the next node.
			if(overwriteAll)
				shouldOverwrite.erase(key == "minables" ? "asteroids" : key);
			else
				continue;
		}
		
		// Handle the attributes which can be "removed."
		if(!hasValue && key != "object")
		{
			child.PrintTrace("Expected key to have a value:");
			continue;
		}
		else if(key == "attributes")
		{
			if(remove)
				for(int i = valueIndex; i < child.Size(); ++i)
					attributes.erase(child.Token(i));
			else
				for(int i = valueIndex; i < child.Size(); ++i)
					attributes.insert(child.Token(i));
		}
 		else if(key == "link")
		{
			if(remove)
				links.erase(GameData::Systems().Get(value));
			else
				links.insert(GameData::Systems().Get(value));
		}
		else if(key == "asteroids")
		{
			if(remove)
			{
				for(auto it = asteroids.begin(); it != asteroids.end(); ++it)
					if(it->Name() == value)
					{
						asteroids.erase(it);
						break;
					}
			}
			else if(child.Size() >= 4)
				asteroids.emplace_back(value, child.Value(valueIndex + 1), child.Value(valueIndex + 2));
		}
		else if(key == "minables")
		{
			const Minable *type = GameData::Minables().Get(value);
			if(remove)
			{
				for(auto it = asteroids.begin(); it != asteroids.end(); ++it)
					if(it->Type() == type)
					{
						asteroids.erase(it);
						break;
					}
			}
			else if(child.Size() >= 4)
				asteroids.emplace_back(type, child.Value(valueIndex + 1), child.Value(valueIndex + 2));
		}
		else if(key == "fleet")
		{
			const Fleet *fleet = GameData::Fleets().Get(value);
			if(remove)
			{
				for(auto it = fleets.begin(); it != fleets.end(); ++it)
					if(it->Get() == fleet)
					{
						fleets.erase(it);
						break;
					}
			}
			else
				fleets.emplace_back(fleet, child.Value(valueIndex + 1));
		}
		// Handle the attributes which cannot be "removed."
		else if(remove)
		{
			child.PrintTrace("Cannot \"remove\" a specific value from the given key:");
			continue;
		}
		else if(key == "pos" && child.Size() >= 3)
			position.Set(child.Value(valueIndex), child.Value(valueIndex + 1));
		else if(key == "government")
			government = GameData::Governments().Get(value);
		else if(key == "music")
			music = value;
		else if(key == "habitable")
			habitable = child.Value(valueIndex);
		else if(key == "belt")
			asteroidBelt = child.Value(valueIndex);
		else if(key == "haze")
			haze = SpriteSet::Get(value);
		else if(key == "trade" && child.Size() >= 3)
			trade[value].SetBase(child.Value(valueIndex + 1));
		else if(key == "object")
			LoadObject(child, planets);
		else
			child.PrintTrace("Skipping unrecognized attribute:");
	}
	
	// Set planet messages based on what zone they are in.
	for(StellarObject &object : objects)
	{
		if(object.message || object.planet)
			continue;
		
		const StellarObject *root = &object;
		while(root->parent >= 0)
			root = &objects[root->parent];
		
		static const string STAR = "You cannot land on a star!";
		static const string HOTPLANET = "This planet is too hot to land on.";
		static const string COLDPLANET = "This planet is too cold to land on.";
		static const string UNINHABITEDPLANET = "This planet is uninhabited.";
		static const string HOTMOON = "This moon is too hot to land on.";
		static const string COLDMOON = "This moon is too cold to land on.";
		static const string UNINHABITEDMOON = "This moon is uninhabited.";
		static const string STATION = "This station cannot be docked with.";
		
		double fraction = root->distance / habitable;
		if(object.IsStar())
			object.message = &STAR;
		else if (object.IsStation())
			object.message = &STATION;
		else if (object.IsMoon())
		{
			if(fraction < .5)
				object.message = &HOTMOON;
			else if(fraction >= 2.)
				object.message = &COLDMOON;
			else
				object.message = &UNINHABITEDMOON;
		}
		else
		{
			if(fraction < .5)
				object.message = &HOTPLANET;
			else if(fraction >= 2.)
				object.message = &COLDPLANET;
			else
				object.message = &UNINHABITEDPLANET;
		}
	}
}
Example #4
0
// Load a planet's description from a file.
void Planet::Load(const DataNode &node, const Set<Sale<Ship>> &ships, const Set<Sale<Outfit>> &outfits)
{
	if(node.Size() < 2)
		return;
	name = node.Token(1);
	
	// If this planet has been loaded before, these sets of items should be
	// reset if they are also defined here, instead of appending to them:
	bool resetAttributes = !attributes.empty();
	bool resetDescription = !description.empty();
	bool resetSpaceport = !spaceport.empty();
	
	for(const DataNode &child : node)
	{
		if(child.Token(0) == "landscape" && child.Size() >= 2)
			landscape = SpriteSet::Get(child.Token(1));
		else if(child.Token(0) == "attributes")
		{
			if(resetAttributes)
			{
				resetAttributes = false;
				attributes.clear();
			}
			for(int i = 1; i < child.Size(); ++i)
				attributes.insert(child.Token(i));
		}
		else if(child.Token(0) == "description" && child.Size() >= 2)
		{
			if(resetDescription)
			{
				resetDescription = false;
				description.clear();
			}
			if(!description.empty() && !child.Token(1).empty() && child.Token(1)[0] > ' ')
				description += '\t';
			description += child.Token(1);
			description += '\n';
		}
		else if(child.Token(0) == "spaceport" && child.Size() >= 2)
		{
			if(child.Token(1) == "clear")
				spaceport.clear();
			else
			{
				if(resetSpaceport)
				{
					resetSpaceport = false;
					spaceport.clear();
				}
				if(!spaceport.empty() && !child.Token(1).empty() && child.Token(1)[0] > ' ')
					spaceport += '\t';
				spaceport += child.Token(1);
				spaceport += '\n';
			}
		}
		else if(child.Token(0) == "shipyard" && child.Size() >= 2)
		{
			if(child.Token(1) == "clear")
				shipSales.clear();
			else
				shipSales.push_back(ships.Get(child.Token(1)));
		}
		else if(child.Token(0) == "outfitter" && child.Size() >= 2)
		{
			if(child.Token(1) == "clear")
				outfitSales.clear();
			else
				outfitSales.push_back(outfits.Get(child.Token(1)));
		}
		else if(child.Token(0) == "government" && child.Size() >= 2)
			government = GameData::Governments().Get(child.Token(1));
		else if(child.Token(0) == "required reputation" && child.Size() >= 2)
			requiredReputation = child.Value(1);
		else if(child.Token(0) == "bribe" && child.Size() >= 2)
			bribe = child.Value(1);
		else if(child.Token(0) == "security" && child.Size() >= 2)
			security = child.Value(1);
		else if(child.Token(0) == "tribute" && child.Size() >= 2)
		{
			tribute = child.Value(1);
			for(const DataNode &grand : child)
			{
				if(grand.Token(0) == "threshold" && grand.Size() >= 2)
					defenseThreshold = grand.Value(1);
				else if(grand.Token(0) == "fleet" && grand.Size() >= 3)
				{
					defenseCount = (grand.Size() >= 3 ? grand.Value(2) : 1);
					defenseFleet = GameData::Fleets().Get(grand.Token(1));
				}
				else
					grand.PrintTrace("Skipping unrecognized attribute:");
			}
		}
		else
			child.PrintTrace("Skipping unrecognized attribute:");
	}
}