Difference between revisions of "Party Management via Dialog"

From Divinity Engine Wiki
Jump to: navigation, search
 
(12 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
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
 
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.
 
I also cover the character creation script inclusion (which is available in other posts), as this is necessary for this to work.
Line 11: Line 17:
 
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.
 
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.
  
<youtube>https://youtu.be/-Wv1Ja4Uw-Q</youtube>
+
<youtube>https://youtu.be/WYBKk4pYfPo</youtube>
 
 
 
 
 
 
  
 
Code for <big>GLO_Party_Management</big>
 
Code for <big>GLO_Party_Management</big>
Line 21: Line 24:
  
 
<pre>
 
<pre>
// Set this variable to your party size N+1  in this example party size is 4 total, including you.
+
// Set this variable to your party size in this example party size is 4 total, including you.
DB_Scottworld_MaxPartySize(5);
+
DB_Scottworld_MaxPartySize(4);
 
</pre>
 
</pre>
  
Line 28: Line 31:
  
 
<pre>
 
<pre>
// Procedure to add the NPC you are talking to into the party..
+
// Procedure to add an NPC to the party..
 
PROC
 
PROC
 
PROC_AddPlayerToParty((CHARACTERGUID)_Char)
 
PROC_AddPlayerToParty((CHARACTERGUID)_Char)
Line 40: Line 43:
 
ShowNotification(_MsgDisplay);
 
ShowNotification(_MsgDisplay);
  
// Procedure to remove the player you are talking to from the party
+
// Procedure to remove player from the party
 
PROC
 
PROC
 
PROC_RemovePlayerFromParty((CHARACTERGUID)_Char)
 
PROC_RemovePlayerFromParty((CHARACTERGUID)_Char)
Line 53: Line 56:
 
ShowNotification(_MsgDisplay);
 
ShowNotification(_MsgDisplay);
  
// Event on player joining the party
+
// Event to check party number and set MAX Flag when an NPC joins party
 
IF
 
IF
 
CharacterJoinedParty(_char)
 
CharacterJoinedParty(_char)
Line 63: Line 66:
 
_PlayerCount == _PlayerMax
 
_PlayerCount == _PlayerMax
 
THEN
 
THEN
// you can probably remove this notification - its just to alert you to the event.
 
 
ShowNotification("Max Party Size Reached");
 
ShowNotification("Max Party Size Reached");
 
GlobalSetFlag("GEN_MaxPlayerCountReached");
 
GlobalSetFlag("GEN_MaxPlayerCountReached");
  
// event on player leaving the party
+
// Event to check party number unset the max flag when a party member leaves.
 
IF
 
IF
 
CharacterLeftParty(_char)
 
CharacterLeftParty(_char)
Line 80: Line 82:
 
GlobalClearFlag("GEN_MaxPlayerCountReached");
 
GlobalClearFlag("GEN_MaxPlayerCountReached");
  
// event on when the fighter joins.
+
// If a NPC sets their InParty flag.. call a proc to add them to the party.
IF
 
ObjectFlagSet("Fighter_InParty", _, _Dialog)
 
AND
 
DialogGetInvolvedNPC(_Dialog, 1, _npc)
 
THEN
 
PROC_AddPlayerToParty((CHARACTERGUID)_npc);
 
 
 
 
 
// event on when the fighter leaves.
 
IF
 
ObjectFlagCleared("Fighter_InParty", _, _Dialog)
 
AND
 
DialogGetInvolvedPlayer(_Dialog, 1, _player)
 
THEN
 
PROC_RemovePlayerFromParty((CHARACTERGUID)_player);
 
 
 
// event on when the rogue joins.
 
IF
 
ObjectFlagSet("Rogue_InParty", _, _Dialog)
 
AND
 
DialogGetInvolvedNPC(_Dialog, 1, _npc)
 
THEN
 
PROC_AddPlayerToParty((CHARACTERGUID)_npc);
 
 
 
// event on when the rogue leaves.
 
IF
 
ObjectFlagCleared("Rogue_InParty", _, _Dialog)
 
AND
 
DialogGetInvolvedPlayer(_Dialog, 1, _player)
 
THEN
 
PROC_RemovePlayerFromParty((CHARACTERGUID)_player);
 
 
 
// event on when the wizard joins.
 
IF
 
ObjectFlagSet("Wizard_InParty", _, _Dialog)
 
AND
 
DialogGetInvolvedNPC(_Dialog, 1, _npc)
 
THEN
 
PROC_AddPlayerToParty((CHARACTERGUID)_npc);
 
 
 
// event on when the wizard leaves.
 
IF
 
ObjectFlagCleared("Wizard_InParty", _, _Dialog)
 
AND
 
DialogGetInvolvedPlayer(_Dialog, 1, _player)
 
THEN
 
PROC_RemovePlayerFromParty((CHARACTERGUID)_player);
 
 
 
// event on when the Ranger joins.
 
 
IF
 
IF
ObjectFlagSet("Ranger_InParty", _, _Dialog)
+
ObjectFlagSet("InParty", _, _Dialog)
 
AND
 
AND
 
DialogGetInvolvedNPC(_Dialog, 1, _npc)
 
DialogGetInvolvedNPC(_Dialog, 1, _npc)
Line 137: Line 90:
 
PROC_AddPlayerToParty((CHARACTERGUID)_npc);
 
PROC_AddPlayerToParty((CHARACTERGUID)_npc);
  
// event on when the ranger leaves.
+
// If a Player clears their InParty flag.. call a proc to remove them from the party.
 
IF
 
IF
ObjectFlagCleared("Ranger_InParty", _, _Dialog)
+
ObjectFlagCleared("InParty", _, _Dialog)
 
AND
 
AND
 
DialogGetInvolvedPlayer(_Dialog, 1, _player)
 
DialogGetInvolvedPlayer(_Dialog, 1, _player)
Line 156: Line 109:
 
DB_CharacterCreationLevels("SYS_Character_Creation_A");
 
DB_CharacterCreationLevels("SYS_Character_Creation_A");
  
 +
// change this to point to your level name
 
DB_GLO_FirstLevelAfterCharacterCreation("Tutorials");
 
DB_GLO_FirstLevelAfterCharacterCreation("Tutorials");
  

Latest revision as of 12:33, 31 October 2017

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);