Ah, yes they would, cause it's gotta go through every player and do a circle compare on their x/y, right?
Here are the instructions for the current code I have. This isn't the best code, but it seems to work ok. It still needs a lot of work, and is nowhere near production ready, this is for devs only. You'll need to import the attached SQL file into your database. I'll be throwing this into the SVN (Unactivated, of course, so it won't actually affect anything) at some point, just need to double check that I have all the #ifdef's I need in there properly
This is now in the SVN, but disabled (uncomment the #define in sockets.h to enable it). Attached is also a picture of what the old spawn system looks like at the same place where I took a picture of my spawn system.
So, a few things that need working on. Fish swim on land, this is a problem with the current mob movement system I think. Not sure what other problems there are, if you run into any let me know.
[Update]
I just updated this to the current system implemented in OSpRose
[Update #2]
Ok, so tac mobs only spawn after tacPoint basic mobs have been killed. Also it now uses the amount field in mobs to spawn multiple of the same mob.
DataTypes.h
--------------------
Find:
Before, Add:
- #ifdef USEIFO
- struct CMob {
- UINT id;
- UINT mobId;
- bool tactical;
- UINT amount;
- CNPCData* thisnpc;
- CMDrops* mobdrop;
- CMDrops* mapdrop;
- };
-
- struct CMobGroup {
- UINT id;
- UINT map;
- UINT limit;
- UINT active;
- UINT tacticalpoints;
- UINT respawntime;
- UINT basicKills;
- fPoint point;
- UINT range;
- clock_t lastRespawnTime;
- vector<CMob*> basicMobs;
- vector<CMob*> tacMobs;
- };
- #endif
ExtraFunctions.cpp
--------------------
Find:
- // delete a spawn
- bool CWorldServer::DeleteSpawn( CSpawnArea* spawn )
Before, Add:
- #ifdef USEIFO
- CMobGroup* CWorldServer::GetMobGroup(UINT id, UINT map ) {
- if (map != 0) {
- for (unsigned j = 0; j < MapList.Index[map]->MobGroupList.size(); j++) {
- CMobGroup* thisgroup = MapList.Index[map]->MobGroupList.at(j);
- if (thisgroup->id == id)
- return thisgroup;
- }
- } else {
- for (map = 0; map < MapList.Map.size(); map++) {
- for (unsigned j = 0; j < MapList.Index[map]->MobGroupList.size(); j++) {
- CMobGroup* thisgroup = MapList.Index[map]->MobGroupList.at(j);
- if (thisgroup->id == id)
- return thisgroup;
- }
- }
- }
- return NULL;
- }
- #endif
Find:
- if( id = thisnpc->id ){return thisnpc;}
Replace With:
- if( id == thisnpc->id ){return thisnpc;}
MapFunctions.cpp
------------------
Find:
- void CMap::RespawnMonster( )
- {
After, Add:
Find (Last closing bracket for the function):
Before, Add:
- #else
- for (UINT j = 0; j < MobGroupList.size(); j++) {
- CMobGroup* thisgroup = MobGroupList.at(j);
- clock_t rtime = clock() - thisgroup->lastRespawnTime;
- if (rtime < thisgroup->respawntime*CLOCKS_PER_SEC || thisgroup->active >= thisgroup->limit)
- continue;
- for (UINT k = thisgroup->active; k < thisgroup->limit; k++) {
- CMob *thismob;
- if (thisgroup->tacMobs.size() > 0 && thisgroup->basicKills > thisgroup->tacticalpoints) {
- UINT mobId = (UINT)(rand() % thisgroup->tacMobs.size());
- thismob = thisgroup->tacMobs.at(mobId);
- thisgroup->basicKills = 0;
- } else {
- UINT mobId = (UINT)(rand() % thisgroup->basicMobs.size());
- thismob = thisgroup->basicMobs.at(mobId);
- }
- for (UINT i = 0; i < thismob->amount; i++) {
- fPoint position = GServer->RandInCircle( thisgroup->point, thisgroup->range );
- AddMonster( thismob->mobId, position, 0, thismob->mobdrop, thismob->mapdrop, thisgroup->id );
- }
- }
- }
- #endif
Startup.cpp
-----------------
Find:
- bool CWorldServer::LoadMonsterSpawn( )
Before, Add:
- #ifdef USEIFO
- bool CWorldServer::LoadMobGroups() {
- Log(MSG_LOAD, "MobGroups data " );
- vector<CMobGroup*> mobGroups;
- MYSQL_ROW row;
- bool flag = true;
- char* tmp = NULL;
- MYSQL_RES *result = DB->QStore("SELECT id, map, x, y, range, respawntime, `limit`, tacticalpoints, moblist FROM list_mobgroups");
- if (result == NULL) return false;
- while (row = mysql_fetch_row(result)) {
- CMobGroup* thisgroup = new (nothrow) CMobGroup;
- if (thisgroup == NULL) {
- Log(MSG_ERROR, "Error allocating memory");
- DB->QFree();
- return false;
- }
- thisgroup->id = atoi(row[0]);
- thisgroup->map = atoi(row[1]);
- thisgroup->point.x = atof(row[2]);
- thisgroup->point.y = atof(row[3]);
- thisgroup->range = atoi(row[4]);
- thisgroup->respawntime = atoi(row[5]);
- thisgroup->limit = atoi(row[6]);
- thisgroup->tacticalpoints = atoi(row[7]);
- char* mobList = row[8];
-
- thisgroup->lastRespawnTime = clock();
- thisgroup->active = 0;
-
- thisgroup->basicMobs.clear();
- thisgroup->tacMobs.clear();
-
- // Fill in basic/tac mobs
- tmp = strtok(mobList, ",|");
- while (tmp != NULL) {
- int mobId = atoi(tmp);
- tmp = strtok(NULL, ",|");
- if (tmp == NULL) {
- Log(MSG_ERROR, "MobGroup %i is invalid", thisgroup->id);
- flag = false;
- break;
- }
- int amount = atoi(tmp);
- tmp = strtok(NULL, ",|");
- if (tmp == NULL) {
- Log(MSG_ERROR, "MobGroup %i is invalid", thisgroup->id);
- flag = false;
- break;
- }
- int tactical = atoi(tmp);
- CMob *thismob = new (nothrow) CMob;
- if (thismob == NULL) {
- Log(MSG_ERROR, "Error allocating memory");
- DB->QFree();
- return false;
- }
- thismob->amount = amount;
- thismob->tactical = tactical;
- thismob->mobId = mobId;
- thismob->thisnpc = GetNPCDataByID( thismob->mobId );
- thismob->mapdrop = GetDropData( thisgroup->map );
- thismob->mobdrop = GetDropData( thismob->thisnpc->dropid );
- if (thismob->thisnpc == NULL) {
- Log(MSG_WARNING, "Invalid mobId - Mob %i will not be added", atoi(row[0]));
- delete thismob;
- continue;
- }
- if (thismob->tactical)
- thisgroup->tacMobs.push_back(thismob);
- else
- thisgroup->basicMobs.push_back(thismob);
- tmp = strtok(NULL, ",|");
- }
- if (!flag) {
- delete thisgroup;
- continue;
- }
- MapList.Index[thisgroup->map]->MobGroupList.push_back(thisgroup);
- mobGroups.push_back(thisgroup);
- }
- DB->QFree( );
- return true;
- }
- #endif
Find:
- bool CWorldServer::LoadMonsters( )
- {
- Log( MSG_LOAD, "Monsters Spawn " );
- // Do our monster spawnin
After, Add:
Find:
Before, Add:
- #else
- for (UINT i = 0; i < MapList.Map.size(); i++) {
- CMap *thismap = MapList.Map.at(i);
- for (UINT j = 0; j < thismap->MobGroupList.size(); j++) {
- CMobGroup* thisgroup = thismap->MobGroupList.at(j);
- // Load some basic mobs onto map
- for (UINT k = 0; k < thisgroup->limit; k++) {
- UINT mobId = (UINT)(rand() % thisgroup->basicMobs.size());
- CMob* thismob = thisgroup->basicMobs.at(mobId);
- for (UINT l = 0; l < thismob->amount; l++) {
- fPoint position = RandInCircle( thisgroup->point, thisgroup->range );
- thismap->AddMonster( thismob->mobId, position, 0, thismob->mobdrop, thismob->mapdrop, thisgroup->id );
- }
- }
- }
- }
- #endif
Find:
- newzone->MonsterSpawnList.clear();
After, Add:
- #ifdef USEIFO
- newzone->MobGroupList.clear();
- #endif
WorldMap.cpp
----------------
Find:
- MonsterSpawnList.clear();
After, Add:
- #ifdef USEIFO
- MobGroupList.clear();
- #endif
Find:
- delete RespawnList.at(i);
After, Add:
- #ifdef USEIFO
- for(UINT i = 0; i < MobGroupList.size(); i++) {
- CMobGroup *thisgroup = MobGroupList.at(i);
- for (UINT j = 0; j < thisgroup->basicMobs.size(); j++)
- delete thisgroup->basicMobs.at(j);
- for (UINT j = 0; j < thisgroup->tacMobs.size(); j++)
- delete thisgroup->tacMobs.at(j);
- delete thisgroup;
- }
- #endif
Find:
- CSpawnArea* thisspawn = GServer->GetSpawnArea( spawnid, this->id );
- if(thisspawn!=NULL)
- thisspawn->amon++;
Replace With:
- #ifndef USEIFO
- CSpawnArea* thisspawn = GServer->GetSpawnArea( spawnid, this->id );
- if(thisspawn!=NULL)
- thisspawn->amon++;
- #else
- CMobGroup* thisgroup = GServer->GetMobGroup( spawnid, this->id );
- if(thisgroup!=NULL)
- thisgroup->active++;
- #endif
Find:
- CSpawnArea* thisspawn = GServer->GetSpawnArea( monster->Position->respawn, monster->Position->Map );
- if(thisspawn!=NULL)
- {
- if(thisspawn->amon >= thisspawn->max)// reset spawn timer if the spawn is full
- thisspawn->lastRespawnTime = clock();
- thisspawn->amon--;
- }
Replace With:
- #ifndef USEIFO
- CSpawnArea* thisspawn = GServer->GetSpawnArea( monster->Position->respawn, monster->Position->Map );
- if(thisspawn!=NULL)
- {
- if(thisspawn->amon >= thisspawn->max)// reset spawn timer if the spawn is full
- thisspawn->lastRespawnTime = clock();
- thisspawn->amon--;
- }
- #else
- CMobGroup* thisgroup = GServer->GetMobGroup( monster->Position->respawn, monster->Position->Map );
- if(thisgroup!=NULL)
- {
- if(thisgroup->active >= thisgroup->limit)// reset spawn timer if the spawn is full
- thisgroup->lastRespawnTime = clock();
- thisgroup->active--;
- thisgroup->basicKills++;
- }
- #endif
WorldMap.h
----------------
Find:
- vector<CSpawnArea*> MonsterSpawnList; // Monster spawn in this map
After, Add:
- #ifdef USEIFO
- vector<CMobGroup*> MobGroupList; // Spawn "Zones"
- #endif
WorldServer.cpp
---------------
Find:
Replace With:
- #ifndef USEIFO
- LoadMonsterSpawn( );
- #else
- LoadMobGroups( );
- #endif
WorldServer.h
-----------------
Find:
- CSpawnArea* GetSpawnArea( UINT id, UINT map=0 );
After, Add:
- #ifdef USEIFO
- CMobGroup* GetMobGroup( UINT id, UINT map=0 );
- #endif
Find:
- bool LoadMonsterSpawn( );
After, Add:
- #ifdef USEIFO
- bool LoadMobGroups( );
- #endif
Common/Sockets.h (Only do this to enable the IFO based spawns)
----------------------
Find:
After, Add: