summaryrefslogblamecommitdiff
path: root/world/map/npc/009-7/core.txt
blob: ab033c662fc1f2a67bf77c6cf70c33b083c4c4b4 (plain) (tree)
1
2
3
4
5
6
7
8

                                                      
                                     
 

                 
 
       




                                                                                                                               
 
       

                                                                                                                                               
 
         

                                                                            

          






                                                                                                                               

 
                                  
 



                                                        
 
          



                                                                                      

          
        

           






                                                                                  

 
                                       
                                    
 

                      
 
       




                                                                                                                            
 
         

                                               

       

                                                                                                                         

          




                                                                             

           








                                                                     
 
           

                                                                                                
 
        


                                                      

          

                                    

 
                                    
                                    
 




                                                       
 
                                              









                                                                               
 
        

                             
 
          







                                                                                                    

          


                                    

           

                                                                                     

 
                            
                                           
 
                                                                              





                                                                                
                                     
 







                                                         
 
          


                                    

 
                                 
 








                                                         
 
          


                                    

 
                                               
                                   
 

                               

 
                                       
 



                                                                          

 
                                                               
                                 
 



                                     

 
                                              
                                   
 


                                                                             

 
                                                              
                                 
 



                                                                                                                                        
 
          

                                            

           



                                                    

          



                                                   

           


                                                        

          

                              

        


                                                          

         


                                    

 
                                      
                                 
 


















                                                                                                                                                                          

 
                                                        
                                    
 












                                                                                                                                                                    

 
                                                                   
                                  
 
                
 
       





                                                 

        

                                    

          





                                                                               
             

                                     

       


                                                     

         
           

 
                                                   
                               
 
                                         
                                                                       

                                        
 
         

                                                         
 
          





                                                         
 
           

                              
 
           





                                                           
 
          


                                    
 
            

                              

          


                                    

           

                                                                                              

           


                                                          
           

         
                                                          





                                                                                                                               

 
                                                
                               
 





                                                                                                                             

 
                                                     
                                      
 




                                                                                                              

 
                                               
                              
 





                                                                                            
 
        





                                                                                                
 
// this file contains the game logic of the fight club

function|script|fightclub_sendrequest
{
    set @loop, 0;
    goto L_Loop;

L_Loop:
    if(@Duel_Queue$[@loop] == @caster_name$) goto L_Exists;
    if(@Duel_Queue$[@loop] == "") goto L_Proceed;
    set @loop, (@loop + 1);
    if(@loop >= getarraysize(@Duel_Queue)) goto L_Full; // this shouldn't happen since we check in magic but we still handle it
    goto L_Loop;

L_Full:
    message @caster_name$, "There is already "+ $@Duel_PlayerQueueLimit +" duel request(s) in the queue of this player, which is the maximum.";
    return;

L_Exists:
    message @caster_name$, "You already requested a duel with this player.";
    return;

L_Proceed:
    misceffect FX_MAGIC_DARKRED, @caster_name$;
    message @caster_name$, "Your request has been sent.";
    set @Duel_Queue$[@loop], @caster_name$;
    if(@Duel_Fighter == 0) message strcharinfo(0), "You have received a new duel request. Talk to Rouge to accept or decline.";
    if(@Duel_Fighter == 0) misceffect FX_MAGIC_DARKRED, strcharinfo(0);
    if(@Duel_Fighter == 1) set @Duel_HasPendingRequest, 1;
    return;
}

function|script|fightclub_getrules
{
    set $@fightclub_myself, getcharid(3);
    if(@target < 1) goto L_Proceed; // get our own rules
    if(attachrid(@target) == 1) goto L_Proceed;
    goto L_Missing;

L_Proceed:
    set $@Temp_NoMagic, (DUELS & $@NoMagicBit);
    if($@fightclub_myself == getcharid(3)) goto L_Proceed2; // the target is ourselves
    if(attachrid($@fightclub_myself) == 1) goto L_Proceed2;
    goto L_Missing;

L_Missing:
    end;

L_Proceed2:
    set $@fightclub_myself, 0;
    set @target, 0;
    if($@Temp_NoMagic != 1)
        mes "(no rules)";
    if($@Temp_NoMagic == 1) mes "- No Magic";
    set $@Temp_NoMagic, 0; // now we clean these vars ASAP because they're globals
    return;
}

// ** called when someone agree to duel
function|script|fightclub_AddToQueue
{
    set @Duel_Loop, 0;
    goto L_Loop;

L_Loop:
    if(($@Duel_Queue_Blue$[@Duel_Loop] == @caster_name$) && ($@Duel_Queue_Red$[@Duel_Loop] == @target_name$)) goto L_Exists;
    if(($@Duel_Queue_Red$[@Duel_Loop] == @caster_name$) && ($@Duel_Queue_Blue$[@Duel_Loop] == @target_name$)) goto L_Exists;
    set @Duel_Loop, (@Duel_Loop + 1);
    if(@Duel_Loop >= getarraysize($@Duel_Queue_ID)) goto L_Proceed;
    goto L_Loop;

L_Exists:
    mes "This battle is already in the queue.";
    close;

L_Full:
    mes "There is already " + $@Duel_QueueLimit + " battles in the queue, which is the maximum. Please try again later.";
    close;

L_Proceed:
    if(getarraysize($@Duel_Queue_ID) >= ($@Duel_QueueLimit + 1)) goto L_Full;
    set @index, getarraysize($@Duel_Queue_ID);
    if(@index >= 1) goto L_Proceed2;
    set @index, 1;
    goto L_Proceed2;

L_Proceed2:
    if($@Duel_Queue_Red$[@index] != "") goto L_NotClean;
    set $@Duel_Queue_Red$[@index], @caster_name$;
    if($@Duel_Queue_Blue$[@index] != "") goto L_NotClean;
    set $@Duel_Queue_Blue$[@index], @target_name$;
    if($@Duel_Queue_ID[@index] != 0) goto L_NotClean;
    set $@Duel_Queue_ID[@index], ($@Duel_Queue_ID[(@index - 1)] + 1);
    if($@Duel_Queue_ID[@index] <= $Duel_LastDuel) goto L_FixId;
    if($@Duel_CurrentDuel < 1) goto L_Request;
    return;

L_NotClean:
    message @caster_name$, "An error occured: array element not empty. Try again in 5 seconds.";
    return;

L_FixId:
    set $@Duel_Queue_ID[@index], ($Duel_LastDuel + 1);
    if($@Duel_CurrentDuel < 1) goto L_Request;
    return;

L_Request:
    callfunc "fightclub_NextBattle";
    return;
}

// ** called when a duel is finished
function|script|fightclub_NextBattle
{
    set $@Duel_Queue_Blue$[0], ""; // clean the 0 index
    set $@Duel_Queue_Red$[0], "";
    set $@Duel_Queue_ID[0], 0;
    set $@Duel_Loop, 1; // start the loop at 1
    goto L_Loop;

L_Loop: // here we shift the array to the left
    if($@Duel_Queue_ID[$@Duel_Loop] < 1) goto L_Empty;
    set $@Duel_Queue_Red$[($@Duel_Loop - 1)], $@Duel_Queue_Red$[$@Duel_Loop];
    set $@Duel_Queue_Red$[$@Duel_Loop], ""; // it is always important to clean
    set $@Duel_Queue_Blue$[($@Duel_Loop - 1)], $@Duel_Queue_Blue$[$@Duel_Loop];
    set $@Duel_Queue_Blue$[$@Duel_Loop], "";
    set $@Duel_Queue_ID[($@Duel_Loop - 1)], $@Duel_Queue_ID[$@Duel_Loop];
    set $@Duel_Queue_ID[$@Duel_Loop], 0;
    set $@Duel_Loop, ($@Duel_Loop + 1);
    if($@Duel_Loop >= getarraysize($@Duel_Queue_ID)) goto L_Proceed;
    goto L_Loop;

L_Empty:
    // the queue is now empty
    return;

L_Proceed:
    callfunc "fightclub_CleanStage";
    set $@Duel_CurrentDuel, $@Duel_Queue_ID[0]; // since the array is shifted, the index is always 0
    set $Duel_LastDuel, $@Duel_Queue_ID[0]; // this is used to keep the same index across reboots
    set $@Duel_BluePlayer, getcharid(3,$@Duel_Queue_Blue$[0]);
    set $@Duel_RedPlayer, getcharid(3,$@Duel_Queue_Red$[0]);
    if(attachrid($@Duel_BluePlayer) != 1) goto L_Missing;
    if(attachrid($@Duel_RedPlayer) == 1) goto L_Proceed2;
    goto L_Missing;

L_Missing:
    callfunc "fightclub_CleanStage";
    callfunc "fightclub_NextBattle";
    return;

L_Proceed2:
    addtimer ($@Duel_TimeBeforeNext * 1000), "#FightClub#utils::OnDelayedNextBattle";
    return;
}

// ** called after the delay
function|script|fightclub_NextBattleProceed
{
    set $@Duel_NoMagic, (DUELS & $@NoMagicBit); // get the rules of the caster
    donpcevent "Rouge#Duels::OnAnnounceNext";
    set $@Duel_Started, 0;
    addtimer ($@Duel_TimeBeforeWarp * 1000), "#FightClub#utils::OnDelayedStart";
    return;
}

function|script|fightclub_StartBattle
{
    set $@Duel_Started, 1;
    npcwarp 40, 45, "Rouge#Duels";
    donpcevent "#FightClub#TimeLimit::OnStartTimer";
    if(attachrid($@Duel_RedPlayer) != 1) goto L_Missing;
    callfunc "fightclub_enter";
    if(attachrid($@Duel_BluePlayer) != 1) goto L_Missing;
    callfunc "fightclub_enter";
    return;

L_Missing:
    callfunc "fightclub_CleanStage";
    callfunc "fightclub_NextBattle";
    return;
}

function|script|fightclub_TimeOut
{
    debugmes "on time out";
    donpcevent "Rouge#Duels::OnAnnounceTimeOut";
    if(attachrid($@Duel_RedPlayer) != 1) goto L_Missing;
    callfunc "fightclub_exit";
    if(attachrid($@Duel_BluePlayer) != 1) goto L_Missing;
    callfunc "fightclub_exit";
    callfunc "fightclub_CleanStage";
    callfunc "fightclub_NextBattle";
    return;

L_Missing:
    callfunc "fightclub_CleanStage";
    callfunc "fightclub_NextBattle";
    return;
}

// ** called when someone uninvited is on stage
function|script|fightclub_Intrusion
{
    // nothing to do here (yet)
    return;
}

function|script|fightclub_EmergencyWipe
{
    callfunc "fightclub_CleanStage";
    callfunc "fightclub_StartUp";
    // TODO: check if everything is clean (function) and mapexit otherwise
    return;
}

// ** called whenever someone wins (to handle rewards and bids)
function|script|fightclub_Victory
{
    // TODO: give some sort of reward
    // TODO: increase score
    // TODO: update leaderboard
    return;
}

// ** called when the player needs to be reset
function|script|fightclub_DestroyMe
{
    callfunc "fightclub_exit";
    percentheal -100, 0; // dying removes @killable, @killer or any temp buff
    return;
}

// ** called when the red or blue player disappears from stage
function|script|fightclub_Missing
{
    // $@Duel_Missing 1 = red, 2 = blue
    if (attachrid($@Duel_BluePlayer) == 1) goto L_Proceed; // we need to attach to at least one player
    if (attachrid($@Duel_RedPlayer) == 1) goto L_Proceed;
    goto L_Resume; // can't attach either of them (this is not a problem since it means they are offline so their vars are clean anyway)

L_Proceed:
    if($@Duel_Missing == 1) goto L_BlueWins;
    goto L_RedWins;

L_BlueWins:
    donpcevent "Rouge#Duels::OnAnnounceBlueForfeit";
    set $@duel_winner, $@Duel_BluePlayer;
    callfunc "fightclub_Victory";
    goto L_Clean;

L_RedWins:
    donpcevent "Rouge#Duels::OnAnnounceRedForfeit";
    set $@duel_winner, $@Duel_RedPlayer;
    callfunc "fightclub_Victory";
    goto L_Clean;

L_KillBlue:
    callfunc "fightclub_exit";
    if(attachrid($@Duel_RedPlayer) == 1) goto L_KillRed;
    goto L_Resume;

L_KillRed:
    callfunc "fightclub_exit";
    goto L_Resume;

L_Clean:
    if(attachrid($@Duel_BluePlayer) == 1) goto L_KillBlue;
    if(attachrid($@Duel_RedPlayer) == 1) goto L_KillRed;
    goto L_Resume; // couldn't kill them

L_Resume:
    callfunc "fightclub_CleanStage";
    callfunc "fightclub_NextBattle";
    return;
}

// ** called after the server boots up
function|script|fightclub_StartUp
{
    if($fightclub_enabled < 1) set $fightclub_enabled, 1; // init the (permanent) enabled global (this will only be done once, when the duel system is merged with master)
    if($@Duel_TimeBeforeNext < 1) set $@Duel_TimeBeforeNext, 5; // init the (temporary) TimeBeforeNext global
    if($@Duel_TimeBeforeWarp < 1) set $@Duel_TimeBeforeWarp, 5; // init the (temporary) TimeBeforeWarp global
    if($@Duel_TimeBeforeStart < 1) set $@Duel_TimeBeforeStart, 3; // init the (temporary) TimeBeforeStart global
    if($@Duel_TimeLimit < 1) set $@Duel_TimeLimit, 120; // init the (temporary) TimeLimit global
    if($@Duel_QueueLimit < 1) set $@Duel_QueueLimit, 5; // init the (temporary) QueueLimit global
    if($@Duel_PlayerQueueLimit < 1) set $@Duel_PlayerQueueLimit, 2; // init the (temporary) PlayerQueueLimit global
    if($@fightclub_password$ == "") set $@fightclub_password$, "Banana"; // init the (temporary) fightclub_password global
    setarray $@Duel_Queue_ID, 0;
    cleararray $@Duel_Queue_ID, 0, ($@Duel_QueueLimit + 1);
    setarray $@Duel_Queue_Blue$, "";
    cleararray $@Duel_Queue_Blue$, "", ($@Duel_QueueLimit + 1);
    setarray $@Duel_Queue_Red$, "";
    cleararray $@Duel_Queue_Red$, "", ($@Duel_QueueLimit + 1);
    set $@Duel_TotalTime, 0;
    // flags below
    set $@DuelPvpBit, (1 << 1);
    set $@NoMagicBit, (1 << 2);
    return;
}

// ** called before and after each duel to wipe the vars
function|script|fightclub_CleanStage
{
    if($@Duel_NoWarp != 1) areawarp "009-7.gat", $@fightclub_x1, $@fightclub_y1, $@fightclub_x2, $@fightclub_y2, "009-7.gat", 31, 40; // kick all players from stage
    set $@Duel_NoWarp, 0;
    set $@Duel_NoMagic, 0; // clean the Duel parameters
    set $@Duel_CurrentDuel, 0; // no duel atm
    set $@Duel_Started, 0; // no duel atm
    set $@Duel_RedPlayer, 0;
    set $@Duel_BluePlayer, 0;
    set $@Duel_Missing, 0;
    set $@Duel_TotalTime, 0;
    npcwarp 32, 45, "Rouge#Duels";
    donpcevent "#FightClub#TimeLimit::OnStopTimer";
    killmonster "009-7.gat", "All";
    return;
}

// ** called by npc; allows the player to change their custom rules
function|script|fightclub_setrules
{
    goto L_Main;

L_Main:
    mes "Your rules are the following: "; mes "";
    callfunc "fightclub_getrules";
    mes ""; mes "What do you want to do?";
    menu
        "Change my rules.", L_Start,
        "Nevermind.", L_Return;

L_Start:
    set DUELS, DUELS | $@NoMagicBit;
    goto L_NoMagic;

L_NoMagic:
    if((DUELS & $@NoMagicBit) != 1) goto L_Done;
    mes "Do you want to allow magic?";
    mes "If disabled, the fighters will not be able to use any kind of spell.";
    menu
        "Yes.", L_NoMagicYes,
        "No.", L_Done;
L_NoMagicYes:
    set DUELS, DUELS &~ $@NoMagicBit;
    goto L_Done;

L_Done:
    next;
    mes "You have succesfully changed your options.";
    goto L_Main;

L_Return:
    return;
}

// ** called by event handler whenever someone dies
function|script|fightclub_death
{
    if(@Duel_Fighter != 1) goto L_NoDuel;
    if(($@Duel_CurrentDuel < 1) || ($@Duel_Started != 1)) goto L_Reset;
    if(@killerrid != 0) goto L_Murdered;
    goto L_Killed;

L_Killed:
    if(getcharid(3) == $@Duel_RedPlayer) goto L_BlueWins;
    goto L_RedWins;

L_RedWins:
    donpcevent "Rouge#Duels::OnAnnounceRedWins";
    set $@duel_winner, $@Duel_RedPlayer;
    callfunc "fightclub_Victory";
    callfunc "fightclub_exit";
    if(attachrid($@Duel_RedPlayer) == 1) goto L_RedWins2;
    goto L_Missing;

L_RedWins2:
    callfunc "fightclub_exit";
    goto L_Proceed;

L_BlueWins:
    donpcevent "Rouge#Duels::OnAnnounceBlueWins";
    set $@duel_winner, $@Duel_BluePlayer;
    callfunc "fightclub_Victory";
    callfunc "fightclub_exit";
    if(attachrid($@Duel_BluePlayer) == 1) goto L_BlueWins2;
    goto L_Missing;

L_Missing:
    callfunc "fightclub_CleanStage";
    callfunc "fightclub_NextBattle";
    return;

L_BlueWins2:
    callfunc "fightclub_exit";
    goto L_Proceed;

L_Proceed:
    callfunc "fightclub_CleanStage";
    callfunc "fightclub_NextBattle";
    return;

L_Murdered:
    if(($@Duel_RedPlayer != @killerrid) && ($@Duel_BluePlayer != @killerrid)) goto L_Stranger;
    goto L_Killed; // now we proceed the same way as L_Killed

L_Stranger:
    // the victim was not murdered by its adversary (wtf)
    if(debug) donpcevent "Debug#Duels::OnKillerNotInDuel";
    callfunc "fightclub_EmergencyWipe";
    return;

L_NoDuel:
    if(debug) donpcevent "Debug#Duels::OnVictimNotInDuel";
    return;

L_Reset: // the player has duel_fighter but no duel is ongoing (happens if the player quit before fightclub_exit can be called)
    if(debug) donpcevent "Debug#Duels::OnVictimInDuelNoDuel";
    callfunc "fightclub_DestroyMe"; // here we attempt to resume the interrupted procedure
    return;
}

// ** called every time a player enters the ring
function|script|fightclub_enter
{
    set @Duel_Fighter, 1;
    warp "009-7.gat", rand($@fightclub_x1,$@fightclub_x2), rand($@fightclub_y1,$@fightclub_y2);
    gmcommand "@alive"; // ensure that you can't duel wih a corpse
    message strcharinfo(0), "Get Ready.";
    addtimer ($@Duel_TimeBeforeStart * 1000), "#FightClub#utils::OnBecomeKiller"; // call fightclub_enter_killer in 3 seconds
    return;
}

// ** called 3 seconds after a player enters the ring
function|script|fightclub_enter_killer
{
    gmcommand "@killable";
    gmcommand "@killer"; // add both killable and killer so if one doesn't kick in, the other (hopefully) will
    set @killer, 1;
    message strcharinfo(0), "GO !";
    return;
}

// ** called every time a player exits the ring
function|script|fightclub_exit
{
    set @Duel_Fighter, 0;
    if(getmap() == "009-7") warp "009-7.gat", 31, 40; // do not warp if player left the room
    if(@killer != 1) goto L_Clean;
    gmcommand "@killable";
    gmcommand "@killer";
    goto L_Clean;

L_Clean:
    set @killer, 0; // the player no longer have @killer
    gmcommand "@alive"; // refill hp/mana
    sc_end 132; sc_end 14; sc_end 37; sc_end 185; // remove effects
    message strcharinfo(0), "Thank you for participating in the fight club!";
    if(@Duel_HasPendingRequest) message strcharinfo(0), "You have received a new duel request.";
    return;
}