Sep. 23rd, 2022

scrottie: (Default)
Boring update. Portlight installed after a quick leak test of the glazing but still need to silicone in the smaller, outer channel (which could hold more glass or plastic but doesn't) or else water doesn't even need to get past the glazing to leak all over. That meant more time with my friend, butyl. Butyl all the things!

Grinding on the part of the hatch, or rather what the hatch sits on, getting ready to put fiberglass on there. That has the original paint by virtue of being hidden under the hatch normally, which is this really thick chaulky stuff, tho it may not have been chaulky 60 years ago, who knows. Got a drip out of an interior screw right under that, so more marine spackle, aka epoxy, to the rescue.

Picked up the box I mailed to myself yesterday and repacked it all in to the four panniers. Wobbly rear rack actually worked better with both sides loaded for balance. Now I have a bunch of winter gear and a warm sleeping bag, but it's still summer. Hmm.

Rio Vista for a few groceries and to stretch my legs today. Tortillaritos are once again the main staple.

Met more dogs at the hidden beach the other day, and their owner who worked in waste water management and wanted to talk about it.

Mostly trying to dive in to this new app and tasks on it but didn't do much of that today as there was some other randomness, almost finishing that portlight, and now I have an overdue shower to attend to.

There are some expendables that don't really have any kind of alternative or replacement that are really, really useful, and I've found enough of them that I need to make a list, so...

3M 4200/5200 polysulphide sealant, but everyone knows this already.
Goo Gone, for removing butyl after you can't scrape any more out.
Plumber's epoxy sticks, for when you need either a very small amount of epoxy, or when you need some thickened epoxy that won't drip or sag. You can slice off a sliver, knead it until the colors are mixed, and then it kicks hard and sets up fast so smear it on whatever repair. Great for filling holes where you've removed screws or filling gaps. This is what, after trying a dozen things, finally stopped the centerboard crack leak so I could epoxy over it.
Plumber's sandpaper cloth. Hand sanding oddly shaped things or wet things don't work well at all with paper backed sandpaper. This stuff doesn't tear or the abrasive doesn't fall off when it gets bent. Related to above.
Isopropyl alcohol. Mucking with disposable gloves so you can use acetone or the like is a wasteful pain. Spray some alcohol on and wipe it down with a clean rag to remove the Goo Gone or sanding dust or whatever.
Adding this Motsenbockers silicone dissolver to this list too. It claims to break down other kinds of sealants too including polyurethane sealants and epoxy (!) but I haven't tested that. If you aren't supposed to get it on acrylic, then it probably is mean to plastics like epoxy.
scrottie: (Default)
MUD player reported that taking gold isn't working. Was a bit slammed and timing was bad so didn't investigate it initially, and besides, that seems kind of impossible... must have been limited to one monster or the area builder or something, and if it really were broken, I would have heard more about it. Eventually I did hear more about it. This player is a great play tester and the bug log is brimming so been trying to get around to dealing with the whole backlog.

So, I test zap'ing (wizards can kill about anything with one command, for testing) some monsters and taking their gold and it works fine. Asking for more info, he can't provide any. It just doesn't work. Eventually get out of him that it says "Taken: 0 gold coins". Snoop him (watch his screen output, another wizard ability) while force'ing (yet another) him to take a pile of coins off the ground, and sure enough, 0 coins, so it's not just something about how many coins a monster has or drops, he really can't pick up gold. Setting my class to barbarian to match his, boom, taking money, it's magically 0 coins instead of whatever it was, so it's definitely barbarian related.

Reading the code for the "take" command, it's perfectly straight forward. Looking at the code for the object that represents piles of money... not so much:


/*
* If we are picked up by a player, then move the money to his "purse",
* and destruct this object.

901128: Changed by JnA to not destruct object until surely picked by the
player, i.e. object moved to the players inventory with move_object()
*/
/*
sdw, 1/2000: fixing JnA's code not to dest/change title untill after whole
process of being picked up finishes
*/
init() {
if (living(environment(this_object()))) {
moneywas=money; money=0; /* so they cant drop/get/drop/get us over and over */

call_out("finish", 0, this_player());
}
}

finish(obj) {
call_other(obj, "add_money", moneywas);
destruct(this_object());
}



init() runs when an object physically encounters a living thing, either when the living thing moves or is moved to where the object is, or the object is moved to where the living thing is. That could be in the living thing's inventory or in the same room, or the living thing to inside of that object.

The gold object wants to self-destruct when picked up, and add the gold coins to the player's count of coins. This is where it does it... or tries to. living(environment(this_player())) indicates whether a living thing is holding it. this_player() is the current living thing it is in contact with.

But it can't self destruct immediately, or else the "Taken: nnnn gold coins" message in the "take" command will error when the object isn't there and the "take" command is trying to ask the object for its short description. The player will get the classic "Your sensitive mind notices a wrongness in the fabric of space." message. So it waits 0 seconds, which is still waiting until after the current command finishes, then moves the gold and self destructs. From comments in the code, it previously waited > 0 seconds, but players were able to drop and pick it up multiple times before it self destructed, and money would be added repeatedly. This is so classic LPMud 2.4.5 bugginess I had to write about it.

So what's going wrong? I added this just inside the if():


tell_object( find_player("scrottie"), "XXX: " + this_player()->query_name() + "\n" ); // XXX


And tried again:


> force otto take money
%Scrottie forced you to: take money.
XXX: 0
XXX: Otto
%Taken: 0 gold coins
Otto takes money from here.
You force Otto to: take money.


Immediately before init() delays sending the money to Otto, it also delays sending the money to 0. LPMud 2.x (and we're in compat mode here) doesn't have a null or void value, only 0. If you call a method that doesn't exist, you don't get an error or an undef, you get 0. Some other living thing that's not a player or monster "touched" the gold first. Aha.

Notice that it's using two different values... living(environment(this_object())) and this_player(). A while back, in response to another report from this player that the "frenzy" barbarian ability doesn't do anything, I found the barbarian soul was using heart_beat to implement frenzy, setting a "heart beat" in the game driver that calls the heart_beat() function every two seconds. Every player has a heart beat. Class abilities are implemented in invisible objects players hold. In 2.4.5, an object didn't have to be living to have a heart beat, but lots of objects using heart beats to poll for something that rarely happens was bogging down games, and cracking down on that became a priority for game admins, so a rule was instituted that only living things should ever have heart beats. Annoyedly, I mark the barbarian soul "living" with enable_commands() so that it can have a heart beat. It's responsible with the heart beat, turning it on during the duration of the spell and off after the spell runs out, so I'm just working around pointless bureaucracy here. Worse, Amylaar's (game driver fork, since the LPMud driver was long ago abandoned and forks took over) 2.x compat mode allows non-living objects to have heart beats, which is correct back compat, but LDMud, which we're currently running (mostly because it's newer and so more recent work was done to make it actually compile) doesn't get this right. So really, I'm working around Amylaar not compiling. (Someone ported a version of Amylaar to the Amiga, and I did a lot of MUD dev locally on my Amiga 1000, so fond memories of Amylaar.)


Anyway, gold that gets picked up by a barbarian first encounters the now-living barbarian soul. living(environment(this_object))) is the player that picked up the gold... but this_player() is the barbarian soul. Second, it encounters the player. Two call_out()s are run, the first for the soul object, the second for the player. The soul one returns first. The amount of gold is blanked to prevent the double-pickup bug and instead recorded in another variable for use by the delayed code. Gold is transferred to the barbarian soul, whose add_money() method doesn't exist, so absolutely nothing happens from the attempted transfer. Then the object is destroyed. The second invocation of delayed code, transferring the same amount of money to the player, never runs.

There are a bunch of ways this could be fixed... instead of delaying code to transfer money to this_player(), it could be sent to environment(this_object()), so they match. We know environment(this_object()) is actually holding the gold, so it's a pretty good guess as to where to send the money. That could be done without a delay, then the money blanked, but the desc cached, and the delay only used to destroy the object after "take" finishes. "take" could call a method in objects to notify them that it has finished. This would fit the preaction/action/postaction design Infocom used. But instead, we get the incredibly, wonderfully buggy that is 2.4.5 LPMud, and I added to this bug a long time ago and then again just a bit ago.

Profile

scrottie: (Default)
scrottie

October 2024

S M T W T F S
  12345
6789101112
13141516171819
20 212223 242526
2728293031  

Style Credit

Expand Cut Tags

No cut tags
Page generated Mar. 29th, 2026 10:41 pm
Powered by Dreamwidth Studios