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.

Reply
 
Thread Tools Display Modes
  #1  
Old 05-26-2004, 12:27 PM
sandy
Hill Giant
 
Join Date: Oct 2002
Posts: 212
Default spawn areas

I got basic spawn areas working

Here's the sql table :
Code:
CREATE TABLE `spawnarea` (
  `id` int(11) NOT NULL default '0',
  `spawngroupID` int(11) NOT NULL default '0',
  `zone` varchar(16) NOT NULL default '',
  `x1` float NOT NULL default '0',
  `y1` float NOT NULL default '0',
  `z1` float NOT NULL default '0',
  `x2` float NOT NULL default '0',
  `y2` float NOT NULL default '0',
  `z2` float NOT NULL default '0',
  `maxmob` int(11) NOT NULL default '0',
  `respawntime` int(11) NOT NULL default '0',
  `variance` tinyint(4) NOT NULL default '0',
  `pause` int(11) NOT NULL default '0',
  KEY `id` (`id`),
  KEY `spawngroupID` (`spawngroupID`),
  KEY `zone` (`zone`)
) TYPE=MyISAM;
I know it is basic but it is a start =)
spawn areas are rects, you define their bounds with the ( x1, y1, z1 ) and ( x2, y2 , z2 ) points
spawngroupID is the id of a spawngroup, add in the spawngroup the monsters you want to spawn in the area
each mob is defined by a spawn entry, ( spawngroupID, npcid, chance )
tweak the chance of each npc to tweak the population of each npc type in the area
maxpop defines the maximum numbers of npcs who can roam in the area

npcs will spawn randomly in the area and roam randomly in the area like the roaming grid type but it doesnt use grids anymore

I think it can be improved in many ways, we had already discussions, and maybe areas could be polygons instead of rects, use areas for other purposes like quests etc ...
__________________
Sandy
Reply With Quote
  #2  
Old 05-26-2004, 01:22 PM
sandy
Hill Giant
 
Join Date: Oct 2002
Posts: 212
Default updates

here are the updates to do : ( based on 24-05-2004 source )

first :
download this :
spawnarea.zip

it contains spawnarea.cpp and spawnarea.h
add these files in your project zone folder, and add them to your zone project

then do the following changes ( there is a lot ) and compile :

in attack.cpp :

line 1885 :

after :

Code:
killer = tempkiller;
	
	if (respawn2 != 0)
	{
		respawn2->Reset();
	}
add :

Quote:
if (spawn_area != 0)
{
spawn_area->Reset( this->GetID() );
}

in command.cpp :

line 2521 :

replace :

Code:
			NPC* npc = new NPC(tmp, 0, c->GetX(), c->GetY(), c->GetZ(), c->GetHeading());
by :

Code:
			NPC* npc = new NPC(tmp, 0, 0, c->GetX(), c->GetY(), c->GetZ(), c->GetHeading());

in MobAI.cpp :

line 1048 :

replace :

Code:
					else if (roamer)
by :

Code:
					else if (roamer || this->CastToNPC()->spawn_area)
line 1058 :

replace :

Code:
                  if (gridno > 0)
by :

Code:
                  if ( (gridno > 0) || ( this->CastToNPC()->spawn_area ) )
line 1207 :

before :

Code:
	int8 ranmax = cur_wp;
	int8 ranmax2 = max_wp - cur_wp;
add :

Code:
	if ( this->CastToNPC()->spawn_area ) {
		this->CastToNPC()->spawn_area->GetWaypoint( cur_wp_x, cur_wp_y, cur_wp_z, cur_wp_pause );
		return;
	}

in npc.cpp :

line 58 :

replace :

Code:
NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float heading, bool IsCorpse)
by :

Code:
NPC::NPC(const NPCType* d, Spawn2* in_respawn, SpawnArea* in_area, float x, float y, float z, float heading, bool IsCorpse)
line 118 :

after :

Code:
	NPCTypedata = new NPCType;
	memcpy(NPCTypedata, d, sizeof(NPCType));
	respawn2 = in_respawn;
add :

Code:
	spawn_area = in_area;

line 914 :

after :

Code:
		if (respawn2 != 0) {
			respawn2->Reset();
		}
add :

Code:
		if (spawn_area) {
			spawn_area->Reset(GetID());
		}
line 1147 :

replace :

Code:
		NPC* npc = new NPC(npc_type, 0, in_x, in_y, in_z, in_heading/8);
by :

Code:
		NPC* npc = new NPC(npc_type, 0, 0, in_x, in_y, in_z, in_heading/8);

in npc.h :

line 29 :

after :

Code:
#include "spawn2.h"
#include "loottable.h"
#include "zonedump.h"
add :

Code:
#include "spawnarea.h"

line 44 :

replace :

Code:
	NPC(const NPCType* data, Spawn2* respawn, float x, float y, float z, float heading, bool IsCorpse = false);
by :

Code:
	NPC(const NPCType* data, Spawn2* respawn, SpawnArea* area, float x, float y, float z, float heading, bool IsCorpse = false);

line 157 :

after :

Code:
	Spawn2*	respawn2;
add :

Code:
	SpawnArea* spawn_area;

in spawn2.cpp :

line 99 :

replace :

Code:
				NPC* npc = new NPC(tmp, this, x, y, z, heading);
by :

Code:
				NPC* npc = new NPC(tmp, this, 0, x, y, z, heading);

in spells.cpp :

line 5312 :

replace :

Code:
	NPC* npc = new NPC(npc_type, 0,
                       this->GetX()+10, this->GetY()+10,
                       this->GetZ(), this->GetHeading());
by :

Code:
	NPC* npc = new NPC(npc_type, 0, 0,
                       this->GetX()+10, this->GetY()+10,
                       this->GetZ(), this->GetHeading());

line 6094 :

replace :

Code:
		NPC* horse = new NPC(npc_type, 0, GetX(), GetY(), GetZ(), GetHeading());
by :

Code:
		NPC* horse = new NPC(npc_type, 0, 0, GetX(), GetY(), GetZ(), GetHeading());

in zone.cpp :

line 383 :

after :

Code:
	spawn_group_list = new SpawnGroupList();
add :

Code:
	spawnarea_list = new SpawnAreaList();

2 lines below :

replace :

Code:
	if (!database.PopulateZoneLists(short_name, &zone_point_list, spawn_group_list))
by :

Code:
	if (!database.PopulateZoneLists(short_name, &zone_point_list, spawn_group_list, spawnarea_list))

line 699 :

before :

Code:
	list<timers*>::iterator iterator1 = TimerList.begin();
add :

Code:
	spawnarea_list->Process();

line 779 :

after :
Code:
bool Zone::Depop() {
add :
Code:
	spawnarea_list->Depop();
line 788 :

after :
Code:
	entity_list.Message(0, 0, "<SYSTEM_MSG>:Zone REPOP IMMINENT");
add :
Code:
	spawnarea_list->Repop();
line 959 :

replace :
Code:
bool Database::PopulateZoneLists(const char* zone_name, LinkedList<ZonePoint*>* zone_point_list, SpawnGroupList* spawn_group_list) {
by :
Code:
bool Database::PopulateZoneLists(const char* zone_name, LinkedList<ZonePoint*>* zone_point_list, SpawnGroupList* spawn_group_list, SpawnAreaList* spawnarea_list ) {
line 999:

after :
Code:
	{
		cerr << "Error3 in PopulateZoneLists query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
		return false;
	}
add :

Code:
	query = 0;
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, spawngroupID, x1, y1, z1, x2, y2, z2, maxmob, respawntime, variance, pause from spawnarea where zone='%s'", zone_name), errbuf, &result)) {
		safe_delete_array(query);
		while((row = mysql_fetch_row(result)))
		{
			SpawnArea* newSpawnArea = new SpawnArea( atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11]) );
			spawnarea_list->AddSpawnArea(newSpawnArea);
		}
		mysql_free_result(result);
	}
	else
	{
		cerr << "Error4 in PopulateZoneLists query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
		return false;
	}

	query = 0;
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT(spawngroupID), spawngroup.name FROM spawnarea,spawngroup WHERE spawnarea.spawngroupID=spawngroup.ID and zone='%s'", zone_name), errbuf, &result))
	{
		safe_delete_array(query);
		while((row = mysql_fetch_row(result))) {
			SpawnGroup* newSpawnGroup = new SpawnGroup( atoi(row[0]), row[1]);
			spawn_group_list->AddSpawnGroup(newSpawnGroup);
		}
		mysql_free_result(result);
	}
	else
	{
		cerr << "Error5 in PopulateZoneLists query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
		return false;
	}

	query = 0;
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT spawnentry.spawngroupID, npcid, chance from spawnentry, spawnarea where spawnentry.spawngroupID=spawnarea.spawngroupID and zone='%s' ORDER by chance", zone_name), errbuf, &result)) {
		safe_delete_array(query);
		while((row = mysql_fetch_row(result)))
		{
			SpawnEntry* newSpawnEntry = new SpawnEntry( atoi(row[1]), atoi(row[2]));
			if (spawn_group_list->GetSpawnGroup(atoi(row[0])))
				spawn_group_list->GetSpawnGroup(atoi(row[0]))->AddSpawnEntry(newSpawnEntry);
			else
				cout << "Error in SpawngroupID: " << atoi(row[0]) << endl;
		}
		mysql_free_result(result);
	}
	else
	{
		cerr << "Error6 in PopulateZoneLists query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
		return false;
	}
line 1302 :

replace :
Code:
					npc_loaded[i] = new NPC(&gmspawntype_dump[npc_dump[i].gmspawntype_index], tmp, npc_dump[i].x, npc_dump[i].y, npc_dump[i].z, npc_dump[i].heading, npc_dump[i].corpse);
by :
Code:
					npc_loaded[i] = new NPC(&gmspawntype_dump[npc_dump[i].gmspawntype_index], tmp, 0, npc_dump[i].x, npc_dump[i].y, npc_dump[i].z, npc_dump[i].heading, npc_dump[i].corpse);
5 lines below :

replace :
Code:
					npc_loaded[i] = new NPC(crap, tmp, npc_dump[i].x, npc_dump[i].y, npc_dump[i].z, npc_dump[i].heading, npc_dump[i].corpse);
by :
Code:
					npc_loaded[i] = new NPC(crap, tmp, 0, npc_dump[i].x, npc_dump[i].y, npc_dump[i].z, npc_dump[i].heading, npc_dump[i].corpse);

in zone . h :

line 53 :

after :
Code:
#ifndef GUILDWARS
	LinkedList<Spawn2*> spawn2_list; // CODER new spawn list
#endif
add :
Code:
	SpawnAreaList* spawnarea_list;

in database.h :

line 51 :

after :
Code:
class Spawn2;
add :
Code:
class SpawnArea;
class SpawnAreaList;
line 196 :

replace :
Code:
	bool	PopulateZoneLists(const char* zone_name, LinkedList<ZonePoint*>* zone_point_list, SpawnGroupList* spawn_group_list);
by :
Code:
	bool	PopulateZoneLists(const char* zone_name, LinkedList<ZonePoint*>* zone_point_list, SpawnGroupList* spawn_group_list, SpawnAreaList* spawnarea_list);

in parser.cpp :

line 738 :

replace :
Code:
					NPC* npc = new NPC(tmp, 0, atof(arglist[3]), atof(arglist[4]), atof(arglist[5]), mob->CastToClient()->GetHeading());
by :
Code:
					NPC* npc = new NPC(tmp, 0, 0, atof(arglist[3]), atof(arglist[4]), atof(arglist[5]), mob->CastToClient()->GetHeading());
__________________
Sandy
Reply With Quote
  #3  
Old 05-26-2004, 01:49 PM
Jezebell
Discordant
 
Join Date: Feb 2004
Location: Florida
Posts: 441
Default

Wow Sandy, sounds awesome!

I will give it a try. Would be awesome if this eventually got added to CVS.
__________________
Eru, the Creator of Arda
ServerOwner for The First Age
An EQEMulator Roleplaying [Custom-Legit] Server
The First Age Website

Running on: Asus A7N8X-Deluxe, AMD Athlon XP 2100+, Geil 1024MB PC3200 Ultra DDR RAM,
WD 40GB 7200rpm ATA-100 HDD, Visiontek 128MB Geforce4 TI 4400, Windows XP Pro SP2
Reply With Quote
  #4  
Old 05-26-2004, 01:56 PM
animepimp
Dragon
 
Join Date: Jan 2004
Posts: 860
Default

Sweet, this'll make zones a lot less repetitive and boring if used right.
Reply With Quote
  #5  
Old 05-26-2004, 02:24 PM
RangerDown
Demi-God
 
Join Date: Mar 2004
Posts: 1,066
Default

Good work Sandy.
Reply With Quote
  #6  
Old 08-03-2004, 04:56 PM
Cripp's Avatar
Cripp
Discordant
 
Join Date: Oct 2003
Location: The Shire
Posts: 474
Default

Hi
anyone know if this works? and does it break anything else?
and can we use this and the normal(or 2 grid) system at same time?

thanks.
__________________
Nug Blazers - ServerOP / founder
^^comming... later!

www.nugblazers.com
Reply With Quote
Reply


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 05:55 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 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3