Пример #1
0
Vector<CreatureObject*> TurretDataComponent::getAvailableTargets(bool aggroOnly) {
	Vector<CreatureObject*> targets;

	ManagedReference<TangibleObject*> turret = cast<TangibleObject*>(getParent());

	if (turret == NULL)
		return targets;

	CloseObjectsVector* vec = (CloseObjectsVector*)turret->getCloseObjects();

	SortedVector<QuadTreeEntry*> closeObjects;

	vec->safeCopyTo(closeObjects);

	int targetTotal = 0;

	for (int i = 0; i < closeObjects.size(); ++i) {
		CreatureObject* creo = cast<CreatureObject*>(closeObjects.get(i));

		if (creo != NULL && checkTarget(creo, turret, aggroOnly)) {
			targets.add(creo);
		}
	}

	return targets;
}
Пример #2
0
void MainWindow::initialize(QString const &target)
{
    emit cancelQuery();

    if (target == NULL || target.isEmpty()) {
        QString *target = new QString();
        QString *argument = new QString();
        PersistenceHandler::loadLast(target, argument, this);
        ui->txtTarget->setText(*target);
        ui->txtArgument->setText(*argument);
        delete target;
        delete argument;

        checkTarget(ui->txtTarget->text());

        forceFocus();
        ui->txtTarget->setFocus(Qt::ActiveWindowFocusReason);
        ui->txtTarget->selectAll();

    } else {
        ui->txtTarget->setText(target);
//        ui->txtArgument->setText("");
        forceFocus();
        ui->txtArgument->setFocus(Qt::ActiveWindowFocusReason);
    }
}
Пример #3
0
/*
 * getActions(Board * const * const board) checks if the unit can execute his action.
 *
 * It takes in as a parameter the board array. It then iterates over it, gets a
 * random direction, checks if the character can do his action then do it.
 *
 * Remark: getActions() needs to be called by casting the two lists with 
 * (Board * const * const) to squash a harmless (in this case) warning
 * from GCC.
 * See http://c-faq.com/ansi/constmismatch.html
 */
void getActions(Board * const * const board) 
{
	Units *units = &gameVar.units;
	Time *times = &gameVar.time;

	for (size_t i = 0; i < gameVar.dim.y; i++) {
		for (size_t j = 0; j < gameVar.dim.x; j++) {
			++times->elapsed;
			board[i][j].direction = rand()%4; 
			switch (board[i][j].character) {
				case WALL:	//fallthrough
				case EMPTY:
					break;
				case DEAD:
					if (rand()%100 == 1) {
						board[i][j].character = EMPTY;
						--units->dead;
					}
				case INF:
					for (board[i][j].direction = 0; board[i][j].direction < 4; board[i][j].direction++) {
						if (checkOutBounds(board[i][j].direction, i, j)) { 
							checkTarget(board, i, j, getActionInf);
						}
					}
					break;
				case DOC:
					if (checkOutBounds(board[i][j].direction, i, j)) {
						checkTarget(board, i, j, getActionDoc);	
					}
					break;
				case CIT:
					if (rand()%100 >= 98 && checkOutBounds(board[i][j].direction, i, j)) {
						checkTarget(board, i, j, getActionCit);
					}
					break;
				case SOL:
					checkSoldierRadius(board, i, j);
					break;
				case NUR:
					if (checkOutBounds(board[i][j].direction, i, j)) {
						checkTarget(board, i, j, getActionNurse);
					}
			}
		}
	}
}
Пример #4
0
/*
 * Extension: Checks and adds to hash table using a bit ID based hash function
 */
void generateUniqueBoardBitHash(BoardNode currentBoard, int rowMove, int colMove, int currRow, int currCol)	{
	BoardNode generatedBoard;
	generatedBoard = makeMove(copyParentToChild(currentBoard,createBoard(currentBoard)),rowMove,colMove,currRow,currCol,DELETE);
	bitEncoder(generatedBoard);
	if(generateBitHashKey(generatedBoard))	{
		addToQueue(generatedBoard);
		checkTarget(generatedBoard);
		freeBoardArray(generatedBoard);
	}
}
Пример #5
0
void BCIViz::drawDriver() const
{
	if(!checkTarget()) return;
	
	const MPoint proof = fTargetPositions[neighbourId[0]] * fAlpha + fTargetPositions[neighbourId[1]] * fBeta + fTargetPositions[neighbourId[2]] * fGamma;
	glBegin(GL_LINES);
	glVertex3f(proof.x, proof.y, proof.z);
	glVertex3f(fDriverPos.x, fDriverPos.y, fDriverPos.z);
	glEnd();
}
Пример #6
0
/*
 * Extension: Checks and adds to hash table using Zobrist hash function 
 */
void generateUniqueBoardHash(BoardNode currentBoard, int rowMove, int colMove, int currRow, int currCol)    {

	int hashKey;
    BoardNode generatedBoard;
	generatedBoard = makeMove(copyParentToChild(currentBoard,createBoard(currentBoard)),rowMove,colMove,currRow,currCol,DELETE);
	hashKey = generateHashKey(generatedBoard);
	if(hashBoard(hashKey,generatedBoard))	{
		addToQueue(generatedBoard);
		checkTarget(generatedBoard);
	}
}
Пример #7
0
/*
 *Basic: adds unqiue boards to linear linked list queue
 */
void generateUniqueBoardWithMove(BoardNode currentBoard, int rowMove, int colMove, int currRow, int currCol)    {

    //!Create a  blank board, copy parent board to it, make the move,  check if it
    //!is unique, add it to queue
    BoardNode generatedBoard;

    if((generatedBoard = compBoardWithList(makeMove(copyParentToChild(currentBoard,createBoard(currentBoard)),rowMove,colMove,currRow,currCol,DELETE))) != NULL)    {
        addToQueue(generatedBoard);
        checkTarget(generatedBoard);
    } else {
        freeBoard(generatedBoard);
    }
}
Пример #8
0
// checks if the requirements are set to generate a report
void MainWindow::checkingRequirements()
{
    checkSrc();
    checkTarget();

    if((srcFolderExists == true) && (targetFolderExists == true)) // src & target exist
    {
        ui->bt_generateIndex->setEnabled(true);
    }
    else
    {
        ui->bt_generateIndex->setEnabled(false);
    }
    updateStatusBar("Finished checking requirements (source and target)");
}
Пример #9
0
int main()
{
	for(int i = 1; i <= target; i++)
	{ 
		for(int j = i; j <= target; j++)
		{
			int k = target - i - j;
			if(checkTarget(i, j, k))
			{
				printf("Result: %d\n", i * j * k);
				return 0;
			}
		}
	}

	printf("FAIL\n");
	return 0;
}
Пример #10
0
void BCIViz::calculateWeight()
{
	if(!checkTarget() || !checkHull()) return;
	
	TriangleRaster tri;
	Facet f = m_hull->getFacet(m_hitTriangle);
	Vertex p0; 
	p0.x = fTargetPositions[neighbourId[0]].x;
	p0.y = fTargetPositions[neighbourId[0]].y;
	p0.z = fTargetPositions[neighbourId[0]].z;
	Vertex p1;
	p1.x = fTargetPositions[neighbourId[1]].x;
	p1.y = fTargetPositions[neighbourId[1]].y;
	p1.z = fTargetPositions[neighbourId[1]].z;
	Vertex p2;
	p2.x = fTargetPositions[neighbourId[2]].x;
	p2.y = fTargetPositions[neighbourId[2]].y;
	p2.z = fTargetPositions[neighbourId[2]].z;

	tri.create(p0, p1, p2);
	tri.isPointWithin(m_hitP, fAlpha, fBeta, fGamma); 
}
Пример #11
0
void ZRUser01(float *myState, float *otherState, float time)
{
//BEGIN::PROC::ZRUser

// These are just some costants, don't pay to much attention to them :)
#define	 WAIT_TIME	   13	// Seconds to wait before starting spinning

#define	 TIME_OPP_STAT   140	// Will only start considering about going
				// to a station after TIME_OPP_STAT seconds.

#define	 ACCURACY_STAT   1.975f // Number between 1 and 2, the higher it is,
				// the more accurate in deciding whether the 
				// opponent is headed towards the station.

#define	 FUEL_STAT	   25	// The minimum amount of fuel required to go
				// to a mining station (below this value, 
				// the sphere's not going anywhere


// msg  : contains the messages received from the opponent
// tt   : contains a condition used a couple of times (space optimization)
// out  : contains the message we're sending our opponent
unsigned short msg,tt,out=0;
// avoid: is true or false whether the collision avoidance system is activated or not
unsigned char avoid;
// Don't worry about x and v ^^
float x[2];
float v[3];
// stat : these are some coordinates of stuff, like stations, asteroids and
//		a couple of corners of the playground
float stat[6][3] =  {   {-0.5f,+0.31f,-0.55f},
			{+0.5f,-0.31f,+0.55f},
			{0,-0.35f,-0.2f},
			{0,+0.35f,+0.2f},
			{-0.5f,+0.65f,-0.55f},
			{+0.5f,-0.65f,+0.55f}};
msg=PgetMessage();
avoid = PisAvoidingCollision();
tt=(tmp && tmp+WAIT_TIME<time);

/*
 * y0b0tics protocol will be used only when 
 * we're controlling the SPH # 1
 */
if (!time) {
	if (myState[0]>0) { // SPH1
		a=0.4; //  a is the X coordinate of the nearest laser
		out=0x0400; // bit 11
		sp=1;
	}
	else
		a=-0.4;
}

/*
 * If the opponent is willing to work
 * on Indigens, we're going to Indigens
 * as well, but we'll try to revolve.
 * Otherwise we keep sending our
 * opponent a "I'll revolve on Opulens"
 * message.
 */
if (time<60 && time) {
	if ((msg>3 && msg<6) || ast==1) {
		out=5;
		act=2; // Revolve
		ast=1; // Indigens
	}
	else {
		out=3;
	}
}
/*
 * If we're headed to a mining station,
 * we're telling our opponents which one
 * it is
 */
else if (act==4 && st<2)
	out=7-st;
PsendMessage(out);
/*
 * First of all, the Laser is taken
 * (btw, there's a "minor" bug in this
 * condition (&& time<60) is needed
 * (will add that as soon as some space
 * is available)
 */
if (!PhaveLaser()) {
	/*
	 * If the opponent is trying to "steal"
	 * our laser, we will get the other one
	 */
	if (avoid && myState[0]*a>0) 
		a*=-1;
	/* v contains the
	 * laser coordinates
	 */
	v[0]=a;
	v[1]=0;
	v[2]=0;
	ZRSetPositionTarget(v);
}
else {
	if (time>TIME_OPP_STAT && st<2) {
		/*
		 * x[0] is given the value of the distance
		 * between us and our opponent
		 */
		mathVecSubtract (v,myState,otherState,3);
		x[0]=mathVecMagnitude (v,3);
		/*
		 * if our opponent is going to a station
		 * we decide to go to the other one, but
		 * only if we're able to arrive first
		 */
		if (checkTarget(otherState,0)>ACCURACY_STAT) {
			/*
			 * Even if we're headed towards a station,
			 * if our opponent is going to
			 * the same station as us, we stop going
			 * there and, instead, we move to the
			 * closest corner of the playground,
			 * so that, even if we don't gain anything,
			 * at least we won't activate the collision
			 * avoidance system
			 */
			if (!st && x[0]<0.65f) {
					st=4;
			}
			else if (st==-1) {
				/*
				 * We go to the other station only if
				 * we can reach it first
				 */
				if (getInTime(stat[0],otherState,stat[1],myState)) {
					st=1;
					act=4;
				}
				else
					st=-2;
			}
		}
		/*
		 * Same stuff as before, but now
		 * the other station is checked.
		 */
		else if (checkTarget(otherState,1)>ACCURACY_STAT) {
			if (st==1 && x[0]<0.65f) {
					st=5;
			}
			else if (st==-1) {
				if (getInTime(stat[1],otherState,stat[0],myState)) {
					st=0;
					act=4;
				}
				else
					st=-2;
			}
		}
		/*
		 * although our opponent is not going to 
		 * a station, we leave the asteroid we're
		 * working on to go to a station.
		 * The time we're leaving the asteroid is
		 * not fixed, but is calculated every time
		 * in order to leave the asteroid as late as
		 * possible
		 */
		else if (PgetPercentFuelRemaining()>FUEL_STAT && st==-1) {
			/*
			 * x[0] contains the value of time
			 * at which we have to leave the asteroid
			 * to reach a station
			 * 180-(time needed to reach a station)
			 */
			x[0]=timeStation(stat[0],myState);
			x[1]=timeStation(stat[1],myState);
				/*
				 * It is then decided which station is
				 * better, keeping in account that, if
				 * we're spinning, our opponent could be
				 * on our way to the station.
				 */
				if ((time>=x[0]) && (x[0]>x[1]) && !(act==3 && otherState[0]<0 && otherState[1]>0 && otherState[2]<0.2)) {
					act=4;
					st=0;
				}
				if ((x[0]<x[1]) && (time>=x[1]) && !(act==3 && otherState[0]>0 && otherState[1]<0 && otherState[2]>-0.2)) {
					act=4;
					st=1;
				}
		}
	}
	/*
	 * act (action) contains a value
	 * related to the action we're
	 * doing.
	 */
	switch (act) {
		/* act = 1 -> melting ice on Opulens */
		case 1:
			meltIce(myState,otherState,time);
			if (PiceMelted()) 
				act=2;  // if the ice is melted, we start revolving
						// on Opulens
			break;
		/* act = 2 -> revolve */
		case 2:
			/*
			 * if the opponent is revolving as
			 * well, we keep revolving as well
			 * for WAIT_TIME seconds. After that
			 * seconds, if the opponent is 
			 * still revolving, we start spinning
			 */
			if (PisRevolving (otherState)==ast-1) {
				if (!tmp)
					tmp=time;
				if (tt && (checkTarget (otherState,ast)<1.9f) && st!=-2) {
					act=3;
					tmp=0;
				}
			}
			revolve(stat[ast],myState,otherState);
			break;
		/* act = 3 -> spinning */
		case 3:
			/*
			 * if the avoiding collision system
			 * is working, it probably means that
			 * our opponent wants to spin and he's
			 * close to us so, after a few seconds,
			 * we let him spin and we start revolving ^^
			 */
			if (avoid) {
				if (!tmp)
					tmp=time;
				if (tt) {
					tmp=0;
					act=2;
				}
			}
			spin(stat[ast],myState);
			break;
		/* act = 4 -> going somewhere */
		case 4:
			SetPosFaster(stat[st],myState);
			break;
		default:
			break;
	}
	if (tt)
		tmp=0;
}
//END::PROC::ZRUser
}
Пример #12
0
void MainWindow::on_txtTarget_textChanged(QString string)
{
    checkTarget(string);
}
Пример #13
0
void LongTimeAction::successAction() {
    checkSource();
    checkTarget();

    if (_actionrunning) {
        _actionrunning = false;

        if (_at == ACTION_CRAFT) {
            if (_source.Type == LUA_DIALOG) {
                _owner->executeCraftingDialogCraftingComplete(_source.dialog);
                return;
            }
        } else if (_script) {
            if ((_at == ACTION_USE)) {
                //a itemscript
                if (_source.Type == LUA_ITEM) {
                    boost::shared_ptr<LuaItemScript>itScript = boost::dynamic_pointer_cast<LuaItemScript>(_script);

                    if (_target.Type == LUA_ITEM || _target.Type == LUA_NONE) {
                        itScript->UseItem(_owner, _source.item, static_cast<unsigned char>(LTS_ACTIONSUCCESSFULL));
                    }
                }
                //a tilescript
                else if (_source.Type == LUA_FIELD) {
                    boost::shared_ptr<LuaTileScript>tiScript = boost::dynamic_pointer_cast<LuaTileScript>(_script);

                    if (_target.Type == LUA_NONE) {
                        tiScript->useTile(_owner, _source.pos, static_cast<unsigned char>(LTS_ACTIONSUCCESSFULL));
                    }
                }
                //a character
                else if (_source.Type == LUA_CHARACTER) {
                    //a monster
                    if (_sourceCharType == Character::monster) {
                        boost::shared_ptr<LuaMonsterScript>monScript = boost::dynamic_pointer_cast<LuaMonsterScript>(_script);

                        if (_target.Type == LUA_NONE) {
                            monScript->useMonster(_source.character,_owner, static_cast<unsigned char>(LTS_ACTIONSUCCESSFULL));
                        }
                    }
                    //a npc
                    else if (_sourceCharType == Character::npc) {
                        boost::shared_ptr<LuaNPCScript>npcScript = boost::dynamic_pointer_cast<LuaNPCScript>(_script);

                        if (_target.Type == LUA_NONE) {
                            npcScript->useNPC(_owner, static_cast<unsigned char>(LTS_ACTIONSUCCESSFULL));
                        }
                    }
                }
            } else if ((_at == ACTION_MAGIC)) {
                boost::shared_ptr<LuaMagicScript>mgScript = boost::dynamic_pointer_cast<LuaMagicScript>(_script);

                if (_target.Type == LUA_NONE) {
                    mgScript->CastMagic(_owner, static_cast<unsigned char>(LTS_ACTIONSUCCESSFULL));
                } else if (_target.Type == LUA_FIELD) {
                    mgScript->CastMagicOnField(_owner,_target.pos, static_cast<unsigned char>(LTS_ACTIONSUCCESSFULL));
                } else if (_target.Type == LUA_CHARACTER) {
                    mgScript->CastMagicOnCharacter(_owner,_target.character, static_cast<unsigned char>(LTS_ACTIONSUCCESSFULL));
                    //Todo add ki handling here
                } else if (_target.Type == LUA_ITEM) {
                    mgScript->CastMagicOnItem(_owner,_target.item, static_cast<unsigned char>(LTS_ACTIONSUCCESSFULL));
                }

            }
        }
    }

    if (!_actionrunning) {
        _script.reset();
        delete _redoaniTimer;
        _redoaniTimer = NULL;
        delete _redosoundTimer;
        _redosoundTimer = NULL;
        delete _timetowaitTimer;
        _timetowaitTimer = NULL;
        _ani = 0;
        _sound = 0;
    }

}
Пример #14
0
bool LongTimeAction::actionDisturbed(Character *disturber) {
    checkSource();
    checkTarget();

    if (_actionrunning) {
        if (_at == ACTION_CRAFT) {
            if (_source.Type == LUA_DIALOG) {
                _actionrunning = false;
                _owner->executeCraftingDialogCraftingAborted(_source.dialog);
            }
        } else if (_script) {
            bool disturbed = false;

            if ((_at == ACTION_USE)) {
                if (_source.Type == LUA_ITEM) {
                    boost::shared_ptr<LuaItemScript>itemScript = boost::dynamic_pointer_cast<LuaItemScript>(_script);

                    if (itemScript->existsEntrypoint("actionDisturbed")) {
                        disturbed = itemScript->actionDisturbed(_owner, disturber);
                    }
                } else if (_source.Type == LUA_FIELD) {
                    boost::shared_ptr<LuaTileScript>tileScript = boost::dynamic_pointer_cast<LuaTileScript>(_script);

                    if (tileScript->existsEntrypoint("actionDisturbed")) {
                        disturbed = tileScript->actionDisturbed(_owner, disturber);
                    }
                } else if (_source.Type == LUA_CHARACTER) {
                    if (_sourceCharType == Character::monster) {
                        boost::shared_ptr<LuaMonsterScript>monsterScript = boost::dynamic_pointer_cast<LuaMonsterScript>(_script);

                        if (monsterScript->existsEntrypoint("actionDisturbed")) {
                            disturbed = monsterScript->actionDisturbed(_owner, disturber);
                        }
                    } else if (_sourceCharType == Character::npc) {
                        boost::shared_ptr<LuaNPCScript>npcScript = boost::dynamic_pointer_cast<LuaNPCScript>(_script);

                        if (npcScript->existsEntrypoint("actionDisturbed")) {
                            disturbed = npcScript->actionDisturbed(_owner, disturber);
                        }
                    }
                }
            } else if ((_at == ACTION_MAGIC)) {
                boost::shared_ptr<LuaMagicScript>magicScript = boost::dynamic_pointer_cast<LuaMagicScript>(_script);

                if (magicScript->existsEntrypoint("actionDisturbed")) {
                    disturbed = magicScript->actionDisturbed(_owner, disturber);
                }
            }

            if (disturbed) {
                abortAction();
                return true;
            } else {
                return false;
            }
        } else {
            _actionrunning = false;
        }
    }

    return false;
}
Пример #15
0
MStatus BCIViz::compute( const MPlug& plug, MDataBlock& block )
{
	if( plug == outValue ) {
		MStatus status;
		
		MDagPath path;
		MDagPath::getAPathTo(thisMObject(), path);
		
		MMatrix worldInverseSpace = path.inclusiveMatrixInverse();
		
		MDataHandle inputdata = block.inputValue(ainput, &status);
        if(status) {
			const MMatrix drvSpace = inputdata.asMatrix();
			fDriverPos.x = drvSpace(3, 0);
			fDriverPos.y = drvSpace(3, 1);
			fDriverPos.z = drvSpace(3, 2);
			
			fDriverPos *= worldInverseSpace;
		}
		
		fTargetPositions.clear();
		
		MArrayDataHandle htarget = block.inputArrayValue( atargets );
		unsigned numTarget = htarget.elementCount();
		
		fTargetPositions.setLength(numTarget);
		
		for(unsigned i = 0; i<numTarget; i++) {
			MDataHandle tgtdata = htarget.inputValue(&status);
			if(status) {
				const MMatrix tgtSpace = tgtdata.asMatrix();
				MPoint tgtPos(tgtSpace(3,0), tgtSpace(3,1), tgtSpace(3,2));
				tgtPos *= worldInverseSpace;
				MVector disp = tgtPos;
				disp.normalize();
				tgtPos = disp;
				fTargetPositions[i] = tgtPos;
			}
			htarget.next();
		}
		
		m_hitTriangle = 0;
		neighbourId[0] = 0;
		neighbourId[1] = 1;
		neighbourId[2] = 2;
		
		if(!checkTarget())
		{
			MGlobal::displayWarning("convex hull must have no less than 4 targes.");
			return MS::kSuccess;
		}
		
		if(!checkFirstFour(fTargetPositions))
		{
			MGlobal::displayWarning("first 4 targes cannot sit on the same plane.");
			return MS::kSuccess;
		}
		
		if(!constructHull())
		{
			MGlobal::displayWarning("convex hull failed on construction.");
			return MS::kSuccess;
		}

		findNeighbours();
		
		calculateWeight();

        MArrayDataHandle outputHandle = block.outputArrayValue( outValue );
		
		int numWeight = fTargetPositions.length();

		m_resultWeights.setLength(numWeight);
		
		for(int i=0; i < numWeight; i++) 
			m_resultWeights[i] = 0.0;
			
		m_resultWeights[neighbourId[0]] = fAlpha;
		m_resultWeights[neighbourId[1]] = fBeta;
		m_resultWeights[neighbourId[2]] = fGamma;
		
		MArrayDataBuilder builder(outValue, numWeight, &status);
		
		for(int i=0; i < numWeight; i++) {
			MDataHandle outWeightHandle = builder.addElement(i);
			outWeightHandle.set( m_resultWeights[i] );
			//MGlobal::displayInfo(MString("wei ") + i + " " + weights[i]);
		}
		
		outputHandle.set(builder);
		outputHandle.setAllClean();
    }

	return MS::kSuccess;
}
Пример #16
0
void Pathfinder::newNode(PathNode* oldnode, PathfindingState& state,
						 unsigned int steps)
{
	PathNode* newnode = new PathNode();
	nodelist.push_back(newnode); // for garbage collection
	newnode->state = state;
	newnode->parent = oldnode;
	newnode->depth = oldnode->depth + 1;
	newnode->stepsfromparent = 0;
	
	double sqrddist;
	
	sqrddist = ((newnode->state.x - oldnode->state.x)*
				(newnode->state.x - oldnode->state.x));
	sqrddist += ((newnode->state.y - oldnode->state.y)*
				 (newnode->state.y - oldnode->state.y));
	sqrddist += ((newnode->state.z - oldnode->state.z)*
				 (newnode->state.z - oldnode->state.z));
	
	unsigned int dist;
	dist = static_cast<unsigned int>(std::sqrt(sqrddist));
	
	int turn = 0;
	
	if (oldnode->depth > 0) {
		turn = state.direction - oldnode->state.direction;
		if (turn < 0) turn = -turn;
		if (turn > 4) turn = 8 - turn;
	}
	
	newnode->cost = oldnode->cost + dist + 32*turn; //!! constant

	bool done = checkTarget(newnode);
	if (done)
		newnode->heuristicTotalCost = 0;
	else
		costHeuristic(newnode);

#if 0
	perr << "trying dir " << state.direction;

	if (steps > 0) {
		perr << ", " << steps << " steps";
	}
	perr << " from ("
		 << oldnode->state.x << "," << oldnode->state.y << ") to ("
		 << newnode->state.x << "," << newnode->state.y
		 << "), cost = " << newnode->cost << ", heurtotcost = "
		 << newnode->heuristicTotalCost << std::endl;
#endif

#ifdef DEBUG
	if (actor->getObjId() == visualdebug_actor) {
		RenderSurface* screen = GUIApp::get_instance()->getScreen();
		screen->BeginPainting();
		drawpath(newnode, 0xFFFFFF00, done);
		screen->EndPainting();
		SDL_Delay(250);
		if (!done) {
			screen->BeginPainting();
			drawpath(newnode, 0xFFB0B000, done);
			screen->EndPainting();
		}
	}
#endif

	nodes.push(newnode);	
}
Пример #17
0
bool Pathfinder::pathfind(std::vector<PathfindingAction>& path)
{
#if 0
	pout << "Actor " << actor->getObjId();

	if (targetitem) {
		pout << " pathfinding to item: ";
		targetitem->dumpInfo();
	} else {
		pout << " pathfinding to (" << targetx << "," << targety << "," << targetz << ")" << std::endl;
	}
#endif

#ifdef DEBUG
	if (actor->getObjId() == visualdebug_actor) {
		RenderSurface* screen = GUIApp::get_instance()->getScreen();
		screen->BeginPainting();
		if (targetitem)
			drawbox(targetitem);
		else
			drawdot(targetx, targety, targetz, 2, 0xFF0000FF);
		screen->EndPainting();
	}
#endif


	path.clear();

	PathNode* startnode = new PathNode();
	startnode->state = start;
	startnode->cost = 0;
	startnode->parent = 0;
	startnode->depth = 0;
	startnode->stepsfromparent = 0;
	nodelist.push_back(startnode);
	nodes.push(startnode);

	unsigned int expandednodes = 0;
	const unsigned int NODELIMIT_MIN = 30;	//! constant
	const unsigned int NODELIMIT_MAX = 200;	//! constant
	bool found = false;
	Uint32 starttime = SDL_GetTicks();

	while (expandednodes < NODELIMIT_MAX && !nodes.empty() && !found) {
		PathNode* node = nodes.top(); nodes.pop();

#if 0
		pout << "Trying node: (" << node->state.x << "," << node->state.y
			 << "," << node->state.z << ") target=(" << targetx << ","
			 << targety << "," << targetz << ")" << std::endl;
#endif

		if (checkTarget(node)) {
			// done!

			// find path length
			PathNode* n = node;
			unsigned int length = 0;
			while (n->parent) {
				n = n->parent;
				length++;
			}
#if 0
			pout << "Pathfinder: path found (length = " << length << ")"
				 << std::endl;
#endif

			unsigned int i = length;
			if (length > 0) length++; // add space for final 'stand' action
			path.resize(length);

			// now backtrack through the nodes to assemble the final animation
			while (node->parent) {
				PathfindingAction action;
				action.action = node->state.lastanim;
				action.direction = node->state.direction;
				action.steps = node->stepsfromparent;
				path[--i] = action;
#if 0
				pout << "anim = " << node->state.lastanim << ", dir = "
					 << node->state.direction << ", steps = "
					 << node->stepsfromparent << std::endl;
#endif

				//TODO: check how turns work
				//TODO: append final 'stand' animation

				node = node->parent;
			}

			if (length) {
				if (node->state.combat)
					path[length-1].action = Animation::combatStand;
				else
					path[length-1].action = Animation::stand;
				path[length-1].direction = path[length-2].direction;
			}

			expandtime = SDL_GetTicks() - starttime;
			return true;
		}

		expandNode(node);
		expandednodes++;

		if(expandednodes >= NODELIMIT_MIN && ((expandednodes) % 5) == 0)
		{
			Uint32 elapsed_ms = SDL_GetTicks() - starttime;
			if(elapsed_ms > 350) break;
		}
	}

	expandtime = SDL_GetTicks() - starttime;

#if 0
	static sint32 pfcalls = 0;
	static sint32 pftotaltime = 0;
	pfcalls++;
	pftotaltime += expandtime;
	pout << "maxout average = " << (pftotaltime / pfcalls) << "ms." << std::endl;
#endif

	return false;
}