summaryrefslogtreecommitdiff
path: root/npc/functions/lockpicks.txt
blob: 9775fa3ed8e78c9695f8730044801c0c0d6fca50 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// TMW2/LoF Script
// Author:
//  Jesusalva
// Description:
//  Lockpicking core

// Important variables:
//  THIEF_EXP
//      Experience on Thief Tree
//  THIEF_RANK
//      Position on the Thief Tree

// LockPicking(num_pins, max_pins, min_rank=num_pins)
// Returns 0 upon failure, 1 upon success
// Closes script if an error happen or if you give up / cannot try.
//
// The 'next' is upon script responsability
// Maximum pin number is infinite. Maximum Pin Positiors range from 2~5.
// If you fail, you can end up having to start again. If you fail too much,
// you'll be caught!
function	script	LockPicking	{
    // If you don't have a LockPick, you can't do this (useless)
    if (!countitem(Lockpicks)) {
        mesc l("You need a @@ to try this.", getitemlink(Lockpicks)), 1;
        close;
    }

    .@d=getarg(0,1);
    .@m=getarg(1,3);
    .@minrank=getarg(2, .@d);

    // Invalid Argument (kill script)
    if (.@d < 1 || .@m < 2 || .@m > 5)
        end;

    // You must be rank (number of locks - 1) to try
    if (THIEF_RANK+1 < .@minrank) {
        mesc l("This lock is beyond your current capacity."), 1;
        close;
    }

    // Create @pins array (the answer)
    for (.@i=0; .@i < .@d;.@i++)
        @pins[.@i] = rand2(1,.@m);

    // Check if you'll try to open it.
    mesc l("This lock is simple, maybe with your thief skills you can manage to pry it open. But beware, you can end up in jail!");
    mesc l("Will you try to unlock it?");
    if (askyesno() == ASK_NO)
        close;

    // Setup your attempt
    delitem Lockpicks, 1;
    @pos=0;
    @chance=min(.@d*.@m-1, THIEF_RANK+.@d);
    mesc l("You insert the hook pick inside the lock, and, without applying any tension, you discover there are only @@ pins to set.", .@d);

    // You have as many attempts as pins and appliable strength.
    // Each thief rank grants you an extra attempt.
    // Each pin takes one attempt.
    // It's not multiplied, so 3 pins with 3 positions: 6 chances, 9 possibilities.
    // There's no penalty, but the attempt is counted working or not!
    // Remember if you fail, all previous pins will be cleared (@pos)
    do {
        mesc l("You are trying to open the @@th pin. What will to do?", @pos+1);

        menuint
            rif(.@m >= 4, l("Apply no pressure")), 4,
            rif(.@m >= 2, l("Apply soft pressure")), 2,
            rif(.@m >= 1, l("Apply normal pressure")), 1,
            rif(.@m >= 3, l("Apply strong pressure")), 3,
            rif(.@m >= 5, l("Apply very strong pressure")), 5,
            rif($@GM_OVERRIDE, "-- skip minigame --"), -1,
            l("Give up!"), 0;

        // Debug
        if (@menuret < 0) {
            if ($@GM_OVERRIDE)
                return 1;
            else
                atcommand("@block "+strcharinfo(0)); // Unacceptable
        }

        if (!@menuret) {
            // 25% chance to save the lockpick
            if (rand2(1,4) == 2)
                getitem Lockpicks, 1;
            else
                dispbottom l("The lockpick broke.");
            close;
        }

        // Is your guess correct?
        if (@pins[@pos] == @menuret) {
            mesc l("*click*");
            @pos+=1;
        } else {
            mesc l("This didn't work. All pins are now unset!");
            @pos=0;
            @chance-=1;
            // We don't need to clear console, each successful attempt IS counted.
            // Therefore, unsetting 3 pins means you must do 3 new attempts!!
            // The biggie is that you're running against time, here!!!
            if (@chance < .@d && rand2(0, THIEF_RANK))
                mesc l("Your thief instincts suggest you to hurry."), 1;
        }

        if (@chance <= 0)
            break;

        if (@pos >= .@d) {
            // 20% chance to save the lockpick
            if (rand2(1,5) == 3)
                getitem Lockpicks, 1;
            else
                dispbottom l("The lockpick broke.");

            // Get EXP and inform the success
            if (THIEF_RANK)
                THIEF_EXP += max(0, .@d*.@m-THIEF_RANK);
            return 1;
        }
    } while (true);

    // Failed
    if (THIEF_RANK)
        THIEF_EXP += 1;
    return 0;
}

// Script helper to say if you were arrested or not
function	script	ArrestedChances	{
    .@runaway=limit(0, readparam2(bLuk)+readparam2(bAgi), 200); // 20%
    .@runaway+=is_night()*125; // 12.5%
    .@runaway+=limit(0, THIEF_RANK*15, 100); // real max 7.5%
    // Max runaway chance: 40%
    if (rand2(1000) < .@runaway)
        return false;
    return true;
}

// Main script
// LootableVault(tier, level, variable)
function	script	LootableVault	{
    .@tier=getarg(0)+1;
    .@level=getarg(1);
    .@var$=getarg(2);
    mesn;
    mesq l("There's a shiny safe here. How much money is inside? Nobody is looking at you, too.");
    // 2*3 = 6 possibilities, 5 attempts
    if (LockPicking(.@tier, .@level)) {
        Zeny=Zeny+getd("$VAULT_"+.@var$);
        setd("$VAULT_"+.@var$, 40);
        mesn;
        mesq l("Booty!");
    } else {
        mesn;
        .@inch=(Zeny/100);
        Zeny-=.@inch;
        setd("$VAULT_"+.@var$, getd("$VAULT_"+.@var$)+.@inch);
        if (ArrestedChances()) {
            mesc l("Arrested!");
            atcommand("@jailfor 5mn "+strcharinfo(0));
        } else {
            if (is_night())
                .@p$=l("The darkness of the night gives you cover.");
            else
                .@p$=l("Your agile legs and sheer luck allows you to outrun the guards.");
            mesc l("You run as far as you could. %s", .@p$);
            warp "000-1", 22, 22;
        }
    }
    return;
}