MegaGlest/source/glest_game/types/resource_type.cpp

255 lines
8.8 KiB
C++

// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martiño Figueroa
//
// You can redistribute this code 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
// ==============================================================
#include "resource_type.h"
#include "util.h"
#include "element_type.h"
#include "logger.h"
#include "renderer.h"
#include "xml_parser.h"
#include "game_util.h"
#include "properties.h"
#include "lang.h"
#include "leak_dumper.h"
using namespace Shared::Util;
using namespace Shared::Xml;
namespace Glest{ namespace Game{
// =====================================================
// class ResourceType
// =====================================================
ResourceType::ResourceType() {
resourceClass=rcTech;
tilesetObject=0;
resourceNumber=0;
interval=0;
defResPerPatch=0;
recoup_cost = false;
model = NULL;
displayInHud = false;
cleanupMemory = true;
}
ResourceType::~ResourceType() {
if(cleanupMemory == true) {
while(particleTypes.empty() == false) {
delete particleTypes.back();
particleTypes.pop_back();
}
}
}
string ResourceType::getName(bool translatedValue) const {
if(translatedValue == false) return name;
Lang &lang = Lang::getInstance();
return lang.getTechTreeString("ResourceTypeName_" + name,name.c_str());
}
void ResourceType::load(const string &dir, Checksum* checksum, Checksum *techtreeChecksum,
std::map<string,vector<pair<string, string> > > &loadedFileList, string techtreePath) {
string path, str;
Renderer &renderer= Renderer::getInstance();
try
{
recoup_cost = true;
name= lastDir(dir);
char szBuf[8096]="";
snprintf(szBuf,8096,Lang::getInstance().getString("LogScreenGameLoadingResourceType","",true).c_str(),formatString(getName(true)).c_str());
Logger::getInstance().add(szBuf, true);
string currentPath = dir;
endPathWithSlash(currentPath);
path= currentPath + name + ".xml";
string sourceXMLFile = path;
checksum->addFile(path);
techtreeChecksum->addFile(path);
//tree
XmlTree xmlTree;
std::map<string,string> mapExtraTagReplacementValues;
mapExtraTagReplacementValues["$COMMONDATAPATH"] = techtreePath + "/commondata/";
xmlTree.load(path, Properties::getTagReplacementValues(&mapExtraTagReplacementValues));
loadedFileList[path].push_back(make_pair(currentPath,currentPath));
const XmlNode *resourceNode= xmlTree.getRootNode();
//image
const XmlNode *imageNode= resourceNode->getChild("image");
image= renderer.newTexture2D(rsGame);
if(image) {
image->load(imageNode->getAttribute("path")->getRestrictedValue(currentPath));
}
loadedFileList[imageNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile,imageNode->getAttribute("path")->getRestrictedValue()));
//type
const XmlNode *typeNode= resourceNode->getChild("type");
resourceClass = strToRc(typeNode->getAttribute("value")->getRestrictedValue());
switch(resourceClass)
{
case rcTech:
{
//model
const XmlNode *modelNode= typeNode->getChild("model");
string modelPath= modelNode->getAttribute("path")->getRestrictedValue(currentPath);
model= renderer.newModel(rsGame, modelPath, false, &loadedFileList, &sourceXMLFile);
loadedFileList[modelPath].push_back(make_pair(sourceXMLFile,modelNode->getAttribute("path")->getRestrictedValue()));
if(modelNode->hasChild("particles")){
const XmlNode *particleNode= modelNode->getChild("particles");
bool particleEnabled= particleNode->getAttribute("value")->getBoolValue();
if(particleEnabled == true) {
for(int k= 0; k < (int)particleNode->getChildCount(); ++k) {
const XmlNode *particleFileNode= particleNode->getChild("particle-file", k);
string particlePath= particleFileNode->getAttribute("path")->getRestrictedValue();
ObjectParticleSystemType *objectParticleSystemType= new ObjectParticleSystemType();
objectParticleSystemType->load(particleFileNode, dir, currentPath + particlePath,
&Renderer::getInstance(), loadedFileList, sourceXMLFile, techtreePath);
loadedFileList[currentPath + particlePath].push_back(make_pair(sourceXMLFile,particleFileNode->getAttribute("path")->getRestrictedValue()));
particleTypes.push_back(objectParticleSystemType);
}
}
}
//default resources
const XmlNode *defaultAmountNode= typeNode->getChild("default-amount");
defResPerPatch= defaultAmountNode->getAttribute("value")->getIntValue();
//resource number
const XmlNode *resourceNumberNode= typeNode->getChild("resource-number");
resourceNumber= resourceNumberNode->getAttribute("value")->getIntValue();
}
break;
case rcTileset:
{
//resource number
const XmlNode *defaultAmountNode= typeNode->getChild("default-amount");
defResPerPatch= defaultAmountNode->getAttribute("value")->getIntValue();
//resource number
const XmlNode *tilesetObjectNode= typeNode->getChild("tileset-object");
tilesetObject= tilesetObjectNode->getAttribute("value")->getIntValue();
}
break;
case rcConsumable:
{
//interval
const XmlNode *intervalNode= typeNode->getChild("interval");
interval= intervalNode->getAttribute("value")->getIntValue();
}
break;
case rcStatic:
{
//recoup_cost
if(typeNode->hasChild("recoup_cost") == true) {
const XmlNode *recoup_costNode= typeNode->getChild("recoup_cost");
if(recoup_costNode != NULL) {
recoup_cost= recoup_costNode->getAttribute("value")->getBoolValue();
}
}
}
break;
default:
break;
}
//displayInHud
if(resourceNode->hasChild("display") == true) {
const XmlNode *displayNode= resourceNode->getChild("display");
displayInHud= displayNode->getAttribute("value")->getBoolValue();
}
else {
displayInHud=true;
}
}
catch(megaglest_runtime_error& ex) {
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
throw megaglest_runtime_error("Error loading resource type: "+ path + "\nMessage: " + ex.what(),!ex.wantStackTrace());
}
catch(const exception &e){
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what());
throw megaglest_runtime_error("Error loading resource type: " + path + "\n" + e.what());
}
}
// ==================== misc ====================
ResourceClass ResourceType::strToRc(const string &s){
if(s=="tech"){
return rcTech;
}
if(s=="tileset"){
return rcTileset;
}
if(s=="static"){
return rcStatic;
}
if(s=="consumable"){
return rcConsumable;
}
throw megaglest_runtime_error("Error converting from string ro resourceClass, found: " + s);
}
void ResourceType::deletePixels() {
if(model != NULL) {
model->deletePixels();
}
}
void ResourceType::saveGame(XmlNode *rootNode) {
//DisplayableType::saveGame(rootNode);
std::map<string,string> mapTagReplacements;
XmlNode *resourceTypeNode = rootNode->addChild("ResourceType");
resourceTypeNode->addAttribute("name",this->getName(), mapTagReplacements);
// ResourceClass resourceClass;
resourceTypeNode->addAttribute("resourceClass",intToStr(resourceClass), mapTagReplacements);
// int tilesetObject; //used only if class==rcTileset
resourceTypeNode->addAttribute("tilesetObject",intToStr(tilesetObject), mapTagReplacements);
// int resourceNumber; //used only if class==rcTech, resource number in the map
resourceTypeNode->addAttribute("resourceNumber",intToStr(resourceNumber), mapTagReplacements);
// int interval; //used only if class==rcConsumable
resourceTypeNode->addAttribute("interval",intToStr(interval), mapTagReplacements);
// int defResPerPatch; //used only if class==rcTileset || class==rcTech
resourceTypeNode->addAttribute("defResPerPatch",intToStr(defResPerPatch), mapTagReplacements);
// bool recoup_cost;
resourceTypeNode->addAttribute("recoup_cost",intToStr(recoup_cost), mapTagReplacements);
//
// Model *model;
if(model != NULL) {
resourceTypeNode->addAttribute("model",model->getFileName(), mapTagReplacements);
}
// ObjectParticleSystemTypes particleTypes;
for(unsigned int i = 0; i < particleTypes.size(); ++i) {
ObjectParticleSystemType *opst = particleTypes[i];
opst->saveGame(resourceTypeNode);
}
}
}}//end namespace