Login
User Name:

Password:



Register
Forgot your password?
LOP 1.39r1
Author: Remcon
Submitted by: Remcon
Yaeger areas
Author: Yaeger
Submitted by: Cyberthrope
The City of Anon
Author: Yaeger
Submitted by: Cyberthrope
The Walls of Anon - Smaug
Author: Yaeger
Submitted by: Cyberthrope
LOP 1.39
Author: Remcon
Submitted by: Remcon
CommonCrawl, Yahoo!, Google

Members: 0
Guests: 1
Stats
Files
Topics
Posts
Members
Newest Member
375
3,323
16,514
561
Aurin
Affiliates
Smaug Building Institute Arthmoor
» SmaugMuds.org » Codebases » AFKMud Support & Development » Possible problem with AFKmud ...
Forum Rules | Mark all | Recent Posts

Possible problem with AFKmud and resets on overland
< Newer Topic :: Older Topic >

Pages:<< prev 1 next >>
Post is unread #1 Oct 16, 2008, 2:53 am   Last edited Oct 16, 2008, 3:58 am by Keberus
Go to the bottom of the page Go to the top of the page


Keberus
Conjurer
GroupFUSS Project Team
Posts341
JoinedJun 4, 2005
WWW AIM MSN

I recently added in overland maps to my FotE based mud (thanks Samson for the snippet ). As usual I was using AFKmud (v1.8) as a reference (thanks again Samson et all ). Anyways, after I got most of the kinks worked out I decided to use AFK's style resets, since my mud uses the newer reset system anyways. So, I changed all the necessary stuffs but noticed something odd once I was done. If you are on a map, and you instaroom, only the resets for the coords you are at stayed. I don't know if it's really a bug or just a workaround for people who didn't want that to be the case. At any rate, I realized it was because when you instaroom, before the resets are added the code calls wipe_resets. Well when on a map, that isn't a good idea since you really are just in the same room. I checked 2.03 and couldn't find anything since I know 1.8 isn't being developed. I kinda threw togother a "fix" for 2.03.

My suggestion is a function like this in roomindex.cpp
void room_index::wipe_coord_resets( short map, short x, short y )
{
   reset_data *pReset;
   list < reset_data * >::iterator rst;

   for( rst = resets.begin(  ); rst != resets.end(  ); )
   {
      pReset = *rst;
      ++rst;
      if( (pReset->arg4 == map) && ( pReset->arg5 == x ) && ( pReset->arg6 == y ) )
      {
          resets.remove( pReset );
          delete_reset( pReset );
      }
   }
}


and in reset.cpp function do_instaroom change:
   if( !ch->in_room->resets.empty() )
      ch->in_room->wipe_resets();


to read as:
   if( !ch->in_room->resets.empty() && ch->has_pcflag(PCFLAG_ONMAP) )
      ch->in_room->wipe_coord_resets( ch->map, ch->mx, ch->my );
   else if( !ch->in_room->resets.empty() )
      ch->in_room->wipe_resets();


Or something similar to that, which should then just delete the resets in the room that have the same coords as the character doing the instaroom. Sorry if my C++ is off, I am not too familar with it.

Later,
KeB .........................
Co-Owner/ Coder
Star Wars: Infinite Galaxy
www.t-n-k-games.com
       
Post is unread #2 Oct 16, 2008, 2:49 pm
Go to the bottom of the page Go to the top of the page


Samson
Scaly but Handsome
GroupAdministrators
Posts3,434
JoinedJan 1, 2002
WWW

Nice catch. I don't think I ever had occasion to try instaroom while standing on the overland. I'll throw this in with the update I was about to package.

And your C++ looks fine. I doubt I'm exactly doing things right with it myself :) .........................
PDNS-Admin | Sandbox | Arthmoor MUD Hosting Services | The Truth About Medievia: A Saga of Code Theft.

"The past was erased, the erasure was forgotten, the lie became truth." -- George Orwell, 1984
       
Post is unread #3 Oct 17, 2008, 1:18 am   Last edited Oct 17, 2008, 1:33 am by Caius
Go to the bottom of the page Go to the top of the page


Caius
Magician
GroupMembers
Posts118
JoinedJan 29, 2006
WWW

Keberus said:


void room_index::wipe_coord_resets( short map, short x, short y )
{
   reset_data *pReset;
   list < reset_data * >::iterator rst;

   for( rst = resets.begin(  ); rst != resets.end(  ); )
   {
      pReset = *rst;
      ++rst;
      if( (pReset->arg4 == map) && ( pReset->arg5 == x ) && ( pReset->arg6 == y ) )
      {
          resets.remove( pReset );
          delete_reset( pReset );
      }
   }
}



Looks like a perfectly reasonable function. Generally speaking you might want to consider using algorithms rather than writing explicit loops, because it's less error prone, often more efficient and can make the code look clear and straight forward (and simply because I like them :biggrin:). I'll first write a suggested version, then offer some brief explanation of what's going on.

#include <functional>

// Predicate function object
class CoordResetDeleter : public std::unary_function< reset_data*, bool >
{
public:
  CoordResetDeleter( int m, int x, int y ) : _map( m ), _x( x ), _y( y ) { }

  bool operator()( reset_data *pReset ) const
  {
    if( pReset->arg4 == _map && pReset->arg5 == _x && pReset->arg6 == _y )
    {
      delete pReset;
      return true;
    }

    return false;
  }

private:
  int _map;
  int _x;
  int _y;
};

// room_index member function
void room_index::wipe_coord_resets( short map, short x, short y )
{
  resets.remove_if( CoordResetDeleter( map, x, y ) );
}

The list.remove_if member function calls the predicate function in its argument for each element in the list (or operator() in the case of function objects). In this case we pass the conditions (map, x and y) to the constructor. If we didn't need to store these variables then we could have used a function instead of a function object.

We inherit from the std::unary_function template, because it creates some typedefS and such that are needed when using it with some STL algorithms, so it's generally a good habit to do it. You'll usually need to include the <functional> header for this.

My choice of name (CoordResetDeleter) is probably not the best. Try finding something that makes the line resets.remove_if( condition_is_fullfilled ) crystal clear to a human reader.

You can often reuse such predicate function classes in many different contexts, so it's definitely worth your time looking into it.

Oh, and a standard disclaimer, I've not tested the above code, may contain typos, etc etc.

Edit: of course with this solution you don't actually need the room_index::wipe_coord_resets member function, you can just call room->resets.remove_if directly in the client code. Unless the resets list is private, that is.
       
Pages:<< prev 1 next >>

 
Contact Us