Party Management via Dialog

From Divinity Engine Wiki
Jump to: navigation, search

PLEASE READ THE DISCUSSION PAGE - There are some key points I missed, which you will need to add to make this work nicely in game.

https://docs.larian.game/Talk:Party_Management_via_Dialog


So here is a rather long 1 hour tutorial (apologies) on how you can give the player the ability to manage a party by talking to NPCs I also cover the character creation script inclusion (which is available in other posts), as this is necessary for this to work.

  • The player can recruit companions via having a dialog with them.
  • They can dismiss them and then remove them from the party.
  • They can replace with another character again by a simple conversation.
  • There are no dependencies on other mods.

There is a also a variable for Maximum party size so you can restrict the number of companions (although the player can swap out whoever they like as long as they don't over do the maximum party number)

Here is the complete video tutorial which starts from a complete blank level. The code is in the post below (and is commented) if you would rather cut and paste.

Code for GLO_Party_Management

INIT SECTION

// Set this variable to your party size in this example party size is 4 total, including you.
DB_Scottworld_MaxPartySize(4);

KB SECTION

// Procedure to add an NPC to the party..
PROC
PROC_AddPlayerToParty((CHARACTERGUID)_Char)
AND
CharacterGetDisplayName(_Char, _, _name)
AND
StringConcatenate(_name, " Has joined your party",_MsgDisplay)
THEN
DB_IsPlayer(_Char);
CharacterMakePlayer(_Char);
ShowNotification(_MsgDisplay);

// Procedure to remove player from the party
PROC
PROC_RemovePlayerFromParty((CHARACTERGUID)_Char)
AND
CharacterGetDisplayName(_Char, _, _name)
AND
StringConcatenate(_name, " Has left your party",_MsgDisplay)
THEN
NOT DB_IsPlayer(_Char);
CharacterMakeNPC(_Char);
CharacterRemoveFromParty(_Char);
ShowNotification(_MsgDisplay);

// Event to check party number and set MAX Flag when an NPC joins party
IF
CharacterJoinedParty(_char)
AND
SysCount("DB_IsPlayer",1,_PlayerCount)
AND
DB_Scottworld_MaxPartySize(_PlayerMax)
AND
_PlayerCount == _PlayerMax
THEN
ShowNotification("Max Party Size Reached");
GlobalSetFlag("GEN_MaxPlayerCountReached");

// Event to check party number unset the max flag when a party member leaves.
IF
CharacterLeftParty(_char)
AND
SysCount("DB_IsPlayer",1,_PlayerCount)
AND
DB_Scottworld_MaxPartySize(_PlayerMax)
AND
_PlayerCount < _PlayerMax
THEN
//ShowNotification("Party Dropped by 1");
GlobalClearFlag("GEN_MaxPlayerCountReached");

// If a NPC sets their InParty flag.. call a proc to add them to the party.
IF
ObjectFlagSet("InParty", _, _Dialog)
AND
DialogGetInvolvedNPC(_Dialog, 1, _npc)
THEN
PROC_AddPlayerToParty((CHARACTERGUID)_npc);

// If a Player clears their InParty flag.. call a proc to remove them from the party.
IF
ObjectFlagCleared("InParty", _, _Dialog)
AND
DialogGetInvolvedPlayer(_Dialog, 1, _player)
THEN
PROC_RemovePlayerFromParty((CHARACTERGUID)_player);


Code for CharacterCreation


INIT SECTION

DB_CharacterCreationLevels("SYS_Character_Creation_A");

// change this to point to your level name
DB_GLO_FirstLevelAfterCharacterCreation("Tutorials");

// level name, start point trigger (this trigger needs to be GLOBAL)
DB_CharacterCreationTransitionInfo("Tutorials",(TRIGGERGUID)TRIGGERGUID_STARTPOINT_1d9675b4-50f6-4665-b630-46c4f5a6f128);


DB_CharacterCreationDummy((CHARACTERGUID)S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406);
DB_CharacterCreationDummy((CHARACTERGUID)S_GLO_CharacterCreationDummy_002_361dacdc-4135-4d3f-a9a2-3cad46ca246a);
DB_CharacterCreationDummy((CHARACTERGUID)S_GLO_CharacterCreationDummy_003_dded8c22-b28e-45c1-a074-eb0954602c8a);
DB_CharacterCreationDummy((CHARACTERGUID)S_GLO_CharacterCreationDummy_004_5f93cae7-6c10-4da1-b9a5-0efafc168c8e);

DB_GenericOrigins((CHARACTERGUID)S_Player_GenericOrigin_7b6c1f26-fe4e-40bd-a5d0-e6ff58cef4fe);
DB_GenericOrigins((CHARACTERGUID)S_Player_GenericOrigin2_c451954c-73bf-46ce-a1d1-caa9bbdc3cfd);
DB_GenericOrigins((CHARACTERGUID)S_Player_GenericOrigin3_41a06985-7851-4c29-8a78-398ccb313f39);
DB_GenericOrigins((CHARACTERGUID)S_Player_GenericOrigin4_41a594ed-b768-4289-9f17-59f701cc6910);[/i]

KB SECTION

IF
DB_CharacterCreationDummy(_Dummy)
THEN
DB_AvailableDummy(_Dummy);

IF
GameModeStarted("Campaign",1)
THEN
DB_InCharacterCreation(0);

IF
GameModeStarted("Campaign",1)
AND
DB_CharacterCreationDummy(_Dummy)
THEN
CharacterMakeNPC(_Dummy);
SetOnStage(_Dummy,0);

IF
GameModeStarted("Campaign",1)
AND
DB_GenericOrigins(_Dummy)
THEN
CharacterMakeNPC(_Dummy);
SetOnStage(_Dummy,0);

IF
GameModeStarted("Campaign",1)
AND
DB_GLO_FirstLevelAfterCharacterCreation(_Level)
AND
DB_CharacterCreationTransitionInfo(_Level,_Trigger)
THEN
SetOnStage(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406,1);
CharacterMakePlayer(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406);
MakePlayerActive(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406);
DB_IsPlayer(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406);
ProcMovePartyToStart(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406,_Trigger);

IF
RegionStarted(_Lvl)
AND
IsGameLevel(_Lvl,1)
THEN
DB_InCharacterCreation(0);

IF
CharacterCreationStarted(_)
AND
CharacterAddToCharacterCreation((CHARACTERGUID)CHARACTERGUID_S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406,0,_Success)
THEN
DB_InCharacterCreation(_Success);

IF
DB_InCharacterCreation(1)
AND
DB_CharacterCreationDummy(_Dummy)
THEN
SetOnStage(_Dummy,1);
TeleportTo(_Dummy,S_CharOriginDest_c9c5e1d7-1998-4d4e-aacb-3970e8823674);
CharacterMakePlayer(_Dummy, NULL_00000000-0000-0000-0000-000000000000);

IF
DB_InCharacterCreation(1)
AND
DB_GenericOrigins((CHARACTERGUID)_Org)
THEN
SetOnStage(_Org,1);
TeleportTo(_Org,S_CharOriginDest_c9c5e1d7-1998-4d4e-aacb-3970e8823674);
CharacterMakePlayer(_Org, NULL_00000000-0000-0000-0000-000000000000);

IF
DB_InCharacterCreation(1)
THEN
IterateUsers("_CCUserSetup");

IF
UserEvent(_User,"_CCUserSetup")
AND
GetUserProfileID(_User,_UserName)
AND
DB_CharacterCreationDummy(_Dummy)
AND
NOT DB_AssignedDummyForUser(_,_Dummy)
AND
NOT DB_AssignedDummyForUser(_UserName,_)
THEN
ProcAssignDummyToUser(_Dummy,_UserName);

IF
UserEvent(_User,"_CCUserSetup")
AND
GetUserProfileID(_User,_UserName)
AND
DB_AssignedDummyForUser(_UserName,_Dummy)
THEN
SetOnStage(_Dummy,1);
CharacterMakePlayer(_Dummy);
CharacterAssignToUser(_User,_Dummy);
MakePlayerActive(_Dummy);
DB_IsPlayer(_Dummy);

IF
CharacterCreationFinished((CHARACTERGUID)NULL_00000000-0000-0000-0000-000000000000)
AND
DB_InCharacterCreation(1)
AND
DB_CurrentLevel(_Lvl)
AND
DB_CharacterCreationLevels(_Lvl)
AND
DB_GLO_FirstLevelAfterCharacterCreation(_FirstLevel)
AND
DB_CharacterCreationTransitionInfo(_FirstLevel,_StartTrigger)
AND
DB_IsPlayer(_Char)
THEN
NOT DB_DoNotFace(_Char);
ProcMovePartyToStart(_Char,_StartTrigger);

IF
RegionStarted(_Region)
AND
IsGameLevel(_Region,1)
THEN
DB_StartedActualGame(1);

IF
UserDisconnected(_UserID,_,_UserProfile)
AND
NOT DB_InCharacterCreation(1)
AND 
NOT DB_StartedActualGame(1)
AND
DB_SelectedCC(_Char,_UserProfile)
THEN
NOT DB_IsPlayer(_Char);
ProcUnRegisterPlayerTriggers(_Char);

PROC
ProcMovePartyToStart((CHARACTERGUID)_NewChar,(TRIGGERGUID)_StartTrigger)
THEN
NOT DB_AlreadyTeleported(1);

PROC
ProcMovePartyToStart((CHARACTERGUID)_NewChar,(TRIGGERGUID)_StartTrigger)
AND
DB_TeleportedToStartCharacters(_Char)
AND
CharacterIsInPartyWith(_Char,_NewChar,1)
THEN
DB_AlreadyTeleported(1);

PROC
ProcMovePartyToStart((CHARACTERGUID)_NewChar,(TRIGGERGUID)_StartTrigger)
AND
NOT DB_AlreadyTeleported(1)
THEN
DB_TeleportedToStartCharacters(_NewChar);
CharacterTeleportPartiesToTrigger(_StartTrigger,"");

IF
RegionStarted(_Level)
AND
IsGameLevel(_Level,0)
AND
IsCharacterCreationLevel(_Level,0)
AND
DB_CharacterCreationDummy(_Dummy)
AND
_Dummy != CHARACTERGUID_S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406
THEN
TeleportTo(_Dummy,CHARACTERGUID_S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406);
CharacterMakePlayer(_Dummy);
DB_IsPlayer(_Dummy);

PROC
ProcRemovePreviousSelectedCharacter((STRING)_UserProfile)
AND
DB_SelectedCC((CHARACTERGUID)_Char,(STRING)_UserProfile)
THEN
ClearTag(_Char,"AVATAR");
NOT DB_IsPlayer(_Char);
ProcUnRegisterPlayerTriggers(_Char);
NOT DB_SelectedCC(_Char,_UserProfile);

PROC
ProcSetSelectedCharCreationPlayer((CHARACTERGUID)_Char,(STRING)_UserProfile)
THEN
ProcRemovePreviousSelectedCharacter(_UserProfile);
SetTag(_Char,"AVATAR");
DB_IsPlayer(_Char);
ProcRegisterPlayerTriggers(_Char);
DB_SelectedCC(_Char,_UserProfile);

IF
UserDisconnected(_UserID,_,_UserProfile)
AND
DB_InCharacterCreation(1)
THEN
ProcRemovePreviousSelectedCharacter(_UserProfile);
ProcRemovePreviousDummy(_UserProfile);

IF
CharacterSelectedInCharCreation(_Char,_UserID)
AND
GetUserProfileID(_UserID,_UserProfile)
THEN
ProcSetSelectedCharCreationPlayer(_Char,_UserProfile);

IF
CharacterSelectedInCharCreation(_Char,_UserID)
AND
CharacterHasTalent(_Char,"AnimalEmpathy",1)
THEN
SetTag(_Char,"PETPAL");

IF
UserConnected(_,_,_UserName)
AND
DB_InCharacterCreation(1)
AND
DB_CharacterCreationDummy(_Dummy)
AND
NOT DB_AssignedDummyForUser(_,_Dummy)
AND
NOT DB_AssignedDummyForUser(_UserName,_)
THEN
ProcAssignDummyToUser(_Dummy,_UserName);

PROC
ProcRemovePreviousDummy((STRING)_UserProfile)
AND
DB_AssignedDummyForUser(_UserProfile,_Dummy)
THEN
NOT DB_AssignedDummyForUser(_UserProfile,_Dummy);
DB_AvailableDummy(_Dummy);

PROC
ProcAssignDummyToUser((CHARACTERGUID)_Dummy,(STRING)_UserName)
AND
DB_AvailableDummy(_Dummy)
THEN
CharacterMakePlayer(_Dummy, NULL_00000000-0000-0000-0000-000000000000);

PROC
ProcAssignDummyToUser((CHARACTERGUID)_Dummy,(STRING)_UserName)
AND
DB_AvailableDummy(_Dummy)
AND
CharacterAddToCharacterCreation(_Dummy,0,1)
THEN
DB_AssignedDummyForUser(_UserName,_Dummy);

PROC
ProcAssignDummyToUser((CHARACTERGUID)_Dummy,(STRING)_UserName)
AND
DB_AvailableDummy(_Dummy)
THEN
DB_AssignedDummyForUser(_UserName,_Dummy);

PROC
ProcAssignDummyToUser((CHARACTERGUID)_Dummy,(STRING)_UserName)
THEN
NOT DB_AvailableDummy(_Dummy);

IF
UserConnected(_UserID,_,_UserName)
AND
DB_InCharacterCreation(1)
AND
DB_AssignedDummyForUser(_UserName,_Dummy)
THEN
SetOnStage(_Dummy,1);
CharacterMakePlayer(_Dummy);
CharacterAssignToUser(_UserID,_Dummy);
MakePlayerActive(_Dummy);

IF
CharacterCreationFinished((CHARACTERGUID)NULL_00000000-0000-0000-0000-000000000000)
AND
DB_GenericOrigins(_Dummy)
AND
NOT DB_SelectedCC(_Dummy,_)
THEN
CharacterRemoveFromParty(_Dummy);
CharacterMakeNPC(_Dummy);
SetOnStage(_Dummy,0);

IF
CharacterCreationFinished((CHARACTERGUID)NULL_00000000-0000-0000-0000-000000000000)
AND
DB_CharacterCreationDummy(_Dummy)
THEN
CharacterRemoveFromParty(_Dummy);
CharacterMakeNPC(_Dummy);
SetOnStage(_Dummy,0);

IF
CharacterCreationFinished(_)
AND
DB_InCharacterCreation(_Value)
THEN
NOT DB_InCharacterCreation(_Value);