summaryrefslogtreecommitdiff
path: root/npc/001-13/main.txt
blob: fe52bfbd526b8cbc040fd37dfc98a6e69ab1d54f (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
// TMW2 Scripts
// Author:
//  Jesusalva
// Description:
//  Controls boss raid showdown (Freeyorp Event System - Boss Raid)

function	script	FYRaid_Select	{
    if ($EVENT$ != "Raid") return;
    sleep2(100); // Anti-flood protection: Hold execution for 100ms
    mes l("Current Boss: %s", $RAIDING_BOSS$);
    .@id = array_find($FYRAID_OWNER, getcharid(3));
    if (.@id >= 0) {
        // Same level (challenge ongoing)
        if ($FYRAID_LV[.@id] == FYRAID_LV) {
            // Was defeated when you weren't loooking (limited precedence)
            if ($FYRAID_HP[.@id] <= 0) {
                mesc l("Boss defeated!"), 3;
                FYRAID_LV+=1;
                $FYRAID_HP[.@id]=0;
                Mobpt += FYRAID_LV * 10;
                getitem EventNaftalin, FYRAID_LV;
            }
            // Time is running out
            else if (gettimetick(2) < $FYRAID_TIME[.@id]) {
                mesc l("You found a Level %d %s!", FYRAID_LV, $RAIDING_BOSS$), 2;
                mesc l("Time left: %s", FuzzyTime($FYRAID_TIME[.@id])), 1;
            }
            // Time has expired - free for next boss
            else if (gettimetick(2) > $FYRAID_TIME[.@id]) {
                mesc l("The boss you discovered has ran away!");
                $FYRAID_LV[.@id] = 0;
                $FYRAID_HP[.@id] = 0;
                $FYRAID_TIME[.@id] = 0;
                Mobpt += rand2(FYRAID_LV);
            }
        }
    }
    next;
    setarray .@opt$, l("Cancel"), -1;
    freeloop(true);
    // Build menu
    for (.@i=0; .@i < getarraysize($FYRAID_OWNER) ; .@i++) {
        if ($FYRAID_HP[.@i] <= 0)
            continue;
        if ($FYRAID_TIME[.@i] < gettimetick(2))
            continue;
        .@hp=$FYRAID_HP[.@i];
        .@lv=$FYRAID_LV[.@i];
        .@on=$FYRAID_OWNER[.@i];
        array_push(.@opt$, (.@on == getcharid(3) ? "**" : "") + l("Level %d (%s HP) (Found by %s)", .@lv, .@hp, strcharinfo(0, l("offline player"), .@on)) + (.@on == getcharid(3) ? "**" : ""));
        array_push(.@opt$, str(.@i));
    }
    freeloop(false);
    menuint2(.@opt$);
    if (@menuret < 0)
        return;
    // Validate again if the prey is still valid
    .@i = @menuret;
    if ($FYRAID_HP[.@i] <= 0) {
        mesc l("Someone else has already defeated this bounty.");
        return;
    }
    if ($FYRAID_TIME[.@i] < gettimetick(2)) {
        mesc l("This bounty has expired.");
        return;
    }
    // Prepare the room (time limit = 3 minutes)
	.@inst = instance_create("Showdown "+getcharid(0), getcharid(3), IOT_CHAR);
    // Failed
    if (.@inst < 0) {
        mesc l("You can only try every %d minutes.", 3);
        return;
    }
    // Attach map
    .@mp$="fyrb@"+getcharid(0);
    instance_attachmap("001-13", .@inst, false, .@mp$);

    // Recreate the boss
    .@lv = $FYRAID_LV[.@i];
    .@mob=monster(.@mp$, 47, 33, $RAIDING_BOSS$, WanderingShadow, 1, "sBossRaid::OnBossDie");
    setunitdata(.@mob, UDT_LEVEL, min(.@lv * 10, 200));
    setunitdata(.@mob, UDT_STR, .@lv * 4);
    setunitdata(.@mob, UDT_AGI, .@lv * 4);
    setunitdata(.@mob, UDT_VIT, .@lv * 5);
    setunitdata(.@mob, UDT_INT, .@lv * 2);
    setunitdata(.@mob, UDT_DEX, .@lv * 6);
    setunitdata(.@mob, UDT_LUK, .@lv * 5);
    setunitdata(.@mob, UDT_ADELAY, max(640, 1672-(.@lv * 24)));
    setunitdata(.@mob, UDT_MAXHP,    2000+.@lv*1000);
    setunitdata(.@mob, UDT_HP,       $FYRAID_HP[.@i]);
    setunitdata(.@mob, UDT_ATKMIN,   90+.@lv*10);
    setunitdata(.@mob, UDT_ATKMAX,   90+.@lv*12);
    setunitdata(.@mob, UDT_DEF,      10+.@lv*5);
    setunitdata(.@mob, UDT_MDEF,     10+.@lv*3);
    setunitdata(.@mob, UDT_HIT,      (BaseLevel+.@lv)*45/10);
    setunitdata(.@mob, UDT_FLEE,     min((BaseLevel+.@lv)*27/10, 750));
    setunitdata(.@mob, UDT_CRIT,     rand2(60, min(180, 60+.@lv)));

	// Save some persistent data
	@map$=.@mp$;
	@id=.@i;
	@mb=.@mob;
	@tm=gettimetick(2)+180;

    // Good luck!
	instance_set_timeout(190, 190, .@inst);
	instance_init(.@inst);
    warp .@mp$, 47, 52;
	addtimer 180000, "sBossRaid::OnTimeout";
	addtimer 60000, "sBossRaid::OnPump";
    dispbottom l("Time left: %s", FuzzyTime(@tm));
    closeclientdialog;
    return;
}

// ------------------------------------------------------------------------------
-	script	sBossRaid	NPC_HIDDEN,{

OnPump:
	if (@map$ != getmap()) end;
	.@msg$=l("In all the mana worlds, I alone am feared.");
	.@lv=$FYRAID_LV[@id];

	// Apply boss skill based on their name
	if ($RAIDING_BOSS$ == "Xakabael the Dark") {
		.@msg$ = l("Witness my sublime rain of death. Regeneration!");
		.@hp=getunitdata(@mb, UDT_HP);
		.@mp=getunitdata(@mb, UDT_MAXHP);
		setunitdata(@mb, UDT_HP, min(.@mp, .@hp+(.@lv * 50)));
	} else if ($RAIDING_BOSS$ == "Janeb the Evil") {
		.@msg$ = l("Chaos shall be the founding stone of my town! Falling star!");
		percentheal -5, -10;
	} else if ($RAIDING_BOSS$ == "Platyna the Red") {
		.@msg$ = l("I, the rightful ruler, demand back this world! Tyranny!");
		percentheal -1, -1;
		SC_Bonus(10+.@lv, any(SC_BLIND, SC_POISON), 1);
	} else if ($RAIDING_BOSS$ == "Benjamin the Frost") {
		.@msg$ = l("Stop on your tracks, unfair being! Freeze!");
		SC_Bonus(10+.@lv, any(SC_FREEZE, SC_SLEEP), 1);
	} else if ($RAIDING_BOSS$ == "Reid the Terrific") {
		.@msg$ = l("There is no free speech. Censorship!");
		SC_Bonus(10+.@lv, SC_SILENCE, 1);
	} else if ($RAIDING_BOSS$ == "Nu'Rem the Destroyer") {
		.@msg$ = l("And then... There was a quake. And all life died. Bleed!");
		SC_Bonus(10+.@lv, SC_BLOODING, 1);
	} else if ($RAIDING_BOSS$ == "Golbenez the Cruel") {
		.@msg$ = l("Puny mortal, do your best to entertain me! Curse!");
		SC_Bonus(10+.@lv, SC_CURSE, 1);
	} else if ($RAIDING_BOSS$ == "King of Typos") {
		.@msg$ = l("The problem with typos is - unpredictable side effects.");
		SC_Bonus(10+.@lv, any(SC_SILENCE, SC_CURSE, SC_FREEZE, SC_BLOODING, SC_BLIND, SC_POISON, SC_DPOISON, SC_POISON, SC_BURNING, SC_SLEEP), 1);
	} else {
		consolewarn("Unknown raiding boss: %s. No skill will be used.", $RAIDING_BOSS$);
	}

	unittalk(@mb, .@msg$);
    dispbottom l("Time left: %s", FuzzyTime(@tm));
	// TODO: Maybe flush the boss HP to upstream to prevent farming?
	addtimer 60000, "sBossRaid::OnPump";
	end;

// Boss defeated
OnBossDie:
    dispbottom l("Boss defeated!");
	// Clear bonus
	getitem EventNaftalin, $FYRAID_LV[@id]/2+1;
	.@new = 0;
	goto OnClose;

// Ran out of time
OnTimeout:
    dispbottom l("Time out!");
	.@new = getunitdata(@mb, UDT_HP);
	goto OnClose;

// What a noob, you died!
OnDie:
    dispbottom l("Killed in action!");
	.@new = getunitdata(@mb, UDT_HP);
	goto OnClose;

// Warp you back
OnClose:
	.@old = $FYRAID_HP[@id];
	.@dmg = .@old - .@new;
	debugmes "Old %d New %d Damage %d", .@old, .@new, .@dmg;
	// Damage Bonus
	if (.@dmg / 2000 > 1)
		getitem EventNaftalin, .@dmg / 2000;

	// Record new HP info and give you rewards
	$FYRAID_HP[@id] = .@new;
    Mobpt += $FYRAID_LV[@id];
    getexp $FYRAID_LV[@id], $FYRAID_LV[@id]/2+1;

	// Send you back
	deltimer("sBossRaid::OnPump");
	deltimer("sBossRaid::OnTimeout");
    sleep2(500);
    teleporthome();
	end;
}

001-13	mapflag	zone	MMO