Jump to content

How to stash party members somewhere?


Recommended Posts

Posted (edited)
10 hours ago, jmerry said:

That's why you grab their script names from a 2DA and build your script up during installation

I'm not sure I want to mandate a late installation here... I guess it might not hurt? I haven't really thought about install order yet.  But all of the mods that cover similar ground (EET itself, EndlessBG1, Transitions, Another Fine Hell) all come before mod NPCs in the install order.

10 hours ago, jmerry said:

regarding bdcut61, unmodded SoD does not include the PlayerN blocks in that scene. I wonder how robust that tweaked version is to a party with multiple NPCs not in the base game. Sure, those blocks should all run simultaneously when this cutscene is run with StartCutSceneEx, but that still leaves a chance to break things if the synchronization is a bit off and the PlayerN objects get redefined as people leave

It's from EET and lots and lots of people play EET with lots of mod NPCs, so... seems okay? Also, the PlayerX values do not get reevaluated until a save/load cycle, so doing this in a single cutscene should be pretty bulletproof.

13 hours ago, jastey said:

K#TELBGT.bcs is for transition to BG2.

Yes - this thread is specifically for a mod component that address the transition to BG2. SoD removes all party members (looks in the cutscenes at DragonSpear Castle post-Skie-death and the next one passing by Sorcerous Sundries) and eventually sends Charname alone to BD6100.are.  For more context, I am working on a "Skip SoD" mod component that removes all party members earlier, at the end of BG1 and then sends Charname, alone, ahead to the end-of-SoD BD6100.are.

So the idea is to mimic how the party-member-removal is handled by SoD. Once you are in BD6100.are, whether in EET or in an EET game that will export to BG2, the game should basically "think" you have completed SoD, and handle the beginning of BG2 accordingly. If that makes sense.

Edited by subtledoctor
Link to comment
5 minutes ago, subtledoctor said:

So the idea is to mimic how the party-member-removal is handled by SoD. Once you are in BD6100.are, whether in EET or in an EET game that will export to BG2, the game should basically "think" you have completed SoD, and handle the beginning of BG2 accordingly. If that makes sense.

In case that was a question, then you could use what EndkessBG1 does if you chose the according reply options. I spent some time fiddling with this, what ENdlessBG1 does is the stablest transition I could get. In short: use as much of the original EET transition (including the K#TELBGT script) as possible).

Link to comment

Okay. Confirming that the PlayerN identifiers can only change for members currently in the party on loading does clear that up; there definitely won't be a load in the middle of a cutscene, so it is safe to use them in this way.

The bit to watch out for here is the distinction between recruited NPCs (not on the list) and additional player-created characters. That's what the !Name("None",PlayerN) conditions are about - additional player-created characters do stick around in the EET version of that cutscene, while recruited NPCs leave.

Link to comment
Posted (edited)
9 hours ago, jastey said:

In case that was a question, then you could use what EndkessBG1 does

This was my first instinct, but I am having a bit of trouble parsing what happens. When I install EndlessBG1 on EET there is a dialogue option that says "I am going to travel in the South for a while" and then this script fires:

Spoiler
 IF
	!AreaCheck("bd6100")  // The Ambush
 THEN
	RESPONSE #100
		CutSceneId(Player1)
		FadeToColor([40.0],0)
		DisableAI(Player1,TRUE)
		DisableAI(Player2,TRUE)
		DisableAI(Player3,TRUE)
		DisableAI(Player4,TRUE)
		DisableAI(Player5,TRUE)
		DisableAI(Player6,TRUE)
		SmallWait(5)
		ActionOverride(Player2,LeaveAreaLUA("bd6100","",[535.340],SE))  // The Ambush
		ActionOverride(Player3,LeaveAreaLUA("bd6100","",[565.280],SE))  // The Ambush
		ActionOverride(Player4,LeaveAreaLUA("bd6100","",[505.300],SE))  // The Ambush
		ActionOverride(Player5,LeaveAreaLUA("bd6100","",[535.230],SE))  // The Ambush
		ActionOverride(Player6,LeaveAreaLUA("bd6100","",[470.270],SE))  // The Ambush
		LeaveAreaLUAPanic("bd6100","",[600.330],SE)  // The Ambush
		LeaveAreaLUA("bd6100","",[600.330],SE)  // The Ambush
		MultiPlayerSync()
		Wait(1)
		SetGlobal("bd_finale","bd6100",6)  // The Ambush
		EndCutSceneMode()
		CreateCreatureObject("K#TELBGT",Player1,0,0,0)  // No such index
 END

So it seems like it moves all the party members to BD6100.are?

And then K#TELBGT.bcs runs through the creature of the same name, which seems to make all party members unselectable, take their equipment (presumably for BG2 import), and then DestroySelf() them if they are not player-created (!Name("none",Player2)). And then jump everyone left directly to BG2?

Spoiler
IF
	Global("K#FrameDelay","LOCALS",0)
THEN
	RESPONSE #100
		DisableAI(Player1,FALSE)
		DisableAI(Player2,FALSE)
		DisableAI(Player3,FALSE)
		DisableAI(Player4,FALSE)
		DisableAI(Player5,FALSE)
		DisableAI(Player6,FALSE)
		SetGlobal("K#FrameDelay","LOCALS",1)
END

IF
	Global("K#FrameDelay","LOCALS",1)
	!Name("None",Player2)
THEN
	RESPONSE #100
		ActionOverride(Player2,MakeUnselectable(1))
		Continue()
END

IF
	Global("K#FrameDelay","LOCALS",1)
	!Name("None",Player3)
THEN
	RESPONSE #100
		ActionOverride(Player3,MakeUnselectable(1))
		Continue()
END

IF
	Global("K#FrameDelay","LOCALS",1)
	!Name("None",Player4)
THEN
	RESPONSE #100
		ActionOverride(Player4,MakeUnselectable(1))
		Continue()
END

IF
	Global("K#FrameDelay","LOCALS",1)
	!Name("None",Player5)
THEN
	RESPONSE #100
		ActionOverride(Player5,MakeUnselectable(1))
		Continue()
END

IF
	Global("K#FrameDelay","LOCALS",1)
	!Name("None",Player6)
THEN
	RESPONSE #100
		ActionOverride(Player6,MakeUnselectable(1))
		Continue()
END

IF
	Global("K#FrameDelay","LOCALS",1)
THEN
	RESPONSE #100
		SetGlobal("K#FrameDelay","LOCALS",2)
		AdvanceTime(ONE_MONTH)
		ActionOverride("K#ImportContainer",TakeCreatureItems(Player1,ALL))
		ActionOverride("K#ImportContainer",TakeCreatureItems(Player2,ALL))
		ActionOverride("K#ImportContainer",TakeCreatureItems(Player3,ALL))
		ActionOverride("K#ImportContainer",TakeCreatureItems(Player4,ALL))
		ActionOverride("K#ImportContainer",TakeCreatureItems(Player5,ALL))
		ActionOverride("K#ImportContainer",TakeCreatureItems(Player6,ALL))
		ActionOverride("K#ImportContainer",TakeCreatureItems("Imoen2",ALL))  // Imoen
		ActionOverride("K#ImportContainer",TakeCreatureItems("Jaheira",ALL))  // Jaheira
		ActionOverride("K#ImportContainer",TakeCreatureItems("Minsc",ALL))  // Minsc
END

IF
	Global("K#FrameDelay","LOCALS",2)
THEN
	RESPONSE #100
		SetGlobal("K#FrameDelay","LOCALS",3)
		ApplySpellRES("K#UNREST",Player1)  // No such index
		ApplySpellRES("K#UNREST",Player2)  // No such index
		ApplySpellRES("K#UNREST",Player3)  // No such index
		ApplySpellRES("K#UNREST",Player4)  // No such index
		ApplySpellRES("K#UNREST",Player5)  // No such index
		ApplySpellRES("K#UNREST",Player6)  // No such index
END

IF
	InPartyAllowDead(Player2)
	!Name("None",Player2)
THEN
	RESPONSE #100
		ActionOverride(Player2,LeaveParty())
		ActionOverride(Player2,DestroySelf())
		Continue()
END

IF
	InPartyAllowDead(Player3)
	!Name("None",Player3)
THEN
	RESPONSE #100
		ActionOverride(Player3,LeaveParty())
		ActionOverride(Player3,DestroySelf())
		Continue()
END

IF
	InPartyAllowDead(Player4)
	!Name("None",Player4)
THEN
	RESPONSE #100
		ActionOverride(Player4,LeaveParty())
		ActionOverride(Player4,DestroySelf())
		Continue()
END

IF
	InPartyAllowDead(Player5)
	!Name("None",Player5)
THEN
	RESPONSE #100
		ActionOverride(Player5,LeaveParty())
		ActionOverride(Player5,DestroySelf())
		Continue()
END

IF
	InPartyAllowDead(Player6)
	!Name("None",Player6)
THEN
	RESPONSE #100
		ActionOverride(Player6,LeaveParty())
		ActionOverride(Player6,DestroySelf())
		Continue()
END

IF
	True()
THEN
	RESPONSE #100
		GivePartyAllEquipment()
		SetGlobal("bd_plot","GLOBAL",700)
		SetGlobal("SPRITE_IS_DEADKHALID","GLOBAL",1)
		SetGlobal("SPRITE_IS_DEADDYNAHEIR","GLOBAL",1)
		SetGlobal("SPRITE_IS_DEADCALAHAN","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADCARBOS","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADDIANA","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADEDWIN","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADFTOWNNASH3","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADGORF","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADIMOEN2","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADKING","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADKNIGHT1","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADPAWN","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADQUEEN","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADROGER","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADSENDAI","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADSHANK","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADTARNOR","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADTAZOK","GLOBAL",0)
		SetGlobal("SPRITE_IS_DEADWILLIAM","GLOBAL",0)
		Wait(1)
		StartMovie("INTRO15F")
		MoveToCampaign("SoA")
		LeaveAreaLUAPanic("AR0602","",[3744.2801],S)  // Irenicus's Dungeon 1st Floor
		ActionOverride(Player1,LeaveAreaLUA("AR0602","",[3744.2801],S))  // Irenicus's Dungeon 1st Floor
		ActionOverride(Player2,LeaveAreaLUA("AR0602","",[3585.2917],SWW))  // Irenicus's Dungeon 1st Floor
		ActionOverride(Player3,LeaveAreaLUA("AR0602","",[3532.2956],NW))  // Irenicus's Dungeon 1st Floor
		ActionOverride(Player4,LeaveAreaLUA("AR0602","",[3374.3068],NNE))  // Irenicus's Dungeon 1st Floor
		ActionOverride(Player5,LeaveAreaLUA("AR0602","",[3824.2447],E))  // Irenicus's Dungeon 1st Floor
		ActionOverride(Player6,LeaveAreaLUA("AR0602","",[3889.2479],SSE))  // Irenicus's Dungeon 1st Floor
		MultiPlayerSync()
		DestroySelf()
END

I can't see where that even leaves room for the ambush cutscene to occur...

My mod has a plot point where the party members are conspicuously removed from the party, leaving Charname alone, and then just like in SoD, Charname must escape through BD0104.are, BD0105.are, and BD6000.are, alone and with no party members, before arriving at BD6200.are. So I cannot just mimic EndlessBG1. What I need to do is more like what SoD itself does, removing the party several areas and cutscenes before Charname ever gets to BD6100. (Also, whatever SoD does to allow multiplayer games to get through this part is presumably a model I could use.)

Put another way: Endless BG1 has an option to skip SoD in its entirety and jumps directly to BG2; my mod skip to the end of SoD, and then play through the last several scenes of SoD before transitioning to BG2.

Maybe what I need to do is spawn a cloned version of K#TELBGT.cre, which runs K#TELBGT.bcs at that earlier stage - or, just copy the actions in that script for use in my own cutscene

Edited by subtledoctor
Link to comment
9 hours ago, subtledoctor said:

So it seems like it moves all the party members to BD6100.are?

Yes. Because then, the leaving and stuff is handled by EET itself (via K#TELBGT), which is also where mod NPCs with an EET transition will have added their own handling of the transition etcpp; the ones who don't will leave anyhow because EET took care of that (via the !"None" script blocks).

Yes, there is also a container in bd6100 (EET) that takes all items for detection of import later etc.

9 hours ago, subtledoctor said:

I can't see where that even leaves room for the ambush cutscene to occur...

Ah, now I get it. The cutscene does not run, EndlessBG1 jumps past it.

Reason again: I tried to make it work in a useful way. But: the SoD kidnapping scene happens after everyone left the party and I&J&K&M&D rejoined. Or not, if there is multiplayer characters. I tried to have it in, it makes a lot of sense, but I either didn't get it to run or NPCs were under some weird spell afterwards, had a purple circle, or whatever. So I decided that the video sequence is enough to let the player know what happened.

Link to comment
Posted (edited)
8 hours ago, jastey said:

tried to make it work in a useful way. But: the SoD kidnapping scene happens after everyone left the party and I&J&K&M&D rejoined. Or not, if there is multiplayer characters. I tried to have it in, it makes a lot of sense, but I either didn't get it to run or NPCs were under some weird spell afterwards, had a purple circle, or whatever.

I think I have worked it out. I am making a clone of K#TELBGT - can't use the same one, because the script will jump ahead to BG2 too early, and I don't want to change that script at all. But I can create a similar creature in the Ducal Palace and again in the FF headquarters, which will:

  1. Make all party members unselectable while Charname goes to the FF HQ for cut-scenes
  2. Take party members'  equipment and put it in K#ImportContainer (might have to refine this to exempt I/J/K/M/D)
  3. Make named party members selectable again, then kick them out of the party
  4. In BD0105, move unnamed party members there and make them selectable again, so they can join Charname through sewers and cave

Then in BD6100, K#TELBGT will operate as usual... some of if might be redundant (move someone's equipment to the import container, but their equipment was already moved there) but that's fine. The ambush scene proceeds as normal, and you get moved to AR0602 in the BG2 campaign.

The purple circle thing was driving me crazy. It is a result of the ActionOverride(PlayerX,MakeUnselectable(3600000)) script actions. I was desperately trying to find a way to undo that, but the game does not have any means of doing so! There is no MakeSelectable() action. But! I discovered that you can simply apply MakeUnselectable() again with a shorter duration, and it will undo the first instance of itself. I wasn't properly setting an EndOfBG1 variable before, which EET uses in its AR0602 initialization scripts. But now I have everyone going unselectable at the appropriate time, everyone leaving the party at the appropriate time, and everyone becoming selectable and reappearing for the party at the appropriate time. So, I guess, so far so good!

I still need to do testing with various NPCs and with player-created non-Charname PCs. And I don't know what will happen in a multiplayer game. The plot here centers around Charname being cloned and separated from the rest of the party, and there is not space for other characters to be part of that. So I think my design decision for multiplayer can mimic what happens to player-created characters: the non-Charname players will see their characters become unselectable and will watch the plot unfold for Player1; then they will be transported to BD0105 where they can rejoin Player1 and regain control of their character. Then EET will transport them to AR0602 however it normally does so (I have no idea) and being freed from the cells in AR0602 will happen however it normally happens for multiplayer (I have no idea). Player2 et al. will lose control of their character for a few seconds, but that's not a big deal, it happens to Player1 plenty of times in the single-player game anyway.

That's the idea, at least. As of this morning I have the first test install where it actually works. Except the part where I need to apply opcode 165 on some people in a cutscene. I have the cutscene script ApplySpellRES() a spell with a 30-second op165 effect, and it just... doesn't happen. I can't figure out why.

Edited by subtledoctor
Link to comment
On 5/4/2024 at 7:09 AM, CrevsDaak said:

I was under the impression scripting Objects remained valid for the entire block once it's already running, in particular when they still are present in the game. Not sure why I think so, as I've never actually tested it, but I think I came to this conclusion when looking into how Objects were selected during the targeting process triggers perform when evaluated, I think I was trying to find out why SCS scripts use Continue() as much as they do (I remember seeing DavidW mention, that it was to hasten how a spellcasting block would be triggered, as the objects remained identical. However, I thought it some complex inner working of the engine instead of understanding that it just entails an immediate sequence of triggers being checked under the same game state).

AI targeting mainly uses LastSeenBy(), which indeed can persist indefinitely (until reload, I think).
I'm not sure it remains true for PlayerX, because they kinda cease to be PlayerX upon leaving. Could be wrong, though.

On 5/4/2024 at 9:57 PM, jmerry said:

Sure, those blocks should all run simultaneously when this cutscene is run with StartCutSceneEx, but that still leaves a chance to break things if the synchronization is a bit off and the PlayerN objects get redefined as people leave.

PlayerX order doesn't change until save and reload. You can kick character in second slot out, then recruit someone, save, and the newly recruited NPC will just replace the old one in the second slot, instead of shifting the whole party.

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...