Welcome to the Builder Academy

Question Create "Guard" Skill (Automatic Rescue)

More
22 Jan 2022 01:18 #9981 by jandulio
I would like to create a "Guard" skill that will automatically "Rescue" someone if they are being attacked.  This skill should last the duration of the player being logged or until they type "guard self".  (Note that the Rescue skill already exists)

Possible ways to do it, with questions:

1) Create a global list of players that are guarding, and run that list every X seconds to check to see if they need to rescue.  Is something like this thread safe?
2) Add a "guarding" field to one of the player structs and keep a pointer to the player they are guarding.  Then simply check that every X seconds and rescue if needed.

There may be other more "CircleMUD" ways of doing this, so I'm hoping someone can help me out. TIA!

Please Log in or Create an account to join the conversation.

More
22 Jan 2022 09:40 #9983 by jandulio
I *think* I figured it all out. If a tbaMUD God could confirm that what I'm doing is okay, that would be great!

What I did:
I ended up using char_data->player_specials that includes 2 new variables for holding who I am guarding, and who is guarding me. (Need both so I can link/unlink properly for changing guards, leaving game, etc.).

My questions:
1) Is it okay to use the player_specials struct within char_data for my own purposes?
2) When I leave the game, I need to unlink. I am doing that in handler.c::extract_char(). Is that the right place? To be safe, I also put it in db.c::free_char() after the check for (ch->player_specials) is not null.

Thanks a MILLION if someone can reply.

Please Log in or Create an account to join the conversation.

More
22 Jan 2022 22:16 #9984 by thomas
I think your idea sounds great.

You'll need to decide if you want mobs to ever be able to guard each other, for instance based on scripts. If not, then just go ahead using player_specials. Otherwise, I'd use char_specials, both NPCs and PCs have those.

Setting up "guarding/guarded_by"-pointers is a decent way, but it limits you in some ways; only one can ever guard a particular player.

Another option would be to simply add a flag "guarded" to the one that is being protected and loop through local (in_room) players to see if they are guarding this particular target if they are being hit in a fight. The list of players in a room is short and quick to traverse. I'd disallow guarding if you were being guarded as well as guarding someone who is already guarding someone else, to prevent loops.
This would also mean an additional lookup on every disconnect through all players, but that full loop would happen much more rarely.

Yet another option is to duplicate the functionality for followers (following/follow_struct-list of followers). But this is much more complicated and error-prone; the following-mechanic has been a frequent source of bugs.

Please Log in or Create an account to join the conversation.

More
22 Jan 2022 23:02 - 23 Jan 2022 03:43 #9987 by jandulio
Thank you so much for the info, it helps A LOT.

The idea of only having "guarded" is a good one. Believe it or not, I originally started that way, but there were some issues that I can't quite recall. I'll head back and see why I thought I needed "guarded by" and changed it.

I didn't even think of loops, so I'll definitely address that!

I thought of the follow code early on and decided against it... well because of the reasons you stated.

Oh, do you know if extract_char() and free_char() are the correct spots to check for unlinking? Should it only to be in one of them? Or would free char() would suffice?

Thanks again so much. I'm so glad I have some help!
Last edit: 23 Jan 2022 03:43 by jandulio.

Please Log in or Create an account to join the conversation.

More
23 Jan 2022 15:01 #9988 by thomas
I would do it in extract_char() which has the purpose of "disconnecting" a char-structure from other objects. free_char() is then called to free the used memory.
Note that there are a couple of special cases you'll need to address when going for the "guarded" flag approach:
1. if there are multiple followers, the guarded flag should stay on if one of them disconnects.
2. if a guarded player disconnects, should guarding characters be notified with a "you stop guarding <name or someone>."?
3. What if I "guard" an NPC?

By the way, just noticed the question about thread safety; you don't need to worry - tbamud (as circlemud before it) is singlethreaded.
The following user(s) said Thank You: jandulio

Please Log in or Create an account to join the conversation.

More
23 Jan 2022 16:16 #9989 by jandulio
Thank you for these corner cases! I will definitely take a look at them. I was already checking for NPC, but the others will need to be looked into.

I'm still vetting the system but it seems to be working well with multiple players trying to guard, players leaving, etc. I'll let you know if anything comes up!

Single threaded, good to hear.

Thanks again SO MUCH!!!

Please Log in or Create an account to join the conversation.

Time to create page: 0.282 seconds