317 lines
12 KiB
C++
317 lines
12 KiB
C++
// ==============================================================
|
|
// This file is part of Glest (www.glest.org)
|
|
//
|
|
// Copyright (C) 2010-2010 Titus Tscharntke
|
|
//
|
|
// 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 "particle_type.h"
|
|
|
|
#include "util.h"
|
|
#include "core_data.h"
|
|
#include "xml_parser.h"
|
|
#include "model.h"
|
|
#include "config.h"
|
|
#include "game_constants.h"
|
|
#include "util.h"
|
|
#include "platform_common.h"
|
|
#include "leak_dumper.h"
|
|
|
|
using namespace Shared::Xml;
|
|
using namespace Shared::Graphics;
|
|
using namespace Shared::Util;
|
|
using namespace Shared::PlatformCommon;
|
|
|
|
namespace Glest{ namespace Game{
|
|
|
|
// =====================================================
|
|
// class ParticleSystemType
|
|
// =====================================================
|
|
|
|
ParticleSystemType::ParticleSystemType() {
|
|
//printf("++ Create ParticleSystemType [%p]\n",this);
|
|
|
|
teamcolorNoEnergy=false;
|
|
teamcolorEnergy=false;
|
|
alternations=false;
|
|
texture=NULL;
|
|
model=NULL;
|
|
minmaxEnabled=false;
|
|
minHp=0;
|
|
maxHp=0;
|
|
minmaxIsPercent=false;
|
|
}
|
|
|
|
ParticleSystemType::~ParticleSystemType() {
|
|
//printf("-- Delete ParticleSystemType [%p] type = [%s]\n",this,type.c_str());
|
|
}
|
|
|
|
void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir,
|
|
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
|
|
string parentLoader, string techtreePath) {
|
|
//texture
|
|
const XmlNode *textureNode= particleSystemNode->getChild("texture");
|
|
bool textureEnabled= textureNode->getAttribute("value")->getBoolValue();
|
|
|
|
if(textureEnabled){
|
|
texture= renderer->newTexture2D(rsGame);
|
|
if(textureNode->getAttribute("luminance")->getBoolValue()){
|
|
texture->setFormat(Texture::fAlpha);
|
|
texture->getPixmap()->init(1);
|
|
}
|
|
else{
|
|
texture->getPixmap()->init(4);
|
|
}
|
|
string currentPath = dir;
|
|
endPathWithSlash(currentPath);
|
|
texture->load(textureNode->getAttribute("path")->getRestrictedValue(currentPath));
|
|
loadedFileList[textureNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(parentLoader,textureNode->getAttribute("path")->getRestrictedValue()));
|
|
}
|
|
else {
|
|
texture= NULL;
|
|
}
|
|
|
|
//model
|
|
if(particleSystemNode->hasChild("model")){
|
|
const XmlNode *modelNode= particleSystemNode->getChild("model");
|
|
bool modelEnabled= modelNode->getAttribute("value")->getBoolValue();
|
|
if(modelEnabled) {
|
|
string currentPath = dir;
|
|
endPathWithSlash(currentPath);
|
|
|
|
string path= modelNode->getAttribute("path")->getRestrictedValue(currentPath);
|
|
model= renderer->newModel(rsGame);
|
|
|
|
model->load(path, false, &loadedFileList, &parentLoader);
|
|
loadedFileList[path].push_back(make_pair(parentLoader,modelNode->getAttribute("path")->getRestrictedValue()));
|
|
}
|
|
}
|
|
else {
|
|
model= NULL;
|
|
}
|
|
|
|
//primitive
|
|
const XmlNode *primitiveNode= particleSystemNode->getChild("primitive");
|
|
primitive= primitiveNode->getAttribute("value")->getRestrictedValue();
|
|
|
|
//offset
|
|
const XmlNode *offsetNode= particleSystemNode->getChild("offset");
|
|
offset.x= offsetNode->getAttribute("x")->getFloatValue();
|
|
offset.y= offsetNode->getAttribute("y")->getFloatValue();
|
|
offset.z= offsetNode->getAttribute("z")->getFloatValue();
|
|
|
|
//color
|
|
const XmlNode *colorNode= particleSystemNode->getChild("color");
|
|
color.x= colorNode->getAttribute("red")->getFloatValue(0.f, 1.0f);
|
|
color.y= colorNode->getAttribute("green")->getFloatValue(0.f, 1.0f);
|
|
color.z= colorNode->getAttribute("blue")->getFloatValue(0.f, 1.0f);
|
|
color.w= colorNode->getAttribute("alpha")->getFloatValue(0.f, 1.0f);
|
|
|
|
//color
|
|
const XmlNode *colorNoEnergyNode= particleSystemNode->getChild("color-no-energy");
|
|
colorNoEnergy.x= colorNoEnergyNode->getAttribute("red")->getFloatValue(0.f, 1.0f);
|
|
colorNoEnergy.y= colorNoEnergyNode->getAttribute("green")->getFloatValue(0.f, 1.0f);
|
|
colorNoEnergy.z= colorNoEnergyNode->getAttribute("blue")->getFloatValue(0.f, 1.0f);
|
|
colorNoEnergy.w= colorNoEnergyNode->getAttribute("alpha")->getFloatValue(0.f, 1.0f);
|
|
|
|
//size
|
|
const XmlNode *sizeNode= particleSystemNode->getChild("size");
|
|
size= sizeNode->getAttribute("value")->getFloatValue();
|
|
|
|
//sizeNoEnergy
|
|
const XmlNode *sizeNoEnergyNode= particleSystemNode->getChild("size-no-energy");
|
|
sizeNoEnergy= sizeNoEnergyNode->getAttribute("value")->getFloatValue();
|
|
|
|
//speed
|
|
const XmlNode *speedNode= particleSystemNode->getChild("speed");
|
|
speed= speedNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
|
|
|
//gravity
|
|
const XmlNode *gravityNode= particleSystemNode->getChild("gravity");
|
|
gravity= gravityNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
|
|
|
//emission rate
|
|
const XmlNode *emissionRateNode= particleSystemNode->getChild("emission-rate");
|
|
emissionRate= emissionRateNode->getAttribute("value")->getFloatValue();
|
|
|
|
//energy max
|
|
const XmlNode *energyMaxNode= particleSystemNode->getChild("energy-max");
|
|
energyMax= energyMaxNode->getAttribute("value")->getIntValue();
|
|
|
|
//speed
|
|
const XmlNode *energyVarNode= particleSystemNode->getChild("energy-var");
|
|
energyVar= energyVarNode->getAttribute("value")->getIntValue();
|
|
|
|
//teamcolorNoEnergy
|
|
if(particleSystemNode->hasChild("teamcolorNoEnergy")){
|
|
const XmlNode *teamcolorNoEnergyNode= particleSystemNode->getChild("teamcolorNoEnergy");
|
|
teamcolorNoEnergy= teamcolorNoEnergyNode->getAttribute("value")->getBoolValue();
|
|
}
|
|
//teamcolorEnergy
|
|
if(particleSystemNode->hasChild("teamcolorEnergy")){
|
|
const XmlNode *teamcolorEnergyNode= particleSystemNode->getChild("teamcolorEnergy");
|
|
teamcolorEnergy= teamcolorEnergyNode->getAttribute("value")->getBoolValue();
|
|
}
|
|
//alternations
|
|
if(particleSystemNode->hasChild("alternations")){
|
|
const XmlNode *alternatingNode= particleSystemNode->getChild("alternations");
|
|
alternations= alternatingNode->getAttribute("value")->getIntValue();
|
|
}
|
|
//mode
|
|
if(particleSystemNode->hasChild("mode")) {
|
|
const XmlNode *modeNode= particleSystemNode->getChild("mode");
|
|
mode= modeNode->getAttribute("value")->getRestrictedValue();
|
|
}
|
|
else {
|
|
mode="normal";
|
|
}
|
|
}
|
|
|
|
void ParticleSystemType::setValues(AttackParticleSystem *ats){
|
|
ats->setTexture(texture);
|
|
ats->setPrimitive(AttackParticleSystem::strToPrimitive(primitive));
|
|
ats->setOffset(offset);
|
|
ats->setColor(color);
|
|
ats->setColorNoEnergy(colorNoEnergy);
|
|
ats->setSpeed(speed);
|
|
ats->setGravity(gravity);
|
|
ats->setParticleSize(size);
|
|
ats->setSizeNoEnergy(sizeNoEnergy);
|
|
ats->setEmissionRate(emissionRate);
|
|
ats->setMaxParticleEnergy(energyMax);
|
|
ats->setVarParticleEnergy(energyVar);
|
|
ats->setModel(model);
|
|
ats->setTeamcolorNoEnergy(teamcolorNoEnergy);
|
|
ats->setTeamcolorEnergy(teamcolorEnergy);
|
|
ats->setAlternations(alternations);
|
|
ats->setBlendMode(ParticleSystem::strToBlendMode(mode));
|
|
}
|
|
|
|
// ===========================================================
|
|
// class ParticleSystemTypeProjectile
|
|
// ===========================================================
|
|
|
|
void ParticleSystemTypeProjectile::load(const string &dir, const string &path,
|
|
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
|
|
string parentLoader, string techtreePath) {
|
|
|
|
try{
|
|
XmlTree xmlTree;
|
|
|
|
std::map<string,string> mapExtraTagReplacementValues;
|
|
mapExtraTagReplacementValues["$COMMONDATAPATH"] = techtreePath + "/commondata/";
|
|
xmlTree.load(path, Properties::getTagReplacementValues(&mapExtraTagReplacementValues));
|
|
loadedFileList[path].push_back(make_pair(parentLoader,parentLoader));
|
|
|
|
const XmlNode *particleSystemNode= xmlTree.getRootNode();
|
|
|
|
ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList,parentLoader, techtreePath);
|
|
|
|
//trajectory values
|
|
const XmlNode *tajectoryNode= particleSystemNode->getChild("trajectory");
|
|
trajectory= tajectoryNode->getAttribute("type")->getRestrictedValue();
|
|
|
|
//trajectory speed
|
|
const XmlNode *tajectorySpeedNode= tajectoryNode->getChild("speed");
|
|
trajectorySpeed= tajectorySpeedNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps;
|
|
|
|
if(trajectory=="parabolic" || trajectory=="spiral"){
|
|
//trajectory scale
|
|
const XmlNode *tajectoryScaleNode= tajectoryNode->getChild("scale");
|
|
trajectoryScale= tajectoryScaleNode->getAttribute("value")->getFloatValue();
|
|
}
|
|
else{
|
|
trajectoryScale= 1.0f;
|
|
}
|
|
|
|
if(trajectory=="spiral"){
|
|
//trajectory frequency
|
|
const XmlNode *tajectoryFrequencyNode= tajectoryNode->getChild("frequency");
|
|
trajectoryFrequency= tajectoryFrequencyNode->getAttribute("value")->getFloatValue();
|
|
}
|
|
else{
|
|
trajectoryFrequency= 1.0f;
|
|
}
|
|
}
|
|
catch(const exception &e){
|
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what());
|
|
throw runtime_error("Error loading ParticleSystem: "+ path + "\n" +e.what());
|
|
}
|
|
}
|
|
|
|
ProjectileParticleSystem *ParticleSystemTypeProjectile::create() {
|
|
ProjectileParticleSystem *ps= new ProjectileParticleSystem();
|
|
|
|
ParticleSystemType::setValues(ps);
|
|
|
|
ps->setTrajectory(ProjectileParticleSystem::strToTrajectory(trajectory));
|
|
ps->setTrajectorySpeed(trajectorySpeed);
|
|
ps->setTrajectoryScale(trajectoryScale);
|
|
ps->setTrajectoryFrequency(trajectoryFrequency);
|
|
|
|
ps->initParticleSystem();
|
|
|
|
return ps;
|
|
}
|
|
|
|
// ===========================================================
|
|
// class ParticleSystemTypeSplash
|
|
// ===========================================================
|
|
|
|
void ParticleSystemTypeSplash::load(const string &dir, const string &path,
|
|
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
|
|
string parentLoader, string techtreePath) {
|
|
|
|
try{
|
|
XmlTree xmlTree;
|
|
|
|
std::map<string,string> mapExtraTagReplacementValues;
|
|
mapExtraTagReplacementValues["$COMMONDATAPATH"] = techtreePath + "/commondata/";
|
|
xmlTree.load(path, Properties::getTagReplacementValues(&mapExtraTagReplacementValues));
|
|
loadedFileList[path].push_back(make_pair(parentLoader,parentLoader));
|
|
|
|
const XmlNode *particleSystemNode= xmlTree.getRootNode();
|
|
|
|
ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList, parentLoader, techtreePath);
|
|
|
|
//emission rate fade
|
|
const XmlNode *emissionRateFadeNode= particleSystemNode->getChild("emission-rate-fade");
|
|
emissionRateFade= emissionRateFadeNode->getAttribute("value")->getFloatValue();
|
|
|
|
//spread values
|
|
const XmlNode *verticalSpreadNode= particleSystemNode->getChild("vertical-spread");
|
|
verticalSpreadA= verticalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f);
|
|
verticalSpreadB= verticalSpreadNode->getAttribute("b")->getFloatValue(-1.0f, 1.0f);
|
|
|
|
const XmlNode *horizontalSpreadNode= particleSystemNode->getChild("horizontal-spread");
|
|
horizontalSpreadA= horizontalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f);
|
|
horizontalSpreadB= horizontalSpreadNode->getAttribute("b")->getFloatValue(-1.0f, 1.0f);
|
|
}
|
|
catch(const exception &e){
|
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what());
|
|
throw runtime_error("Error loading ParticleSystem: "+ path + "\n" +e.what());
|
|
}
|
|
}
|
|
|
|
SplashParticleSystem *ParticleSystemTypeSplash::create(){
|
|
SplashParticleSystem *ps= new SplashParticleSystem();
|
|
|
|
ParticleSystemType::setValues(ps);
|
|
|
|
ps->setEmissionRateFade(emissionRateFade);
|
|
ps->setVerticalSpreadA(verticalSpreadA);
|
|
ps->setVerticalSpreadB(verticalSpreadB);
|
|
ps->setHorizontalSpreadA(horizontalSpreadA);
|
|
ps->setHorizontalSpreadB(horizontalSpreadB);
|
|
|
|
ps->initParticleSystem();
|
|
|
|
return ps;
|
|
}
|
|
|
|
}}//end mamespace
|