2010-04-24 05:57:38 +02:00
|
|
|
// ==============================================================
|
|
|
|
// This file is part of Glest (www.glest.org)
|
|
|
|
//
|
2011-12-14 08:40:48 +01:00
|
|
|
// Copyright (C) 2001-2008 Martiño Figueroa
|
2010-04-24 05:57:38 +02:00
|
|
|
//
|
|
|
|
// 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 "object.h"
|
|
|
|
|
|
|
|
#include "faction_type.h"
|
2011-03-02 00:36:33 +01:00
|
|
|
#include "config.h"
|
2010-04-24 05:57:38 +02:00
|
|
|
#include "tech_tree.h"
|
|
|
|
#include "resource.h"
|
|
|
|
#include "upgrade.h"
|
|
|
|
#include "object_type.h"
|
|
|
|
#include "resource.h"
|
|
|
|
#include "util.h"
|
2010-04-24 13:15:15 +02:00
|
|
|
#include "randomgen.h"
|
2010-09-10 17:47:19 +02:00
|
|
|
#include "renderer.h"
|
2010-04-24 05:57:38 +02:00
|
|
|
#include "leak_dumper.h"
|
2012-04-04 02:30:16 +02:00
|
|
|
#include "game.h"
|
2010-04-24 05:57:38 +02:00
|
|
|
|
|
|
|
using namespace Shared::Util;
|
|
|
|
|
|
|
|
namespace Glest{ namespace Game{
|
|
|
|
|
2011-02-15 05:34:19 +01:00
|
|
|
ObjectStateInterface *Object::stateCallback=NULL;
|
2010-04-24 05:57:38 +02:00
|
|
|
|
|
|
|
// =====================================================
|
|
|
|
// class Object
|
|
|
|
// =====================================================
|
|
|
|
|
2013-10-02 22:22:10 +02:00
|
|
|
Object::Object(ObjectType *objectType, const Vec3f &pos, const Vec2i &mapPos) : BaseColorPickEntity() {
|
2010-04-24 13:15:15 +02:00
|
|
|
RandomGen random;
|
2010-04-24 05:57:38 +02:00
|
|
|
|
2013-09-28 07:06:04 +02:00
|
|
|
random.init(static_cast<int>(pos.x * pos.z));
|
2010-06-15 18:27:52 +02:00
|
|
|
this->lastRenderFrame = 0;
|
2010-04-24 05:57:38 +02:00
|
|
|
this->objectType= objectType;
|
|
|
|
resource= NULL;
|
2012-04-04 02:30:16 +02:00
|
|
|
highlight= 0.f;
|
2013-05-19 14:30:10 +02:00
|
|
|
animated= false;
|
2010-09-10 02:28:14 +02:00
|
|
|
this->mapPos = mapPos;
|
2013-10-02 22:22:10 +02:00
|
|
|
this->pos= pos + Vec3f(random.randRange(-0.6f, 0.6f), 0.0f, random.randRange(-0.6f, 0.6f));
|
2010-04-24 05:57:38 +02:00
|
|
|
rotation= random.randRange(0.f, 360.f);
|
|
|
|
if(objectType!=NULL){
|
|
|
|
variation = random.randRange(0, objectType->getModelCount()-1);
|
2011-06-22 22:26:39 +02:00
|
|
|
TilesetModelType *tmt=objectType->getTilesetModelType(variation);
|
2013-09-28 07:06:04 +02:00
|
|
|
if(tmt->getRotationAllowed() != true) {
|
2011-06-22 22:26:39 +02:00
|
|
|
rotation=0;
|
|
|
|
}
|
2013-10-08 06:36:21 +02:00
|
|
|
if(tmt->getRandomPositionEnabled() != true) {
|
|
|
|
this->pos = pos;
|
|
|
|
}
|
2013-05-19 14:30:10 +02:00
|
|
|
animated=tmt->getAnimSpeed()>0;
|
2010-04-24 05:57:38 +02:00
|
|
|
}
|
2011-03-05 15:34:36 +01:00
|
|
|
visible=false;
|
2012-03-27 01:24:29 +02:00
|
|
|
animProgress=0.0f;
|
2010-04-24 05:57:38 +02:00
|
|
|
}
|
|
|
|
|
2011-11-23 09:00:09 +01:00
|
|
|
Object::~Object() {
|
2011-12-03 01:39:03 +01:00
|
|
|
Renderer &renderer = Renderer::getInstance();
|
2011-03-06 23:50:04 +01:00
|
|
|
// fade(and by this remove) all unit particle systems
|
|
|
|
while(unitParticleSystems.empty() == false) {
|
2011-12-03 01:39:03 +01:00
|
|
|
bool particleValid = renderer.validateParticleSystemStillExists(unitParticleSystems.back(),rsGame);
|
2011-11-23 09:00:09 +01:00
|
|
|
if(particleValid == true) {
|
|
|
|
unitParticleSystems.back()->fade();
|
|
|
|
}
|
2011-03-06 23:50:04 +01:00
|
|
|
unitParticleSystems.pop_back();
|
|
|
|
}
|
2013-09-24 06:29:53 +02:00
|
|
|
Renderer::getInstance().removeParticleSystemsForParticleOwner(this,rsGame);
|
2010-09-10 21:44:00 +02:00
|
|
|
renderer.removeObjectFromQuadCache(this);
|
2011-02-15 05:34:19 +01:00
|
|
|
if(stateCallback) {
|
|
|
|
stateCallback->removingObjectEvent(this);
|
|
|
|
}
|
2011-03-06 23:50:04 +01:00
|
|
|
delete resource;
|
2011-12-03 01:39:03 +01:00
|
|
|
resource = NULL;
|
2013-01-23 22:03:00 +01:00
|
|
|
|
|
|
|
recycleUniqueColor();
|
2011-03-06 23:50:04 +01:00
|
|
|
}
|
|
|
|
|
2011-11-23 09:00:09 +01:00
|
|
|
void Object::end() {
|
2011-03-06 23:50:04 +01:00
|
|
|
// set Objects to fading and remove them from list.
|
|
|
|
// its needed because otherwise they will be accessed from the destructor
|
2011-03-02 00:36:33 +01:00
|
|
|
while(unitParticleSystems.empty() == false) {
|
2011-11-23 09:00:09 +01:00
|
|
|
bool particleValid = Renderer::getInstance().validateParticleSystemStillExists(unitParticleSystems.back(),rsGame);
|
|
|
|
if(particleValid == true) {
|
|
|
|
unitParticleSystems.back()->fade();
|
|
|
|
}
|
2011-03-02 00:36:33 +01:00
|
|
|
unitParticleSystems.pop_back();
|
|
|
|
}
|
2010-04-24 05:57:38 +02:00
|
|
|
}
|
|
|
|
|
2011-11-23 09:00:09 +01:00
|
|
|
void Object::initParticles() {
|
2011-12-03 01:39:03 +01:00
|
|
|
if(this->objectType == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
2011-11-23 09:00:09 +01:00
|
|
|
if(this->objectType->getTilesetModelType(variation)->hasParticles()) {
|
2011-06-22 22:26:39 +02:00
|
|
|
ModelParticleSystemTypes *particleTypes= this->objectType->getTilesetModelType(variation)->getParticleTypes();
|
2011-03-09 02:32:27 +01:00
|
|
|
initParticlesFromTypes(particleTypes);
|
2011-03-02 00:36:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-23 09:00:09 +01:00
|
|
|
void Object::initParticlesFromTypes(const ModelParticleSystemTypes *particleTypes) {
|
2011-12-03 01:39:03 +01:00
|
|
|
bool showTilesetParticles = Config::getInstance().getBool("TilesetParticles", "true");
|
|
|
|
if(showTilesetParticles == true && GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false &&
|
|
|
|
particleTypes->empty() == false && unitParticleSystems.empty() == true) {
|
2011-06-22 22:26:39 +02:00
|
|
|
for(ObjectParticleSystemTypes::const_iterator it= particleTypes->begin(); it != particleTypes->end(); ++it){
|
|
|
|
UnitParticleSystem *ups= new UnitParticleSystem(200);
|
2013-09-23 19:16:34 +02:00
|
|
|
ups->setParticleOwner(this);
|
2011-06-22 22:26:39 +02:00
|
|
|
(*it)->setValues(ups);
|
2013-09-28 07:06:04 +02:00
|
|
|
ups->setPos(this->pos);
|
2011-06-22 22:26:39 +02:00
|
|
|
ups->setRotation(this->rotation);
|
2013-09-26 18:37:32 +02:00
|
|
|
ups->setFactionColor(Vec3f(0, 0, 0));
|
2011-06-22 22:26:39 +02:00
|
|
|
ups->setVisible(false);
|
|
|
|
this->unitParticleSystems.push_back(ups);
|
|
|
|
Renderer::getInstance().manageParticleSystem(ups, rsGame);
|
|
|
|
}
|
|
|
|
}
|
2011-03-09 02:32:27 +01:00
|
|
|
}
|
2013-09-23 19:16:34 +02:00
|
|
|
|
|
|
|
void Object::end(ParticleSystem *particleSystem) {
|
|
|
|
vector<UnitParticleSystem *>::iterator iterFind = find(unitParticleSystems.begin(),unitParticleSystems.end(),particleSystem);
|
|
|
|
if(iterFind != unitParticleSystems.end()) {
|
|
|
|
unitParticleSystems.erase(iterFind);
|
|
|
|
}
|
|
|
|
}
|
2011-03-09 02:32:27 +01:00
|
|
|
|
2013-10-02 22:22:10 +02:00
|
|
|
void Object::setHeight(float height) {
|
2013-09-28 07:06:04 +02:00
|
|
|
pos.y = height;
|
2011-03-02 00:36:33 +01:00
|
|
|
|
|
|
|
for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it != unitParticleSystems.end(); ++it) {
|
2011-11-23 09:00:09 +01:00
|
|
|
bool particleValid = Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame);
|
|
|
|
if(particleValid == true) {
|
2013-09-28 07:06:04 +02:00
|
|
|
(*it)->setPos(this->pos);
|
2011-11-23 09:00:09 +01:00
|
|
|
}
|
2011-03-02 00:36:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-11 08:44:26 +02:00
|
|
|
void Object::updateHighlight() {
|
2012-04-04 02:30:16 +02:00
|
|
|
//highlight
|
|
|
|
if(highlight > 0.f) {
|
2013-06-11 08:44:26 +02:00
|
|
|
//const Game *game = Renderer::getInstance().getGame();
|
|
|
|
//highlight -= 1.f / (Game::highlightTime * game->getWorld()->getUpdateFps(-1));
|
|
|
|
highlight -= 1.f / (Game::highlightTime * GameConstants::updateFps);
|
2012-04-04 02:30:16 +02:00
|
|
|
}
|
2013-06-11 08:44:26 +02:00
|
|
|
}
|
2012-04-04 02:30:16 +02:00
|
|
|
|
2013-06-11 08:44:26 +02:00
|
|
|
void Object::update() {
|
|
|
|
//if(objectType != NULL && objectType->getTilesetModelType(variation) != NULL &&
|
|
|
|
// objectType->getTilesetModelType(variation)->getAnimSpeed() != 0.0) {
|
|
|
|
if(animated == true) {
|
2012-03-27 01:24:29 +02:00
|
|
|
// printf("#1 Object updating [%s] Speed [%d] animProgress [%f]\n",this->objectType->getTilesetModelType(variation)->getModel()->getFileName().c_str(),objectType->getTilesetModelType(variation)->getAnimSpeed(),animProgress);
|
|
|
|
|
2013-06-11 08:44:26 +02:00
|
|
|
if(objectType != NULL && objectType->getTilesetModelType(variation) != NULL) {
|
2013-10-02 22:22:10 +02:00
|
|
|
float heightFactor = 1.f;
|
|
|
|
const float speedDivider= 100.f;
|
|
|
|
float speedDenominator = (speedDivider * GameConstants::updateFps);
|
2013-04-17 02:12:54 +02:00
|
|
|
|
2013-06-11 08:44:26 +02:00
|
|
|
// smooth TwoFrameanimations
|
2013-10-02 22:22:10 +02:00
|
|
|
float f=1.0f;
|
2013-06-11 08:44:26 +02:00
|
|
|
if(objectType->getTilesetModelType(variation)->getSmoothTwoFrameAnim()==true){
|
|
|
|
f=abs(std::sin(animProgress*2*3.16))+0.4f;
|
|
|
|
}
|
2013-04-17 02:12:54 +02:00
|
|
|
|
2013-10-02 22:22:10 +02:00
|
|
|
float newAnimProgress = animProgress + f*(((float)objectType->getTilesetModelType(variation)->getAnimSpeed() * heightFactor) / speedDenominator);
|
2012-03-27 01:24:29 +02:00
|
|
|
|
2013-06-11 08:44:26 +02:00
|
|
|
animProgress = newAnimProgress;
|
|
|
|
if(animProgress > 1.f) {
|
|
|
|
animProgress = 0.f;
|
|
|
|
}
|
2012-03-27 01:24:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-04 02:30:16 +02:00
|
|
|
void Object::resetHighlight(){
|
|
|
|
highlight= 1.f;
|
|
|
|
}
|
|
|
|
|
2011-01-18 08:52:06 +01:00
|
|
|
Model *Object::getModelPtr() const {
|
2011-12-03 01:39:03 +01:00
|
|
|
Model* result = NULL;
|
|
|
|
if(objectType==NULL) {
|
2011-06-22 22:26:39 +02:00
|
|
|
if(resource != NULL && resource->getType() != NULL){
|
2011-12-03 01:39:03 +01:00
|
|
|
result = resource->getType()->getModel();
|
2011-06-22 22:26:39 +02:00
|
|
|
}
|
2011-12-03 01:39:03 +01:00
|
|
|
}
|
|
|
|
else {
|
2011-06-22 22:26:39 +02:00
|
|
|
result=objectType->getTilesetModelType(variation)->getModel();
|
|
|
|
}
|
|
|
|
return result;
|
2011-01-18 08:52:06 +01:00
|
|
|
}
|
|
|
|
|
2011-12-03 01:39:03 +01:00
|
|
|
const Model *Object::getModel() const {
|
|
|
|
Model* result = NULL;
|
|
|
|
if(objectType == NULL){
|
2011-06-22 22:26:39 +02:00
|
|
|
if(resource != NULL && resource->getType() != NULL){
|
|
|
|
result=resource->getType()->getModel();
|
|
|
|
}
|
2011-12-03 01:39:03 +01:00
|
|
|
}
|
|
|
|
else {
|
2011-06-22 22:26:39 +02:00
|
|
|
result=objectType->getTilesetModelType(variation)->getModel();
|
|
|
|
}
|
|
|
|
return result;
|
2010-04-24 05:57:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Object::getWalkable() const{
|
|
|
|
return objectType==NULL? false: objectType->getWalkable();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Object::setResource(const ResourceType *resourceType, const Vec2i &pos){
|
2011-12-03 01:39:03 +01:00
|
|
|
delete resource;
|
2010-04-24 05:57:38 +02:00
|
|
|
resource= new Resource();
|
|
|
|
resource->init(resourceType, pos);
|
2011-03-09 02:32:27 +01:00
|
|
|
initParticlesFromTypes(resourceType->getObjectParticleSystemTypes());
|
2010-04-24 05:57:38 +02:00
|
|
|
}
|
|
|
|
|
2011-03-05 15:34:36 +01:00
|
|
|
void Object::setVisible( bool visible)
|
|
|
|
{
|
|
|
|
this->visible=visible;
|
|
|
|
for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it != unitParticleSystems.end(); ++it) {
|
2011-11-23 09:00:09 +01:00
|
|
|
bool particleValid = Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame);
|
|
|
|
if(particleValid == true) {
|
2011-03-05 15:34:36 +01:00
|
|
|
(*it)->setVisible(visible);
|
|
|
|
}
|
2011-11-23 09:00:09 +01:00
|
|
|
}
|
2011-03-05 15:34:36 +01:00
|
|
|
}
|
|
|
|
|
2011-12-13 02:30:52 +01:00
|
|
|
string Object::getUniquePickName() const {
|
|
|
|
string result = "";
|
|
|
|
if(resource != NULL) {
|
2013-06-13 10:55:48 +02:00
|
|
|
result += resource->getDescription(false) + " : ";
|
2011-12-13 02:30:52 +01:00
|
|
|
}
|
|
|
|
result += mapPos.getString();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2012-03-13 00:08:22 +01:00
|
|
|
void Object::saveGame(XmlNode *rootNode) {
|
|
|
|
std::map<string,string> mapTagReplacements;
|
|
|
|
XmlNode *objectNode = rootNode->addChild("Object");
|
|
|
|
|
|
|
|
// ObjectType *objectType;
|
|
|
|
if(objectType != NULL) {
|
|
|
|
objectNode->addAttribute("objectType",intToStr(objectType->getClass()), mapTagReplacements);
|
|
|
|
}
|
|
|
|
// vector<UnitParticleSystem*> unitParticleSystems;
|
|
|
|
for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) {
|
|
|
|
UnitParticleSystem *ptr= unitParticleSystems[i];
|
|
|
|
if(ptr != NULL) {
|
|
|
|
ptr->saveGame(objectNode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Resource *resource;
|
|
|
|
if(resource != NULL) {
|
|
|
|
resource->saveGame(objectNode);
|
|
|
|
}
|
|
|
|
// Vec3f pos;
|
|
|
|
objectNode->addAttribute("pos",pos.getString(), mapTagReplacements);
|
|
|
|
// float rotation;
|
2013-10-02 22:22:10 +02:00
|
|
|
objectNode->addAttribute("rotation",floatToStr(rotation,6), mapTagReplacements);
|
2012-03-13 00:08:22 +01:00
|
|
|
// int variation;
|
|
|
|
objectNode->addAttribute("variation",intToStr(variation), mapTagReplacements);
|
|
|
|
// int lastRenderFrame;
|
|
|
|
objectNode->addAttribute("lastRenderFrame",intToStr(lastRenderFrame), mapTagReplacements);
|
|
|
|
// Vec2i mapPos;
|
|
|
|
objectNode->addAttribute("mapPos",mapPos.getString(), mapTagReplacements);
|
|
|
|
// bool visible;
|
|
|
|
objectNode->addAttribute("visible",intToStr(visible), mapTagReplacements);
|
|
|
|
}
|
2012-03-13 16:21:25 +01:00
|
|
|
|
|
|
|
void Object::loadGame(const XmlNode *rootNode,const TechTree *techTree) {
|
|
|
|
const XmlNode *objectNode = rootNode->getChild("Object");
|
|
|
|
|
|
|
|
//description = objectNode->getAttribute("description")->getValue();
|
|
|
|
|
|
|
|
// ObjectType *objectType;
|
|
|
|
// if(objectType != NULL) {
|
|
|
|
// objectNode->addAttribute("objectType",intToStr(objectType->getClass()), mapTagReplacements);
|
|
|
|
// }
|
|
|
|
// // vector<UnitParticleSystem*> unitParticleSystems;
|
|
|
|
// for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) {
|
|
|
|
// UnitParticleSystem *ptr= unitParticleSystems[i];
|
|
|
|
// if(ptr != NULL) {
|
|
|
|
// ptr->saveGame(objectNode);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// Resource *resource;
|
|
|
|
if(resource != NULL) {
|
|
|
|
resource->loadGame(objectNode,0,techTree);
|
|
|
|
}
|
|
|
|
// Vec3f pos;
|
2013-10-02 22:22:10 +02:00
|
|
|
pos = Vec3f::strToVec3(objectNode->getAttribute("pos")->getValue());
|
2012-03-13 16:21:25 +01:00
|
|
|
// float rotation;
|
|
|
|
rotation = objectNode->getAttribute("rotation")->getFloatValue();
|
|
|
|
// int variation;
|
|
|
|
variation = objectNode->getAttribute("variation")->getIntValue();
|
|
|
|
// int lastRenderFrame;
|
|
|
|
lastRenderFrame = objectNode->getAttribute("lastRenderFrame")->getIntValue();
|
|
|
|
// Vec2i mapPos;
|
|
|
|
mapPos = Vec2i::strToVec2(objectNode->getAttribute("mapPos")->getValue());
|
|
|
|
// bool visible;
|
2012-04-16 22:15:57 +02:00
|
|
|
visible = objectNode->getAttribute("visible")->getIntValue() != 0;
|
2012-03-13 16:21:25 +01:00
|
|
|
}
|
|
|
|
|
2010-04-24 05:57:38 +02:00
|
|
|
}}//end namespace
|