- updated code to protect against null pointers and uninitialized values and threading issues
This commit is contained in:
parent
196d1240f1
commit
adc62b7df8
|
@ -598,6 +598,9 @@ void Unit::setModelFacing(CardinalDir value) {
|
|||
// ====================================== get ======================================
|
||||
|
||||
Vec2i Unit::getCenteredPos() const {
|
||||
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
||||
MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId);
|
||||
|
||||
if(type == NULL) {
|
||||
char szBuf[8096]="";
|
||||
snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str());
|
||||
|
@ -608,6 +611,9 @@ Vec2i Unit::getCenteredPos() const {
|
|||
}
|
||||
|
||||
Vec2f Unit::getFloatCenteredPos() const {
|
||||
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
||||
MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId);
|
||||
|
||||
if(type == NULL) {
|
||||
char szBuf[8096]="";
|
||||
snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str());
|
||||
|
|
|
@ -95,6 +95,7 @@ UnitUpdater::~UnitUpdater() {
|
|||
delete pathFinder;
|
||||
pathFinder = NULL;
|
||||
|
||||
MutexSafeWrapper safeMutex(&mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__));
|
||||
while(attackWarnings.empty() == false) {
|
||||
AttackWarningData* awd=attackWarnings.back();
|
||||
attackWarnings.pop_back();
|
||||
|
@ -304,6 +305,7 @@ void UnitUpdater::updateUnitCommand(Unit *unit, int frameIndex) {
|
|||
|
||||
bool commandUsesPathFinder = (frameIndex < 0);
|
||||
if(frameIndex > 0) {
|
||||
if(unit->getCurrCommand() != NULL && unit->getCurrCommand()->getCommandType() != NULL) {
|
||||
commandUsesPathFinder = unit->getCurrCommand()->getCommandType()->usesPathfinder();
|
||||
|
||||
// Clear previous cached unit data
|
||||
|
@ -311,9 +313,12 @@ void UnitUpdater::updateUnitCommand(Unit *unit, int frameIndex) {
|
|||
clearUnitPrecache(unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(commandUsesPathFinder == true) {
|
||||
if(unit->getCurrCommand() != NULL && unit->getCurrCommand()->getCommandType() != NULL) {
|
||||
unit->getCurrCommand()->getCommandType()->update(this, unit, frameIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if((minorDebugPerformance && frameIndex > 0) && (chrono.getMillis() - elapsed1) >= 1) {
|
||||
//CommandClass cc = unit->getCurrCommand()->getCommandType()->commandTypeClass;
|
||||
|
@ -379,7 +384,7 @@ void UnitUpdater::updateStop(Unit *unit, int frameIndex) {
|
|||
|
||||
//use it to attack
|
||||
if(ast != NULL) {
|
||||
if(attackableOnSight(unit, &sighted, ast)) {
|
||||
if(attackableOnSight(unit, &sighted, ast, (frameIndex >= 0))) {
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
unit->giveCommand(new Command(ct, sighted->getPos()));
|
||||
break;
|
||||
|
@ -393,7 +398,7 @@ void UnitUpdater::updateStop(Unit *unit, int frameIndex) {
|
|||
else if(unit->getType()->hasCommandClass(ccMove)) {
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
if(attackerOnSight(unit, &sighted)) {
|
||||
if(attackerOnSight(unit, &sighted, (frameIndex >= 0))) {
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
Vec2i escapePos = unit->getPos() * 2 - sighted->getPos();
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
@ -464,7 +469,13 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
|
|||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
||||
|
||||
Command *command= unit->getCurrCommand();
|
||||
if(command == NULL) {
|
||||
return;
|
||||
}
|
||||
const AttackCommandType *act= static_cast<const AttackCommandType*>(command->getCommandType());
|
||||
if(act == NULL) {
|
||||
return;
|
||||
}
|
||||
Unit *target= NULL;
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
@ -478,7 +489,9 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
|
|||
}
|
||||
|
||||
//if found
|
||||
if(attackableOnRange(unit, &target, act->getAttackSkillType())) {
|
||||
//if(frameIndex < 0) {
|
||||
{
|
||||
if(attackableOnRange(unit, &target, act->getAttackSkillType(),(frameIndex >= 0))) {
|
||||
if(frameIndex < 0) {
|
||||
if(unit->getEp() >= act->getAttackSkillType()->getEpCost()) {
|
||||
unit->setCurrSkill(act->getAttackSkillType());
|
||||
|
@ -496,7 +509,7 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
|
|||
if(command->getUnit() != NULL) {
|
||||
pos= command->getUnit()->getCenteredPos();
|
||||
}
|
||||
else if(attackableOnSight(unit, &target, act->getAttackSkillType())) {
|
||||
else if(attackableOnSight(unit, &target, act->getAttackSkillType(), (frameIndex >= 0))) {
|
||||
pos= target->getPos();
|
||||
}
|
||||
else {
|
||||
|
@ -512,8 +525,12 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
|
|||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
|
||||
TravelState tsValue = tsImpossible;
|
||||
if(frameIndex < 0) {
|
||||
//{
|
||||
//printf("In [%s::%s Line: %d] START pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str());
|
||||
//fflush(stdout);
|
||||
switch(this->game->getGameSettings()->getPathFinderType()) {
|
||||
case pfBasic:
|
||||
tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex);
|
||||
|
@ -521,6 +538,8 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
|
|||
default:
|
||||
throw megaglest_runtime_error("detected unsupported pathfinder type!");
|
||||
}
|
||||
//printf("In [%s::%s Line: %d] END pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str());
|
||||
//fflush(stdout);
|
||||
}
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
@ -589,6 +608,7 @@ void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
|
|||
}
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
}
|
||||
}
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
}
|
||||
|
@ -623,7 +643,7 @@ void UnitUpdater::updateAttackStopped(Unit *unit, int frameIndex) {
|
|||
unit->setCurrSkill(asct->getAttackSkillType());
|
||||
unit->setTarget(result.second);
|
||||
}
|
||||
else if(attackableOnRange(unit, &enemy, asct->getAttackSkillType())) {
|
||||
else if(attackableOnRange(unit, &enemy, asct->getAttackSkillType(),(frameIndex >= 0))) {
|
||||
unit->setCurrSkill(asct->getAttackSkillType());
|
||||
unit->setTarget(enemy);
|
||||
}
|
||||
|
@ -699,7 +719,7 @@ void UnitUpdater::updateBuild(Unit *unit, int frameIndex) {
|
|||
//std::pair<float,Vec2i> distance = map->getUnitDistanceToPos(unit,command->getPos(),command->getUnitType());
|
||||
//unit->setCurrentUnitTitle("Distance: " + floatToStr(distance.first) + " build pos: " + distance.second.getString() + " current pos: " + unit->getPos().getString());
|
||||
|
||||
if(unit->getCurrSkill()->getClass() != scBuild) {
|
||||
if(unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() != scBuild) {
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
//if not building
|
||||
|
@ -909,12 +929,14 @@ void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) {
|
|||
|
||||
//printf("In UpdateHarvest [%d - %s] unit->getCurrSkill()->getClass() = %d\n",unit->getId(),unit->getType()->getName().c_str(),unit->getCurrSkill()->getClass());
|
||||
|
||||
if(unit->getCurrSkill()->getClass() != scHarvest) {
|
||||
if(unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() != scHarvest) {
|
||||
//if not working
|
||||
if(unit->getLoadCount() == 0) {
|
||||
//if not loaded go for resources
|
||||
Resource *r = map->getSurfaceCell(Map::toSurfCoords(command->getPos()))->getResource();
|
||||
if(r != NULL && hct->canHarvest(r->getType())) {
|
||||
SurfaceCell *sc = map->getSurfaceCell(Map::toSurfCoords(command->getPos()));
|
||||
if(sc != NULL) {
|
||||
Resource *r = sc->getResource();
|
||||
if(r != NULL && hct != NULL && hct->canHarvest(r->getType())) {
|
||||
//if can harvest dest. pos
|
||||
bool canHarvestDestPos = false;
|
||||
|
||||
|
@ -1110,6 +1132,7 @@ void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) {
|
|||
}
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
}
|
||||
}
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
}
|
||||
|
@ -2062,19 +2085,19 @@ bool UnitUpdater::searchForResource(Unit *unit, const HarvestCommandType *hct) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool UnitUpdater::attackerOnSight(Unit *unit, Unit **rangedPtr){
|
||||
bool UnitUpdater::attackerOnSight(Unit *unit, Unit **rangedPtr, bool evalMode){
|
||||
int range= unit->getType()->getSight();
|
||||
return unitOnRange(unit, range, rangedPtr, NULL);
|
||||
return unitOnRange(unit, range, rangedPtr, NULL,evalMode);
|
||||
}
|
||||
|
||||
bool UnitUpdater::attackableOnSight(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast){
|
||||
bool UnitUpdater::attackableOnSight(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast, bool evalMode) {
|
||||
int range= unit->getType()->getSight();
|
||||
return unitOnRange(unit, range, rangedPtr, ast);
|
||||
return unitOnRange(unit, range, rangedPtr, ast, evalMode);
|
||||
}
|
||||
|
||||
bool UnitUpdater::attackableOnRange(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast){
|
||||
bool UnitUpdater::attackableOnRange(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast,bool evalMode) {
|
||||
int range= ast->getTotalAttackRange(unit->getTotalUpgrade());
|
||||
return unitOnRange(unit, range, rangedPtr, ast);
|
||||
return unitOnRange(unit, range, rangedPtr, ast, evalMode);
|
||||
}
|
||||
|
||||
bool UnitUpdater::findCachedCellsEnemies(Vec2i center, int range, int size, vector<Unit*> &enemies,
|
||||
|
@ -2167,12 +2190,12 @@ void UnitUpdater::findEnemiesForCell(const Vec2i pos, int size, int sightRange,
|
|||
|
||||
//if the unit has any enemy on range
|
||||
bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
|
||||
const AttackSkillType *ast) {
|
||||
const AttackSkillType *ast,bool evalMode) {
|
||||
vector<Unit*> enemies;
|
||||
bool result=false;
|
||||
//we check command target
|
||||
const Unit *commandTarget = NULL;
|
||||
if(unit->anyCommand()) {
|
||||
if(unit->anyCommand() && unit->getCurrCommand() != NULL) {
|
||||
commandTarget = static_cast<const Unit*>(unit->getCurrCommand()->getUnit());
|
||||
}
|
||||
if(commandTarget != NULL && commandTarget->isDead()) {
|
||||
|
@ -2229,7 +2252,7 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
|
|||
for(int i = 0; i< enemies.size(); ++i) {
|
||||
Unit *enemy = enemies[i];
|
||||
|
||||
if(enemy->isAlive() == true) {
|
||||
if(enemy != NULL && enemy->isAlive() == true) {
|
||||
// Here we default to first enemy if no attackers found
|
||||
if(enemySeen == NULL) {
|
||||
*rangedPtr = enemy;
|
||||
|
@ -2283,7 +2306,7 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
|
|||
onlyEnemyUnits = false;
|
||||
}
|
||||
|
||||
if(onlyEnemyUnits == false &&
|
||||
if(evalMode == false && onlyEnemyUnits == false &&
|
||||
enemyUnit->getTeam() != world->getThisTeamIndex()) {
|
||||
Vec2f enemyFloatCenter = enemyUnit->getFloatCenteredPos();
|
||||
// find nearest Attack and cleanup old dates
|
||||
|
@ -2291,6 +2314,7 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
|
|||
float currentDistance = 0.f;
|
||||
float nearestDistance = 0.f;
|
||||
|
||||
MutexSafeWrapper safeMutex(&mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__));
|
||||
for(int i = attackWarnings.size() - 1; i >= 0; --i) {
|
||||
if(world->getFrameCount() - attackWarnings[i]->lastFrameCount > 200) { //after 200 frames attack break we warn again
|
||||
AttackWarningData *toDelete =attackWarnings[i];
|
||||
|
@ -2338,6 +2362,8 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr,
|
|||
awd->lastFrameCount=world->getFrameCount();
|
||||
awd->attackPosition.x=enemyFloatCenter.x;
|
||||
awd->attackPosition.y=enemyFloatCenter.y;
|
||||
|
||||
MutexSafeWrapper safeMutex(&mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__));
|
||||
attackWarnings.push_back(awd);
|
||||
|
||||
if(world->getAttackWarningsEnabled() == true) {
|
||||
|
@ -2409,6 +2435,7 @@ vector<Unit*> UnitUpdater::enemyUnitsOnRange(const Unit *unit,const AttackSkillT
|
|||
|
||||
void UnitUpdater::findUnitsForCell(Cell *cell, const Unit *unit,vector<Unit*> &units) {
|
||||
//all fields
|
||||
if(cell != NULL) {
|
||||
for(int k = 0; k < fieldCount; k++) {
|
||||
Field f= static_cast<Field>(k);
|
||||
|
||||
|
@ -2420,6 +2447,7 @@ void UnitUpdater::findUnitsForCell(Cell *cell, const Unit *unit,vector<Unit*> &u
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<Unit*> UnitUpdater::findUnitsInRange(const Unit *unit, int radius) {
|
||||
int range = radius;
|
||||
|
|
|
@ -80,6 +80,7 @@ private:
|
|||
PathFinder *pathFinder;
|
||||
Game *game;
|
||||
//RandomGen random;
|
||||
Mutex mutexAttackWarnings;
|
||||
float attackWarnRange;
|
||||
AttackWarnings attackWarnings;
|
||||
|
||||
|
@ -143,10 +144,10 @@ private:
|
|||
|
||||
//misc
|
||||
bool searchForResource(Unit *unit, const HarvestCommandType *hct);
|
||||
bool attackerOnSight(Unit *unit, Unit **enemyPtr);
|
||||
bool attackableOnSight(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast);
|
||||
bool attackableOnRange(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast);
|
||||
bool unitOnRange(Unit *unit, int range, Unit **enemyPtr, const AttackSkillType *ast);
|
||||
bool attackerOnSight(Unit *unit, Unit **enemyPtr, bool evalMode=false);
|
||||
bool attackableOnSight(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast, bool evalMode=false);
|
||||
bool attackableOnRange(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast, bool evalMode=false);
|
||||
bool unitOnRange(Unit *unit, int range, Unit **enemyPtr, const AttackSkillType *ast,bool evalMode=false);
|
||||
void enemiesAtDistance(const Unit *unit, const Unit *priorityUnit, int distance, vector<Unit*> &enemies);
|
||||
|
||||
Unit * findPeerUnitBuilder(Unit *unit);
|
||||
|
|
|
@ -966,7 +966,7 @@ Unit *World::nearestStore(const Vec2i &pos, int factionIndex, const ResourceType
|
|||
Unit *u= getFaction(factionIndex)->getUnit(i);
|
||||
if(u != NULL) {
|
||||
float tmpDist= u->getPos().dist(pos);
|
||||
if(tmpDist < currDist && u->getType()->getStore(rt) > 0 && u->isOperative()) {
|
||||
if(tmpDist < currDist && u->getType() != NULL && u->getType()->getStore(rt) > 0 && u->isOperative()) {
|
||||
currDist= tmpDist;
|
||||
currUnit= u;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue