The Dink Network

Killing magic and items commands broken. (Fixes inside)

January 28th 2019, 06:25 PM
Jester Male Australia
You feed the madness, and it feeds on you. 
EDIT: probably should have been a development thread.

I mean, it sort of works. But they both have bugs, unless my DinkC is just being completely awful (tested in both freedink and 1.08).
Also, before reading any further, I will break down what's broken about it, but I will say, I created a script that can be called from external to fix the 3 commands that are buggy instead of copying and pasting code everytime, because it was annoying the shit outta me and I wanted to streamline the fix, I mean it's not a game changing bug, but it annoyed me enough to do this nonetheless. These 3 commands are:

First what's broken about each one:
Kill_cur_item() and kill_cur_magic(), as soon as these commands are called, the game will not execute the rest of the script. The DinkC reference states this was the case in 1.07 and earlier, but it happens in FreeDink and 1.08 as well. This results in the item or magic being killed, but the image/thumbnail still sits in the status bar/HUD as if it was still armed (the player can't use it though, because it is actually gone from the inventory). Also, this means it has to be the last line you run in a script, since the script will stop dead in it's tracks as soon as you call these commands. Better make sure it's not a spawned script or a script attached to 1000 as well, because it won't die, it'll just stay running for the rest of the game.

Kill_this_magic("script_name") is only an issue if the magic you are trying to kill is currently armed. If this is the case, it will kill it, and get rid of it properly, but it will also make the thumbnail for the currently armed weapon vanish from the status bar/HUD as well. Opposite scenario to above, since the weapon still exists and is armed, so the player can still use it, it just looks like they have nothing armed. They can always go back in the inventory and re-select to get the image to come back on the status bar, but they shouldn't have to right?
This one only applies to kill_this_magic(). Kill_this_item() works fine, even if the item is selected.

Now the fixes:
Kill_cur_item() and kill_this_magic() - the workaround to get this one working as it should is obviously to spawn a separate script to run the command, since it's gonna stop executing the script anyway, unfortunately as mentioned above, the script will run forever, so to assure the script dies, just add script_attach(0); in the spawned script before running kill_cur_item().
This does not rectify the issue of the thumbnail not dying along with the actual spell though, and drawing the status will not correct this. So I created a sprite that consists of just 1 pixel in paint (so that it's not visible in game), added a null item with the 1 pixel graphic as the thumbnail for that item, retrieved the slot of that item with get_item("script"), armed it and spawned the same kill_cur_item script as before, in doing this, it's just using the same bug as before to your advantage, it will add a 1 pixel item, arm it, and kill it off instantly (so it will look like nothing is armed), getting rid of the previous image that SHOULD have been killed off.

There is probably another way to fix these things, but I've already streamlined it in a script I can call from external everytime I want to use these commands, so this workaround is adequate and makes the commands work perfectly as they should.

kill_this_magic() - So the issue here is that when armed, and killed with this command, you lose the thumbnail for your weapon as well.. kind of strange, but so is most of DinkC. Again arm_weapon, draw status, and a bunch of other commands I tried don't correct this. The fix is simple. Store &cur_weapon in a local. Set &magic_level to 0; (otherwise the magic bar may remain as well, happened in testing), run the kill_this_magic command, set &cur_weapon back to the previously stored local, and draw status. Done.
I however wanted to streamline this with external also, and since there's no way to pass on the "script name" to use in the "kill_this_magic" command as far as I know, instead you can pass the slot number of the spell using get_magic, and then the rest is automated using the kill_cur_magic method above. The external script arms that slot, and then does the above kill_cur_magic with the fix applied, and then arms the old magic again - in game it's instantaneous and there is no visual swap between spells.

I know these are only graphical bugs, but tbh, they pissed me off enough to apply a fix. I'm happy to release a my external scripts for streamlined use, with a small instructional wmv if wanted. I'm sure I'm not the first person to stumble upon these bugs. Although funnily enough, in most dmods, once spells are acquired, they are not killed off, so maybe not.

August 15th 2021, 01:26 AM
Jester Male Australia
You feed the madness, and it feeds on you. 
My previous self overlooked an even simpler fix, using "set_callback_random()"

Fix used for kill_cur_item(), and can be altered to work with kill_cur_magic:

void main(void)
 //set a callback to the 'killscript()' proc, with a wait time of 1.
 //so after we run the flawed 'kill_cur_item()' function, it immediately runs 'killscript()'
 set_callback_random("killscript", 1, 1);

 //flawed 'kill_cur_item()' function - will stop the current script executing

void killscript(void)
 //this will run immediately after 'kill_cur_item()'
 //draw the status to make the item image vanish properly

 //kill off this script so it doesn't remain in memory.

And the issue of `kill_this_magic()` also making the item image vansih in the status bar and sometimes leaving behind the magic charge bar, which only happens if the magic it's killing off is equipped, is fixed like this:

void main(void)
 //store '&cur_weapon' in a local variable
 int &fix_weap = &cur_weapon;

 //kill fireball

 //fix unwanted side effects with magic charge bar and empty slot staying equipped
 &cur_magic = 0;
 &magic_cost = 0;
 &magic_level = 0

 //restore &cur_weapon, arm it, and draw the status
 &cur_weapon = &fix_weap;