Jump to content

Protagonist resurrection mod


Recommended Posts

@Endarire I think it's possible, but it's a mess. See below.

 

There's no way to say "this would have dropped the creature to 0 HP" without going through with the kill. Unless you move the goalposts.

Taking inspiration from certain "immortal" enemies, you would give player 1 min HP 1, +N max HP, and have script things happen when they drop to N or lower. Not ideal, since certain spell effects depend on current HP - you're effectively moving that threshold.

 

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.

 

 

The drawback of these approaches is that they're not instant. It can take a bit for the scripts to detect your marker, so the character might fight on when they should be dead. Worse, regeneration can really mess up the low-HP part; by the time the script gets around to checking again, you might be out of the "dead' zone.

Link to comment

Yeah, I took quick look on Imoen's belt and it doesn't look simple at all.

 

Meanwhile I have hard time using this "Player1 can die" flag. It seems that when all party members all dead game change location to last visited master area and it seems I cannot do anything to prevent it. Some discussion around it can be found here.

I work with following script snippet:

IF
	StateCheck(Player1, STATE_REALLY_DEAD)
THEN
	RESPONSE #100
		ClearAllActions()
		StartCutSceneMode()

		SmallWait(15)
		FadeToColor([20.0],0)
		SmallWait(30)
		
		ApplySpell(Player1,CLERIC_RAISE_DEAD)  // SPPR504.SPL (Raise Dead)
		
		CopyGroundPilesTo("AR4802",[353.334])  // Temple of Helm (Nalin)
		DestroyGroundPiles()
		
		ActionOverride(Player1,LeaveAreaLUA("AR4802","",[473.395],NE))  // Temple of Helm (Nalin)
		
		ApplySpell(Player1,CLERIC_HEAL)  // SPPR607.SPL (Heal)
		
		SmallWait(15)
		FadeFromColor([20.0],0)
		SmallWait(30)
		EndCutSceneMode()
END

There are two problems:

  1. When switch to master area occurs before CopyGroundPilesTo() the ground piles are copied form master area, not actual death area
  2. When switch to master area occurs before resurrection, then character is not resurrected (game crash or just nothing happens, depending on where script is running: baldur.bcs or area script)

I tried different things: moving script from baldur.bcs to area script and vice versa, wrapping it with cut scene, invoking SetMasterArea() action at very begging. But those problems still occurs randomly in every setup.

If someone want to play with it a bit, I pushed code here.

Link to comment

Recently I pushed version with "hybrid" approach:

  • "Player1 can die" flag is set which should prevent "game over" on personification (and I guess also on charm). But I didn't tested it closely. For solo runs petrification would be end of the road anyway for now, because there is no one that can unpetrify you. There is obviously a lot of TODOs here.
  • Also, at the begging of game Protagonist receives ring that protects form "normal" death. When 1 HP is reached, party is teleported to Nashkel temple and resurrected/healed. Coping ground piles (to get back loot from eventual dead companions) works only on "master" areas thou. I think fix would be to move this script block to area script (currently in baldur.bcs)

So, I guess if you will keep close to Nashkel you can have some testing close to real game conditions. I'm curious how this idea will work in BG for you.

 

I slowly prepare to attack the next topic, which is obviously detect sensible respawn points. I want to start with plot critical rules and scenario that I previously marked as "fallback", so detecting this place based on chapter and some other game progress related variables. I guess it could be something like:

  • Prologue: Temple in Candlekeep
  • Chapter 1: Temple in Friendly Arm Inn
  • Chapter 2: Temple in Nashkel
  • Chapter 3: Temple in Beregost
  • Chapter 4: Temple in Friendly Arm Inn
  • Chapter 5: Lady's Hall in BG (here of course there is biggest choice of temples)
  • Chapter 6:
    • before entering Candlekeep: Friendly Arm Inn
    • after entering but before accusation: Temple in Candlekeep
    • after accusation: Candlekeep prison cell and game continuous form now on with prison cutscene
    • after cutscene: begging of dungeon
  • Chapter 7:
    • before Sarevok disclosure: Friendly Arm Inn
    • after that: Lady's Hall in BG

Any comments welcome.

Edited by marchitek
Link to comment

So for mod areas: death prevention would work same way, because I know how change flag and extend scripts of all areas in game without need of explicit specification.

 

Respawn place resolving is a bit more tricky topic. Let me first quote myself about what I plan:

On 3/6/2022 at 11:29 AM, marchitek said:

3. Detecting respawn point

I'm thinking about resolving in three groups of steps:

  • plot critical rules (e.g. for Candlekeep catacombs, Irenicus dungeons, Spellhold dungeons etc.)
  • based on last visited outdoor area
  • some fallback based on game chapter etc.

And let me discuss it backwards:

  • For "some fallback based on game chapter etc." it will be compatible with other mods unless they add new chapter. Ofc total conversion mods also cannot be supported at this point.
  • For "based on last visited outdoor area" could be problem to affect mod areas in sensible manner. However I can know at installation time all master areas in the game, but I cannot know where they should point (to which respawn point). So still it will resolve place of last visited master area from original game, because I need to configure it explicitly beforehand. If player will travel to mod area from near original game area, this should produce sensible results after all.
  • For "plot critical rules" this is most tricky part. Let's say some mod adds adventure on distance island, that turns out to be occupied by werewolves and stuff. If player dies here it would be hard to produce sensible result. I guess for such cases player will need to switch to "reload" approach to the game. (BTW I need to add Isle of Balduran to my list of "plot critical" places).

In general my idea is to make this mod as much configurable without diving much into code. Let's see how it will go. I must say mod areas handling is not top priority to me, because I don't play with mods that add them (at leas at current time), but its obviously something that I keep in mind.

Link to comment

Regarding penalty for getting killed, here was some discussion about possibility of percentage penalty. It seems it is impossible/very complicated. So the way to go would be penalty based on thresholds. Actually, maybe it will have more sense, since level progression table is not consistent at this point either.

So I took fighter level progression (it's simplest) and for each level calculated: (next level xp value - current level xp value) * 10% and I got in result something like this:

Level: 1 2 3 4 5 6 7 8 9 10
XP for level: 0 2000 4000 8000 16000 32000 64000 125000 250000 500000
Result: 200 200 400 800 1600 3200 6100 12500 25000 25000

And for every next level also 25000. So I guess I will implement for now thresholds like this:

Character XP -> XP penalty
>2000 -> 200
>4000 -> 400
>8000 -> 800
>16000 -> 1600
>32000 -> 3200
>64000 -> 6100
>125000 -> 12500
>250000 -> 25000

And those values also make sense to me if look at it as "current party gold -> gold penalty".

Any comments welcome.

Edited by marchitek
Link to comment

Hi. Protagonist resurrection is definitely awesome. I'm interested in it more as a way to change the game over condition from protagonist death to total party kill ("TPK") – on the proviso that the goal would be to resurrect the protagonist – but your idea has some appeal also.

I have solutions for your "ground piles" and "return to point of death" problems. Also, as you mentioned moving the entire party only in response to the issue of being locked into party-required areas, I thought you might be interested in a few ways to account for that so your party doesn't have to teleport every time the protagonist dies?

Here are snippets of some of the scripts I've been testing; they are sufficient to test and to illustrate the concepts, but they aren't complete.

In Baldur.bcs:

Spoiler

IF
    NumInPartyAlive(0)
THEN
    RESPONSE #100
        SetGlobal("BK_TPK_Variable","GLOBAL",1)
        ClearAllActions()
        StartCutSceneMode()
        FadeToColor([45.0],0)
        Wait(3)
        ApplySpellRES("BKPRRP1",Player1)  // Resurrection
        Wait(1)
        ActionOverride(Player1,MoveGlobalObject("Minsc",Player1))  // Minsc
        StartCutSceneEx("BK_Cut1",TRUE)
END

IF
    StateCheck(Player1,STATE_REALLY_DEAD)
    NumInPartyAliveGT(0)
THEN
    RESPONSE #100
        SetGlobal("BK_Player1_Dead_Variable","GLOBAL",1)
        Wait(1)
        ApplySpellRES("BKPRRP1",Player1)  // Resurrection
END

The first block is for TPKs. I didn't bother adding anything to deal with dead NPC companions at that stage. For your purposes, presumably you want to address that later. The second block is for when the protagonist dies but has at least 1 NPC companion left alive. The IF triggers are a convenient shorthand for now to show what the blocks are intended to do – and do in fact do when a simple Ctrl-Y is used – but more careful scripting will be needed. I'll return to "Minsc" later, but for now just think of him as a placeholder for a specific .cre that is a global object.

BKPRRP1 is a copy of the Resurrection spell with the animation/sound removed and several alternative effects added. The purpose of these effects, and of the second block in general, is to make the protagonist a creature that is technically alive and present in the party but otherwise virtually undetectable. This is one way of getting around barriers and scripts that assume that Player1 is always in the party.

This is the cutscene BK_Cut1.bcs (referenced in block 1 of Baldur.bcs):

Spoiler

IF
    AreaCheck("AR2600")  // Candlekeep (prologue), exterior
THEN
    RESPONSE #100
        CutSceneId(Player1)
        SetGlobal("BK_Temple_Location","GLOBAL",1)
        SetMasterArea("AR2600")  // Candlekeep (prologue), exterior
        ActionOverride(Player1,CreateItem("POTN40",1,0,0))  // Potion of Invulnerability
END

IF
    AreaCheck("AR2616")  // Candlekeep (prologue), Inn ground floor
THEN
    RESPONSE #100
        CutSceneId(Player1)
        SetGlobal("BK_Temple_Location","GLOBAL",1)
        SetMasterArea("AR2616")  // Candlekeep (prologue), Inn ground floor
        ActionOverride(Player1,CreateItem("POTN40",1,0,0))  // Potion of Invulnerability
END

IF
    AreaCheck("AR3900")  // Ulcaster School, exterior (Ulcaster, Icharyd)
THEN
    RESPONSE #100
        CutSceneId(Player1)
        SetGlobal("BK_Temple_Location","GLOBAL",4)
        SetMasterArea("AR3900")  // Ulcaster School, exterior (Ulcaster, Icharyd)
END

IF
    AreaCheck("AR3901")  // Ulcaster School, dungeon
THEN
    RESPONSE #100
        CutSceneId(Player1)
        SetGlobal("BK_Temple_Location","GLOBAL",4)
        SetMasterArea("AR3901")  // Ulcaster School, dungeon
END

IF
    AreaCheck("AR3351")  // Feldepost's Inn, ground floor (Marl) // 600 copies of this block, as placeholders for the total number of areas in BG1
THEN
    RESPONSE #100
        CutSceneId(Player1)
        SetMasterArea("AR3351")  // Feldepost's Inn, ground floor (Marl)
END

IF
    True()
THEN
    RESPONSE #100
        CutSceneId(Player1)
        StartCutSceneEx("BK_Cut2",TRUE)
END

605 IF blocks might sound like a lot but, when placed inside a cutscene, its trivial. SetMasterArea() solves your problem with the ground piles. Obviously there's no need to use SetMasterArea() on areas that are already master areas, but it's simpler to install that way, and by always using SetMasterArea() you can cover mod-added areas without needing to know their master/sub area relationships. This block also gives you fine control over which areas correspond to which temple, rather than a blanket approach based on Chapter.

This is the cutscene BK_Cut2.bcs, as referenced in BK_Cut1.bcs

Spoiler

IF
    Global("BK_Temple_Location","GLOBAL",1)
THEN
    RESPONSE #100
        CutSceneId(Player1)
        CopyGroundPilesTo("AR2600",[3880.600])  // Candlekeep (prologue), exterior
        Wait(1)
        DestroyGroundPiles()
        LeaveAreaLUA("AR2600","",[3967.635],NE)  // Candlekeep (prologue), exterior
        Wait(1)
        FadeFromColor([45.0],0)
        Wait(3)
        ApplySpell(Player1,CLERIC_RESURRECTION)  // SPPR712.SPL (Resurrection)
        EndCutSceneMode()
END

IF
    Global("BK_Temple_Location","GLOBAL",4)
THEN
    RESPONSE #100
        CutSceneId(Player1)
        CopyGroundPilesTo("AR4802",[353.334])  // Temple of Helm (Nalin)
        SmallWait(5)
        DestroyGroundPiles()
        LeaveAreaLUA("AR4802","",[473.395],NE)  // Temple of Helm (Nalin)
        SmallWait(5)
        FadeFromColor([45.0],0)
        Wait(3)
        ApplySpell(Player1,CLERIC_RESURRECTION)  // SPPR712.SPL (Resurrection)
        EndCutSceneMode()
END

The only thing about the above script which is not self-explanatory is that Resurrection has been modded with oppcode 321: Remove Effects By Resource, specifying BKPRRP1. This undoes the permanent hidden effects applied by my modded resurrection spell in Baldur.bcs.

ActionOverride(Player1,MoveGlobalObject("Minsc",Player1)):

As noted above, "Minsc" here is a placeholder for a specific .cre that is a global object. It would be an invsi-creature that you interact with only via bcs. It's purpose is to mark the point where the protagonist dies, so that you can return to that precise point via MoveGlobalObject(O:Object*,O:Target*).

To answer a couple of things you mentioned earlier in the thread:

- bdbaldur.bcs is the script for Siege of Dragonspear.

- bdtgaze is I imagine related to the tanari (Aec'Letec) from Tales of the Sword Coast.

Any variable or file name beginning "bd" or "oh" is almost certainly Beamdog or Overhaul Games.

As far as feedback is concerned, I am very much not a fan of the blanket "Chapter X = Resurrection here" approach. I think you should divide up the map (in which case Gullykin can also be used). As a further possibility, and particularly if you are looking to dump the protagonist back into battle straight away, why not create an area unconnected to the World map to put the newly-resurrected party members in? Populate it with a fate spirit, and have it's dialogue give options for where the protagonist goes from there.

Edited by The_Baffled_King
Link to comment

Hi @The_Baffled_King, thank you for this detailed feedback!

 

7 hours ago, The_Baffled_King said:

I thought you might be interested in a few ways to account for that so your party doesn't have to teleport every time the protagonist dies?

That's true, but it's not priority for me. I think that for the first version would be enough if I will teleport to temple for cases where normally would be "game over". But for sure, extending it, so it would happen only when all party members are dead, makes a lot of sense.

 

I backed off form relaying only on "Player1 can die" flag because I experienced problems that make whole solution unreliable.

Let's take simplified version of you script in baldur.bcs:

7 hours ago, The_Baffled_King said:

IF
    NumInPartyAlive(0)
THEN
    RESPONSE #100
        ApplySpellRES("BKPRRP1",Player1)  // Resurrection
END

I had similar piece of code and I was problem with following test case:

  • start new game
  • enter Candlekeep Inn
  • kill Protagonist

Sometimes Protagonist was resurrected, but sometimes, areas was switched to exterior Candlekeep area and game crashes. I think this area switch is related with mechanics, when your party member dies in child area, when rest of party is in master area. Then games switch view to master area. In this case, when it happens before resurrection, game crashes because there is no Protagonist to resurrect on current area (which is now Candlekeep exterior). Moving this script to area bcs file also not helps, crash not occur but either resurrection, so it is not good. Please let me know, if in your approach this problem doesn't happen.

Similar problem I had with CopyGroundPiles(). Even if resurrection was successful it usually copied ground piles from exterior area, not actual area where Protagonist was killed.

There are some other problems with CopyGroundPiles():

  • it will copy piles only from one area when in fact different PCs could be killed on different areas, e.g. you fight Mulahey, one of companion is dead in his chamber but Protagonist escaped on previous area, then if Protagonist would be killed there, CopyGroundPiles() won't work on equipment of dead companion.
  • there are ground piles in the game that imitates normal containers, e.g. some of the treasures in Ulcaster dungeons are undestructable ground piles. CopyGroundPiles() targeting them, I've checked that. You could probably replace such cases witch normal containers somehow, but this is for sure additional complication.

I decided to skip this CopyGroundPiles() for now. I prevent protagonist death with min hp opcode so equipment is not lost when "dead" (= has 1 hp). I have no handling for retrieving loot of dead companions, but I focus on solo scenarios right now, to make things simper.

 

7 hours ago, The_Baffled_King said:

605 IF blocks might sound like a lot but, when placed inside a cutscene, its trivial. SetMasterArea() solves your problem with the ground piles.

Interesting. I was trying SetMasterArea() in this context without success, but maybe I will try again using your way. The only thing I'm worried about is this area switching that I mentioned above. It could be that if this switch will occur before AreaCheck(), the your result could be wrong (wrong action block would be triggered).

 

7 hours ago, The_Baffled_King said:

It would be an invsi-creature that you interact with only via bcs. It's purpose is to mark the point where the protagonist dies, so that you can return to that precise point via MoveGlobalObject(O:Object*,O:Target*).

I tested moving Protagonist with MoveGlobal() action and I had problem when moving between areas. Although Protagonist was moved, camera was still on old location and there was nothing to do about it. Maybe MoveGlobalObject() works differently or maybe something else I was missing, e.g. this ActionOverride() wrapper.

Would you be a problem for sure to share full codebase of your mod? It would be easier for me to test and compare our solutions, My recent code is currently here.

 

7 hours ago, The_Baffled_King said:

[...]

Any variable or file name beginning "bd" or "oh" is almost certainly Beamdog or Overhaul Games.

Ah,, that makes sense! Thank you!

 

7 hours ago, The_Baffled_King said:

I am very much not a fan of the blanket "Chapter X = Resurrection here" approach. I think you should divide up the map (in which case Gullykin can also be used).

I totally agree. I bring up this "Chapter X = Resurrection here" concept as kind of minimal implementation, but now I also think that it is not worth an effort to implement this. I will strat with resolving respawn point based on master area right away.

 

7 hours ago, The_Baffled_King said:

As a further possibility, and particularly if you are looking to dump the protagonist back into battle straight away, why not create an area unconnected to the World map to put the newly-resurrected party members in? Populate it with a fate spirit, and have it's dialogue give options for where the protagonist goes from there.

This is in general good idea. Has some advantages and disadvantages, but ofc respawn in temple also has some disadvantages too. I started with "temple" approach because imho it fits better to BG1 and it seems to be less work (don't need to create separate area, dialogues, area leave mechanism etc). Resolving correct temple wouldn't be that big a problem from what I see. I'm thinking about adding some kind of "waypoints" in the future, so it could handle need for fast travel after resurrection. But from the other hand, I must say "pocket plane" approach could be easier to extend in future. I definitely would think about that.

 

EDIT

I tested your code @The_Baffled_King and it works flawless, I don't know what was my mistake before. This splitting steps between separate custscenes files is great, thank you for showing me this. CopyGroundPiles() still suffers drawback that I mentioned above, but I suppose it's still better solution then my latest version.

Do you think having this resurrection in two steps is necessary? I replaced ApplySpellRES("BKPRRP1",Player1) with normal resurrection and it seems also fine.

Edited by marchitek
Link to comment
On 3/27/2022 at 12:48 PM, marchitek said:

Hi @The_Baffled_King, thank you for this detailed feedback!

You're welcome. It helps to get a few pointers when you're starting out, especially because the IESDP can occasionally be wrong or incomplete.

On 3/27/2022 at 12:48 PM, marchitek said:

I backed off form relaying only on "Player1 can die" flag because I experienced problems that make whole solution unreliable.

The problem I've experienced with Player1 can die flag occurs when Player1 dies in a sub area without another party NPC present. The body will not be there when another party NPC arrives. The game can continue but, once you try to resurrect the protagonist, however you try to do so, the game will crash. This happens even when moving a party NPC to the sub area where the protagonist died before casting Raise Dead from a scroll at the protagonist's portrait, and even though Exists(Player1) returns TRUE.

On 3/27/2022 at 12:48 PM, marchitek said:

I had similar piece of code and I was problem with following test case:

  • start new game
  • enter Candlekeep Inn
  • kill Protagonist

Sometimes Protagonist was resurrected, but sometimes, areas was switched to exterior Candlekeep area and game crashes. I think this area switch is related with mechanics, when your party member dies in child area, when rest of party is in master area. Then games switch view to master area. In this case, when it happens before resurrection, game crashes because there is no Protagonist to resurrect on current area (which is now Candlekeep exterior). Moving this script to area bcs file also not helps, crash not occur but either resurrection, so it is not good. Please let me know, if in your approach this problem doesn't happen.

This is the behaviour I get when Player1 dies in a sub area, in order of priority:

1. Is there a party NPC in your Sub Area (does not matter which party slot, or if another NPC is in the Master Area)? [No Action]
2. Is there a party NPC in the Master Area? [View point moves to NPC in Master Area]
3. Is there a party NPC in a DIFFERENT Sub Area [View point moves to vacamt spot in Master Area]

So, when I try to instantaneously resurrect the protagonist without interrupting the game (using the second block in Baldur.bcs), I get occasional crashes if I spam CtrlY.

On 3/27/2022 at 12:48 PM, marchitek said:

Similar problem I had with CopyGroundPiles(). Even if resurrection was successful it usually copied ground piles from exterior area, not actual area where Protagonist was killed.

AreaCheck() + SetMasterArea() resolves this problem 100% of the time.

On 3/27/2022 at 12:48 PM, marchitek said:

There are some other problems with CopyGroundPiles():

Yes, I don't like this method at all (also, if you die IN a temple, your stuff is gone forever!). But I thought I'd have a go at solving it, anyway.

On 3/27/2022 at 12:48 PM, marchitek said:

Interesting. I was trying SetMasterArea() in this context without success, but maybe I will try again using your way. The only thing I'm worried about is this area switching that I mentioned above. It could be that if this switch will occur before AreaCheck(), the your result could be wrong (wrong action block would be triggered).

The script I've posted has worked for me (in test conditions) close to 100% of the time. Very occasionally it crashes. I don't regard that as a problem when the alternative is game over anyway! I'm unsure whether BK_Cut1.bcs would be better of worse by removing the IF True() Block at the bottom and adding its "StartCutSceneEx("BK_Cut2",TRUE)" to every one of the 600 blocks above it. Generally that kind of distinction doesn't matter but, when the game is very keen to switch area, it would be good to know. I don't know whether lines of script in blocks for which the IF condition has not been met have any effect at all on the compiler. Perhaps someone else will tell you.

As far as the block itself is concerned, I should clarify that I've been testing with the non-dummy AreaChecks (ie. notFeldepost's Inn) both at the very top and very bottom of BK_Cut1.bcs. Anyway, as far a reliability is concerned, I suspect you'll find that you can't make a "Protagonist Resurrection" mod that works with 100% reliability for BG:EE - if you could, then someone would have done it already!

On 3/27/2022 at 12:48 PM, marchitek said:

I tested moving Protagonist with MoveGlobal() action and I had problem when moving between areas. Although Protagonist was moved, camera was still on old location and there was nothing to do about it. Maybe MoveGlobalObject() works differently or maybe something else I was missing, e.g. this ActionOverride() wrapper.

 MoveGlobalObject() does work differently - the 2 objects do not have to be in the same area. Note that if Player1 dies in a master area, and you LeaveAreaLUA() them to a sub-area to be resurrected, then you can MoveGlobalObject() them back to the master area in which they died - at the spot bookmarked by "Minsc". That is not so great in itself, because you'll also want to move back to non-master areas. But that's not why I suggested it. If you're dead set on jumping back to right where you died, then I believe this would work:

1. Add an action to the response blocks in BK_Cut1.bcs, setting a variable with a unique value for each area;

2. Once you're ready for the fate spirit to send you back, have its dialogue trigger a cutscene;

3. Apply blindness, invisibility, non-detection to Player1 [Edit: Blindness was so you don't see anything in the region of [1.1] that you teleport to in the following step, but changing the visual range stat works even better (with an action or an effect). Invisibility and non-detection were so the same was true of other creatures, if necessary. They won't do anything in a cutscene, but I'm not 100% that they can't register your presence and act differently afterwards];

4. Player1 LeaveAreaLUA("ARXXX","",[1.1],X) back to the area they died in (as indicated by the variable in step 1);

5. MoveGlobalObject(Player1,"Minsc");

6. DestroySelf("Minsc")

7. Remove blindness, invisibility, non-detection on Player1

8. MoveGlobalObject(Player2,"Player1") x5 for the party; [Edit: On second thoughts, doing this then moving to positional offsets (in the next step) risks having party members with selection circles stuck inside each other. Probably better to CreateCreatureObjectOffset("PlaceHolderForPlayer2",Player1,P:Offset*); MakeGlobalOverride("PlaceHolderForPlayer2"); and then MoveGlobalObject(Player2,"PlaceHolderForPlayer2"), instead of this and the next step];

9. MoveToObjectOffset(Player1,P:Offset*) x5, so the party isn't all sat on Player1;

10. EndCutSceneMode().

11. Round 2 - fight!

On 3/27/2022 at 12:48 PM, marchitek said:

Would you be a problem for sure to share full codebase of your mod? It would be easier for me to test and compare our solutions, My recent code is currently here.

 It would, because my mod doesn't exist! I think I did a site search for master area, and I was already interested in protagonist resurrection, so I just thought "hmm, I wonder...".

On 3/27/2022 at 12:48 PM, marchitek said:

I will strat with resolving respawn point based on master area right away.

 Well, if you want to give AreaCheck() a whirl, then you're basically there already without modding any other files!

On 3/27/2022 at 12:48 PM, marchitek said:

I started with "temple" approach because imho it fits better to BG1 and it seems to be less work (don't need to create separate area, dialogues, area leave mechanism etc)

 You may find that this won't work as you want it to work. You'll be able to mod the Raise Dead spell offered in the temple, but you also talked about detecting current XP, and deducting a rough percentage (based on thresholds) of XP. I don't think you can do that with a single store.

Anyway, I'm tapping out of further lengthy replies on the stuff that I'm not looking to do myself. Good luck with it; it's a cool idea. For me, I need to see if I can get Player1 reliably resurrecting without interrupting the game (in other words, replace block 2 in my Baldur.bcs with something less likely to crash).

Edited by The_Baffled_King
Link to comment

In brief, because I realize I missed your edit (sorry):

Glad it works for you, too. I'm afraid there's no solving CopyGroundPiles(), at least in the sense of collecting loot that wasn't yours already.

11 hours ago, marchitek said:

I replaced ApplySpellRES("BKPRRP1",Player1) with normal resurrection and it seems also fine.

Yep. BKPRRP1.SPL was mainly for the block 2. It resurrects the protagonist invisible, with no animation, and with no foot circle, so I can play on without worry that a lack of Player1 will crash the game. I kept it for block 1 because it also removes the sound effect and animation for the resurrection spell - and its weird to hear/see it before 'waking up' at a temple.

11 hours ago, marchitek said:

Do you think having this resurrection in two steps is necessary?

Do you mean two resurrection spells, or the two separate cutscenes?

I wanted to resurrect the protagonist ASAP, and before going into an external cutscene, because having no Player1 is not normal and the game is a bit finicky. So the first resurrection was timed for as soon as the FadeToColour() has nearly finished. The second resurrection does two things: first, it provides the animation and sound effect, for aesthetic purposes; second, it heals any damage taken if the first resurrection put Player1 into a spot with a continuous damage effect (eg Ice Storm).

It is possible that the safest thing to do is to wait on the resurrection until the temple. I have just tried that (Player1 in sub area; other party NPC in different area; no initial resurrection; then go LeaveAreaLUA(AR4802) > SetMasterArea(AR4802) > resurrection all in the second cutscene, BK_Cut2.bcs. It ran 15 or so times without a crash, then I got bored. Honestly, the single most important thing seems to be to move into cutscene mode ASAP. I'm afraid optimal scripting is beyond me; you're better hearing from others.

One final thing: maybe the parsing in cutscenes was what tripped you up? It's different to that in other .bcs files, and also there are 2 types. StartCutScene("name") and StartCutSceneEx("name",FALSE) execute all blocks without checking conditions. StartCutSceneEx("name",TRUE) executes all blocks that evaluate to TRUE.

Link to comment
21 hours ago, The_Baffled_King said:

Anyway, I'm tapping out of further lengthy replies on the stuff that I'm not looking to do myself. Good luck with it; it's a cool idea.

Sure. I will need some time anyway to process all the help that you already gave me. 😀 Good luck for you too!

 

16 hours ago, The_Baffled_King said:

[...] Honestly, the single most important thing seems to be to move into cutscene mode ASAP. I'm afraid optimal scripting is beyond me; you're better hearing from others.

One final thing: maybe the parsing in cutscenes was what tripped you up? It's different to that in other .bcs files, and also there are 2 types. StartCutScene("name") and StartCutSceneEx("name",FALSE) execute all blocks without checking conditions. StartCutSceneEx("name",TRUE) executes all blocks that evaluate to TRUE.

Yes, I would also bet on cutscenes. I remember that I tested that but very briefly (it looks that too briefly). StartCutSceneEx would be great for me to avoid big switch blocks that would normally polluted area or global scripts. I saw it somewhere during browsing IESDP, but it didn't bring my attention, now, based on your examples, I can see how cool tool it could be in my case.

 

16 hours ago, The_Baffled_King said:

Yep. BKPRRP1.SPL was mainly for the block 2. It resurrects the protagonist invisible, with no animation, and with no foot circle, so I can play on without worry that a lack of Player1 will crash the game.

I would be grateful if you could upload this spl file. I'm just starting with opcodes etc and this could be very helpful for me to see what are possibilities for this.

 

21 hours ago, The_Baffled_King said:

MoveGlobalObject() does work differently - the 2 objects do not have to be in the same area. Note that if Player1 dies in a master area, and you LeaveAreaLUA() them to a sub-area to be resurrected, then you can MoveGlobalObject() them back to the master area in which they died - at the spot bookmarked by "Minsc". That is not so great in itself, because you'll also want to move back to non-master areas. But that's not why I suggested it. If you're dead set on jumping back to right where you died, then I believe this would work: [...]

I would definitely try that. I was going to start with StorePartyLocation(), but this is one global state, if other script use it before player choose to go back, my state would be gone.

Link to comment
7 hours ago, marchitek said:

StartCutSceneEx would be great for me to avoid big switch blocks that would normally polluted area or global scripts.

Another way to avoid the above is to use scripts run from invisible creatures, which end in DestroySelf() once their purpose is served.

A few warnings/tips regarding cutscenes, as they are a pain: (1) Switch() does not work in a cutscene; (2) response blocks that lack a CutSceneId() at their beginning will not execute, although the rest of the cutscene will work okay; (3) you can use a generic resource for that purpose if its convenient/necessary - for example, many in SoD use CutSceneId("bdcutid") - although I assume that the resource has to exist as a .cre; (4) although a cutscene script executes only once, so a cutscene cannot make use of the new value of a variable changed within that cutscene, you can get around that by re-starting the cutscene from within itself - the IESDP has a really helpful example of that.

7 hours ago, marchitek said:

I would be grateful if you could upload this spl file. I'm just starting with opcodes etc and this could be very helpful for me to see what are possibilities for this.

Sure. I just took the vanilla Resurrection spell (SPPR712.SPL) and used NearInfinity to mod it, so compare against that. Note that I only really took a good look at opcodes myself recently. I am far from an expert on their use and, honestly, it's not something I want to focus on.

With BKPRRP1.SPL, the orignal Effect #2 (sound and animation) is removed. Effects #2, #3, and #4 are the ones I added. They carry out the visual requirements for turning a Player1 that has been killed into a sort of ghost, although more would be needed to negate the other influences that the Player1 would have on the game.

With BKPR712.SPL, Effect #27 is the one I added (the original Effect #27 is Effect #28). See how oppcode 321 targets BKPRRP1.SPL, removing the changes it made? The prefix is changed from "PR" to "BK" for convenience; for a mod I would change every spell that has the Raise Dead oppcode, adding oppcode 321 to negate BKPRRP1.SPL.

7 hours ago, marchitek said:

I would definitely try that. I was going to start with StorePartyLocation(), but this is one global state, if other script use it before player choose to go back, my state would be gone.

Yeah, it's a shame. You can store location co-ordinates in a variable, but only for Create() Move() actions, when what you need is to jump or to teleport to the locations.

BKPRRP1.SPL BKPR712.SPL

Edited by The_Baffled_King
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...