summaryrefslogblamecommitdiff
path: root/npc/001-13/main.txt
blob: d1557d273857782dc9c2105ab41bb822e605f508 (plain) (tree)
1
2
3
4
5
6
7
8






                                                                   
                               















                                                                          
                                                           



                                                                                 
                                                           







                                                                

                











                                                            
                                                                                                                                                                                                 















                                                                 



                                







                                                                                   
                                                                                                                                          
                           
                               
                                                                               

                        
                                                                                             
                                                      
                                          
                                                    




                                                               
                                                                       


















                                                                       
                                                   
                                                
                                             

                                                  






















                                                                          









                                                                                 
                                      






                                                                              
                                                         


                                                                                          
                                                            


                                                                                      
                                                           
                                                         

                                                                         
                                                                                     
                                                          

                                                                   
                                             
                                                      

                                                                                       
                                              
                                                         

                                                                                
                                           
                                                        

                                                                                      
                                                                                                                                                      
                                                          





                                                                                                
                                                                        
                                                                               



                                                   






                                                   
                                                    
                  
                                                      







                                         





                                         

                




                                                           
                                
                              

                                                                
                       

                                                    







                                                  
                                         
                
                                                       
                                                          








                                                           


                           



                                   
// TMW2 Scripts
// Author:
//  Jesusalva
// Description:
//  Controls boss raid showdown (Freeyorp Event System - Boss Raid)

function	script	FYRaid_Select	{
    .@abort = getarg(0, false);
    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);
            }
        }
    }
    if (.@abort)
        return;
    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;
    }
    if (ispcdead()) {
        mesc l("You are dead.");
        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
    // TODO: Different scenarios: Sewer, Concrete Dungeon, Crypt, Desert Castle, Mountain, Snowland, Lake Region, Ukar Shrine, Woodland...
    .@lv = $FYRAID_LV[.@i];
    .@mp$="fyrb@"+getcharid(0);
    instance_attachmap(sprintf("001-13-%d", (.@lv % 4)), .@inst, false, .@mp$);

    // Recreate the boss
    .@mob=monster(.@mp$, 47, 33, $RAIDING_BOSS$, WanderingShadow, 1, "sBossRaid::OnBossDie");
    setunitdata(.@mob, UDT_LEVEL, min(.@lv * 7, 200));
    setunitdata(.@mob, UDT_STR, .@lv * 4);
    setunitdata(.@mob, UDT_AGI, min(.@lv * 4, 255));
    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+(FYRAID_LV/5*500));
    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;
    .@tski = limit(10000, 46000-(.@lv*500), 40000);
	addtimer 180000, "sBossRaid::OnTimeout";
	addtimer .@tski, "sBossRaid::OnPump";
    dispbottom l("Time left: %s", FuzzyTime(@tm));
    closeclientdialog;
    // Spawn an auxiliar every 5 levels AFTER level 10
    if (.@lv > 10) {
        .@qnt = (.@lv % 5) + 1;
        .@str = (.@lv / 5);
        explode(.@n$, $RAIDING_BOSS$, " ");
        .@n$ = l("%s's Minion", .@n$);
        for (.@i=0;.@i < .@qnt;.@i++) {
            .@m=areamonster(.@mp$, 44, 31, 50, 34, .@n$, MeagerShadow, 1);
            setunitdata(.@m, UDT_STR,    .@str);
            setunitdata(.@m, UDT_AGI,    .@str);
            setunitdata(.@m, UDT_VIT,    .@str);
            setunitdata(.@m, UDT_INT,    .@str);
            setunitdata(.@m, UDT_DEX,    .@str);
            setunitdata(.@m, UDT_LUK,    .@str);
            setunitdata(.@m, UDT_ATKMIN, BaseLevel+.@str*3);
            setunitdata(.@m, UDT_ATKMAX, BaseLevel+.@str*4);
            setunitdata(.@m, UDT_MAXHP,  .@str*400);
            setunitdata(.@m, UDT_HP,     .@str*400);
            setunitdata(.@m, UDT_HIT,    BaseLevel+.@lv+rand2(.@str*5));
            setunitdata(.@m, UDT_FLEE,   1+rand2(.@str));
            setunitdata(.@m, UDT_CRIT,   1+rand2(.@str));
        }
    }
    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];
	.@t = min(45, 10+rand2(.@lv));

	// 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)));
        .@mob=(rand2(.@lv) > 50 ? DeathCat : GreenSlime);
	} else if ($RAIDING_BOSS$ == "Janeb the Evil") {
		.@msg$ = l("Chaos shall be the founding stone of my town! Falling star!");
		percentheal -5, -10;
        .@mob=(rand2(.@lv) > 50 ? BlackScorpion : RedSlime);
	} else if ($RAIDING_BOSS$ == "Platyna the Red") {
		.@msg$ = l("I, the rightful ruler, demand back this world! Tyranny!");
		percentheal -1, -1;
		SC_Bonus(.@t, any(SC_BLIND, SC_POISON), 1);
        .@mob=(rand2(.@lv) > 50 ? DarkLizard : Assassin);
	} else if ($RAIDING_BOSS$ == "Benjamin the Frost") {
		.@msg$ = l("Stop on your tracks, unfair being! Freeze!");
		SC_Bonus((.@t / 2), any(SC_FREEZE, SC_SLEEP, SC_SLEEP, SC_SLEEP), 1);
        .@mob=(rand2(.@lv) > 50 ? BlueSlime : WhiteSlime);
	} else if ($RAIDING_BOSS$ == "Reid the Terrific") {
		.@msg$ = l("There is no free speech. Censorship!");
		SC_Bonus(.@t, SC_SILENCE, 1);
        .@mob=(rand2(.@lv) > 50 ? Thug : RedMushroom);
	} else if ($RAIDING_BOSS$ == "Nu'Rem the Destroyer") {
		.@msg$ = l("And then... There was a quake. And all life died. Bleed!");
		SC_Bonus(.@t, SC_BLOODING, 1);
        .@mob=(rand2(.@lv) > 50 ? BlackSlime : OldSnake);
	} else if ($RAIDING_BOSS$ == "Golbenez the Cruel") {
		.@msg$ = l("Puny mortal, do your best to entertain me! Curse!");
		SC_Bonus(.@t, SC_CURSE, 1);
        .@mob=(rand2(.@lv) > 50 ? FireSkull : Skeleton);
	} else if ($RAIDING_BOSS$ == "King of Typos") {
		.@msg$ = l("The problem with typos is - unpredictable side effects.");
		SC_Bonus(.@t, any(SC_SILENCE, SC_CURSE, SC_FREEZE, SC_BLOODING, SC_BLIND, SC_POISON, SC_DPOISON, SC_POISON, SC_BURNING, SC_SLEEP), 1);
        .@mob=(rand2(.@lv) > 50 ? Swashbuckler : Bluepar);
	} 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 max(20000, 46000-($FYRAID_LV[@id]*1000)), "sBossRaid::OnPump";
    // Spawn reinforcements when applicable
    if (.@mob && rand2(100) < .@lv) {
        monster(@map$, 47, 33, "Minion", .@mob, 1);
    }
	end;

// Boss defeated
OnBossDie:
    dispbottom l("Boss defeated!");
	// Clear bonus
	getitem EventNaftalin, $FYRAID_LV[@id]/2+1;
	getexp $FYRAID_LV[@id], $FYRAID_LV[@id]/2+1;
	.@new = 0;
	specialeffect(FX_FANFARE, SELF, getcharid(3));
	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:
    // Time Penalty every time you attack the boss yourself
    if (.@new > 0 && $FYRAID_OWNER[@id] == getcharid(3))
        $FYRAID_TIME[@id] -= 300;

    // Update boss parameters
	.@old = $FYRAID_HP[@id];
	.@dmg = .@old - .@new;
    if ($@GM_OVERRIDE)
    	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);
    if (@aurora_map$ != "" && @aurora_x && @aurora_y) {
        // TODO: Maybe not if you're dead...? (heal hack?)
        warp @aurora_map$, @aurora_x, @aurora_y;
        @aurora_map$="";
        @aurora_x=0;
        @aurora_y=0;
    } else {
        teleporthome();
    }
    FYRaid_Select(true); // Formally close the raid session
	close;
}

001-13	mapflag	zone	MMO
001-13-0	mapflag	zone	MMO
001-13-1	mapflag	zone	MMO
001-13-2	mapflag	zone	MMO