Jump to content

Protagonist resurrection mod


Recommended Posts

On 3/13/2022 at 9:42 AM, jmerry said:

On the instant kill side, this is the best I can figure. Add a marker effect to every such instant kill; a different marker for every kill type. The marker has the same resistance parameters as the kill, and anything that grants immunity to that kill type also grants immunity to the corresponding marker. Except for your one effect for the protagonist, which grants immunity to the kill type but not the marker. Then your script detects the marker and does stuff.

You can be immune to specific opcodes, specific projectiles, specific display strings, specific visual effects, specific portrait icons, or specific spells. You can't just add dummy opcodes that only act as markers to the game. You can't detect the cosmetic stuff in scripts. That leaves spells as the best option; the marker effect is a "Cast Spell" effect, with the spell itself being impossible to block or resist and applying a local variable or something, and immunity to the original instant death effect granting immunity to that particular spell.

I'm getting to the point that I'm starting to understand what you suggested here @jmerry. For normal death prevention I would go for "min 1 HP" option and I would pretend that regeneration problem not exist (for now). In BG1, where my focus is right now, there is not that many instant kill scenarios, but petrification can be good example of such. My plan is to prepare spl file that would apply petrification opcode. I would then replace with WeiDU every case of applying petrification opcode to applying of this "petrification" spl and also replace every petrification opcode immunity with immunity to this exact spl (probably same for cure). I would make protagonist immune to petrification opcode. So at this point everything that I add to my "petrification" spl next to petrification opcode would work on protagonist in cases when normally petrifaction would take place, I guess this would be place for my "marker".

As far as marker goes I see couple of eventual candidates:

  • Setting variable in LOCALS as you suggested, but I'm not sure how to read such variable for Player1. Would TriggerOverride(Player1, Global("somevar", "LOCALS", ..)) work when I put it in baldur.bcs? Because AFAIK there is no "local" script for Player1 that is uneffected by "Disable Party AI" button.
  • Setting current hp to 1. For non protagonist creatures it should make no difference, since they would be petrified anyway. Again regeneration can screw up thing here. Also I wouldn't be able to detect in script what was the cause of death, what could be handy to apply some visuals (fake death effect on normal death, stone effect on petrification etc.)
  • Setting some splstate. I guess it could be done with opcode328. Problem is that there is no "petrified" state there and I'm not sure if this table can be extended with custom one.
  • Setting STATE_STONE_DEATH. It is set by petrification opcode, but I don't see option to set it myself omitting this opcode.
Link to comment
On 4/9/2022 at 12:19 PM, marchitek said:

As far as marker goes I see couple of eventual candidates:

  • Setting variable in LOCALS as you suggested, but I'm not sure how to read such variable for Player1. Would TriggerOverride(Player1, Global("somevar", "LOCALS", ..)) work when I put it in baldur.bcs? Because AFAIK there is no "local" script for Player1 that is uneffected by "Disable Party AI" button.
  • Setting current hp to 1. For non protagonist creatures it should make no difference, since they would be petrified anyway. Again regeneration can screw up thing here. Also I wouldn't be able to detect in script what was the cause of death, what could be handy to apply some visuals (fake death effect on normal death, stone effect on petrification etc.)
  • Setting some splstate. I guess it could be done with opcode328. Problem is that there is no "petrified" state there and I'm not sure if this table can be extended with custom one.
  • Setting STATE_STONE_DEATH. It is set by petrification opcode, but I don't see option to set it myself omitting this opcode.

Answering myself:

  • Setting local variable with opcode 309 on Player1 works. It can be read/updated later in scripts with TriggerOverride/ActionOverride.
  • splstate can be modified, but number of possible values is limited, so better to avoid it if possible (more info)
  • Setting STATE_STONE_DEATH would probably still be cleanest solution, but still don't know if there is a way to set it manually (omitting actual petrification).

So far so good with local variable as a marker. This was probably last technical thing that required investigation. I have implemented resolving nearest respawn point with some plot critical restrictions, applying respawn penalty (xp + gold), respawn triggering (normal death + petrification + whole party charmed), some simple respawn process. Still some coding left, but I think it's safe to say that Alpha is on its way.*
 

* Unless I forgot about something that will kick me in the butt at the very end.

Link to comment

I was able to prepare first working version, I released it as part of bigger project called "Diablofication". I created separate thread for it here.

If someone is interested in what exactly I mange to achieve in terms of "protagonist resurrection" topic, here is some sum up.
In general, I apply on protagonist min 1 HP effect together with some immunities to instant kill opcodes. Then I add to every item/spell that applies instant kill opcodes additional effect (with the same conditions, saving throws etc) that sets local variable on target creature. Then I am able to detect in scripts that protagonist is affected by instant kill effect and I can trigger respawn in temple. To detect respawn place I set on every master area proper global variable in OnCreation() block, I check it later in respawn script and act accordingly. Applying gold and XP penalty is rather straightforward, jus bunch of script blocks that check thresholds and run proper actions (all hidden in cutscenes to not pollute global script, thanks again @The_Baffled_King!).

Link to comment

Good stuff, marchitek, I had the feeling you'd get where you wanted to go in time (well, except for the bit about CopyGroundPilesTo(), but it is what it is).

I will probably take a good look at what you have if/when the time comes for me to try to implement what I want for protagonist deaths. I'm still firmly on the side of TPK = game over, rather than protaganist will always be resurrected, but it's a matter of playstyle preference rather than being objectively better.

Also, while I'm here, I thought I'd share an idea I had which might allow you to resurrect party members with their equipment, assuming that's still something you want. The idea makes use of oppcode #236 (0xEC) Spell Effect: Image Projection, which creates an "Image" which is a copy of the targeted creature. I figured it might be possible to create some kind of script and/or effect that uses this oppcode to periodically create what is in effect a backup of non-protagonist party members.

The Image has duplicates of all of the targeted creature(s) items that are flagged with DROPPABLE and not flagged with NONDROPABLE. All items on the Image are flagged with NONDROPABLE, so, without more, they are obviously useless for your purposes. However, you can use SetItemFlags() to remove the NONDROPABLE flag, which I am assuming would make the items on the Image droppable.

In normal circumstances, this still wouldn't be particularly useful, because you would have to run a staggeringly long script targeting every item the copied NPC could conceivably have in its inventory. But I figure that this becomes relatively painless in the unusal circumstance you are catering for, whereby you're teleporting the party out of combat to specific locations where nothing is really happening, as you can run said script from a cutscene or a creature created solely when said script needs to be run.

So, to put that all together: (1) you periodically create a backup of your party NPCs, perhaps on arrival in an area; (2) you move the backups to the resurrection temple with the PC; (3) if the NPC is still alive, then you remove the backup via DestroySelf(); (4) if the NPC is dead, you run a script to remove the NONDROPABLE flags on the items carried by the backup; (5) you remove the backup via Kill(), thus dropping whatever the dead NPC carried at the point it was "backed up".

Note that I haven't tested any of this at all, and there might very well be glaring flaws that I'm overlooking. I just thought I'd throw it out there in case the idea appeals and the concept can be made to work! Hopefully if anybody reading this knows of any reason why my idea can't work, they will give you a heads-up.

EDIT: I noticed you mention a planned component "Randomization and diversification of game content" - cue applause! Randomization, together with changes that give more choices on how to proceed, is in in my view better than pretty much anything else in terms of mods (well, I would say that the vastly improved AI in SCS is the literal best thing out there - although one of the reasons it's so good is the variety introduced in terms of spell selection and AI behaviour).

Edited by The_Baffled_King
Link to comment
On 4/26/2022 at 8:53 PM, The_Baffled_King said:

Also, while I'm here, I thought I'd share an idea I had which might allow you to resurrect party members with their equipment, assuming that's still something you want. The idea makes use of oppcode #236 (0xEC) Spell Effect: Image Projection, which creates an "Image" which is a copy of the targeted creature. I figured it might be possible to create some kind of script and/or effect that uses this oppcode to periodically create what is in effect a backup of non-protagonist party members.

[...]

That's sounds super promising. I was wondering about something like this, but I haven't a clue how to handle it technically. In my situation it can be super useful to me because I can protect companions as I currently protect protagonist, but instead of triggering respawn I would backup their equipment, remove their equipment and kill them. Then I will need to detect resurrection/removing form party and give back equipment from backup in such situation (+ quest items should be dropped normally I suppose). I will definitely test that.

 

On 4/26/2022 at 8:53 PM, The_Baffled_King said:

I noticed you mention a planned component "Randomization and diversification of game content" - cue applause! Randomization, together with changes that give more choices on how to proceed, is in in my view better than pretty much anything else in terms of mods. [...]

Yes, totally agree. I have in mind something like random generated equipment using some predefined prefix/suffix. So e.g. instead swords +1 all around player could get here and there sword +1 with some small random effect.

Link to comment
18 hours ago, marchitek said:

Yes, totally agree. I have in mind something like random generated equipment using some predefined prefix/suffix. So e.g. instead swords +1 all around player could get here and there sword +1 with some small random effect.

You can't go full Diablo on that; items in the Infinity Engine can't be flat out created during gameplay, but have to be defined in advance.

What you can do is run loops that create variations on an item and splice together names and descriptions in your mod code; I did this for my joke kit mod "incorporating" up to two pieces of jewelry into the kit's key item. This doesn't even have to break translation friendliness; tra files are fundamentally just big lists of string variable definitions.

So, for example, we could have modifiers like "of flame" (+1 fire damage), "of defense" (-2 damage, +2 AC), "of accuracy" (-2 damage, +2 to hit), or "keen" (+1 crit range). Loop through the base items you'd like to modify, add a suffix to the item code corresponding to the modifier (after first defining a base item code with your modder prefix), apply the new abilities to the item, create names and descriptions by concatenating strings, and there.

Then you create random treasure tables with your new items in them, assign those random treasures to monsters, and it's good. Oversimplifying, of course.

Link to comment
8 hours ago, jmerry said:

You can't go full Diablo on that; items in the Infinity Engine can't be flat out created during gameplay, but have to be defined in advance.

What you can do is run loops that create variations on an item and splice together names and descriptions in your mod code; I did this for my joke kit mod "incorporating" up to two pieces of jewelry into the kit's key item. This doesn't even have to break translation friendliness; tra files are fundamentally just big lists of string variable definitions.

So, for example, we could have modifiers like "of flame" (+1 fire damage), "of defense" (-2 damage, +2 AC), "of accuracy" (-2 damage, +2 to hit), or "keen" (+1 crit range). Loop through the base items you'd like to modify, add a suffix to the item code corresponding to the modifier (after first defining a base item code with your modder prefix), apply the new abilities to the item, create names and descriptions by concatenating strings, and there.

Then you create random treasure tables with your new items in them, assign those random treasures to monsters, and it's good. Oversimplifying, of course.

Exactly. I wasn't even dreaming about making this generation during gameplay, but I guess installation time generation is totally fine. Interesting idea with ranom treasures table, I didn't know that it is possible to add new one. One drawback of this approach is that you need to generate every possible combination during installation (and it should be a lot to have actual diversity) . I was thinking about something like scanning CRE files and containers, checking what need to be generated and then generate and assign. So in fact even more "installation time".

Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...