PDA

View Full Version : A nice & clean Spawn Point List



icyman2
06-01-2009, 11:34 AM
So, I am happily camping a_misc_thing00 over the weekend, and with various other groups in the zone camping an_other_misc_thing00, I start to see things in my Spawn Point List I don't want/need/care to see. These things are auras, mounts and mercenaries. The spawn time is a little on the long side for the named I am camping, and I haven't been into SEQ code for years, so here's an excuse to start to familiarize myself again with the code.

(Great to see some smart use of Qt containers/lists, and things properly being handed around via [const] reference, etc, etc. It's looking a lot more professional/efficient than I recall years ago.) :)

So I decide that to match the current style of the classes, I should add a few is*() inline methods to Spawn. Pretty easy, not totally satisfied with my logic, but there doesn't seem to be any "low" level recognition of auras, mounts nor mercenaries. So, I filter based upon the name and class information available.

(When I mention name below, I am referring to Spawn::m_name. Class refers to Spawn::m_class.)

An aura, has "Aura" somewhere in the name, and is class 62 (an LDON Object).

A mount, has a name ending in "s_Mount00", and is level 30 (this seems to be true of any mount).

A mercenary, as far as I can tell, has a name like Bob1234 or Bob12345 (I bet this starts at 001 upon a server restart, but I will probably never be able to check this, I work fulltime, unless I experience a server crash some day). I'd prefer to detect this via some kind of bit from spawnStruct, or wherever (my low level knowledge of these structures is almost non-existant). Since it appears mobs only ever have two digits at the end of their name (ie, 00), it may be ok to filter on any name that ends in 3 or more digits. Dunno, haven't checked this out yet. It currently looks for 4 or more digits (since this is what I have personally seen).

To take advantage of these new checks in the Spawn class, I added a second if to SpawnMonitor::checkSpawnPoint(..). I could (and probably should) have combined those two ifs, as part of the first one attempts to filter on mounts. I've used it all weekend, with no auras, mounts nor mercs in my Spawn Point List, and no crashes in SEQ.

These changes were made against the latest in subversion at the time. (5.13.4.1 / revision 730)


Index: spawnmonitor.cpp
================================================== =================
--- spawnmonitor.cpp (revision 730)
+++ spawnmonitor.cpp (working copy)
@@ -231,7 +231,12 @@
// ignore everything but mobs
if ( ( spawn->NPC() != SPAWN_NPC ) || ( spawn->petOwnerID() != 0 ) || (spawn->level() == 30 && spawn->race() == 216) )
return;
-
+
+ if ( spawn->isMount() == true || spawn->isAura() == true || spawn->isMercenary() == true ){
+ seqWarn("+++ TOSSED -> mount || aura || merc -> %s", spawn->name().ascii());
+ return;
+ }
+
QString key = SpawnPoint::key( *spawn );

SpawnPoint* sp;
Index: spawn.h
================================================== =================
--- spawn.h (revision 730)
+++ spawn.h (working copy)
@@ -284,6 +284,18 @@
{ return (raceTeam() == spawn->raceTeam()); }
bool isSameDeityTeam(const Spawn* spawn) const
{ return (deityTeam() == spawn->deityTeam()); }
+ bool isMount() const {
+ // Example: Bob`s_Mount00
+ return this->m_level == 30 && this->m_name.endsWith("s_Mount00") == true;
+ }
+ bool isAura() const {
+ // Example: Aura_of_the_Zealot00
+ return this->m_class == 62 && this->m_name.contains("Aura") > 0;
+ }
+ bool isMercenary() const {
+ // Example: Bob12345
+ return this->m_name.length() > 5 && this->m_name.right(4).toUInt() > 0;
+ }

// virtual set method overload
void setPos(int16_t x, int16_t Pos, int16_t z,

ieatacid
06-01-2009, 02:56 PM
There's a mercenary flag in the spawn memory struct so it must come from the wire with that flag.

BRB with an easier way to check.

ieatacid
06-01-2009, 03:09 PM
Index: src/everquest.h
================================================== =================
--- src/everquest.h (revision 727)
+++ src/everquest.h (working copy)
@@ -1092,6 +1092,7 @@
};
/*0000*/ char title[32];
/*0000*/ char suffix[32];
+/*0000*/ uint8_t isMercenary;
};

#if 0
@@ -1220,7 +1221,9 @@

/*0000*/ char title[0]; // only read if(hasTitleOrSuffix & 4)
/*0000*/ char suffix[0]; // only read if(hasTitleOrSuffix & 8)
-/*0000*/ char unknown20[32];
+/*0000*/ char unknown20[8];
+/*0000*/ uint8_t isMercenary;
+/*0000*/ char unknown20[24];
};
#endif

Index: src/spawnshell.cpp
================================================== =================
--- src/spawnshell.cpp (revision 724)
+++ src/spawnshell.cpp (working copy)
@@ -624,8 +624,14 @@
strcpy(spawn->suffix,name.latin1());
}

- netStream.skipBytes(33);
+ // unknowns
+ netStream.skipBytes(8);

+ spawn->isMercenary = netStream.readUInt8();
+
+ // unknowns
+ netStream.skipBytes(24);
+
// now we're at the end

retVal=netStream.pos()-netStream.data();

icyman2
06-01-2009, 04:25 PM
Nice! Thanks for that. :)

This patch replaces the one above. I attempted to properly populate the m_mercenary member I added to Spawn in the appropriate places (Spawn::update(), Spawn::Spawn(uint16_t id, ..), etc).

I assumed the value of spawnStruct::isMercenary was 0 if the spawn was not a mercenary, otherwise it was a mercenary.


Index: spawnmonitor.cpp
================================================== =================
--- spawnmonitor.cpp (revision 730)
+++ spawnmonitor.cpp (working copy)
@@ -231,7 +231,12 @@
// ignore everything but mobs
if ( ( spawn->NPC() != SPAWN_NPC ) || ( spawn->petOwnerID() != 0 ) || (spawn->level() == 30 && spawn->race() == 216) )
return;
-
+
+ if ( spawn->isMount() == true || spawn->isAura() == true || spawn->mercenary() != 0 ){
+ seqWarn("+++ TOSSED -> mount || aura || merc -> %s", spawn->name().ascii());
+ return;
+ }
+
QString key = SpawnPoint::key( *spawn );

SpawnPoint* sp;
Index: spawn.h
================================================== =================
--- spawn.h (revision 730)
+++ spawn.h (working copy)
@@ -284,6 +284,18 @@
{ return (raceTeam() == spawn->raceTeam()); }
bool isSameDeityTeam(const Spawn* spawn) const
{ return (deityTeam() == spawn->deityTeam()); }
+ bool isMount() const {
+ // Example: Bob`s_Mount00
+ return this->m_level == 30 && this->m_name.endsWith("s_Mount00") == true;
+ }
+ bool isAura() const {
+ // Example: Aura_of_the_Zealot00
+ return this->m_class == 62 && this->m_name.contains("Aura") > 0;
+ }
+ bool isMercenary() const {
+ // Example: Bob12345
+ return this->m_name.length() > 5 && this->m_name.right(4).toUInt() > 0;
+ }

// virtual set method overload
void setPos(int16_t x, int16_t Pos, int16_t z,
Index: spawn.cpp
================================================== =================
--- spawn.cpp (revision 730)
+++ spawn.cpp (working copy)
@@ -331,6 +331,7 @@
setTypeflag(0);
setGM(0);
setConsidered(false);
+ setMercenary(0);

// turn on auto delete for the track list
m_spawnTrackList.setAutoDelete(true);
@@ -388,6 +389,7 @@
setDeltas(s->deltaX(), s->deltaY(), s->deltaZ());
setHeading(s->heading(), s->deltaHeading());
setConsidered(s->considered());
+ setMercenary(s->mercenary());

// the new copy will own the spawn track list
m_spawnTrackList.setAutoDelete(false);
@@ -452,6 +454,8 @@

setNotUpdated(false);

+ setMercenary(s->isMercenary);
+
// finally, note when this update occurred.
updateLast();
}
@@ -526,6 +530,8 @@
setGuildID(s->guildID);
else
setGuildID(0xffff);
+
+ setMercenary(s->isMercenary);
}

void Spawn::killSpawn()

icyman2
06-01-2009, 06:35 PM
Raiding atm, and I see a "Eye_of_Player00". Another thing to clean up. :) I have a bard, I'll test after raid with his helm & get the stats. Not sure what bits I can look into other than it's an NPC, obviously.

icyman2
06-02-2009, 08:51 AM
Oops, fell asleep after raid - will check it out tonight.

icyman2
06-03-2009, 03:39 PM
Ok, debugging this, the best I could come up with is:

Spawn::m_name == "Eye_of_Player00"
Spawn::m_race == 108 // Eye
Spawn::m_level == 1

So, I added an isEye() to Spawn.h (not very descriptive, I agree).


Index: spawn.h
================================================== =================
--- spawn.h (revision 730)
+++ spawn.h (working copy)
@@ -284,6 +284,22 @@
{ return (raceTeam() == spawn->raceTeam()); }
bool isSameDeityTeam(const Spawn* spawn) const
{ return (deityTeam() == spawn->deityTeam()); }
+ bool isMount() const {
+ // Example: Bob`s_Mount00
+ return this->m_level == 30 && this->m_name.endsWith("s_Mount00") == true;
+ }
+ bool isAura() const {
+ // Example: Aura_of_the_Zealot00
+ return this->m_class == 62 && this->m_name.contains("Aura") > 0;
+ }
+ uint8_t mercenary() const {
+ // Example: Bob12345
+ return this->m_mercenary;
+ }
+ bool isEye() const {
+ // Example: Eye_of_Bob00
+ return this->m_race == 108 && this->m_level ==1 && this->m_name.startsWith(QString("Eye_of_")) == true;
+ }

// virtual set method overload
void setPos(int16_t x, int16_t Pos, int16_t z,
@@ -329,6 +345,7 @@
void setLastName(const QString& lastName)
{ m_lastName = lastName; }
void setNotUpdated(bool notUpdated) { m_notUpdated = notUpdated; }
+ void setMercenary(uint8_t mercenary) { this->m_mercenary = mercenary; }


protected:
@@ -366,6 +383,7 @@
uint8_t m_gm;
bool m_considered;
bool m_notUpdated;
+ uint8_t m_mercenary;
};

Index: spawnmonitor.cpp
================================================== =================
--- spawnmonitor.cpp (revision 730)
+++ spawnmonitor.cpp (working copy)
@@ -231,7 +231,12 @@
// ignore everything but mobs
if ( ( spawn->NPC() != SPAWN_NPC ) || ( spawn->petOwnerID() != 0 ) || (spawn->level() == 30 && spawn->race() == 216) )
return;
-
+
+ if ( spawn->isMount() == true || spawn->isAura() == true || spawn->mercenary() != 0 || spawn->isEye() == true){
+ seqWarn("+++ TOSSED -> mount || aura || merc -> %s", spawn->name().ascii());
+ return;
+ }
+
QString key = SpawnPoint::key( *spawn );

SpawnPoint* sp;

purple
06-04-2009, 07:06 AM
If you're going to parse names, do not do it in isX() const methods, please. Names do not change often enough and the map may want to use these methods for deciding on coloring, an operation that happens very frequently.

Instead, you should use a member variable and parse at the times the names change (i.e. when the spawn is added, spawn rename, etc.).

I much prefer the ieatacid style of actually bothering to find the flag for things. I spent some time trying to find stuff for auras and had a couple leads, but never got a chance to take it anywhere. I know this is harder than parsing strings, but it's going to be mu