diff --git a/source/g3d_viewer/main.cpp b/source/g3d_viewer/main.cpp index 88a16d7a..5d7f0ae1 100644 --- a/source/g3d_viewer/main.cpp +++ b/source/g3d_viewer/main.cpp @@ -1450,7 +1450,7 @@ void MainWindow::loadProjectileParticle(string path) { for(std::vector::const_iterator it= projectileParticleSystemTypes.begin(); it != projectileParticleSystemTypes.end(); ++it) { - ProjectileParticleSystem *ps = (*it)->create(); + ProjectileParticleSystem *ps = (*it)->create(NULL); if(size > 0) { Vec3f vec = Vec3f(0.f, height / 2.f, 0.f); @@ -1559,7 +1559,7 @@ void MainWindow::loadSplashParticle(string path) { // uses ParticleSystemTypeSp //ParticleSystemTypeSplash for(std::vector::const_iterator it= splashParticleSystemTypes.begin(); it != splashParticleSystemTypes.end(); ++it) { - SplashParticleSystem *ps = (*it)->create(); + SplashParticleSystem *ps = (*it)->create(NULL); if(size > 0) { Vec3f vec = Vec3f(0.f, height / 2.f, 0.f); diff --git a/source/glest_game/ai/path_finder.cpp b/source/glest_game/ai/path_finder.cpp index ed0d9b4e..d257ba01 100644 --- a/source/glest_game/ai/path_finder.cpp +++ b/source/glest_game/ai/path_finder.cpp @@ -250,11 +250,11 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu if(path->isStuck() == true && (unit->getLastStuckPos() == finalPos || path->getBlockCount() > 500) && - unit->isLastStuckFrameWithinCurrentFrameTolerance() == true) { + unit->isLastStuckFrameWithinCurrentFrameTolerance(frameIndex >= 0) == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { char szBuf[8096]=""; - snprintf(szBuf,8096,"path->isStuck() == true unit->getLastStuckPos() [%s] finalPos [%s] path->getBlockCount() [%d] tolerance: %d",unit->getLastStuckPos().getString().c_str(),finalPos.getString().c_str(),path->getBlockCount(),unit->isLastStuckFrameWithinCurrentFrameTolerance()); + snprintf(szBuf,8096,"path->isStuck() == true unit->getLastStuckPos() [%s] finalPos [%s] path->getBlockCount() [%d]",unit->getLastStuckPos().getString().c_str(),finalPos.getString().c_str(),path->getBlockCount()); unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); } diff --git a/source/glest_game/graphics/particle_type.cpp b/source/glest_game/graphics/particle_type.cpp index bfb31181..dba7fd1a 100644 --- a/source/glest_game/graphics/particle_type.cpp +++ b/source/glest_game/graphics/particle_type.cpp @@ -292,6 +292,7 @@ void ParticleSystemType::setValues(AttackParticleSystem *ats){ // add instances of all children; some settings will cascade to all children for(Children::iterator i=children.begin(); i!=children.end(); ++i){ UnitParticleSystem *child = new UnitParticleSystem(); + child->setParticleOwner(ats->getParticleOwner()); (*i)->setValues(child); ats->addChild(child); child->setState(ParticleSystem::sPlay); @@ -439,9 +440,9 @@ void ParticleSystemTypeProjectile::load(const XmlNode* particleFileNode, const s } } -ProjectileParticleSystem *ParticleSystemTypeProjectile::create() { +ProjectileParticleSystem *ParticleSystemTypeProjectile::create(ParticleOwner *owner) { ProjectileParticleSystem *ps= new ProjectileParticleSystem(); - + ps->setParticleOwner(owner); ParticleSystemType::setValues(ps); ps->setTrajectory(ProjectileParticleSystem::strToTrajectory(trajectory)); @@ -525,9 +526,9 @@ void ParticleSystemTypeSplash::load(const XmlNode* particleFileNode, const strin } } -SplashParticleSystem *ParticleSystemTypeSplash::create(){ +SplashParticleSystem *ParticleSystemTypeSplash::create(ParticleOwner *owner) { SplashParticleSystem *ps= new SplashParticleSystem(); - + ps->setParticleOwner(owner); ParticleSystemType::setValues(ps); ps->setEmissionRateFade(emissionRateFade); diff --git a/source/glest_game/graphics/particle_type.h b/source/glest_game/graphics/particle_type.h index 39a9014b..dea1436d 100644 --- a/source/glest_game/graphics/particle_type.h +++ b/source/glest_game/graphics/particle_type.h @@ -132,7 +132,7 @@ public: void load(const XmlNode *particleFileNode, const string &dir, const string &path, RendererInterface *renderer, std::map > > &loadedFileList, string parentLoader, string techtreePath); - ProjectileParticleSystem *create(); + ProjectileParticleSystem *create(ParticleOwner *owner); virtual void saveGame(XmlNode *rootNode); }; @@ -148,7 +148,7 @@ public: void load(const XmlNode *particleFileNode, const string &dir, const string &path, RendererInterface *renderer, std::map > > &loadedFileList, string parentLoader, string techtreePath); - SplashParticleSystem *create(); + SplashParticleSystem *create(ParticleOwner *owner); virtual void saveGame(XmlNode *rootNode); diff --git a/source/glest_game/graphics/unit_particle_type.cpp b/source/glest_game/graphics/unit_particle_type.cpp index 5810766b..75f187a3 100644 --- a/source/glest_game/graphics/unit_particle_type.cpp +++ b/source/glest_game/graphics/unit_particle_type.cpp @@ -207,6 +207,7 @@ const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){ // add instances of all children; some settings will cascade to all children for(Children::iterator i=children.begin(); i!=children.end(); ++i){ UnitParticleSystem *child = new UnitParticleSystem(); + child->setParticleOwner(ups->getParticleOwner()); (*i)->setValues(child); ups->addChild(child); } diff --git a/source/glest_game/type_instances/command.cpp b/source/glest_game/type_instances/command.cpp index 027b99be..f55819d2 100644 --- a/source/glest_game/type_instances/command.cpp +++ b/source/glest_game/type_instances/command.cpp @@ -147,6 +147,26 @@ std::string Command::toString(bool translatedValue) const { return result; } +Checksum Command::getCRC() { + Checksum crcForCmd; + + crcForCmd.addInt(commandType->getId()); + crcForCmd.addInt(originalPos.x); + crcForCmd.addInt(originalPos.y); + crcForCmd.addInt(pos.x); + crcForCmd.addInt(pos.y); + crcForCmd.addInt(unitRef.getUnitId()); + crcForCmd.addInt(facing); + if(unitType != NULL) { + crcForCmd.addInt(unitType->getId()); + } + crcForCmd.addInt(stateType); + crcForCmd.addInt(stateValue); + crcForCmd.addInt(unitCommandGroupId); + + return crcForCmd; +} + void Command::saveGame(XmlNode *rootNode, Faction *faction) { std::map mapTagReplacements; XmlNode *commandNode = rootNode->addChild("Command"); diff --git a/source/glest_game/type_instances/command.h b/source/glest_game/type_instances/command.h index e86b94f1..302e2519 100644 --- a/source/glest_game/type_instances/command.h +++ b/source/glest_game/type_instances/command.h @@ -95,6 +95,8 @@ public: void saveGame(XmlNode *rootNode, Faction *faction); static Command * loadGame(const XmlNode *rootNode,const UnitType *ut,World *world); + + Checksum getCRC(); }; }}//end namespace diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index b7b424e3..e85a2d89 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -2300,13 +2300,19 @@ Checksum Faction::getCRC() { } void Faction::addCRC_DetailsForWorldFrame(int worldFrameCount,bool isNetworkServer) { - int MAX_FRAME_CACHE = 1500; + int MAX_FRAME_CACHE = 250; if(isNetworkServer == true) { - MAX_FRAME_CACHE += 700; + MAX_FRAME_CACHE += 250; } crcWorldFrameDetails[worldFrameCount] = this->toString(true); //if(worldFrameCount <= 0) printf("Adding world frame: %d log entries: %lld\n",worldFrameCount,(long long int)crcWorldFrameDetails.size()); + for(unsigned int i = 0; i < units.size(); ++i) { + Unit *unit = units[i]; + unit->getRandom()->clearLastCaller(); + unit->clearNetworkCRCDecHpList(); + } + if(crcWorldFrameDetails.size() > MAX_FRAME_CACHE) { //printf("===> Removing older world frame log entries: %lld\n",(long long int)crcWorldFrameDetails.size()); diff --git a/source/glest_game/type_instances/object.cpp b/source/glest_game/type_instances/object.cpp index 1b78becf..87b8722c 100644 --- a/source/glest_game/type_instances/object.cpp +++ b/source/glest_game/type_instances/object.cpp @@ -106,6 +106,7 @@ void Object::initParticlesFromTypes(const ModelParticleSystemTypes *particleType particleTypes->empty() == false && unitParticleSystems.empty() == true) { for(ObjectParticleSystemTypes::const_iterator it= particleTypes->begin(); it != particleTypes->end(); ++it){ UnitParticleSystem *ups= new UnitParticleSystem(200); + ups->setParticleOwner(this); (*it)->setValues(ups); ups->setPos(this->pos); ups->setRotation(this->rotation); @@ -117,6 +118,13 @@ void Object::initParticlesFromTypes(const ModelParticleSystemTypes *particleType } } +void Object::end(ParticleSystem *particleSystem) { + vector::iterator iterFind = find(unitParticleSystems.begin(),unitParticleSystems.end(),particleSystem); + if(iterFind != unitParticleSystems.end()) { + unitParticleSystems.erase(iterFind); + } +} + void Object::setHeight(float height) { pos.y=height; diff --git a/source/glest_game/type_instances/object.h b/source/glest_game/type_instances/object.h index cca31c83..352fc16e 100644 --- a/source/glest_game/type_instances/object.h +++ b/source/glest_game/type_instances/object.h @@ -49,7 +49,7 @@ public: virtual ~ObjectStateInterface() {} }; -class Object : public BaseColorPickEntity { +class Object : public BaseColorPickEntity, public ParticleOwner { private: typedef vector UnitParticleSystems; @@ -109,6 +109,8 @@ public: virtual string getUniquePickName() const; void saveGame(XmlNode *rootNode); void loadGame(const XmlNode *rootNode,const TechTree *techTree); + + virtual void end(ParticleSystem *particleSystem); }; }}//end namespace diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 12e77769..67a69463 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -440,7 +440,7 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, //RandomGen random; random.init(id); - pathFindRefreshCellCount = random.randRange(10,20); + pathFindRefreshCellCount = random.randRange(10,20,intToStr(__LINE__)); if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) { throw megaglest_runtime_error("#2 Invalid path position = " + pos.getString()); @@ -498,7 +498,7 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, if (type->hasSkillClass(scBeBuilt) == false) { float rot= 0.f; random.init(id); - rot+= random.randRange(-5, 5); + rot+= random.randRange(-5, 5,intToStr(__LINE__)); rotation= rot; lastRotation= rot; targetRotation= rot; @@ -560,8 +560,6 @@ Unit::~Unit() { Renderer::getInstance().cleanupParticleSystems(fireParticleSystems,rsGame); // Must set this to null of it will be used below in stopDamageParticles() - Renderer::getInstance().cleanupParticleSystems(attackParticleSystems,rsGame); - if(Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) { this->fire = NULL; } @@ -587,6 +585,8 @@ Unit::~Unit() { delete currentAttackBoostOriginatorEffect.currentAppliedEffect; currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; + Renderer::getInstance().cleanupParticleSystems(attackParticleSystems,rsGame); + #ifdef LEAK_CHECK_UNITS Unit::mapMemoryList2[this->unitPath] = this->getId(); #endif @@ -1090,6 +1090,7 @@ void Unit::setCurrSkill(const SkillType *currSkill) { //printf("Adding NON-queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime()); UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); (*it)->setValues(ups); ups->setPos(getCurrVector()); if(getFaction()->getTexture()) { @@ -1286,15 +1287,15 @@ void Unit::setVisible(const bool visible) { } } - if(attackParticleSystems.empty() == false) { - for(vector::iterator it= attackParticleSystems.begin(); it != attackParticleSystems.end(); ++it) { - if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { + //if(attackParticleSystems.empty() == false) { + // for(vector::iterator it= attackParticleSystems.begin(); it != attackParticleSystems.end(); ++it) { + // if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { // Not sure this is a good idea since the unit be not be visible but the attack particle might be. // This means you won't see the attacking projectile until the unit moves into view. //(*it)->setVisible(visible); - } - } - } + // } + // } + //} if(currentAttackBoostEffects.empty() == false) { for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { @@ -2106,6 +2107,7 @@ void Unit::updateAttackBoostProgress(const Game* game) { //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = new UnitParticleSystem(200); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setParticleOwner(this); currentAttackBoostOriginatorEffect.currentAppliedEffect->upst->setValues( currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos( @@ -2213,6 +2215,7 @@ void Unit::updateAttackBoostProgress(const Game* game) { //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = new UnitParticleSystem(200); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setParticleOwner(this); currentAttackBoostOriginatorEffect.currentAppliedEffect->upst->setValues( currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos( @@ -2466,6 +2469,7 @@ void Unit::updateTimedParticles() { //printf("STARTING queued particle system type [%s] [%f] [%f] [%f] [%f]\n",pst->getType().c_str(),truncateDecimal(pst->getStartTime()),truncateDecimal(pst->getEndTime()),truncateDecimal(animProgress),truncateDecimal(lastAnimProgress)); UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); pst->setValues(ups); ups->setPos(getCurrVector()); if(getFaction()->getTexture()) { @@ -2602,6 +2606,7 @@ bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) { //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; effect->ups = new UnitParticleSystem(200); + effect->ups->setParticleOwner(this); effect->upst->setValues(effect->ups); effect->ups->setPos(getCurrVector()); if(getFaction()->getTexture()) { @@ -2973,14 +2978,18 @@ bool Unit::repair(){ } //decrements HP and returns if dead -bool Unit::decHp(int i) { +bool Unit::decHp(int decrementValue) { + char szBuf[8096]=""; + snprintf(szBuf,8095,"this->hp = %d, decrementValue = %d",this->hp,decrementValue); + addNetworkCRCDecHp(szBuf); + if(this->hp == 0) { return false; } checkItemInVault(&this->hp,this->hp); int original_hp = this->hp; - this->hp -= i; + this->hp -= decrementValue; if(original_hp != this->hp) { //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); @@ -3724,6 +3733,7 @@ void Unit::checkCustomizedParticleTriggers(bool force) { //printf("STARTING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp); UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); pst->setValues(ups); ups->setPos(getCurrVector()); if(getFaction()->getTexture()) { @@ -3748,6 +3758,7 @@ void Unit::startDamageParticles() { if(pst->getMinmaxEnabled() == false && damageParticleSystemsInUse.find(i) == damageParticleSystemsInUse.end()) { UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); pst->setValues(ups); ups->setPos(getCurrVector()); if(getFaction()->getTexture()) { @@ -3763,6 +3774,7 @@ void Unit::startDamageParticles() { // start fire if(type->getProperty(UnitType::pBurnable) && this->fire == NULL) { FireParticleSystem *fps = new FireParticleSystem(200); + fps->setParticleOwner(this); const Game *game = Renderer::getInstance().getGame(); fps->setSpeed(2.5f / game->getWorld()->getUpdateFps(this->getFactionIndex())); fps->setPos(getCurrVector()); @@ -3776,6 +3788,7 @@ void Unit::startDamageParticles() { if(showUnitParticles == true) { // smoke UnitParticleSystem *ups= new UnitParticleSystem(400); + ups->setParticleOwner(this); ups->setColorNoEnergy(Vec4f(0.0f, 0.0f, 0.0f, 0.13f)); ups->setColor(Vec4f(0.115f, 0.115f, 0.115f, 0.22f)); ups->setPos(getCurrVector()); @@ -4017,15 +4030,25 @@ void Unit::setLastStuckFrameToCurrentFrame() { lastStuckFrame = getFrameCount(); } -bool Unit::isLastStuckFrameWithinCurrentFrameTolerance() { +bool Unit::isLastStuckFrameWithinCurrentFrameTolerance(bool evalMode) { //const int MIN_FRAME_ELAPSED_RETRY = 300; const int MAX_BLOCKED_FRAME_THRESHOLD = 25000; int MIN_FRAME_ELAPSED_RETRY = 6; if(lastStuckFrame < MAX_BLOCKED_FRAME_THRESHOLD) { - MIN_FRAME_ELAPSED_RETRY = random.randRange(2,6); + if(evalMode == true) { + MIN_FRAME_ELAPSED_RETRY = 4; + } + else { + MIN_FRAME_ELAPSED_RETRY = random.randRange(2,6,intToStr(__LINE__)); + } } else { - MIN_FRAME_ELAPSED_RETRY = random.randRange(6,8); + if(evalMode == true) { + MIN_FRAME_ELAPSED_RETRY = 7; + } + else { + MIN_FRAME_ELAPSED_RETRY = random.randRange(6,8,intToStr(__LINE__)); + } } bool result (getFrameCount() - lastStuckFrame <= (MIN_FRAME_ELAPSED_RETRY * 100)); return result; @@ -4069,6 +4092,41 @@ bool Unit::showTranslatedTechTree() const { return (this->game != NULL ? this->game->showTranslatedTechTree() : true); } +void Unit::end(ParticleSystem *particleSystem) { + vector::iterator iterFind = find(attackParticleSystems.begin(),attackParticleSystems.end(),particleSystem); + if(iterFind != attackParticleSystems.end()) { + attackParticleSystems.erase(iterFind); + } + vector::iterator iterFind1 = find(smokeParticleSystems.begin(),smokeParticleSystems.end(),particleSystem); + if(iterFind1 != smokeParticleSystems.end()) { + smokeParticleSystems.erase(iterFind1); + } + iterFind = find(fireParticleSystems.begin(),fireParticleSystems.end(),particleSystem); + if(iterFind != fireParticleSystems.end()) { + fireParticleSystems.erase(iterFind); + } + iterFind1 = find(damageParticleSystems.begin(),damageParticleSystems.end(),particleSystem); + if(iterFind1 != damageParticleSystems.end()) { + damageParticleSystems.erase(iterFind1); + } + + iterFind1 = find(unitParticleSystems.begin(),unitParticleSystems.end(),particleSystem); + if(iterFind1 != unitParticleSystems.end()) { + unitParticleSystems.erase(iterFind1); + } + + if(particleSystem == fire) { + fire = NULL; + } +} + +string Unit::getNetworkCRCDecHpList() const { + string result = ""; + for(unsigned int index = 0; index < networkCRCDecHpList.size(); ++index) { + result += networkCRCDecHpList[index] + " "; + } + return result; +} std::string Unit::toString(bool crcMode) const { std::string result = ""; @@ -4165,6 +4223,17 @@ std::string Unit::toString(bool crcMode) const { } result += "\n"; +// int obsIdx = 0; +// for(Observers::const_iterator iterList = observers.begin(); iterList != observers.end(); ++iterList) { +// const UnitObserver *observer = *iterList; +// if(observer != NULL) { +// } +// +// obsIdx++; +// } + + result += "\n"; + result += "modelFacing = " + intToStr(modelFacing.asInt()) + "\n"; result += "retryCurrCommandCount = " + intToStr(retryCurrCommandCount) + "\n"; @@ -4176,8 +4245,32 @@ std::string Unit::toString(bool crcMode) const { result += "inBailOutAttempt = " + intToStr(inBailOutAttempt) + "\n"; result += "random = " + intToStr(random.getLastNumber()) + "\n"; + result += "randomlastCaller = " + random.getLastCaller() + "\n"; result += "pathFindRefreshCellCount = " + intToStr(pathFindRefreshCellCount) + "\n"; + result += "lastStuckFrame = " + uIntToStr(lastStuckFrame) + "\n"; + result += "lastStuckPos = " + lastStuckPos.getString() + "\n"; + + if(attackParticleSystems.size() > 0) { + result += "attackParticleSystems count = " + intToStr(attackParticleSystems.size()) + "\n"; + } + if(networkCRCParticleLogInfo != "") { + result += "networkCRCParticleLogInfo = " + networkCRCParticleLogInfo + "\n"; + } + result += "networkCRCParticleObserverLogInfo = " + networkCRCParticleObserverLogInfo + "\n"; + if(networkCRCDecHpList.size() > 0) { + result += "getNetworkCRCDecHpList() = " + getNetworkCRCDecHpList() + "\n"; + } + + for(unsigned int index = 0; index < attackParticleSystems.size(); ++index) { + ParticleSystem *ps = attackParticleSystems[index]; + if(ps != NULL && + Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { + + result += "attackParticleSystems #" + intToStr(index) + " = " + ps->toString() + "\n"; + } + } + return result; } @@ -4649,6 +4742,7 @@ Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction * if(unitNode->hasChild("FireParticleSystem") == true) { XmlNode *fireNode = unitNode->getChild("FireParticleSystem"); result->fire = new FireParticleSystem(); + result->fire->setParticleOwner(result); result->fire->loadGame(fireNode); //result->fire->setTexture(CoreData::getInstance().getFireTexture()); result->fireParticleSystems.push_back(result->fire); @@ -4696,6 +4790,7 @@ Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction * XmlNode *node = unitParticleSystemNodeList[i]; UnitParticleSystem *ups = new UnitParticleSystem(); + ups->setParticleOwner(result); ups->loadGame(node); result->unitParticleSystems.push_back(ups); @@ -4722,6 +4817,7 @@ Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction * XmlNode *node = unitParticleSystemNodeList[i]; UnitParticleSystem *ups = new UnitParticleSystem(); + ups->setParticleOwner(result); ups->loadGame(node); result->damageParticleSystems.push_back(ups); result->damageParticleSystemsInUse[i]=ups; @@ -4802,6 +4898,7 @@ Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction * // printf("Load Smoke particle i = %d\n",i); UnitParticleSystem *ups = new UnitParticleSystem(); + ups->setParticleOwner(result); ups->loadGame(node); //ups->setTexture(CoreData::getInstance().getFireTexture()); result->smokeParticleSystems.push_back(ups); @@ -5066,6 +5163,10 @@ Checksum Unit::getCRC() { //Commands commands; crcForUnit.addInt64((int64)commands.size()); + for(Commands::const_iterator it= commands.begin(); it != commands.end(); ++it) { + uint32 crc = (*it)->getCRC().getSum(); + crcForUnit.addBytes(&crc,sizeof(uint32)); + } //printf("#11 Unit: %d CRC: %u observers.size(): %ld\n",id,crcForUnit.getSum(),observers.size()); @@ -5116,7 +5217,10 @@ Checksum Unit::getCRC() { //bool ignoreCheckCommand; //uint32 lastStuckFrame; + crcForUnit.addInt(lastStuckFrame); //Vec2i lastStuckPos; + crcForUnit.addInt(lastStuckPos.x); + crcForUnit.addInt(lastStuckPos.y); //uint32 lastPathfindFailedFrame; //Vec2i lastPathfindFailedPos; @@ -5155,6 +5259,16 @@ Checksum Unit::getCRC() { if(consoleDebug) printf("#17 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + crcForUnit.addInt64((int64)attackParticleSystems.size()); + for(unsigned int index = 0; index < attackParticleSystems.size(); ++index) { + ParticleSystem *ps = attackParticleSystems[index]; + if(ps != NULL && + Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { + uint32 crc = ps->getCRC().getSum(); + crcForUnit.addBytes(&crc,sizeof(uint32)); + } + } + return crcForUnit; } diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index e70b67be..c14ab6ad 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -320,7 +320,7 @@ public: virtual void saveGame(XmlNode *rootNode); }; -class Unit : public BaseColorPickEntity, ValueCheckerVault { +class Unit : public BaseColorPickEntity, ValueCheckerVault, public ParticleOwner { private: typedef list Commands; typedef list Observers; @@ -477,6 +477,11 @@ private: string networkCRCLogInfo; + string networkCRCParticleLogInfo; + + string networkCRCParticleObserverLogInfo; + vector networkCRCDecHpList; + public: Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); virtual ~Unit(); @@ -744,7 +749,7 @@ public: int64 getSpeedDenominator(int64 updateFPS); bool isChangedActiveCommand() const { return changedActiveCommand; } - bool isLastStuckFrameWithinCurrentFrameTolerance(); + bool isLastStuckFrameWithinCurrentFrameTolerance(bool evalMode); inline uint32 getLastStuckFrame() const { return lastStuckFrame; } inline void setLastStuckFrame(uint32 value) { lastStuckFrame = value; } void setLastStuckFrameToCurrentFrame(); @@ -774,9 +779,19 @@ public: void addAttackParticleSystem(ParticleSystem *ps); + void setNetworkCRCParticleLogInfo(string networkCRCParticleLogInfo) { this->networkCRCParticleLogInfo = networkCRCParticleLogInfo; } + void setNetworkCRCParticleObserverLogInfo(string networkCRCParticleObserverLogInfo) { this->networkCRCParticleObserverLogInfo = networkCRCParticleObserverLogInfo; } + + void clearNetworkCRCDecHpList() { networkCRCDecHpList.clear(); } + Checksum getCRC(); + virtual void end(ParticleSystem *particleSystem); + private: + void addNetworkCRCDecHp(string info) { networkCRCDecHpList.push_back(info); } + string getNetworkCRCDecHpList() const; + float computeHeight(const Vec2i &pos) const; void calculateXZRotation(); void updateTarget(); diff --git a/source/glest_game/types/damage_multiplier.cpp b/source/glest_game/types/damage_multiplier.cpp index 0ee2f422..d2ce8500 100644 --- a/source/glest_game/types/damage_multiplier.cpp +++ b/source/glest_game/types/damage_multiplier.cpp @@ -70,19 +70,19 @@ void DamageMultiplierTable::init(int attackTypeCount, int armorTypeCount){ this->attackTypeCount= attackTypeCount; this->armorTypeCount= armorTypeCount; - int valueCount= attackTypeCount*armorTypeCount; - values= new float[valueCount]; + int valueCount= attackTypeCount * armorTypeCount; + values= new double[valueCount]; for(int i=0; igetId()+att->getId()]; +double DamageMultiplierTable::getDamageMultiplier(const AttackType *att, const ArmorType *art) const { + return values[attackTypeCount * art->getId() + att->getId()]; } -void DamageMultiplierTable::setDamageMultiplier(const AttackType *att, const ArmorType *art, float value){ - values[attackTypeCount*art->getId()+att->getId()]= value; +void DamageMultiplierTable::setDamageMultiplier(const AttackType *att, const ArmorType *art, double value) { + values[attackTypeCount * art->getId() + att->getId()] = value; } void DamageMultiplierTable::saveGame(XmlNode *rootNode) { @@ -98,7 +98,7 @@ void DamageMultiplierTable::saveGame(XmlNode *rootNode) { int valueCount= attackTypeCount * armorTypeCount; for(unsigned int i=0; i < valueCount; ++i) { XmlNode *valuesNode = damageMultiplierTableNode->addChild("values"); - valuesNode->addAttribute("value",intToStr(values[i]), mapTagReplacements); + valuesNode->addAttribute("value",doubleToStr(values[i]), mapTagReplacements); } } diff --git a/source/glest_game/types/damage_multiplier.h b/source/glest_game/types/damage_multiplier.h index b811f999..edc451a5 100644 --- a/source/glest_game/types/damage_multiplier.h +++ b/source/glest_game/types/damage_multiplier.h @@ -79,7 +79,7 @@ public: class DamageMultiplierTable { private: - float *values; + double *values; int attackTypeCount; int armorTypeCount; @@ -88,8 +88,8 @@ public: ~DamageMultiplierTable(); void init(int attackTypeCount, int armorTypeCount); - float getDamageMultiplier(const AttackType *att, const ArmorType *art) const; - void setDamageMultiplier(const AttackType *att, const ArmorType *art, float value); + double getDamageMultiplier(const AttackType *att, const ArmorType *art) const; + void setDamageMultiplier(const AttackType *att, const ArmorType *art, double value); void saveGame(XmlNode *rootNode); }; diff --git a/source/glest_game/types/tech_tree.cpp b/source/glest_game/types/tech_tree.cpp index eaed19ab..e3cbbe48 100644 --- a/source/glest_game/types/tech_tree.cpp +++ b/source/glest_game/types/tech_tree.cpp @@ -238,7 +238,7 @@ void TechTree::load(const string &dir, set &factions, Checksum* checksum const XmlNode *damageMultiplierNode= damageMultipliersNode->getChild("damage-multiplier", i); const AttackType *attackType= getAttackType(damageMultiplierNode->getAttribute("attack")->getRestrictedValue()); const ArmorType *armorType= getArmorType(damageMultiplierNode->getAttribute("armor")->getRestrictedValue()); - float multiplier= damageMultiplierNode->getAttribute("value")->getFloatValue(); + double multiplier= damageMultiplierNode->getAttribute("value")->getFloatValue(); damageMultiplierTable.setDamageMultiplier(attackType, armorType, multiplier); Window::handleEvent(); @@ -446,7 +446,7 @@ const AttackType *TechTree::getAttackType(const string &name) const{ throw megaglest_runtime_error("Attack Type not found: "+name); } -float TechTree::getDamageMultiplier(const AttackType *att, const ArmorType *art) const{ +double TechTree::getDamageMultiplier(const AttackType *att, const ArmorType *art) const { return damageMultiplierTable.getDamageMultiplier(att, art); } diff --git a/source/glest_game/types/tech_tree.h b/source/glest_game/types/tech_tree.h index 2ea25b78..2bd7d403 100644 --- a/source/glest_game/types/tech_tree.h +++ b/source/glest_game/types/tech_tree.h @@ -97,7 +97,7 @@ public: int getAttackTypeCount() const { return attackTypes.size(); } const AttackType * getAttackTypeByIndex(int index) const { return &attackTypes[index]; } - float getDamageMultiplier(const AttackType *att, const ArmorType *art) const; + double getDamageMultiplier(const AttackType *att, const ArmorType *art) const; std::vector validateFactionTypes(); std::vector validateResourceTypes(); diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index fc7701bb..251279e6 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -137,8 +137,16 @@ bool UnitUpdater::updateUnit(Unit *unit) { //start attack particle system if(unit->getCurrSkill()->getClass() == scAttack) { const AttackSkillType *ast= static_cast(unit->getCurrSkill()); - float attackStartTime= ast->getAttackStartTime(); - if(attackStartTime>=unit->getLastAnimProgressAsFloat() && attackStartTimegetAnimProgressAsFloat()){ + double attackStartTime = truncateDecimal(ast->getAttackStartTime()); + double lastAnimProgress = truncateDecimal(unit->getLastAnimProgressAsFloat()); + double animProgress = truncateDecimal(attackStartTime < unit->getAnimProgressAsFloat()); + bool startAttackParticleSystemNow = (attackStartTime >= lastAnimProgress && attackStartTime < animProgress); + + char szBuf[8096]=""; + snprintf(szBuf,8095,"attackStartTime = %f, lastAnimProgress = %f, animProgress = %f startAttackParticleSystemNow = %d",attackStartTime,lastAnimProgress,animProgress,startAttackParticleSystemNow); + unit->setNetworkCRCParticleLogInfo(szBuf); + + if(startAttackParticleSystemNow == true) { startAttackParticleSystem(unit); } } @@ -2184,30 +2192,33 @@ void UnitUpdater::updateSwitchTeam(Unit *unit, int frameIndex) { // ==================== attack ==================== void UnitUpdater::hit(Unit *attacker){ - hit(attacker, static_cast(attacker->getCurrSkill()), attacker->getTargetPos(), attacker->getTargetField()); + hit(attacker, dynamic_cast(attacker->getCurrSkill()), attacker->getTargetPos(), attacker->getTargetField()); } void UnitUpdater::hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField){ //hit attack positions - if(ast->getSplash()){ + if(ast != NULL && ast->getSplash()){ PosCircularIterator pci(map, targetPos, ast->getSplashRadius()); while(pci.next()) { Unit *attacked= map->getCell(pci.getPos())->getUnit(targetField); if(attacked != NULL) { - if(ast->getSplashDamageAll() - || attacker->isAlly(attacked) == false - || ( targetPos.x==pci.getPos().x && targetPos.y==pci.getPos().y )) { + if(ast->getSplashDamageAll() || + attacker->isAlly(attacked) == false || + ( targetPos.x == pci.getPos().x && targetPos.y == pci.getPos().y )) { + attacker->setLastAttackedUnitId(attacked->getId()); scriptManager->onUnitAttacking(attacker); - damage(attacker, ast, attacked, pci.getPos().dist(targetPos)); + double distance = pci.getPos().dist(targetPos); + distance = truncateDecimal(distance); + damage(attacker, ast, attacked, distance); } } } } else{ Unit *attacked= map->getCell(targetPos)->getUnit(targetField); - if(attacked!=NULL){ + if(attacked != NULL) { damage(attacker, ast, attacked, 0.f); } } @@ -2229,22 +2240,25 @@ void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attac int var = ast->getAttackVar(); int armor = attacked->getType()->getTotalArmor(attacked->getTotalUpgrade()); double damageMultiplier = world->getTechTree()->getDamageMultiplier(ast->getAttackType(), attacked->getType()->getArmorType()); + damageMultiplier = truncateDecimal(damageMultiplier); //compute damage //damage += random.randRange(-var, var); - damage += attacker->getRandom()->randRange(-var, var); + damage += attacker->getRandom()->randRange(-var, var, string(__FILE__) + intToStr(__LINE__)); damage /= distance+1; damage -= armor; damage *= damageMultiplier; + damageMultiplier = truncateDecimal(damageMultiplier); if(damage < 1) { damage= 1; } + int damageVal = static_cast(damage); attacked->setLastAttackerUnitId(attacker->getId()); //damage the unit - if(attacked->decHp(static_cast(damage))) { + if(attacked->decHp(damageVal)) { world->getStats()->kill(attacker->getFactionIndex(), attacked->getFactionIndex(), attacker->getTeam() != attacked->getTeam(),attacked->getType()->getCountUnitDeathInStats(),attacked->getType()->getCountUnitKillInStats()); if(attacked->getType()->getCountKillForUnitUpgrade() == true){ attacker->incKills(attacked->getTeam()); @@ -2274,7 +2288,10 @@ void UnitUpdater::startAttackParticleSystem(Unit *unit){ ProjectileParticleSystem *psProj = 0; - const AttackSkillType *ast= static_cast(unit->getCurrSkill()); + const AttackSkillType *ast= dynamic_cast(unit->getCurrSkill()); + if(ast == NULL) { + throw megaglest_runtime_error("Start attack particle ast == NULL!"); + } ParticleSystemTypeProjectile *pstProj= ast->getProjParticleType(); ParticleSystemTypeSplash *pstSplash= ast->getSplashParticleType(); @@ -2291,7 +2308,7 @@ void UnitUpdater::startAttackParticleSystem(Unit *unit){ //projectile if(pstProj!=NULL){ - psProj= pstProj->create(); + psProj= pstProj->create(unit); psProj->setPath(startPos, endPos); psProj->setObserver(new ParticleDamager(unit, this, gameCamera)); psProj->setVisible(visible); @@ -2307,7 +2324,7 @@ void UnitUpdater::startAttackParticleSystem(Unit *unit){ //splash if(pstSplash != NULL) { - SplashParticleSystem *psSplash= pstSplash->create(); + SplashParticleSystem *psSplash= pstSplash->create(unit); psSplash->setPos(endPos); psSplash->setVisible(visible); if(unit->getFaction()->getTexture()) { @@ -2551,8 +2568,8 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr, } } - if(isUltra || isMega) { - if( attackingEnemySeen!=NULL && unit->getRandom()->randRange(0,2)!=2 ) { + if(evalMode == false && (isUltra || isMega)) { + if( attackingEnemySeen!=NULL && unit->getRandom()->randRange(0,2,string(__FILE__) + intToStr(__LINE__)) != 2 ) { *rangedPtr = attackingEnemySeen; enemySeen = attackingEnemySeen; //printf("Da hat er wen gefunden:%s\n",enemySeen->getType()->getName(false).c_str()); @@ -2837,8 +2854,14 @@ void ParticleDamager::update(ParticleSystem *particleSystem) { Unit *attacker= attackerRef.getUnit(); if(attacker != NULL) { + //string auditBeforeHit = particleSystem->toString(); + unitUpdater->hit(attacker, ast, targetPos, targetField); + //char szBuf[8096]=""; + //snprintf(szBuf,8095,"ParticleDamager::update attacker particleSystem before: %s\nafter: %s",auditBeforeHit.c_str(),particleSystem->toString().c_str()); + //attacker->setNetworkCRCParticleObserverLogInfo(szBuf); + //play sound StaticSound *projSound= ast->getProjSound(); if(particleSystem->getVisible() && projSound != NULL) { diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 0a056252..eae2b355 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -701,7 +701,7 @@ void World::updateAllFactionUnits() { int unitBlockCount = unit->getPath()->getBlockCount(); bool isStuck = unit->getPath()->isStuck(); - bool isStuckWithinTolerance = unit->isLastStuckFrameWithinCurrentFrameTolerance(); + bool isStuckWithinTolerance = unit->isLastStuckFrameWithinCurrentFrameTolerance(false); uint32 lastStuckFrame = unit->getLastStuckFrame(); if(unitUpdater.updateUnit(unit) == true) { diff --git a/source/shared_lib/include/graphics/particle.h b/source/shared_lib/include/graphics/particle.h index e99176d0..bd241ae0 100644 --- a/source/shared_lib/include/graphics/particle.h +++ b/source/shared_lib/include/graphics/particle.h @@ -75,7 +75,7 @@ public: // class ParticleObserver // ===================================================== -class ParticleObserver{ +class ParticleObserver { public: virtual ~ParticleObserver(){}; virtual void update(ParticleSystem *particleSystem)= 0; @@ -83,6 +83,11 @@ public: virtual void loadGame(const XmlNode *rootNode, void *genericData) = 0; }; +class ParticleOwner { +public: + virtual void end(ParticleSystem *particleSystem)= 0; +}; + // ===================================================== // class ParticleSystem // ===================================================== @@ -145,6 +150,7 @@ protected: int alternations; int particleSystemStartDelay; ParticleObserver *particleObserver; + ParticleOwner *particleOwner; public: //conmstructor and destructor @@ -198,15 +204,21 @@ public: virtual void fade(); int isEmpty() const; + virtual void setParticleOwner(ParticleOwner *particleOwner) { this->particleOwner = particleOwner;} + virtual ParticleOwner * getParticleOwner() { return this->particleOwner;} + virtual void callParticleOwnerEnd(ParticleSystem *particleSystem); + //children virtual int getChildCount() { return 0; } virtual ParticleSystem* getChild(int i); - string toString() const; + virtual string toString() const; virtual void saveGame(XmlNode *rootNode); virtual void loadGame(const XmlNode *rootNode); + virtual Checksum getCRC(); + protected: //protected Particle *createParticle(); @@ -242,6 +254,10 @@ public: virtual void saveGame(XmlNode *rootNode); virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + + virtual Checksum getCRC(); }; // ===================================================== @@ -279,6 +295,10 @@ public: virtual void saveGame(XmlNode *rootNode); virtual void loadGame(const XmlNode *rootNode); + virtual string toString() const; + + virtual Checksum getCRC(); + protected: typedef std::vector Children; Children children; @@ -390,6 +410,10 @@ public: virtual void saveGame(XmlNode *rootNode); virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + + virtual Checksum getCRC(); }; // ===================================================== @@ -412,7 +436,11 @@ public: virtual bool deathTest(Particle *p); void setRadius(float radius); - void setWind(float windAngle, float windSpeed); + void setWind(float windAngle, float windSpeed); + + virtual string toString() const; + + virtual Checksum getCRC(); }; // ===================================================== @@ -433,7 +461,11 @@ public: virtual bool deathTest(Particle *p); void setRadius(float radius); - void setWind(float windAngle, float windSpeed); + void setWind(float windAngle, float windSpeed); + + virtual string toString() const; + + virtual Checksum getCRC(); }; // =========================================================================== @@ -459,6 +491,10 @@ public: virtual void saveGame(XmlNode *rootNode); virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + + virtual Checksum getCRC(); }; // ===================================================== @@ -488,12 +524,13 @@ private: Vec3f zVector; Trajectory trajectory; - float trajectorySpeed; + double trajectorySpeed; //parabolic - float trajectoryScale; - float trajectoryFrequency; - + double trajectoryScale; + double trajectoryFrequency; + + double arriveDestinationDistance; void rotateChildren(); public: @@ -509,9 +546,9 @@ public: virtual void updateParticle(Particle *p); void setTrajectory(Trajectory trajectory) {this->trajectory= trajectory;} - void setTrajectorySpeed(float trajectorySpeed) {this->trajectorySpeed= trajectorySpeed;} - void setTrajectoryScale(float trajectoryScale) {this->trajectoryScale= trajectoryScale;} - void setTrajectoryFrequency(float trajectoryFrequency) {this->trajectoryFrequency= trajectoryFrequency;} + void setTrajectorySpeed(double trajectorySpeed) {this->trajectorySpeed= trajectorySpeed;} + void setTrajectoryScale(double trajectoryScale) {this->trajectoryScale= trajectoryScale;} + void setTrajectoryFrequency(double trajectoryFrequency) {this->trajectoryFrequency= trajectoryFrequency;} void setPath(Vec3f startPos, Vec3f endPos); @@ -519,6 +556,10 @@ public: virtual void saveGame(XmlNode *rootNode); virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + + virtual Checksum getCRC(); }; // ===================================================== @@ -532,13 +573,13 @@ public: private: ProjectileParticleSystem *prevParticleSystem; - float emissionRateFade; - float verticalSpreadA; - float verticalSpreadB; - float horizontalSpreadA; - float horizontalSpreadB; + double emissionRateFade; + double verticalSpreadA; + double verticalSpreadB; + double horizontalSpreadA; + double horizontalSpreadB; - float startEmissionRate; + double startEmissionRate; public: SplashParticleSystem(int particleCount= 1000); @@ -550,15 +591,18 @@ public: virtual void initParticleSystem(); - void setEmissionRateFade(float emissionRateFade) {this->emissionRateFade= emissionRateFade;} - void setVerticalSpreadA(float verticalSpreadA) {this->verticalSpreadA= verticalSpreadA;} - void setVerticalSpreadB(float verticalSpreadB) {this->verticalSpreadB= verticalSpreadB;} - void setHorizontalSpreadA(float horizontalSpreadA) {this->horizontalSpreadA= horizontalSpreadA;} - void setHorizontalSpreadB(float horizontalSpreadB) {this->horizontalSpreadB= horizontalSpreadB;} + void setEmissionRateFade(double emissionRateFade) {this->emissionRateFade= emissionRateFade;} + void setVerticalSpreadA(double verticalSpreadA) {this->verticalSpreadA= verticalSpreadA;} + void setVerticalSpreadB(double verticalSpreadB) {this->verticalSpreadB= verticalSpreadB;} + void setHorizontalSpreadA(double horizontalSpreadA) {this->horizontalSpreadA= horizontalSpreadA;} + void setHorizontalSpreadB(double horizontalSpreadB) {this->horizontalSpreadB= horizontalSpreadB;} virtual void saveGame(XmlNode *rootNode); virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + virtual Checksum getCRC(); }; // ===================================================== diff --git a/source/shared_lib/include/util/randomgen.h b/source/shared_lib/include/util/randomgen.h index 9a319abb..87422c99 100644 --- a/source/shared_lib/include/util/randomgen.h +++ b/source/shared_lib/include/util/randomgen.h @@ -13,6 +13,8 @@ #ifndef _SHARED_UTIL_RANDOM_H_ #define _SHARED_UTIL_RANDOM_H_ +#include +#include #include "leak_dumper.h" namespace Shared { namespace Util { @@ -29,20 +31,25 @@ private: private: int lastNumber; + std::vector lastCaller; //#ifdef USE_STREFLOP // streflop::RandomState randomState; //#endif + int rand(std::string lastCaller); + public: RandomGen(); void init(int seed); - int rand(); - int randRange(int min, int max); - float randRange(float min, float max); + int randRange(int min, int max,std::string lastCaller=""); + float randRange(float min, float max,std::string lastCaller=""); int getLastNumber() const { return lastNumber; } void setLastNumber(int value) { lastNumber = value; } + + std::string getLastCaller() const; + void clearLastCaller() { lastCaller.clear(); } }; }}//end namespace diff --git a/source/shared_lib/sources/graphics/particle.cpp b/source/shared_lib/sources/graphics/particle.cpp index 53934a61..5060b57c 100644 --- a/source/shared_lib/sources/graphics/particle.cpp +++ b/source/shared_lib/sources/graphics/particle.cpp @@ -122,9 +122,11 @@ ParticleSystem::ParticleSystem(int particleCount) { teamcolorEnergy= false; alternations= 0; particleSystemStartDelay= 0; + + this->particleOwner = NULL; } -ParticleSystem::~ParticleSystem(){ +ParticleSystem::~ParticleSystem() { if(checkMemory) { printf("-- Delete ParticleSystem [%p]\n",this); memoryObjectList[this]--; @@ -138,6 +140,49 @@ ParticleSystem::~ParticleSystem(){ particleObserver = NULL; } +void ParticleSystem::callParticleOwnerEnd(ParticleSystem *particleSystem) { + if(this->particleOwner != NULL) { + this->particleOwner->end(particleSystem); + } +} +Checksum ParticleSystem::getCRC() { + Checksum crcForParticleSystem; + + //std::vector particles; + + crcForParticleSystem.addInt(random.getLastNumber()); + crcForParticleSystem.addInt(blendMode); + crcForParticleSystem.addInt(state); + crcForParticleSystem.addInt(active); + crcForParticleSystem.addInt(visible); + crcForParticleSystem.addInt(aliveParticleCount); + crcForParticleSystem.addInt(particleCount); + + //string textureFileLoadDeferred; + //int textureFileLoadDeferredSystemId; + //Texture::Format textureFileLoadDeferredFormat; + //int textureFileLoadDeferredComponents; + + //Texture *texture; + //Vec3f pos; + //Vec4f color; + //Vec4f colorNoEnergy; + //float emissionRate; + //float emissionState; + crcForParticleSystem.addInt(maxParticleEnergy); + crcForParticleSystem.addInt(varParticleEnergy); + //float particleSize; + //float speed; + //Vec3f factionColor; + crcForParticleSystem.addInt(teamcolorNoEnergy); + crcForParticleSystem.addInt(teamcolorEnergy); + crcForParticleSystem.addInt(alternations); + crcForParticleSystem.addInt(particleSystemStartDelay); + //ParticleObserver *particleObserver; + + return crcForParticleSystem; +} + // =============== VIRTUAL ====================== //updates all living particles and creates new ones @@ -261,7 +306,7 @@ void ParticleSystem::setVisible(bool visible){ } string ParticleSystem::toString() const { - string result = ""; + string result = "ParticleSystem "; result += "particles = " + intToStr(particles.size()); @@ -478,23 +523,28 @@ void ParticleSystem::loadGame(const XmlNode *rootNode) { void ParticleSystem::fade(){ //printf("**************Fading particle System:\n[%s]\n",this->toString().c_str()); + bool alreadyFading = (state == sFade); if(particleObserver != NULL){ if(state != sPlay) { char szBuf[8096]=""; - snprintf(szBuf,8096,"state != sPlay, state = [%d]",state); + snprintf(szBuf,8096,"state != sPlay, state = [%d]\n",state); //throw megaglest_runtime_error(szBuf); //printf(szBuf); SystemFlags::OutputDebug(SystemFlags::debugError,"%s",szBuf); } - assert(state == sPlay); + //assert(state == sPlay); } + state= sFade; - if(particleObserver != NULL){ - particleObserver->update(this); - particleObserver=NULL; + if(alreadyFading == false) { + if(particleObserver != NULL){ + particleObserver->update(this); + particleObserver=NULL; + } + for(int i=getChildCount()-1; i>=0; i--) { + getChild(i)->fade(); + } } - for(int i=getChildCount()-1; i>=0; i--) - getChild(i)->fade(); } int ParticleSystem::isEmpty() const{ @@ -648,6 +698,15 @@ void FireParticleSystem::updateParticle(Particle *p){ } +string FireParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nFireParticleSystem "; + result += "\nradius = " + floatToStr(radius); + result += "\nwindSpeed = " + windSpeed.getString(); + + return result; +} // ================= SET PARAMS ==================== void FireParticleSystem::setRadius(float radius){ @@ -688,6 +747,15 @@ void FireParticleSystem::loadGame(const XmlNode *rootNode) { windSpeed = Vec3f::strToVec3(fireParticleSystemNode->getAttribute("windSpeed")->getValue()); } +Checksum FireParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + //float radius; + //Vec3f windSpeed; + + return crcForParticleSystem; +} + // =========================================================================== // GameParticleSystem // =========================================================================== @@ -863,6 +931,7 @@ void GameParticleSystem::loadGame(const XmlNode *rootNode) { XmlNode *node = childrenNodeList[i]; UnitParticleSystem *ups = new UnitParticleSystem(); + //ups->setParticleOwner(!!!); ups->loadGame(node); //children.push_back(ups); @@ -890,6 +959,29 @@ void GameParticleSystem::loadGame(const XmlNode *rootNode) { tween = gameParticleSystemNode->getAttribute("tween")->getFloatValue(); } +Checksum GameParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + return crcForParticleSystem; +} + +string GameParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nGameParticleSystem "; + result += "\nchildren = " + intToStr(children.size()); + result += "\nprimitive = " + intToStr(primitive); + + //string modelFileLoadDeferred; + //Model *model; + result += "\nmodelCycle = " + floatToStr(modelCycle); + result += "\noffset = " + offset.getString(); + result += "\ndirection = " + direction.getString(); + result += "\ntween = " + floatToStr(tween); + + return result; +} + // =========================================================================== // UnitParticleSystem // =========================================================================== @@ -1291,11 +1383,50 @@ void UnitParticleSystem::loadGame(const XmlNode *rootNode) { //} } +Checksum UnitParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + return crcForParticleSystem; +} + +string UnitParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nUnitParticleSystem "; + result += "\nradius = " + floatToStr(radius); + result += "\nminRadius = " + floatToStr(minRadius); + result += "\nwindSpeed = " + windSpeed.getString(); + result += "\ncRotation = " + cRotation.getString(); + result += "\nfixedAddition = " + fixedAddition.getString(); + result += "\noldPosition = " + oldPosition.getString(); + result += "\nenergyUp = " + intToStr(energyUp); + result += "\nstartTime = " + floatToStr(startTime); + result += "\nendTime = " + floatToStr(endTime); + result += "\nrelative = " + intToStr(relative); + result += "\nrelativeDirection = " + intToStr(relativeDirection); + result += "\nfixed = " + intToStr(fixed); + result += "\nshape = " + intToStr(shape); + + result += "\nangle = " + floatToStr(angle); + result += "\nsizeNoEnergy = " + floatToStr(sizeNoEnergy); + result += "\ngravity = " + floatToStr(gravity); + result += "\nrotation = " + floatToStr(rotation); + result += "\nisVisibleAtNight = " + intToStr(isVisibleAtNight); + result += "\nisVisibleAtDay = " + intToStr(isVisibleAtDay); + result += "\nisDaylightAffected = " + intToStr(isDaylightAffected); + result += "\nradiusBasedStartenergy = " + intToStr(radiusBasedStartenergy); + result += "\nstaticParticleCount = " + intToStr(staticParticleCount); + result += "\ndelay = " + intToStr(delay); + result += "\nlifetime = " + intToStr(lifetime); + result += "\nemissionRateFade = " + floatToStr(emissionRateFade); + //GameParticleSystem* parent; + + return result; +} + // =========================================================================== // RainParticleSystem // =========================================================================== - - RainParticleSystem::RainParticleSystem(int particleCount) : ParticleSystem(particleCount){ setWind(0.0f, 0.0f); @@ -1346,6 +1477,22 @@ void RainParticleSystem::setWind(float windAngle, float windSpeed){ #endif } +Checksum RainParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + return crcForParticleSystem; +} + +string RainParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nRainParticleSystem "; + result += "\nwindSpeed = " + windSpeed.getString(); + result += "\nradius = " + floatToStr(radius); + + return result; +} + // =========================================================================== // SnowParticleSystem // =========================================================================== @@ -1397,6 +1544,22 @@ void SnowParticleSystem::setWind(float windAngle, float windSpeed){ #endif } +Checksum SnowParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + return crcForParticleSystem; +} + +string SnowParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nSnowParticleSystem "; + result += "\nwindSpeed = " + windSpeed.getString(); + result += "\nradius = " + floatToStr(radius); + + return result; +} + // =========================================================================== // AttackParticleSystem // =========================================================================== @@ -1431,6 +1594,22 @@ void AttackParticleSystem::loadGame(const XmlNode *rootNode) { gravity = attackParticleSystemNode->getAttribute("gravity")->getFloatValue(); } +Checksum AttackParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + return crcForParticleSystem; +} + +string AttackParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nAttackParticleSystem "; + result += "\nsizeNoEnergy = " + floatToStr(sizeNoEnergy); + result += "\ngravity = " + floatToStr(gravity); + + return result; +} + // =========================================================================== // ProjectileParticleSystem // =========================================================================== @@ -1452,7 +1631,7 @@ ProjectileParticleSystem::ProjectileParticleSystem(int particleCount) : modelCycle=0.0f; nextParticleSystem= NULL; - + arriveDestinationDistance = 0.0f; //printf("#aXX trajectorySpeed = %f\n",trajectorySpeed); } @@ -1473,13 +1652,25 @@ void ProjectileParticleSystem::update(){ //printf("Projectile particle system updating...\n"); if(state == sPlay){ - lastPos= pos; - flatPos+= zVector * trajectorySpeed; - Vec3f targetVector= endPos - startPos; - Vec3f currentVector= flatPos - startPos; + lastPos = pos; + flatPos += zVector * truncateDecimal(trajectorySpeed); + flatPos.x = truncateDecimal(flatPos.x); + flatPos.y = truncateDecimal(flatPos.y); + flatPos.z = truncateDecimal(flatPos.z); + + Vec3f targetVector = endPos - startPos; + targetVector.x = truncateDecimal(targetVector.x); + targetVector.y = truncateDecimal(targetVector.y); + targetVector.z = truncateDecimal(targetVector.z); + + Vec3f currentVector = flatPos - startPos; + currentVector.x = truncateDecimal(currentVector.x); + currentVector.y = truncateDecimal(currentVector.y); + currentVector.z = truncateDecimal(currentVector.z); // ratio - float relative= clamp(currentVector.length() / targetVector.length(), 0.0f, 1.0f); + double relative= clamp(currentVector.length() / targetVector.length(), 0.0f, 1.0f); + relative = truncateDecimal(relative); //printf("Update particle targetVector [%s][%f] currentVector [%s][%f] relative = %f\n",targetVector.getString().c_str(),targetVector.length(),currentVector.getString().c_str(),currentVector.length(),relative); @@ -1498,16 +1689,17 @@ void ProjectileParticleSystem::update(){ switch(trajectory) { case tLinear: { pos= flatPos; - } + } break; case tParabolic: { - float scaledT= 2.0f * (relative - 0.5f); - float paraboleY= (1.0f - scaledT * scaledT) * trajectoryScale; + double scaledT = truncateDecimal(2.0f * (relative - 0.5f)); + double paraboleY = truncateDecimal((1.0f - scaledT * scaledT) * trajectoryScale); pos= flatPos; - pos.y+= paraboleY; - } + pos.y += paraboleY; + pos.y = truncateDecimal(pos.y); + } break; case tSpiral: { @@ -1519,6 +1711,9 @@ void ProjectileParticleSystem::update(){ pos+= xVector * cos(relative * trajectoryFrequency * targetVector.length()) * trajectoryScale; pos+= yVector * sin(relative * trajectoryFrequency * targetVector.length()) * trajectoryScale; #endif + pos.x = truncateDecimal(pos.x); + pos.y = truncateDecimal(pos.y); + pos.z = truncateDecimal(pos.z); } break; @@ -1529,12 +1724,17 @@ void ProjectileParticleSystem::update(){ direction= pos - lastPos; direction.normalize(); + direction.x = truncateDecimal(direction.x); + direction.y = truncateDecimal(direction.y); + direction.z = truncateDecimal(direction.z); + // trigger update of child particles positionChildren(); rotateChildren(); //arrive destination - if(flatPos.dist(endPos) < 0.5f){ + arriveDestinationDistance = truncateDecimal(flatPos.dist(endPos)); + if(arriveDestinationDistance < 0.5f) { fade(); model= NULL; @@ -1557,11 +1757,11 @@ void ProjectileParticleSystem::update(){ void ProjectileParticleSystem::rotateChildren() { //### only on horizontal plane :( #ifdef USE_STREFLOP - float rotation = streflop::atan2(static_cast(direction.x), static_cast(direction.z)); + double rotation = truncateDecimal(streflop::atan2(static_cast(direction.x), static_cast(direction.z))); #else - float rotation = atan2(direction.x, direction.z); + double rotation = truncateDecimal(atan2(direction.x, direction.z)); #endif - rotation = radToDeg(rotation); + rotation = truncateDecimal(radToDeg(rotation)); for(Children::iterator it = children.begin(); it != children.end(); ++it) (*it)->setRotation(rotation); } @@ -1570,7 +1770,8 @@ void ProjectileParticleSystem::initParticle(Particle *p, int particleIndex){ ParticleSystem::initParticle(p, particleIndex); - float t= static_cast (particleIndex) / emissionRate; + double t= static_cast (particleIndex) / emissionRate; + t = truncateDecimal(t); p->pos= pos + (lastPos - pos) * t; p->lastPos= lastPos; @@ -1582,7 +1783,8 @@ void ProjectileParticleSystem::initParticle(Particle *p, int particleIndex){ } void ProjectileParticleSystem::updateParticle(Particle *p){ - float energyRatio= clamp(static_cast (p->energy) / maxParticleEnergy, 0.f, 1.f); + double energyRatio= clamp(static_cast (p->energy) / maxParticleEnergy, 0.f, 1.f); + energyRatio = truncateDecimal(energyRatio); p->lastPos+= p->speed; p->pos+= p->speed; @@ -1688,6 +1890,7 @@ void ProjectileParticleSystem::loadGame(const XmlNode *rootNode) { if(projectileParticleSystemNode->hasChild("SplashParticleSystem") == true) { XmlNode *splashParticleSystemNode = projectileParticleSystemNode->getChild("SplashParticleSystem"); nextParticleSystem = new SplashParticleSystem(); + nextParticleSystem->setParticleOwner(this->getParticleOwner()); nextParticleSystem->loadGame(splashParticleSystemNode); } // Vec3f lastPos; @@ -1716,6 +1919,39 @@ void ProjectileParticleSystem::loadGame(const XmlNode *rootNode) { trajectoryFrequency = projectileParticleSystemNode->getAttribute("trajectoryFrequency")->getFloatValue(); } +Checksum ProjectileParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + return crcForParticleSystem; +} + +string ProjectileParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nProjectileParticleSystem "; + if(nextParticleSystem != NULL) { + //result += "\nnextParticleSystem = " + nextParticleSystem->toString() + "\n"; + result += "\nnextParticleSystem = NOT NULL\n"; + } + result += "\nlastPos = " + lastPos.getString(); + result += "\nstartPos = " + startPos.getString(); + result += "\nendPos = " + endPos.getString(); + result += "\nflatPos = " + flatPos.getString(); + + result += "\nxVector = " + xVector.getString(); + result += "\nyVector = " + yVector.getString(); + result += "\nzVector = " + zVector.getString(); + + result += "\ntrajectory = " + intToStr(trajectory); + result += "\ntrajectorySpeed = " + doubleToStr(trajectorySpeed); + result += "\ntrajectoryScale = " + doubleToStr(trajectoryScale); + result += "\ntrajectoryFrequency = " + doubleToStr(trajectoryFrequency); + + result += "\narriveDestinationDistance = " + doubleToStr(arriveDestinationDistance); + + return result; +} + // =========================================================================== // SplashParticleSystem // =========================================================================== @@ -1730,7 +1966,7 @@ SplashParticleSystem::SplashParticleSystem(int particleCount) : prevParticleSystem= NULL; - emissionRateFade= 1; + emissionRateFade= 1.0f; verticalSpreadA= 1.0f; verticalSpreadB= 0.0f; horizontalSpreadA= 1.0f; @@ -1751,9 +1987,11 @@ void SplashParticleSystem::initParticleSystem() { void SplashParticleSystem::update() { ParticleSystem::update(); if(state != sPause) { - emissionRate-= emissionRateFade; + emissionRate -= emissionRateFade; + + double t = 1.0f - ((emissionRate + startEmissionRate) / (startEmissionRate * 2.0f)); + t = truncateDecimal(t); - float t= 1.0f - ((emissionRate + startEmissionRate) / (startEmissionRate * 2.0f)); t= clamp(t, 0.0f, 1.0f); setTween(t,t); @@ -1802,18 +2040,18 @@ void SplashParticleSystem::saveGame(XmlNode *rootNode) { } // float emissionRateFade; - splashParticleSystemNode->addAttribute("emissionRateFade",floatToStr(emissionRateFade,16), mapTagReplacements); + splashParticleSystemNode->addAttribute("emissionRateFade",doubleToStr(emissionRateFade,16), mapTagReplacements); // float verticalSpreadA; - splashParticleSystemNode->addAttribute("verticalSpreadA",floatToStr(verticalSpreadA,16), mapTagReplacements); + splashParticleSystemNode->addAttribute("verticalSpreadA",doubleToStr(verticalSpreadA,16), mapTagReplacements); // float verticalSpreadB; - splashParticleSystemNode->addAttribute("verticalSpreadB",floatToStr(verticalSpreadB,16), mapTagReplacements); + splashParticleSystemNode->addAttribute("verticalSpreadB",doubleToStr(verticalSpreadB,16), mapTagReplacements); // float horizontalSpreadA; - splashParticleSystemNode->addAttribute("horizontalSpreadA",floatToStr(horizontalSpreadA,16), mapTagReplacements); + splashParticleSystemNode->addAttribute("horizontalSpreadA",doubleToStr(horizontalSpreadA,16), mapTagReplacements); // float horizontalSpreadB; - splashParticleSystemNode->addAttribute("horizontalSpreadB",floatToStr(horizontalSpreadB,16), mapTagReplacements); + splashParticleSystemNode->addAttribute("horizontalSpreadB",doubleToStr(horizontalSpreadB,16), mapTagReplacements); // // float startEmissionRate; - splashParticleSystemNode->addAttribute("startEmissionRate",floatToStr(startEmissionRate,16), mapTagReplacements); + splashParticleSystemNode->addAttribute("startEmissionRate",doubleToStr(startEmissionRate,16), mapTagReplacements); } void SplashParticleSystem::loadGame(const XmlNode *rootNode) { @@ -1828,6 +2066,7 @@ void SplashParticleSystem::loadGame(const XmlNode *rootNode) { if(splashParticleSystemNode->hasChild("ProjectileParticleSystem") == true) { XmlNode *projectileParticleSystemNode = splashParticleSystemNode->getChild("ProjectileParticleSystem"); prevParticleSystem = new ProjectileParticleSystem(); + prevParticleSystem->setParticleOwner(this->getParticleOwner()); prevParticleSystem->loadGame(projectileParticleSystemNode); } @@ -1845,6 +2084,31 @@ void SplashParticleSystem::loadGame(const XmlNode *rootNode) { startEmissionRate = splashParticleSystemNode->getAttribute("startEmissionRate")->getFloatValue(); } +Checksum SplashParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + return crcForParticleSystem; +} + +string SplashParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nSplashParticleSystem "; + if(prevParticleSystem != NULL) { + //result += "\nprevParticleSystem = " + prevParticleSystem->toString() + "\n"; + result += "\nprevParticleSystem = NOT NULL\n"; + } + + result += "\nemissionRateFade = " + doubleToStr(emissionRateFade); + result += "\nverticalSpreadA = " + doubleToStr(verticalSpreadA); + result += "\nverticalSpreadB = " + doubleToStr(verticalSpreadB); + result += "\nhorizontalSpreadA = " + doubleToStr(horizontalSpreadA); + result += "\nhorizontalSpreadB = " + doubleToStr(horizontalSpreadB); + result += "\nstartEmissionRate = " + doubleToStr(startEmissionRate); + + return result; +} + // =========================================================================== // ParticleManager // =========================================================================== @@ -1910,14 +2174,13 @@ void ParticleManager::update(int renderFps){ currentParticleCount+= ps->getAliveParticleCount(); bool showParticle= true; - if(dynamic_cast (ps) != NULL || dynamic_cast (ps) != NULL){ - showParticle= ps->getVisible() || (ps->getState() == ParticleSystem::sFade); + if( dynamic_cast (ps) != NULL || + dynamic_cast (ps) != NULL) { + showParticle = ps->getVisible() || (ps->getState() == ParticleSystem::sFade); } if(showParticle == true){ ps->update(); - if(ps->isEmpty() && ps->getState() == ParticleSystem::sFade){ - //delete ps; - //*it= NULL; + if(ps->isEmpty() && ps->getState() == ParticleSystem::sFade) { cleanupParticleSystemsList.push_back(ps); } } @@ -1958,37 +2221,42 @@ void ParticleManager::cleanupParticleSystems(ParticleSystem *ps) { // } // deleteList[ps]++; + if(ps != NULL) { + ps->callParticleOwnerEnd(ps); + } + delete ps; this->particleSystems.erase(this->particleSystems.begin() + index); } } -void ParticleManager::cleanupParticleSystems(vector &particleSystems){ +void ParticleManager::cleanupParticleSystems(vector &cleanupParticleSystemsList){ + if(cleanupParticleSystemsList.empty() == false) { + for(int i= cleanupParticleSystemsList.size()-1; i >= 0; i--) { + ParticleSystem *ps= cleanupParticleSystemsList[i]; + cleanupParticleSystems(ps); + } - for(int i= particleSystems.size()-1; i >= 0; i--){ - ParticleSystem *ps= particleSystems[i]; - cleanupParticleSystems(ps); + cleanupParticleSystemsList.clear(); } - - particleSystems.clear(); - //this->particleSystems.remove(NULL); } -void ParticleManager::cleanupUnitParticleSystems(vector &particleSystems){ - - for(int i= particleSystems.size()-1; i >= 0; i--){ - ParticleSystem *ps= particleSystems[i]; - cleanupParticleSystems(ps); +void ParticleManager::cleanupUnitParticleSystems(vector &cleanupParticleSystemsList){ + if(cleanupParticleSystemsList.empty() == false) { + for(int i= cleanupParticleSystemsList.size()-1; i >= 0; i--) { + ParticleSystem *ps= cleanupParticleSystemsList[i]; + cleanupParticleSystems(ps); + } + cleanupParticleSystemsList.clear(); } - particleSystems.clear(); - //this->particleSystems.remove(NULL); } void ParticleManager::manage(ParticleSystem *ps){ assert((std::find(particleSystems.begin(),particleSystems.end(),ps) == particleSystems.end()) && "particle cannot be added twice"); particleSystems.push_back(ps); - for(int i=ps->getChildCount()-1; i>=0; i--) + for(int i = ps->getChildCount() - 1; i >= 0; i--) { manage(ps->getChild(i)); + } } void ParticleManager::end(){ @@ -2002,6 +2270,9 @@ void ParticleManager::end(){ // } // deleteList[ps]++; + if(ps != NULL) { + ps->callParticleOwnerEnd(ps); + } delete ps; particleSystems.pop_back(); } diff --git a/source/shared_lib/sources/util/randomgen.cpp b/source/shared_lib/sources/util/randomgen.cpp index 04204a37..e1fff917 100644 --- a/source/shared_lib/sources/util/randomgen.cpp +++ b/source/shared_lib/sources/util/randomgen.cpp @@ -52,18 +52,26 @@ void RandomGen::init(int seed){ //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] seed = %d, lastNumber = %d\n",__FILE__,__FUNCTION__,__LINE__,seed,lastNumber); } -int RandomGen::rand() { +int RandomGen::rand(string lastCaller) { //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] lastNumber = %d\n",__FILE__,__FUNCTION__,__LINE__,lastNumber); - lastNumber= (a*lastNumber + b) % m; + this->lastNumber = (a*lastNumber + b) % m; + this->lastCaller.push_back(lastCaller); //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] lastNumber = %d\n",__FILE__,__FUNCTION__,__LINE__,lastNumber); return lastNumber; } -int RandomGen::randRange(int min, int max){ - assert(min<=max); +std::string RandomGen::getLastCaller() const { + std::string result = ""; + for(unsigned int index = 0; index < lastCaller.size(); ++index) { + result += lastCaller[index] + " "; + } + return result; +} +int RandomGen::randRange(int min, int max,string lastCaller) { + //assert(min<=max); if(min > max) { char szBuf[8096]=""; snprintf(szBuf,8096,"In [%s::%s Line: %d] min > max, min = %d, max = %d",__FILE__,__FUNCTION__,__LINE__,min,max); @@ -74,9 +82,12 @@ int RandomGen::randRange(int min, int max){ // int res = streflop::Random(min, max); // streflop //#else int diff= max-min; - int res= min + static_cast(truncateDecimal(static_cast(diff+1),2)*RandomGen::rand() / m); + //int res= min + static_cast(truncateDecimal(static_cast(diff+1),2)*RandomGen::rand() / m); + double numerator = static_cast(diff + 1) * static_cast(RandomGen::rand(lastCaller)); + int res= min + static_cast(truncateDecimal(numerator / static_cast(m))); + //int res= min + static_cast(truncateDecimal(static_cast(diff+1 * RandomGen::rand()) / static_cast(m))); //#endif - assert(res>=min && res<=max); + //assert(res>=min && res<=max); if(res < min || res > max) { char szBuf[8096]=""; snprintf(szBuf,8096,"In [%s::%s Line: %d] res < min || res > max, min = %d, max = %d, res = %d",__FILE__,__FUNCTION__,__LINE__,min,max,res); @@ -88,8 +99,8 @@ int RandomGen::randRange(int min, int max){ return res; } -float RandomGen::randRange(float min, float max){ - assert(min<=max); +float RandomGen::randRange(float min, float max,string lastCaller) { + //assert(min<=max); if(min > max) { char szBuf[8096]=""; snprintf(szBuf,8096,"In [%s::%s Line: %d] min > max, min = %f, max = %f",__FILE__,__FUNCTION__,__LINE__,min,max); @@ -99,12 +110,12 @@ float RandomGen::randRange(float min, float max){ //#ifdef USE_STREFLOP // float res = streflop::Random(min, max, randomState); // streflop //#else - float rand01= static_cast(RandomGen::rand())/(m-1); + float rand01= static_cast(RandomGen::rand(lastCaller))/(m-1); float res= min+(max-min)*rand01; res = truncateDecimal(res); //#endif - assert(res>=min && res<=max); + //assert(res>=min && res<=max); if(res < min || res > max) { char szBuf[8096]=""; snprintf(szBuf,8096,"In [%s::%s Line: %d] res < min || res > max, min = %f, max = %f, res = %f",__FILE__,__FUNCTION__,__LINE__,min,max,res); diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index 7ed3797a..2512d52f 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -27,6 +27,7 @@ IF(BUILD_MEGAGLEST_TESTS) SET(DIRS_WITH_SRC ./ shared_lib/graphics + shared_lib/util shared_lib/xml) SET(MG_INCLUDES_ROOT "./") diff --git a/source/tests/shared_lib/graphics/math_util_test.cpp b/source/tests/shared_lib/graphics/math_util_test.cpp index 12b905cb..81b88919 100644 --- a/source/tests/shared_lib/graphics/math_util_test.cpp +++ b/source/tests/shared_lib/graphics/math_util_test.cpp @@ -22,7 +22,7 @@ using namespace Shared::Graphics; // -// Tests for XmlIo +// Tests for math_util // class MathUtilTest : public CppUnit::TestFixture { // Register the suite of tests for this fixture