Go Back   EQEmulator Home > EQEmulator Forums > Archives > Archive::Development > Archive::Development

Archive::Development Archive area for Development's posts that were moved here after an inactivity period of 90 days.

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #3  
Old 03-23-2002, 02:58 PM
Malevolent
Hill Giant
 
Join Date: Mar 2002
Posts: 171
Default Code Snippets

According to my tests, stuff moves across the screen. While a bit rough, it gets the job done (for now). This will put together a data structure that allows one to setup a way to move npc types around a zone. Currently, the data is not persistent and only loads the points when the zone is booted. Is there really a good reason to make persistent pathing points? Anyway, here is the code, hope it helps!

database structure:

Code:
CREATE TABLE path_points(
  id int(11) NOT NULL auto_increment,
  npctypeid int(11) NOT NULL default '0',	//from table npc_types, using key (id)
  zone varchar(16) NOT NULL default '',		//short zone name
  x float NOT NULL default '0',
  y float NOT NULL default '0',
  z float NOT NULL default '0',
  MoveRate float NOT NULL default '0',		//float representing how fast the critter needs to move
  step int NOT NULL default '0',		//what step in the linear sequence are we?
  primary key (id)
 );

insert into path_points(npctypeid,zone,x,y,z,MoveRate,step) values ('4057','misty',-200,-200,0,1.00,0);
insert into path_points(npctypeid,zone,x,y,z,MoveRate,step) values ('4057','misty',-100,-100,0,1.00,1);
Changes to zone.h
Code:
///////////////////////
//Malevolent:
//Data structure that contains information about a zone's pathing points
struct PathPoint {
	float x;
	float y;
	float z;
	int step;
	float movement_increment; //float value to increase movement value by
	int NPC_TypeID;	  //maybe make this an array of ints, so more than 1 npc can use a path?
};


Public:

LinkedList<PathPoint*> PathPointsList; //Malevolent: pathing points collection
Changes to zone.cpp
Code:
///////////////////////////////
//Malevolent: PathPoint, load data
bool Database::PopulateZonePathPoint(char* zone_name, LinkedList<PathPoint*> &PathPointsList, int32 repopdelay) {
	//, LinkedList<PathPoint*> &PathPointsList, int32 repopdelay
	
	char errbuf[MYSQL_ERRMSG_SIZE];
	char* query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;

	MakeAnyLenString(&query, "SELECT x, y, z, zone, npctypeid, MoveRate FROM path_points WHERE zone='%s'", zone_name);

	if (RunQuery(query, strlen(query), errbuf, &result))
	{
		delete[] query;
		while(row = mysql_fetch_row(result))
		{
			PathPoint* pp = new PathPoint;
			
			ZonePoint* zp = new ZonePoint;
			pp->x = atof(row[0]);			//x coordinate to move to
			pp->y = atof(row[1]);			//y coordinate to move to
			pp->z = atof(row[2]);		 //z coordinate currently not used
			pp->movement_increment = atof(row[5]);	//movement incremental value (how far to move the critter)
			pp->NPC_TypeID = atoi(row[4]);	//the *npc_type* to move...todo: make it the spawn id
			
			PathPointsList.Insert(pp);

		}
		mysql_free_result(result);
	}
	else
	{
		cerr << "Error in PopulateZonePathPoints query '" << query << "' " << errbuf << endl;
		delete[] query;
		return false;
	}

	return true;
}

Changes to npc.cpp

Code:
//////////////////////////////
//Malevolent:
//Walk npc to one of the pathpoints setup for it in db
void NPC::PathPointSendTo()
{

	//Build list
	LinkedListIterator<PathPoint*> iterator(zone->PathPointsList);	
	iterator.Reset();

	while(iterator.MoreElements())	
	{

		PathPoint* pp = iterator.GetData();
			
		if (this->GetPathPointStep() == pp->step)	/// are we on the right step? 
		if (this->GetNPCTypeID() == pp->NPC_TypeID)	///make sure that the npc matches
		{

			//todo: find a better way to get there--maybe add a flag to use different pathfinding techniques?

			if (pp->x > this->GetX())
			{			
				this->x_pos=this->GetX()+pp->movement_increment;
			}

			if (pp->y > this->GetY())
			{			
				this->y_pos=this->GetY()+pp->movement_increment;			
			}

			//what's a good way to check for optimal z coordinate?
			this->z_pos=0;
			
			//lastly, check to ensure that we haven't completed out objective
			//and if so, then increase the step value
			if ((pp->x < this->GetX()) && pp->y < this->GetY())
				this->SetPathPointStep(this->GetPathPointStep()+1);

			//Update spawn position. Don't use fale as it kills performance
			SendPosUpdate(true);

			//todo some way to reset the step counter (after respawn or after ticks, or maybe just let it loop, /shrug?)
		
		} //end if 

		iterator.Advance();		
		
	}//end while
	
}
npc.cpp, within ::Process() right before the final return true;

Code:
	//Malevolent
	//Walk through the zone pathing points
	//if the target is not engaged and if the movement timer says its ok
	if(!this->IsEngaged()&&movement_timer->Check())
	{
	this->PathPointSendTo();
		return true;
	}
npc.cpp in npc::npc
Code:
    SetPathPointStep(0); //always start out at step 0 for a new npc
npc.h
Code:
public:
	void PathPointSendTo();
	uint32	GetPathPointStep()		{ return PathPointStep; }
	void    SetPathPointStep(int step_value);
Protected:
	uint32  PathPointStep;

--MV

(formerly known as ScotchTape)
Reply With Quote
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 01:04 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3