Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exploit: The gate guard can be bribed multiple times with Dusty as a follower #182

Merged
merged 2 commits into from Mar 31, 2021

Conversation

szapp
Copy link
Collaborator

@szapp szapp commented Mar 31, 2021

Describe the bug
When bringing Dusty to the Swamp Camp, the player can indefinitely bribe the gate guard to get EXP.

Expected behavior
The gate guard can only be bribed once when bringing Dusty to the Swamp Camp.

Steps to reproduce the issue

  1. Bribe the gate guard with Dusty following you.
  2. Save the game
  3. Load the save.
  4. Bribe the gate guard again (if you have enough ore).

@AmProsius AmProsius added the validation: validated label Mar 6, 2021
@szapp
Copy link
Collaborator

@szapp szapp commented Mar 6, 2021

The info condition:

FUNC INT DIA_Grd_216_DustyZoll_Condition()
{
var C_NPC Dusty; Dusty = Hlp_GetNpc(Vlk_524_Dusty);
if (Dusty.aivar[AIV_PARTYMEMBER] == TRUE)
&& (Npc_GetDistToNpc(hero,dusty)<2000)
{
return 1;
};
};

The dialog lines (following the correct dialog choice):

func void DIA_Grd_216_DustyZoll_LittleWalk()
{
AI_Output (other, self,"DIA_Grd_216_Dusty_Zoll_LittleWalk_15_00"); //We're just going for a stroll. Here's 100 ore.
if (Npc_HasItems (hero,itminugget) >= 100)
{
AI_Output (self, other,"DIA_Grd_216_Dusty_Zoll_LittleWalk_13_00"); //I never saw anything.
B_GiveInvItems (hero, self, ItMiNugget, 100);
DIA_Grd_216_DustyZoll.permanent = 0;
B_LogEntry (CH1_RecruitDusty,"I managed to bribe the guards at the rear south gate. Everyone has a price!");
B_GiveXP (XP_BribedDustyGuard);
AI_StopProcessInfos (self);
}
else
{
AI_Output (self, other,"DIA_Grd_216_Dusty_Zoll_LittleWalk_13_02"); //Are you having me on? You won't get off that easy, kid!
AI_StopProcessInfos (self);
Npc_SetTarget (self,other);
AI_StartState (self,ZS_Attack,1,"");
B_ExchangeRoutine (Vlk_524_Dusty,"start");
var C_NPC dusty; dusty = Hlp_GetNpc(Vlk_524_Dusty);
dusty.aivar[AIV_PARTYMEMBER] = FALSE;
dusty.flags = 0; // Immortal löschen
};
};

The only reference point whether the bribe was paid is the log entry. The info condition will have to be extended by a check for that specific entry in the respective log topic. The function for doing that is already supplied by G1CP.

The difficult thing is to find the exact wording of the log entry. To do so the byte code of the dialog function will have to searched to find the string symbol that is pushed when calling B_LogEntry. Should be possible.

@szapp szapp added the provided fix label Mar 6, 2021
@szapp
Copy link
Collaborator

@szapp szapp commented Mar 6, 2021

An alternativ would be to check the amount of ore the guard has. Given he is immortal (is he?), that amount should not change. Such a check won’t be very robust and will depend on how much the bribe is and how much ore the guard had beforehand.

@szapp szapp added compatibility: difficult type: session fix labels Mar 6, 2021
@AmProsius
Copy link
Owner Author

@AmProsius AmProsius commented Mar 7, 2021

Can we introduce new global variables like Diego_GomezAudience or thorus_bribed? I don't know exactly how they work, but that seems to be a safer way.

Edit: This might not work due to the fact that if the patch gets removed and reinstalled, the variables will be resetted. 🤔

@AmProsius AmProsius added this to Info condition in Fix templates Mar 7, 2021
@szapp
Copy link
Collaborator

@szapp szapp commented Mar 7, 2021

Can we introduce new global variables like Diego_GomezAudience or thorus_bribed? I don't know exactly how they work, but that seems to be a safer way.

Yes, here some information how that works. Only some types of variables are written to and restored from game saves:

  • Integer variables (global and local) are saved

  • String variables are not saved

  • Integer and string constants are not saved and even preserve their value over the session. Although they are “constants” they may be set later. Both of these properties allow to use them to track things across the entire session, e.g.

    const int once = FALSE;
    if (!once) {
        // Do something only once for the session
        // This if-block will never be executed again until quitting the executable and launching it again
        once = TRUE;
    };
  • Integer array and string array variables, so called “static Daedalus arrays”, e.g. var int var[3];, are not saved; only their first element. (In Gothic 2 they are, but only global ones, in Gothic they are not saved at all).

Edit: This might not work due to the fact that if the patch gets removed and reinstalled, the variables will be resetted. 🤔

Yes and no. In the context of patches, variables introduced by a patch remain in game saves even when the patch is removed. This allows to remove and reintroduce a patch and continue where left off. It’s only when Ninja is uninstalled that these variables are lost from game saves.

So yes, using a variable is very suitable here. Setting it to true will allow to add a reliable check in the condition function. But since we are writing a patch, there are two problems:

  1. As you said, if Ninja is removed, the content of the variable will be lost.
  2. The variable is only set if the patch is active during the dialog. If the patch is installed later, the fix will not work.

This is going against the idea of allowing to add and remove the patch at any time.

@AmProsius
Copy link
Owner Author

@AmProsius AmProsius commented Mar 7, 2021

Thanks for the insight!

This is going against the idea of allowing to add and remove the patch at any time.

So we will continue to find additional conditions for the Info-Block.

@szapp
Copy link
Collaborator

@szapp szapp commented Mar 7, 2021

This approach here should be reliable enough:

The only reference point whether the bribe was paid is the log entry. The info condition will have to be extended by a check for that specific entry in the respective log topic. The function for doing that is already supplied by G1CP.

The difficult thing is to find the exact wording of the log entry. To do so the byte code of the dialog function will have to searched to find the string symbol that is pushed when calling B_LogEntry. Should be possible.

@AmProsius AmProsius added this to To Do in v1.1.0 via automation Mar 11, 2021
@AmProsius AmProsius added this to the v1.1.0 milestone Mar 11, 2021
@AmProsius AmProsius changed the title Dusty exploit Exploit: The gate guard can be bribed multiple times with Dusty as a follower Mar 12, 2021
@szapp szapp added the impl: unknown label Mar 16, 2021
@szapp szapp moved this from Hook Daedalus function to Unsorted in Fix templates Mar 16, 2021
@szapp szapp self-assigned this Mar 29, 2021
@szapp szapp moved this from Unsorted to Dialog: Info condition in Fix templates Mar 31, 2021
@szapp
Copy link
Collaborator

@szapp szapp commented Mar 31, 2021

The test is automatic. It may still be worth to check it manually (with saving and loading as written in the issue description). I have not tested that yet.

@szapp szapp requested a review from AmProsius Mar 31, 2021
@szapp szapp removed their assignment Mar 31, 2021
@szapp szapp moved this from To Do to In Progress in v1.1.0 Mar 31, 2021
@AmProsius AmProsius merged commit 9dfa676 into master Mar 31, 2021
v1.1.0 automation moved this from In Progress to Done Mar 31, 2021
@AmProsius AmProsius deleted the bug182 branch Mar 31, 2021
szapp added a commit that referenced this issue Apr 19, 2021
@szapp szapp moved this from Modify dialog conditions to Add dialog conditions in Fix templates Feb 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility: difficult impl: unknown provided fix type: session fix validation: validated
Projects
Fix templates
Add dialog conditions
v1.1.0
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

2 participants