Easy hack wasn't as easy as I thought. I figured I could kill an NPC by setting it's scriptstate to whatever and forcing it's [event.inuse] or [event.health] to 0, but that did the same as <DNP. I'm guessing there's some function that gets called when damage takes an NPC's health below 0, and the 0x0200 flag negates this, but I have no clue where to look for it, so I figure I could write my own function. However, I'm not sure what the format of it all is. For example, I know whenever there's a call, there's usually an add ESP x after it, and at the start of functions there's sub ESP x. What's that about?
Also, would I have to push values like [event.x] and [event.y] first, and if so how do I get them after? Usually I've just been using long jumps when I need extra code space, and that method maintains the value of [ebp+8]. However, I want this one to be usable for multiple entities (in case I run into this problem again).
My first idea was for the function to work like this, with whatever else needed to go in there for it to not crash of course.
Code:
Call A
add esp, ???
A: push ebp
mov ebp, esp
sub esp, ???
generate smoke 2x at coords [npc.x, npc.y]
play a sound
mov [npc.inuse], 0
mov esp, ebp
pop ebp
retn
Then I figured I probably had to push the values first... Maybe push [ebp+8], so I can get the right values without taking too much space in the NPC code, of which I can only compress so much. Also, the npc.struct is at 4bba34+[event.NPCID]*0x18, so I could do something like that to get it's proper death sound right?
Then I had the idea that, if I knew how to unset flag 0x0200, I could bypass all this tricky business altogether. But, it doesn't look like the NPC's flags are stored in [ebp+8]. Or, are they?
EDIT: Anyway, I'm going to sleep on it right now.