Last active
March 25, 2020 11:54
-
-
Save LaughingLeader/018f044cadd2de1e4aa71dc9f5936c0e to your computer and use it in GitHub Desktop.
A code snippet for making a status stack with story scripting, for Divinity: Original Sin 2 Classic and Definitive Edition.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Version 1 | |
SubGoalCombiner SGC_AND | |
INITSECTION | |
MyMod_StackingStatuses_InitSettings(); | |
KBSECTION | |
//REGION SETTINGS_INITIALIZING | |
PROC | |
MyMod_StackingStatuses_InitSettings() | |
THEN | |
// We clear any previously stored data to support older saves, for if you end up changing your stacking statuses. | |
MyMod_StackingStatuses_ClearRegistered("HASTED"); | |
/* Stacking status registration. | |
Params: | |
1 - The status that gets applied to increase the stack. | |
2 - The stacking status that gets applied when the stack increases. | |
3 - (Optional) The duration of the stacking status. If omitted, -1.0 is used for a permanent status. | |
*/ | |
MyMod_StackingStatuses_Register_Stack("HASTED", "FORTIFIED", 12.0); | |
MyMod_StackingStatuses_Register_Stack("HASTED", "MAGIC_SHELL", 12.0); | |
MyMod_StackingStatuses_Register_Stack("HASTED", "HOLY_FIRE", 12.0); | |
MyMod_StackingStatuses_Register_Stack("HASTED", "INF_POWER", 12.0); | |
/* | |
To test these placeholder statuses, simply open the ReCon with F11 in the editor, | |
then enter statusapply HASTED 0 in the console. | |
*/ | |
//END_REGION | |
//REGION REGISTRATION | |
/* Set the initial stack index to 0 if it's never been set for this applying status. */ | |
PROC | |
MyMod_StackingStatuses_Register_Stack((STRING)_ApplyStatus, (STRING)_StackingStatus, (REAL)_Duration) | |
AND | |
NOT DB_MyMod_StackingStatuses_Count(_ApplyStatus, _) | |
THEN | |
DB_MyMod_StackingStatuses_Count(_ApplyStatus, 0); | |
/* Register the status with an index, so it can be used later in status applying rules. */ | |
PROC | |
MyMod_StackingStatuses_Register_Stack((STRING)_ApplyStatus, (STRING)_StackingStatus, (REAL)_Duration) | |
AND | |
DB_MyMod_StackingStatuses_Count(_ApplyStatus, _StackNumber) | |
AND | |
IntegerSum(_StackNumber, 1, _NextStackNumber) | |
THEN | |
DB_MyMod_StackingStatuses_Stacks(_ApplyStatus, _StackNumber, _StackingStatus, _Duration); | |
NOT DB_MyMod_StackingStatuses_Count(_ApplyStatus, _StackNumber); | |
DB_MyMod_StackingStatuses_Count(_ApplyStatus, _NextStackNumber); | |
/* The default duration if not set is -1.0. */ | |
PROC | |
MyMod_StackingStatuses_Register_Stack((STRING)_ApplyStatus, (STRING)_StackingStatus) | |
THEN | |
MyMod_StackingStatuses_Register_Stack(_ApplyStatus, _StackingStatus, -1.0); | |
/* This proc is for clearing stored status settings data, for if/when you change stacks, names, durations, etc. | |
This data needs to be updated in older saves that used your mod. */ | |
PROC | |
MyMod_StackingStatuses_ClearRegistered((STRING)_ApplyStatus) | |
AND | |
DB_MyMod_StackingStatuses_Count(_ApplyStatus, _StackNumber) | |
THEN | |
NOT DB_MyMod_StackingStatuses_Count(_ApplyStatus, _StackNumber); | |
PROC | |
MyMod_StackingStatuses_ClearRegistered((STRING)_ApplyStatus) | |
AND | |
DB_MyMod_StackingStatuses_Stacks(_ApplyStatus, _StackNumber, _StackingStatus, _Duration) | |
THEN | |
NOT DB_MyMod_StackingStatuses_Stacks(_ApplyStatus, _StackNumber, _StackingStatus, _Duration); | |
//END_REGION | |
//REGION DEBUG | |
PROC | |
MyMod_DebugMessage((STRING)_Message, (INTEGER)_StackNumber, (STRING)_Status) | |
AND | |
IntegertoString(_StackNumber, _StackNumStr) | |
AND | |
StringConcatenate("(", _StackNumStr, _StrA) | |
AND | |
StringConcatenate(_StrA, ") ", _StrB) | |
AND | |
StringConcatenate(_StrB, _Status, _StatusInfoStr) | |
AND | |
StringConcatenate(_Message, _StatusInfoStr, _DebugMessage) | |
THEN | |
DebugBreak(_DebugMessage); | |
//END_REGION | |
//REGION CLEAR_DATA | |
/* Procedures are custom script-defined rules that can be called in the THEN section. | |
They fully complete before the next line in the rule where they're called. | |
Here we're clearing these temporary databases since we only use these for if/else conditions in our rules. | |
*/ | |
PROC | |
MyMod_StackingStatuses_ClearData((CHARACTERGUID)_Character, (STRING)_ApplyStatus) | |
AND | |
DB_MyMod_StackingStatuses_Temp_ActiveStack(_Character, _ApplyStatus, _StackNumber, _StackingStatus) | |
THEN | |
NOT DB_MyMod_StackingStatuses_Temp_ActiveStack(_Character, _ApplyStatus, _StackNumber, _StackingStatus); | |
PROC | |
MyMod_StackingStatuses_ClearData((CHARACTERGUID)_Character, (STRING)_ApplyStatus) | |
AND | |
DB_MyMod_StackingStatuses_Temp_StackChanged(_Character, _ApplyStatus, _StackingStatus) | |
THEN | |
NOT DB_MyMod_StackingStatuses_Temp_StackChanged(_Character, _ApplyStatus, _StackingStatus); | |
//END_REGION | |
//REGION QUERIES | |
/* Queries are custom script-defined rules. | |
If the query reaches the THEN section, the condition is "true". | |
They fully complete before the next line in the rule where they're called. | |
This query is for checking if a character has a stacking status, for future use. | |
*/ | |
QRY | |
MyMod_StackingStatuses_QRY_HasStackingStatus((CHARACTERGUID)_Character, (STRING)_ApplyStatus) | |
AND | |
DB_MyMod_StackingStatuses_Stacks(_ApplyStatus, _StackNumber, _StackingStatus, _Duration) | |
AND | |
HasActiveStatus(_Character, _StackingStatus, 1) | |
THEN | |
DB_NOOP(1); | |
//END_REGION | |
//REGION STACK_STATUS_LOGIC | |
/* Here we're checking for the current stacking status, if any, to determine where we are in the stack count. */ | |
PROC | |
MyMod_StackingStatuses_OnApplyStatus((CHARACTERGUID)_Character, (STRING)_ApplyStatus, (GUIDSTRING)_Source) | |
AND | |
DB_MyMod_StackingStatuses_Stacks(_ApplyStatus, _StackNumber, _StackingStatus, _Duration) | |
AND | |
HasActiveStatus(_Character, _StackingStatus, 1) | |
THEN | |
MyMod_StackingStatuses_ClearData(_Character, _ApplyStatus); // In case statuses from previous stacks are active. | |
DB_MyMod_StackingStatuses_Temp_ActiveStack(_Character, _ApplyStatus, _StackNumber, _StackingStatus); | |
/* If no stacking status is found for the applying status, we start at stack 0. | |
DB_MyMod_StackingStatuses_Temp_StackChanged is used to prevent the next rule, so we only increase the stack one at a time. | |
*/ | |
PROC | |
MyMod_StackingStatuses_OnApplyStatus((CHARACTERGUID)_Character, (STRING)_ApplyStatus, (GUIDSTRING)_Source) | |
AND | |
NOT DB_MyMod_StackingStatuses_Temp_StackChanged(_Character, _ApplyStatus, _) | |
AND | |
NOT DB_MyMod_StackingStatuses_Temp_ActiveStack(_Character, _ApplyStatus, _, _) | |
AND | |
DB_MyMod_StackingStatuses_Stacks(_ApplyStatus, 0, _StackingStatus, _Duration) | |
THEN | |
DB_MyMod_StackingStatuses_Temp_StackChanged(_Character, _ApplyStatus, _StackingStatus); | |
ApplyStatus(_Character, _StackingStatus, _Duration, 1, _Source); | |
MyMod_DebugMessage("[MyMod:CharacterStatusApplied] Applying first status in stack: ", 0, _StackingStatus); | |
/* If a stacking status is found, we increase the stack count and get the next status to apply, if any. */ | |
PROC | |
MyMod_StackingStatuses_OnApplyStatus((CHARACTERGUID)_Character, (STRING)_ApplyStatus, (GUIDSTRING)_Source) | |
AND | |
NOT DB_MyMod_StackingStatuses_Temp_StackChanged(_Character, _ApplyStatus, _) | |
AND | |
DB_MyMod_StackingStatuses_Temp_ActiveStack(_Character, _ApplyStatus, _StackNumber, _CurrentStackingStatus) | |
AND | |
IntegerSum(_StackNumber, 1, _NextStackNumber) | |
AND | |
DB_MyMod_StackingStatuses_Stacks(_ApplyStatus, _NextStackNumber, _StackingStatus, _Duration) | |
THEN | |
DB_MyMod_StackingStatuses_Temp_StackChanged(_Character, _ApplyStatus, _StackingStatus); | |
ApplyStatus(_Character, _StackingStatus, _Duration, 1, _Source); | |
MyMod_DebugMessage("[MyMod:CharacterStatusApplied] Increasing stack and applying status: ", _NextStackNumber, _StackingStatus); | |
/* Finally we clear DB_MyMod_StackingStatuses_Temp_ActiveStack and DB_MyMod_StackingStatuses_Temp_StackChanged. */ | |
PROC | |
MyMod_StackingStatuses_OnApplyStatus((CHARACTERGUID)_Character, (STRING)_ApplyStatus, (GUIDSTRING)_Source) | |
THEN | |
MyMod_StackingStatuses_ClearData(_Character, _ApplyStatus); | |
//END_REGION | |
//REGION APPLY_STATUS_EVENTS | |
/* We listen for specific statuses here, instead of a generic status variable, | |
since hidden status are constantly applied while the game is running. | |
HIT, INSURFACE, aura statuses, etc. are always happening, so avoiding generic status events rules is a great way to avoid log spam / unnecessary rules from running. | |
For your actual statuses, simply replace HASTED with the status you apply to increase the stack, i.e. MYMOD_MISERY_APPLY | |
*/ | |
IF | |
CharacterStatusApplied(_Character, "HASTED", _Source) | |
THEN | |
MyMod_StackingStatuses_OnApplyStatus(_Character, "HASTED", _Source); | |
//END_REGION | |
EXITSECTION | |
ENDEXITSECTION | |
ParentTargetEdge "__Start" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment