Seifert69 / DikuMUD3

DikuMUD III using HTML and websockets.
GNU Lesser General Public License v2.1
192 stars 48 forks source link

Bugfixes and improvements to the clan system. #360

Closed bonnedav closed 1 year ago

bonnedav commented 1 year ago

Changes include:

Seifert69 commented 1 year ago

@bonnedav I need your help please. I'm unsure what this PR does. My primary confusion is why it is a "command". Would it not be better simply to call the clan_update() command for each player when they login?

It seems like the clans are not setup in the distribution. When I am logged in as Papi and I try to run the cupdate command I get the log error:

(LOG: load_string(): File does not exist: ../lib/clan/strings/clan.delete) (LOG: _players/01: Error in clan.delete)

I'm wondering if we maybe should setup a single working clan zone in the distribution? (I wouldn't know how to do that).

bonnedav commented 1 year ago

The issue i am trying to solve with cupdate is that currently when a player is removed from a clan while they are offline, they are only removed from the clan's roster and retain the clan extras. This levees them with access to the clan that they should not have because most commands only check the extras and not the roster. I have it running a command on login because I am not sure how to execute a DIL function on a player directly, the code should work either way. The clan.delete file stores the players who need to have their clan extras removed once they login, it is only supposed to exist while there are players who still need to be cleaned up. I have it remove the file if it updates the last player in the list because the save function won't save an empty file.

Seifert69 commented 1 year ago

Thanks for the explanation, that makes sense. I would like it to not be a command, but simply be a clean-up that we can call at login time. Could I ask you to modify the code a bit with my help?

We should change the command function from this:

dilbegin cupdate (arg:string);

to something like this:

dilbegin cupdate(pc : unitptr);

and then replace all "self" in your code with "pc".

and then in basis.zon, replace this line:

exec("cupdate", self);

with this line:

cupdate@clans(self);

(Looking at this I suppose that you don't have change self->pc since it's self already when called, but it's kind of nice to be able to call it from anywhere)

In basis.zon where you call cupdate, you need to add:

external
    cupdate@clans(pc : unitptr);

in the function where you call cupdate.

And then 'undo' the command changes.

Ping me on Discord or mail me if you have questions. If you want me to do it, that's OK too. I really appreciate your help. Thanks!

bonnedav commented 1 year ago

I have made the changes locally, however the str functions in cupdate now use the strings directory for basis.zon rather then the one for clans.zon, meaning that it cannot read or write the same clan.update file as the cremove command does.

Seifert69 commented 1 year ago

Sorry about leading you astray there. Bug or feature? I better not change that behavior. Would you mind trying this instead:

Remove parameters for cupdate() and use 'self' as you did before:

dilbegin cupdate();

In basis.zon, copy that DIL program to run on the player like this:

dilcopy("cupdate@clans()", self); // This will copy the cupdate program onto the player and will execute shortly after

bonnedav commented 1 year ago

I have made, tested, and committed the requested changes. Can you explain what was going on with the str functions when I did it the first way please. I plan to make further updates and improvements to clans and other systems in the future so any information you could provide on quirks like that is greatly appreciated. Thank you.

Seifert69 commented 1 year ago

Thanks for the updates, appreciated. They're being merged now.

Regarding the help file, please edit those on the WIKI. I'll pull them into the game's help. There's a script that I run once in a while.

I'm not 100% sure what you're asking, but I think I know, so here's my reply:

Hopefully, it's clear why a command wasn't preferable. I presume it was a hack around calling a function at login.

So there were two things at play. 1) Where does it read the clan files from 2) What is 'self'

The answer to 1) is that the zone of the DIL top-frame (first DIL program to run) determines which folder it looks for files. So if a function in the basis zone calls a function in the clans zone, then we're still in the basis/ zone. That meant we couldn't call cupdate@clans() from the login function. To get around that, we instead copied the cupdate@clans() program onto the player logging in. That means that a moment later, the cupdate program will run. But now it'll run as itself being the top frame, and it isn't called from basis.

The answer to 2 is that all programs run on (any) object in the game. The object it is running on is 'self' in the DIL variables. So when you copy the program onto the player, the 'self' is the player.

Ping me on Discord/builder if you have questions :-)