Results 1 to 8 of 8

Thread: Clean Spawn Points

  1. #1
    Registered User
    Join Date
    Jun 2003
    Posts
    113

    Clean Spawn Points

    I've noticed that we have several things showing up as spawn points that should not. This include mounts, Auras, and Mercenaries. This can make the spawn points in your camp very messy if you have auras you refresh or if you use mercenaries or mounts. I found a thread in the archive on this, but looks like it never got implemented:

    http://www.showeq.net/forums/archive...hp/t-6218.html

    Here's the patch I have so far. Seems to be working but needs more testing. Uses the flags for aura and mercenary that are already in the spawn structure. Aura was part of "OtherData" and I broke out OtherData in everquest.h to make it clear what is where. This will be helpful for when the values move around after a patch. There is no flag for mount so we have two options. First we can parse the name looking for Mount. This is what was done in the archived thread. But I don't really like that method. The existing method was already looking for horse mounts using race and I stuck with that, for now at least, but it means a lot more races added in.

    Let me know if there is any interest in this or any suggestions for changes to it.

    Code:
    Index: src/spawnshell.cpp
    ===================================================================
    --- src/spawnshell.cpp	(revision 784)
    +++ src/spawnshell.cpp	(working copy)
    @@ -601,7 +601,7 @@
        }
        */
     
    -   if(spawn->otherData & 4)	    // aura stuff
    +   if(spawn->aura)	    // aura stuff
        {
            netStream.readText();	// skip 2 variable len strings
            netStream.readText();
    @@ -710,13 +710,13 @@
        spawn->posData[4] = netStream.readUInt32NC();
        spawn->posData[5] = netStream.readUInt32NC();
        
    -   if(spawn->otherData & 16)
    +   if(spawn->hasTitle)
        {
           name = netStream.readText();
           strcpy(spawn->title, name.latin1());
        }
     
    -   if(spawn->otherData & 32)
    +   if(spawn->hasSuffix)
        {
           name = netStream.readText();
           strcpy(spawn->suffix, name.latin1());
    Index: src/spawn.cpp
    ===================================================================
    --- src/spawn.cpp	(revision 784)
    +++ src/spawn.cpp	(working copy)
    @@ -435,6 +435,9 @@
     
       setTypeflag(s->bodytype);
       setGM(s->gm);
    +  setIsMount(calcIsMount(s->race, s->level));
    +  setIsMercenary(s->isMercenary);
    +  setIsAura(s->aura);
     
       // If it is a corpse with Unknown (NPC) religion.
       if ((s->NPC == SPAWN_PC_CORPSE) && (s->deity == DEITY_UNKNOWN))
    @@ -979,6 +982,53 @@
       d << m_lastName;
     }
     
    +bool Spawn::calcIsMount(uint32_t race, uint8_t level)
    +{
    +  bool isMountRace;
    +  switch (race)
    +  {
    +	case 216: //Horse
    +	case 348: //Drogmore
    +	case 517: //Nightmare/Unicorn
    +	case 518: //Horse
    +	case 519: //Nightmare/Unicorn
    +	case 594: //Worg
    +	case 623: //Wrulon Mount
    +	case 625: //Sokokar Mount
    +	case 631: //Hydra Mount
    +	case 652: //Cliknar Mount
    +	case 654: //Spider Mount
    +	case 655: //Bear Mount
    +	case 656: //Rat Mount
    +	case 657: //Sessiloid Mount
    +	case 671: //Topiary Lion Mount
    +	case 672: //Rot Dog Mount
    +	case 673: //Goral Mount
    +	case 674: //Selyran Mount
    +	case 675: //Sclera Mount
    +	case 676: //Braxy Mount
    +	case 677: //Kangon Mount
    +	case 679: //Wurm Mount
    +	case 682: //Helicopter backpack
    +	case 684: //Steam Escalator
    +	case 709: //Skystrider
    +	case 721: //Severed Hand
    +      isMountRace = true;
    +	  break;
    +	default:
    +	  isMountRace = false;
    +	  break;
    +  }
    +  if (level == 30 && isMountRace)
    +  {
    +	  return true;
    +  }
    +  else
    +  {
    +	  return false;
    +  }
    +}
    +
     //----------------------------------------------------------------------
     // Door
     Door::Door(const doorStruct* d)
    Index: src/spawnmonitor.cpp
    ===================================================================
    --- src/spawnmonitor.cpp	(revision 784)
    +++ src/spawnmonitor.cpp	(working copy)
    @@ -229,7 +229,7 @@
     void SpawnMonitor::checkSpawnPoint(const Spawn* spawn )
     {
       // ignore everything but mobs
    -  if ( ( spawn->NPC() != SPAWN_NPC ) || ( spawn->petOwnerID() != 0 ) || (spawn->level() == 30 && spawn->race() == 216) )
    +  if ( ( spawn->NPC() != SPAWN_NPC ) || ( spawn->petOwnerID() != 0 ) || spawn->isMount() || spawn->isAura() || spawn->isMercenary() )
         return;
       
       QString		key = SpawnPoint::key( *spawn );
    Index: src/spawn.h
    ===================================================================
    --- src/spawn.h	(revision 784)
    +++ src/spawn.h	(working copy)
    @@ -284,6 +284,12 @@
         { return (raceTeam() == spawn->raceTeam()); }
       bool isSameDeityTeam(const Spawn* spawn) const
         { return (deityTeam() == spawn->deityTeam()); }
    +  bool isMount() const
    +    { return m_isMount; }
    +  bool isAura() const
    +    { return m_isAura; }
    +  bool isMercenary() const
    +    { return m_isMercenary; }
     
       // virtual set method overload
       void setPos(int16_t x, int16_t Pos, int16_t z,
    @@ -323,6 +329,9 @@
       void setNPC(uint8_t NPC) { m_NPC = NPC; }
       void setTypeflag(uint8_t typeflag) { m_typeflag = typeflag; }
       void setGM(uint8_t gm) { m_gm = gm; }
    +  void setIsMount(bool isMount) { m_isMount = isMount; }
    +  void setIsMercenary(uint8_t isMercenary) {m_isMercenary = (isMercenary != 0); }
    +  void setIsAura(unsigned aura) {m_isAura = (aura != 0); }
       void setID(uint16_t id) { m_ID = id; }
       void setLastName(const char * lastName)
         { m_lastName = QString::fromUtf8(lastName); }
    @@ -334,6 +343,7 @@
      protected:
       void calcRaceTeam();
       void calcDeityTeam();
    +  bool calcIsMount(uint32_t, uint8_t);
     
       // spawn specific data
       QString m_lastName;
    @@ -364,6 +374,9 @@
       uint8_t m_typeflag;
       uint8_t m_animation;
       uint8_t m_gm;
    +  bool m_isMount;
    +  bool m_isMercenary;
    +  bool m_isAura;
       bool m_considered;
       bool m_notUpdated;
     };
    Index: src/everquest.h
    ===================================================================
    --- src/everquest.h	(revision 784)
    +++ src/everquest.h	(working copy)
    @@ -1053,11 +1053,25 @@
                  unsigned   targetcyclable:1;
                  unsigned   padding1:2;
                  unsigned   trader:1;
    -             unsigned   buyer:1;
    +             unsigned   padding8:1;
                };
                int32_t miscData;
              };
    -/*0000*/ uint8_t  otherData;                     // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
    +/*0000*/ union
    +         {
    +	       struct
    +	       {
    +	    	 unsigned  buyer:1;
    +	    	 unsigned  offline:1;
    +	    	 unsigned  aura:1;
    +	    	 unsigned  padding9:1;
    +	    	 unsigned  hasTitle:1;
    +	    	 unsigned  hasSuffix:1;
    +	    	 unsigned  padding10:1;
    +	    	 unsigned  padding11:1;
    +	       };
    +	       uint8_t  otherData;
    +         };
     /*0000*/ uint32_t race;
     /*0000*/ uint8_t  charProperties;
     /*0000*/ uint32_t bodytype;

  2. #2
    Registered User
    Join Date
    Jun 2003
    Posts
    113

    Re: Clean Spawn Points

    Did some testing on this last night and it seems to be working well. No more spawn points for auras, mercenaries or mounts. All other spawn points seem to still be coming up fine. I'm sure I don't have all the mount races yet, but those can be added as we find them.

  3. #3
    Developer
    Join Date
    Jul 2004
    Posts
    920

    Re: Clean Spawn Points

    That looks like a good patch to my old eyes. That race switch does't look that bad to me if there is no discernable flag for mounts. Do you have to do the level == 30 part?

    Are there are handlers that modify race? The illusion handler or the shroud handler? Any of the spawn update handlers? I guess things don't ever change into a mount or an aura so maybe it's not a big deal.

    Helicopter backpack!??!

  4. #4
    Registered User
    Join Date
    Jun 2003
    Posts
    113

    Re: Clean Spawn Points

    There are some specific races which are mount only. For example: Spider Mount. However there are others that can be mounts or non-mounts. For example, Worg. The level = 30 check is just a safety in case a race is for both mount and other NPCs to prevent removing the spawn point for a non-mount instance of the race.

    I hadn't thought to check for other flags that may indicate mount. I don't expect to find anything, but it's at least worth a look.

    I didn't get the real name for "Helicopter backpack". As I was testing things out I noted there was a player with mount I didn't have raceID for yet. I added the ID then headed over to see what the mount was. I saw it looked like a backpack with helicopter prop on top, but the player zoned before I could get it's real name from his buff. It's not one I was able to find in station cash store, so I'm not sure where else I may look for proper name.

  5. #5
    Registered User
    Join Date
    Jun 2003
    Posts
    113

    Re: Clean Spawn Points

    Well I parsed out all the spawns from a 5 hour log file looking at every variable pulled out by fillSpawnStruct. There is no unique variable or combination of variables that can be used to uniquely identify a mount based on those variables. There are some common values among mounts, like State is always 100 or 102 and Body Type is always 21, but those things are also true of other NPCs that aren't mounts. It may be something that isn't parsed out by fillSpawnStruct (one of the skips maybe) could help, but I didn't dig that far. This leaves me with 2 options:
    1. Parse on the name looking for something ending in Mount.
    2. What I have done above which is level = 30 and race = a mount race. I was able to add in another 5 or so mount races based on this last parse.
    Code:
    	case 216: //Horse
    	case 348: //Drogmore
    	case 492: //Horse
    	case 517: //Nightmare/Unicorn
    	case 518: //Horse
    	case 519: //Nightmare/Unicorn
    	case 583: //Kirin
    	case 584: //Puma
    	case 594: //Worg
    	case 597: //Cragslither
    	case 598: //Wrulon
    	case 623: //Wrulon Mount
    	case 625: //Sokokar Mount
    	case 631: //Hydra Mount
    	case 652: //Cliknar Mount
    	case 654: //Spider Mount
    	case 655: //Bear Mount
    	case 656: //Rat Mount
    	case 657: //Sessiloid Mount
    	case 671: //Topiary Lion Mount
    	case 672: //Rot Dog Mount
    	case 673: //Goral Mount
    	case 674: //Selyran Mount
    	case 675: //Sclera Mount
    	case 676: //Braxy Mount
    	case 677: //Kangon Mount
    	case 679: //Wurm Mount
    	case 680: //???
    	case 682: //Helicopter backpack
    	case 684: //Steam Escalator
    	case 709: //Skystrider
    	case 720: //???
    	case 721: //Severed Hand
    Maybe I'm crazy but I still prefer the level and race option over parsing the name.

  6. #6
    Developer
    Join Date
    Jul 2004
    Posts
    920

    Re: Clean Spawn Points

    Yeah I think that is your best bet too. It just is kludgy. That doesn't necessarily mean don't do it!

    Something has to hook a person to a mount. It would be interesting to collect packet dumps for:
    1) Zoning into an empty-ish zone to that has someone in it who is on horse compared to zoning into an empty-ish zone that has the same guy not on a horse
    2) What packets show up when someone summons a horse? Do you receive movements packets for both the horse and the person? Just the server combine the mount + player into a single mob?

    I wonder if the mount code is specialized pet code and there is an owner spawn id somewhere.

    Anyways, don't take my yammering too seriously. What you have is good enough to check in.

  7. #7
    Registered User
    Join Date
    Jun 2003
    Posts
    113

    Re: Clean Spawn Points

    Hmm, I hadn't thought about testing it that way. I may go ahead with it as is for now, but I still want to investigate further. Guild Hall makes a good empty place to play in now. I'll sit a char in and see the difference on the zone in packets between them being mounted vs not mounted. You're right in that there has to be something tying the two of them together. Otherwise we'd never get the graphic of the person sitting on the horse.

  8. #8
    Registered User
    Join Date
    Jun 2003
    Posts
    113

    Re: Clean Spawn Points

    The only difference in the spawn structure between a mounted and unmounted player is in the bytes in the position data. Checking the position data value the only change is in Z, which isn't surprising since a mounted player is a little higher off the ground. Even checked the padding in the position data and that didn't change. This is comparing the full log entries, so can say for sure nothing in the player's spawn structure ties it to the mount. This means the mount's spawn structure must tie it to the player. I expect the value is hidden somewhere in the bytes that are skipped reading the spawn structure. Maybe I can find the player's ID in there.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

You may post new threads
You may post replies
You may post attachments
You may edit your posts
HTML code is Off
vB code is On
Smilies are On
[IMG] code is On