summaryrefslogtreecommitdiff
path: root/npc/soren-2/main.txt
blob: 932d8e8812b18c5b6093c03301508660298b3fa1 (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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
// TMW2 Scripts
// Author:
//   Jesusalva
// Description:
//   Celestia Yeti King's quest. This controls Soren's House Indoors. It will
//   handle Lobby event, and is called by Soren's House script.
//   It'll then spawn monsters and/or items, but with addtimer technology.
//   Once all monsters are dead, and minimum time is over, a portal will show up.
//   This later control is done by npctimer. The spawn logic continues, though.
//   The addtimer will use compareandsetq, and the warp will use it too, so if
//   you haven't spawned your quota, you won't be able to use the portal.
//
//      The use of         compareandsetq HurnscaldQuest_Celestia
//      Ensures you're NOT capable of skipping to final stage in order to finish
//      the quest. Nice attempt, but that won't work. The scripts will advance,
//      but you'll stay at the same quest state, and when it's checked, you will
//      be with bound hands.
//
//  OnCheck:
//      Everytime you kill a monster, this checks if all mobs are dead, and you
//      have finished your share of spawns. Friends can really make your life
//      harder.
//  OnSanctum:
//      This runs every once in a while, and may either spawn things, or drop
//      items. ...Needless to say, if it spawn things, everyone on the room will
//      get mad at you. Luck you, here's not PVP.
//
//      One last thing. If you're way past your share, you'll get warnings about
//      messing other players life. Simply use the warp, or leave the house and
//      come back. If you don't, you'll be kicked from the game via @kick.
//      Why? Because Jesusalva did this script.

soren-2,38,29,0	script	#SorenSanctum	NPC_NO_SPRITE,0,0,{
    if (@sorensanctum == 0 && $@GM_OVERRIDE && is_admin())
        doevent("#SorenSanctum::OnStart");
    end;

OnTouch:
    if (@sorensanctum >= 5 && !mobcount(.map$, "#SorenSanctum::OnCheck")) {
        /*
        dispbottom l("Error, contact Jesusalva! Missing warp. Healing & Reseting temporaly.");
        percentheal 100, 100;*/
        @sorensanctum=0;
        compareandsetq HurnscaldQuest_Celestia, 4, 5;
        warp "001-7", 30, 42;
    }
    end;

OnCheck:
    // This doesn't works (or didn't used to), maybe because the way it's called
    if (!mobcount("soren-2", "#SorenSanctum::OnCheck"))
        setnpcdisplay "#SorenSanctum", NPC_SUMMONING_CIRC;
    else
        setnpcdisplay "#SorenSanctum", NPC_NO_SPRITE;
    // Repeat if possible
    if (!playerattached())
        end;
    if (getmap() == "soren-2")
        addtimer2(10000, "#SorenSanctum::OnCheck");
    end;

OnSanctum:
    ++@sorensanctum;
    if (ispcdead() || !isin("soren-2", 24, 27, 40, 36))
        end;

    // Decide if we'll spawn or add items. Previous failures are NOT considerated.
    .@odds=rand(1, 10000);
    .@amount=(rand2(0, 5)/2)+1;
    .@lx=24; .@ly=27;
    .@ux=40; .@uy=36;

    // Core Logic, Part 1
    // Decide rarity

    // 1%: Super Rare drop
    // 9%: Rare Drop
    // 20%: Normal Drop
    // 40%: Normal Spawn
    // 10%: Rare Spawn
    // 19%: Drop + Spawn
    // 1%: Super Rare Spawn

    if (.@odds <= 100 || .@odds >= 9900) {
        .@bonus=2;
    } else if (.@odds <= 1000 || (.@odds >= 7000 && .@odds < 8000)) {
        .@bonus=1;
    }

    // Generate which monster/item would be dropped, depending on your (un)luck at ODDS (FIXME - Mobs not on par with everything else or players level)
    .@mid=rand(1,10)+.@bonus;
    switch (.@mid) {
        case 1:
                .@monsterId = AngryRedScorpion ; break;
        case 2:
                .@monsterId = CaveMaggot ; break; // Replace!
        case 3:
                .@monsterId = SeaSlime ; break;
        case 4:
                .@monsterId = AlphaMouboo ; break;
        case 5:
                .@monsterId = LavaSlime ; break;
        case 6:
                .@monsterId = BlackScorpion ; break;
        case 7:
                .@monsterId = Snake ; break;
        case 8:
                .@monsterId = FallenGuard2 ; break;
        case 9:
                .@monsterId = FallenGuard1 ; break;
        case 10:
                .@monsterId = Moonshroom ; break;
        default:
                .@monsterId = Yeti ; break;
    }
    // Item Gen
    .@mid=rand(1,10)+.@bonus;
    switch (.@mid) {
        case 1:
                .@itemId = Acorn ; break;
        case 2:
                .@itemId = Bread ; break;
        case 3:
                .@itemId = Aquada ; break;
        case 4:
                .@itemId = StrengthPotion ; break;
        case 5:
                .@itemId = Plushroom ; break;
        case 6:
                .@itemId = Piberries ; break;
        case 7:
                .@itemId = Croconut ; break;
        case 8:
                .@itemId = Chagashroom ; break;
        case 9:
                .@itemId = Manana ; break;
        case 10:
                .@itemId = HastePotion ; break;
        default:
                .@itemId = rand(CopperOre, TitaniumOre) ; break;
    }

    // Rare drop
    if (rand(1,6900) == 1337)
        .@itemId=RaidTrousers;

    // Core Logic, part 3
    // Make Items or Monsters
    if (.@odds <= 3333) {
        makeitem(.@itemId, 1, .map$, rand(.@lx, .@ux), rand(.@ly, .@uy));
    } else if (.@odds <= 7000 || .@odds > 9900) {
        areamonster .map$, .@lx, .@ly, .@ux, .@uy, strmobinfo(1, .@monsterId), .@monsterId, .@amount;
    } else {
        areamonster .map$, .@lx, .@ly, .@ux, .@uy, strmobinfo(1, .@monsterId), .@monsterId, .@amount;
        makeitem(.@itemId, 1, .map$, rand(.@lx, .@ux), rand(.@ly, .@uy));
    }

    // Revert sprite if needed
    if (.@odds > 2000) {
        setnpcdisplay .name$, NPC_NO_SPRITE;
    } else if (!mobcount(.map$, "#SorenSanctum::OnCheck")) {
        setnpcdisplay .name$, NPC_SUMMONING_CIRC;
    }

    // Handle maximum overtime you can do here: 10 cycles, or 3m20s ~ 6m40s
    if (@sorensanctum == 8) {
        specialeffect(28);
        dispbottom col(l("WARNING: Do not spend unecessary time on Soren's House, you'll be disconnected!"), 1);
        percentheal -5, -20;
    }
    if (@sorensanctum == 9) {
        specialeffect(28);
        dispbottom col(l("FINAL WARNING: Do not spend unecessary time on Soren's House, you'll be disconnected!!"), 1);
        percentheal -20, -100;
    }
    if (@sorensanctum >= 10) {
        atcommand "@kick "+strcharinfo(0);
        npctalk l("The power of Soren's House kicks @@ like a game master.", strcharinfo(0));
    }

    // Random 20~40 seconds before next cycle. (Minimum 100~200 seconds, or 1m40s~3m20s)
    // If you're past minimum, it'll be a little slower to don't affect other players too much.
    // These values are for single player. If there are more users, the timer will tick for longer.
    if (@sorensanctum < 5)
        addtimer(rand(15000, 35000)+getusers(1)*5000, "#SorenSanctum::OnSanctum");
    else
        addtimer(rand(25000, 35000)+getusers(1)*5000, "#SorenSanctum::OnSanctum");

    // Enforce the policy
    addtimer2(10000, "#SorenSanctum::OnCheck");
    goto OnCheck;




OnStart:
    // If you're not on stage 4, skip this. I could set here to stage 5, so this
    // intro won't play again. But if it plays again, your progress is reset, and
    // it is harder this way, so I'm not touching on quest state :>
    if (getq(HurnscaldQuest_Celestia) != 4)
        end;
    addtimer(200, "#SorenSanctum::OnStep1"); // Allow client to update stuff
    end;

OnStep1:
    // When we reach here, we have both a player attached, and the player was already warped.
    // I don't know if you walked in and out the house, though. If you do, this will loop...
    // Which is actually bad for you, as that will reset your progress!!
    npctalk3 l("Well well well, @@, good job in reaching Soren's House.", strcharinfo(0));
    addtimer(3000, "#SorenSanctum::OnStep2");
    end;

OnStep2:
    //setnpcdisplay .name$, NPC_YETI_KING;
    npctalk3 l("You done well in getting so far. I didn't thought you would make it.");
    addtimer(3000, "#SorenSanctum::OnStep3");
    end;

OnStep3:
    npctalk3 l("The Cave Of Trials, and the Soren's Village... There's only one thing left.");
    addtimer(3000, "#SorenSanctum::OnStep4");
    end;

OnStep4:
    npctalk3 l("...You still have not overcome his house.");
    addtimer(3000, "#SorenSanctum::OnStep5");
    end;

OnStep5:
    //setnpcdisplay .name$, NPC_NO_SPRITE;
    npctalk3 l("Defeat a few waves of Soren's House. Once you're done, this will become a warp. Hurry before it closes.");
    @sorensanctum=0;
    addtimer(5000, "#SorenSanctum::OnSanctum");
    end;

OnInit:
    end;
}