sandy
05-26-2004, 12:27 PM
I got basic spawn areas working
Here's the sql table :
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
05-26-2004, 01:22 PM
here are the updates to do : ( based on 24-05-2004 source )
first :
download this :
spawnarea.zip (http://www.projecteq.net/files/sandy/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 :
killer = tempkiller;
if (respawn2 != 0)
{
respawn2->Reset();
}
add :
if (spawn_area != 0)
{
spawn_area->Reset( this->GetID() );
}
in command.cpp :
line 2521 :
replace :
NPC* npc = new NPC(tmp, 0, c->GetX(), c->GetY(), c->GetZ(), c->GetHeading());
by :
NPC* npc = new NPC(tmp, 0, 0, c->GetX(), c->GetY(), c->GetZ(), c->GetHeading());
in MobAI.cpp :
line 1048 :
replace :
else if (roamer)
by :
else if (roamer || this->CastToNPC()->spawn_area)
line 1058 :
replace :
if (gridno > 0)
by :
if ( (gridno > 0) || ( this->CastToNPC()->spawn_area ) )
line 1207 :
before :
int8 ranmax = cur_wp;
int8 ranmax2 = max_wp - cur_wp;
add :
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 :
NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float heading, bool IsCorpse)
by :
NPC::NPC(const NPCType* d, Spawn2* in_respawn, SpawnArea* in_area, float x, float y, float z, float heading, bool IsCorpse)
line 118 :
after :
NPCTypedata = new NPCType;
memcpy(NPCTypedata, d, sizeof(NPCType));
respawn2 = in_respawn;
add :
spawn_area = in_area;
line 914 :
after :
if (respawn2 != 0) {
respawn2->Reset();
}
add :
if (spawn_area) {
spawn_area->Reset(GetID());
}
line 1147 :
replace :
NPC* npc = new NPC(npc_type, 0, in_x, in_y, in_z, in_heading/8);
by :
NPC* npc = new NPC(npc_type, 0, 0, in_x, in_y, in_z, in_heading/8);
in npc.h :
line 29 :
after :
#include "spawn2.h"
#include "loottable.h"
#include "zonedump.h"
add :
#include "spawnarea.h"
line 44 :
replace :
NPC(const NPCType* data, Spawn2* respawn, float x, float y, float z, float heading, bool IsCorpse = false);
by :
NPC(const NPCType* data, Spawn2* respawn, SpawnArea* area, float x, float y, float z, float heading, bool IsCorpse = false);
line 157 :
after :
Spawn2* respawn2;
add :
SpawnArea* spawn_area;
in spawn2.cpp :
line 99 :
replace :
NPC* npc = new NPC(tmp, this, x, y, z, heading);
by :
NPC* npc = new NPC(tmp, this, 0, x, y, z, heading);
in spells.cpp :
line 5312 :
replace :
NPC* npc = new NPC(npc_type, 0,
this->GetX()+10, this->GetY()+10,
this->GetZ(), this->GetHeading());
by :
NPC* npc = new NPC(npc_type, 0, 0,
this->GetX()+10, this->GetY()+10,
this->GetZ(), this->GetHeading());
line 6094 :
replace :
NPC* horse = new NPC(npc_type, 0, GetX(), GetY(), GetZ(), GetHeading());
by :
NPC* horse = new NPC(npc_type, 0, 0, GetX(), GetY(), GetZ(), GetHeading());
in zone.cpp :
line 383 :
after :
spawn_group_list = new SpawnGroupList();
add :
spawnarea_list = new SpawnAreaList();
2 lines below :
replace :
if (!database.PopulateZoneLists(short_name, &zone_point_list, spawn_group_list))
by :
if (!database.PopulateZoneLists(short_name, &zone_point_list, spawn_group_list, spawnarea_list))
line 699 :
before :
list<timers*>::iterator iterator1 = TimerList.begin();
add :
spawnarea_list->Process();
line 779 :
after :
bool Zone::Depop() {
add :
spawnarea_list->Depop();
line 788 :
after :
entity_list.Message(0, 0, "<SYSTEM_MSG>:Zone REPOP IMMINENT");
add :
spawnarea_list->Repop();
line 959 :
replace :
bool Database::PopulateZoneLists(const char* zone_name, LinkedList<ZonePoint*>* zone_point_list, SpawnGroupList* spawn_group_list) {
by :
bool Database::PopulateZoneLists(const char* zone_name, LinkedList<ZonePoint*>* zone_point_list, SpawnGroupList* spawn_group_list, SpawnAreaList* spawnarea_list ) {
line 999:
after :
{
cerr << "Error3 in PopulateZoneLists query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
add :
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 :
npc_loaded[i] = new NPC(&gmspawntype_dump[npc_dump[i].gmspawntype_inde x], tmp, npc_dump[i].x, npc_dump[i].y, npc_dump[i].z, npc_dump[i].heading, npc_dump[i].corpse);
by :
npc_loaded[i] = new NPC(&gmspawntype_dump[npc_dump[i].gmspawntype_inde x], 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 :
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 :
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 :
#ifndef GUILDWARS
LinkedList<Spawn2*> spawn2_list; // CODER new spawn list
#endif
add :
SpawnAreaList* spawnarea_list;
in database.h :
line 51 :
after :
class Spawn2;
add :
class SpawnArea;
class SpawnAreaList;
line 196 :
replace :
bool PopulateZoneLists(const char* zone_name, LinkedList<ZonePoint*>* zone_point_list, SpawnGroupList* spawn_group_list);
by :
bool PopulateZoneLists(const char* zone_name, LinkedList<ZonePoint*>* zone_point_list, SpawnGroupList* spawn_group_list, SpawnAreaList* spawnarea_list);
in parser.cpp :
line 738 :
replace :
NPC* npc = new NPC(tmp, 0, atof(arglist[3]), atof(arglist[4]), atof(arglist[5]), mob->CastToClient()->GetHeading());
by :
NPC* npc = new NPC(tmp, 0, 0, atof(arglist[3]), atof(arglist[4]), atof(arglist[5]), mob->CastToClient()->GetHeading());
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.