Example #1
0
void Conversation::Save(DataWriter &out) const
{
	if(!identifier.empty())
		out.Write("conversation", identifier);
	else
		out.Write("conversation");
	out.BeginChild();
	{
		for(unsigned i = 0; i < nodes.size(); ++i)
		{
			out.Write("label", i);
			const Node &node = nodes[i];
			
			if(node.scene)
				out.Write("scene", node.sceneName);	
			if(!node.conditions.IsEmpty())
			{
				if(node.data.size() > 1)
					out.Write("branch", TokenName(node.data[0].second), TokenName(node.data[1].second));
				else
					out.Write("apply", TokenName(node.data[0].second));
				
				out.BeginChild();
				{
					node.conditions.Save(out);
				}
				out.EndChild();
				continue;
			}
			if(node.isChoice)
			{
				out.Write(node.data.empty() ? "name" : "choice");
				out.BeginChild();
			}
			for(const auto &it : node.data)
			{
				// Break the text up into paragraphs.
				size_t begin = 0;
				while(begin != it.first.length())
				{
					size_t pos = it.first.find('\n', begin);
					if(pos == string::npos)
						pos = it.first.length();
					out.Write(it.first.substr(begin, pos - begin));
					if(pos == it.first.length())
						break;
					begin = pos + 1;
				}
				int index = it.second;
				if(index > 0 && static_cast<unsigned>(index) >= nodes.size())
					index = -1;
				
				WriteToken(index, out);
			}
			if(node.isChoice)
				out.EndChild();
		}
	}
	out.EndChild();
}
Example #2
0
void GameData::WriteEconomy(DataWriter &out)
{
	out.Write("economy");
	out.BeginChild();
	{
		if(!purchases.empty())
		{
			out.Write("purchases");
			out.BeginChild();
			for(const auto &pit : purchases)
				for(const auto &cit : pit.second)
					out.Write(pit.first->Name(), cit.first, cit.second);
			out.EndChild();
		}
		out.WriteToken("system");
		for(const auto &cit : GameData::Commodities())
			out.WriteToken(cit.name);
		out.Write();
		
		for(const auto &sit : GameData::Systems())
		{
			out.WriteToken(sit.second.Name());
			for(const auto &cit : GameData::Commodities())
				out.WriteToken(static_cast<int>(sit.second.Supply(cit.name)));
			out.Write();
		}
	}
	out.EndChild();
}
Example #3
0
// Save depreciation records.
void Depreciation::Save(DataWriter &out, int day) const
{
	out.Write(NAME[isStock]);
	out.BeginChild();
	{
		for(const auto &sit : ships)
		{
			out.Write("ship", sit.first->ModelName());
			out.BeginChild();
			{
				// If this is a planet's stock, remember how many outfits in
				// stock are fully depreciated. If it's the player's stock,
				// anything not recorded is considered fully depreciated, so
				// there is no reason to save records for those items.
				for(const auto &it : sit.second)
					if(isStock || (it.second && it.first > day - MAX_AGE))
						out.Write(it.first, it.second);
			}
			out.EndChild();
		}
		for(const auto &oit : outfits)
		{
			out.Write("outfit", oit.first->Name());
			out.BeginChild();
			{
				for(const auto &it : oit.second)
					if(isStock || (it.second && it.first > day - MAX_AGE))
						out.Write(it.first, it.second);
			}
			out.EndChild();
		}
	}
	out.EndChild();
}
Example #4
0
// Save the cargo manifest to a file.
void CargoHold::Save(DataWriter &out) const
{
	bool first = true;
	for(const auto &it : commodities)
		if(it.second)
		{
			if(first)
			{
				out.Write("cargo");
				out.BeginChild();
				out.Write("commodities");
				out.BeginChild();
			}
			first = false;
			
			out.Write(it.first, it.second);
		}
	if(!first)
		out.EndChild();
	
	bool firstOutfit = true;
	for(const auto &it : outfits)
		if(it.second && !it.first->Name().empty())
		{
			// It is possible this cargo hold contained no commodities, meaning
			// we must print the opening tag now.
			if(first)
			{
				out.Write("cargo");
				out.BeginChild();
			}
			first = false;
			
			// If this is the first outfit to be written, print the opening tag.
			if(firstOutfit)
			{
				out.Write("outfits");
				out.BeginChild();
			}
			firstOutfit = false;
			
			out.Write(it.first->Name(), it.second);
		}
	if(!firstOutfit)
		out.EndChild();
	if(!first)
		out.EndChild();
	
	// Mission cargo is not saved because it is repopulated when the missions
	// are read rather than when the cargo is read.
}
Example #5
0
void GameEvent::Save(DataWriter &out) const
{
	out.Write("event");
	out.BeginChild();
	{
		if(date)
			out.Write("date", date.Day(), date.Month(), date.Year());
		conditionsToApply.Save(out);
		
		for(const System *system : systemsToUnvisit)
			if(system && !system->Name().empty())
				out.Write("unvisit", system->Name());
		for(const Planet *planet : planetsToUnvisit)
			if(planet && !planet->Name().empty())
				out.Write("unvisit planet", planet->Name());
		
		for(const System *system : systemsToVisit)
			if(system && !system->Name().empty())
				out.Write("visit", system->Name());
		for(const Planet *planet : planetsToVisit)
			if(planet && !planet->Name().empty())
				out.Write("visit planet", planet->Name());
		
		for(const DataNode &change : changes)
			out.Write(change);
	}
	out.EndChild();
}
Example #6
0
// Note: the Save() function can assume this is an instantiated mission, not
// a template, so it only has to save a subset of the data.
void MissionAction::Save(DataWriter &out) const
{
	if(system.empty())
		out.Write("on", trigger);
	else
		out.Write("on", trigger, system);
	out.BeginChild();
	{
		if(!dialogText.empty())
		{
			out.Write("dialog");
			out.BeginChild();
			{
				// Break the text up into paragraphs.
				size_t begin = 0;
				while(true)
				{
					size_t pos = dialogText.find("\n\t", begin);
					if(pos == string::npos)
						pos = dialogText.length();
					out.Write(dialogText.substr(begin, pos - begin));
					if(pos == dialogText.length())
						break;
					begin = pos + 2;
				}
			}
			out.EndChild();
		}
		if(!conversation.IsEmpty())
			conversation.Save(out);
		
		for(const auto &it : gifts)
			out.Write("outfit", it.first->Name(), it.second);
		if(payment)
			out.Write("payment", payment);
		for(const auto &it : events)
			out.Write("event", it.first, it.second);
		for(const auto &name : fail)
			out.Write("fail", name);
		
		conditions.Save(out);
	}
	out.EndChild();
}
Example #7
0
void Personality::Save(DataWriter &out) const
{
	out.Write("personality");
	out.BeginChild();
	{
		out.Write("confusion", confusionMultiplier);
		for(const auto &it : TOKEN)
			if(flags & it.second)
				out.Write(it.first);
	}
	out.EndChild();
}
Example #8
0
// Write account information to a saved game file.
void Account::Save(DataWriter &out) const
{
	out.Write("account");
	out.BeginChild();
	{
		out.Write("credits", credits);
		if(salariesOwed)
			out.Write("salaries", salariesOwed);
		out.Write("score", creditScore);
		
		out.Write("history");
		out.BeginChild();
		{
			for(int64_t worth : history)
				out.Write(worth);
		}
		out.EndChild();
		
		for(const Mortgage &mortgage : mortgages)
			mortgage.Save(out);
	}
	out.EndChild();
}
Example #9
0
void ConditionSet::Save(DataWriter &out) const
{
	for(const Entry &entry : entries)
		out.Write(entry.name, entry.op, entry.value);
	for(const ConditionSet &child : children)
	{
		out.Write(child.isOr ? "or" : "and");
		out.BeginChild();
		{
			child.Save(out);
		}
		out.EndChild();
	}
}
Example #10
0
void Galaxy::Save(DataWriter &file) const
{
    if(name.isEmpty())
        file.Write("galaxy");
    else
        file.Write("galaxy", name);
    file.BeginChild();
    {
        file.Write("pos", position.x(), position.y());
        file.Write("sprite", sprite);
        for(const DataNode &node : unparsed)
            file.Write(node);
    }
    file.EndChild();
}
Example #11
0
void Planet::Save(DataWriter &file) const
{
    file.Write("planet", name);
    file.BeginChild();
    {
        if(!attributes.empty())
        {
            file.WriteToken("attributes");
            for(const QString &it : attributes)
                file.WriteToken(it);
            file.Write();
        }

        file.Write("landscape", landscape);

        // Break the descriptions into paragraphs.
        for(const QString &str : description.split('\n', QString::SkipEmptyParts))
        {
            file.WriteToken("description");
            file.WriteToken(str, '`');
            file.Write();
        }
        for(const QString &str : spaceport.split('\n', QString::SkipEmptyParts))
        {
            file.WriteToken("spaceport");
            file.WriteToken(str, '`');
            file.Write();
        }

        for(const QString &it : shipyard)
            file.Write("shipyard", it);
        for(const QString &it : outfitter)
            file.Write("outfitter", it);

        if(!std::isnan(requiredReputation))
            file.Write("required reputation", requiredReputation);
        if(!std::isnan(bribe))
            file.Write("bribe", bribe);
        if(!std::isnan(security))
            file.Write("security", security);

        for(const DataNode &node : unparsed)
            file.Write(node);
    }
    file.EndChild();
}
Example #12
0
// Save a mission. It is safe to assume that any mission that is being saved
// is already "instantiated," so only a subset of the data must be saved.
void Mission::Save(DataWriter &out, const string &tag) const
{
	out.Write(tag, name);
	out.BeginChild();
	{
		out.Write("name", displayName);
		if(!description.empty())
			out.Write("description", description);
		if(!blocked.empty())
			out.Write("blocked", blocked);
		if(hasDeadline)
			out.Write("deadline", deadline.Day(), deadline.Month(), deadline.Year());
		if(cargoSize)
		{
			out.Write("cargo", cargo, cargoSize);
			if(illegalCargoFine)
			{
				out.BeginChild();
				{
					out.Write("illegal", illegalCargoFine);
				}
				out.EndChild();
			}
		}
		if(passengers)
			out.Write("passengers", passengers);
		if(!isVisible)
			out.Write("invisible");
		if(hasPriority)
			out.Write("priority");
		if(isMinor)
			out.Write("minor");
		if(autosave)
			out.Write("autosave");
		if(location == LANDING)
			out.Write("landing");
		if(location == ASSISTING)
			out.Write("assisting");
		if(location == BOARDING)
			out.Write("boarding");
		if(location == JOB)
			out.Write("job");
		if(!clearance.empty())
		{
			out.Write("clearance", clearance);
			clearanceFilter.Save(out);
		}
		if(!hasFullClearance)
			out.Write("infiltrating");
		if(repeat != 1)
			out.Write("repeat", repeat);
		
		if(!toComplete.IsEmpty())
		{
			out.Write("to", "complete");
			out.BeginChild();
			{
				toComplete.Save(out);
			}
			out.EndChild();
		}
		if(!toFail.IsEmpty())
		{
			out.Write("to", "fail");
			out.BeginChild();
			{
				toFail.Save(out);
			}
			out.EndChild();
		}
		if(destination)
			out.Write("destination", destination->Name());
		for(const System *system : waypoints)
			out.Write("waypoint", system->Name());
		
		for(const NPC &npc : npcs)
			npc.Save(out);
		
		// Save all the actions, because this might be an "available mission" that
		// has not been received yet but must still be included in the saved game.
		for(const auto &it : actions)
			it.second.Save(out);
		for(const auto &it : onEnter)
			it.second.Save(out);
	}
	out.EndChild();
}
Example #13
0
// Save a full description of this ship, as currently configured.
void Ship::Save(DataWriter &out) const
{
	out.Write("ship", modelName);
	out.BeginChild();
	{
		out.Write("name", name);
		sprite.Save(out);
		
		if(neverDisabled)
			out.Write("never disabled");
		
		out.Write("attributes");
		out.BeginChild();
		{
			out.Write("category", baseAttributes.Category());
			for(const auto &it : baseAttributes.Attributes())
				if(it.second)
					out.Write(it.first, it.second);
		}
		out.EndChild();
		
		out.Write("outfits");
		out.BeginChild();
		{
			for(const auto &it : outfits)
				if(it.first && it.second)
				{
					if(it.second == 1)
						out.Write(it.first->Name());
					else
						out.Write(it.first->Name(), it.second);
				}
		}
		out.EndChild();
		
		cargo.Save(out);
		out.Write("crew", crew);
		out.Write("fuel", fuel);
		out.Write("shields", shields);
		out.Write("hull", hull);
		out.Write("position", position.X(), position.Y());
		
		for(const Point &point : enginePoints)
			out.Write("engine", point.X(), point.Y());
		for(const Armament::Weapon &weapon : armament.Get())
		{
			const char *type = (weapon.IsTurret() ? "turret" : "gun");
			if(weapon.GetOutfit())
				out.Write(type, 2. * weapon.GetPoint().X(), 2. * weapon.GetPoint().Y(),
					weapon.GetOutfit()->Name());
			else
				out.Write(type, 2. * weapon.GetPoint().X(), 2. * weapon.GetPoint().Y());
		}
		for(const Bay &bay : fighterBays)
			out.Write("fighter", 2. * bay.point.X(), 2. * bay.point.Y());
		for(const Bay &bay : droneBays)
			out.Write("drone", 2. * bay.point.X(), 2. * bay.point.Y());
		for(const auto &it : explosionEffects)
			if(it.first && it.second)
				out.Write("explode", it.first->Name(), it.second);
		
		if(currentSystem)
			out.Write("system", currentSystem->Name());
		else
		{
			shared_ptr<const Ship> parent = GetParent();
			if(parent && parent->currentSystem)
				out.Write("system", parent->currentSystem->Name());
		}
		if(landingPlanet)
			out.Write("planet", landingPlanet->Name());
		if(isParked)
			out.Write("parked");
	}
	out.EndChild();
}
Example #14
0
// Write a conversation to file.
void Conversation::Save(DataWriter &out) const
{
	out.Write("conversation");
	out.BeginChild();
	{
		for(unsigned i = 0; i < nodes.size(); ++i)
		{
			// The original label names are not preserved anywhere. Instead,
			// the label for every node is just its node index.
			out.Write("label", i);
			const Node &node = nodes[i];
			
			if(node.scene)
				out.Write("scene", node.scene->Name());	
			if(!node.conditions.IsEmpty())
			{
				// The only thing differentiating a "branch" from an "apply" node
				// is that a branch has two data entries instead of one.
				if(node.data.size() > 1)
					out.Write("branch", TokenName(node.data[0].second), TokenName(node.data[1].second));
				else
					out.Write("apply", TokenName(node.data[0].second));
				
				// Write the condition set as a child of this node.
				out.BeginChild();
				{
					node.conditions.Save(out);
				}
				out.EndChild();
				continue;
			}
			if(node.isChoice)
			{
				out.Write(node.data.empty() ? "name" : "choice");
				out.BeginChild();
			}
			for(const auto &it : node.data)
			{
				// Break the text up into paragraphs.
				size_t begin = 0;
				while(begin < it.first.length())
				{
					// Find the next line break.
					size_t pos = it.first.find('\n', begin);
					// Text should always end with a line break, but just in case:
					if(pos == string::npos)
						pos = it.first.length();
					out.Write(it.first.substr(begin, pos - begin));
					// Skip the actual newline character when writing the text out.
					begin = pos + 1;
				}
				// Check what node the conversation goes to after this.
				int index = it.second;
				if(index > 0 && static_cast<unsigned>(index) >= nodes.size())
					index = Conversation::DECLINE;
				
				// Write the node that we go to next after this.
				WriteToken(index, out);
			}
			if(node.isChoice)
				out.EndChild();
		}
	}
	out.EndChild();
}