summaryrefslogblamecommitdiff
path: root/world/map/npc/033-1/kimarr.txt
blob: 490ca063da6b4fdca2dc87f6ef2eff6bbf6c03ea (plain) (tree)
1
2
3
4
5
6
7
8
9
                       


                             



                                               
                                                                                              
                                                               
                                                            
                                                                          

                                                                   
                                                                           
                                                                









                                                                                               
                                                                              
                                                                                  
                                                                                                                              




                                                                                              



                                           
























                                                                                                                         

                                                       

          




                                                                                                                                                          

                          
 
               











                                                                                                     










                                                                            
 

                    
                                                                            












                                                                               
                                                                 

                 

                                                                             
         
                   
                                                                                                     

         
                     

                                    
                                
                   
                                                                                        


                               
 



                   
                                                             


                                                       
        


                                                                                       


                                                                                     

       








                                           
                                                                     
                        
                             
                 
                 

               

                                                                                              
                 
 
            
                                                                                              
        
 
            





                                                                              


                                            



                                                                       
                                         
                            
                        


                          

                  
 
         

                                                                                  

                    
 









                                                                                                                      


                                            

                    
 
           
                                                 
                            
 
             


                               




                                                                                             


                            
                  

                             
                                                                                               
                           
                         
 
               
                                                                                                        


                                                                                                                       



                                                                                               
                                                                                 
                                                                       
                                                                                     
                                                                        

                                                                                     
                                                                 
                                                                                     
 
                          



                              
                                                        
                         
 



                      
              

                              
                                           
                                           
                                           


                                                                 

                                      
                         
                  

        
            
                                                                                                  
        

        
                 






                              


                                                     

           
                   
                             
                                      
                             



                                                     


                                                      

                                 
                       






                                                                            
                                                      
                         
 
                         











                                                                     
 






                                                                 



                    
 



                 
                                         
                     
                                                                                                                                                       

                          
 
        




                                                                          
                 



                                                                                                






                                                  
 
// Fluffy hunting quest
// initially by Jenalya
// more by alastrim
// broken by o11c, then fixed

// Variables:
// global $@Fluffy_Hunting - state of the quest
//      0: nobody is hunting
//      1: somebody is hunting. The script checks every second if there is food on the ground.
//      2: not used anymore, was: food dropped but no spawn yet
//      3: not used anymore, was: monsters have been spawned
// global $@Fluffy_Time - the number of seconds since you entered the area
// global $@Fluffy_Spawn - how many fluffies have been spawned
// global $@Fluffy_Kills - how many fluffies you have killed so far
// global $@Fluffy_Min - how many fluffies you have to kill to get a reward
// global $@Fluffy_Alive - how many fluffies are currently alive
// global $@Fluffy_PC_Deaths - used to keep track of whether the fluffies kill you
// global $@Fluffy_Fighter$ - name of the person hunting fluffies (only used for ornamentation)
// global $@Fluffy_FighterID - ID of the person hunting fluffies
// nibble 0 of QUEST_Barbarians - state for this and adjacent NPCs
//      0: haven't talked about it
//      1: heard about it
//      2: finished quest
//      3: got reward

// Note: if you're going to reenable the "drop multiple times" feature
// 1: please do it every second, not just once you've killed everything - Done
// 2: you should change $@Fluffy_Spawn to $@Fluffy_Alive and decrement it on kills
//  Kept $@Fluffy_Spawn and added $@Fluffy_Alive. The script spawns the amount related to what you drop at each specific time.
// 3: add a variable to spawn more fluffies if you drop more than 100 apples, as you kill them

// Also, the $@Fluffy_Extra behaviour should be reconsidered (hardly anything spawns ...)
// that's the only reason I didn't make that one a local variable like it really is


033-1.gat,74,32,0|script|Kimarr|218,{
    if ($@Fluffy_FighterID == getcharid(3))
        goto L_Attention;

    set @Q_Barbarians_MASK, NIBBLE_0_MASK;
    set @Q_Barbarians_SHIFT, NIBBLE_0_SHIFT;

    set @state, ((QUEST_Barbarians & @Q_Barbarians_MASK) >> @Q_Barbarians_SHIFT);

    if (@state >= 3) goto L_Again;
    if (@state == 2) goto L_Reward;
    if (@state == 1) goto L_Ask;

    mes "[Barbarian]";
    mes "\"Greetings, little person.\"";
    next;
    mes "\"I am Kimarr, hunter and warrior of the Mangarr.\"";
    next;
    mes "\"You are very small, better be careful in this snowy mountains. It is cold and dangerous monsters are here.\"";
    menu
        "Hello, my name is " + strcharinfo(0) + " and I'm not small. I'm a great warrior!",-,
        "I'm " + strcharinfo(0) + ", don't underestimate me. I'm an experienced adventurer!" ,-,
        "I'm the legendary " + strcharinfo(0) + ", I've fought countless battles.",-;

    mes "Kimarr seems to be amused.";
    mes "[Kimarr]";
    mes "\"Really? Do you want to prove it?\"";
    menu
        "Sure! What shall I do?", -,
        "No, I don't need to prove anything.", L_Close;

L_Explain:
    mes "[Kimarr]";
    mes "\"Every young member of our tribe proves his or her worth by hunting monsters.\"";
    next;
    mes "\"The first monsters to hunt are fluffies. Fluffies give a good meal for a young person and the fur can be used to make clothes and blankets.\"";
    next;
    set @state, 1;
    callsub S_Update_Mask;

L_Explain_Game:
    mes "[Kimarr]";
    mes "\"In that cave there are living fluffies. They like to eat apples.\"";
    next;
    mes "\"I also saw one of them getting excited about one of that sweet things you call 'cake'.\"";
    next;
    mes "\"You should be careful, other monsters living here might like the food as well\"";
    next;
    mes "\"Go to the cave entrance and throw food on the floor to make them come out.\"";
    next;
    mes "\"Then hunt as many fluffies as you can until I tell you to stop.\"";
    next;
    mes "\"Drop more food when no fluffies are left.\"";
    next;

// dialog starts here if you've asked about it but not done it (@state == 1)
L_Ask:
    mes "[Kimarr]";
    mes "\"So, are you going to try?\"";
    menu
        "Yeah, let's start!", L_Game,
        "Could you explain again?", L_Explain_Game,
        "Maybe later.", -;
    goto L_Close;

L_AlreadyGotReward:
    callsub S_Clean;
    mes "Once again you prove you are worth as a hunter, " + strcharinfo(0);
    goto L_Close;

L_Reward1:
    if (@state >= 2)
        goto L_AlreadyGotReward;

    set @state, 2;
    callsub S_Update_Mask;
    callsub S_Clean;

    // as far as I can tell, this fails because it won't resume from the "next"
    // when the script is executed via the "OnFluffyDeath" callback
    // (I haven't tried via the 301st call of OnTimer1000)
    message strcharinfo(0), "Kimarr: talk to me for your reward";
    goto L_Close;

// this label is reached on completion of the quest, or, if you inventory was
// full at the time, when you next initiate dialog (with @state == 2)
L_Reward:
    mes "[Kimarr]";
    mes "\"That was very impressive - now you can call yourself a hunter, " + strcharinfo(0) + ".\"";
    next;

    getinventorylist;
    if (@inventorylist_count == 100)
        goto L_Full_Inv;
    set @inventorylist_count, 0;
    mes "[Kimarr]";
    mes "\"Take this as a symbol of your strength. You're a member of our tribe now.\"";
    getitem "YetiSkinShirt", 1;
    set @state, 3;
    callsub S_Update_Mask;

    goto L_Close;

L_Full_Inv:
    mes "[Kimarr]";
    mes "\"You can't carry the reward I want to give you.\"";
    goto L_Close;

// dialog starts here after you've completed this quest
L_Again:
    mes "[Kimarr]";
    mes "\"Does the hunter " + strcharinfo(0) + " want to hunt some fluffies again?\"";
    menu
        "Yeah!", L_Game,
        "Can you tell me who were the most successful fluffy hunters?", L_ShowRecord,
        "Not now.", L_Close;

L_Game:
    if ($@Fluffy_Hunting)
        goto L_Someone_Else;
    set $@Fluffy_Hunting, 1;
    set $@Fluffy_Kills, 0;
    set $@Fluffy_PC_Deaths, PC_DIE_COUNTER;
    set $@Fluffy_Fighter$, strcharinfo(0);
    set $@Fluffy_FighterID, getcharid(3);
    set $@Fluffy_Time, 0;

//TODO: set minimum number of killed fluffies (maybe based on level?)
    set $@Fluffy_Min, 2;
    warp "033-1.gat", 79, 34;
    initnpctimer;
    goto L_Close;

L_Someone_Else:
    mes "[Kimarr]";
    mes "\"At the moment someone else is hunting. Let's wait until that hunting has ended.\"";
    goto L_Close;

L_Attention:
    message strcharinfo(0), "Kimarr: You should be focused on hunting fluffies, not talking.";
    end;

OnTimer1000:
// Checking if player is logged
    if (isloggedin($@Fluffy_FighterID) == 0)
        goto L_GotOut;
    attachrid($@Fluffy_FighterID);
// Checking if player is still in the map or used a towell or spell to get out
    if (getareausers("033-1.gat", 79, 28, 88, 42) == 0)
        goto L_GotOut;
    if (PC_DIE_COUNTER > $@Fluffy_PC_Deaths)
        goto L_Died;
// Checking if there is more than 1 player in the fight area
    if (getareausers("033-1.gat", 79, 28, 88, 42) > 1)
        areatimer "033-1.gat", 79, 28, 88, 42, 10, "Kimarr::OnToomany";
    
    set $@Fluffy_Time, $@Fluffy_Time + 1;
    if ($@Fluffy_Time > 180)
        goto L_TimeOver;
        goto L_CheckDrops;

L_ContinueTimer:
    setnpctimer 0;
    end;

L_GotOut:
    // TODO: this is the only use of $@Fluffy_Fighter$, can we remove it?
    npctalk "What a strange thing... " + $@Fluffy_Fighter$ + " just disappeared!";
    callsub S_Clean;
    end;

OnToomany:
    if (getcharid(3) != $@Fluffy_FighterID)
    goto L_Warp;
    end;

L_Warp:
    warp "033-1.gat", 77, 34;
    npctalk "Hey " + strcharinfo(0) + "! What are you doing there? This hunt is for " + $@Fluffy_Fighter$ + " alone!";
    end;

L_Died:
    warp "033-1.gat", 77, 34;
    message strcharinfo(0), "You are dead.";
    callsub S_Clean;
    end;

L_TimeOver:
    message strcharinfo(0), "Your time is over.";
    goto L_MaybeRecordScore;

L_CheckDrops:
    if ($@Fluffy_Alive >= 100)
        goto L_TooManyFluffies;
    set @Fluffy_Toomany, 0;
    set @Fluffy_RedApple,      getareadropitem("033-1.gat", 79, 29, 88, 42, "RedApple", 1);
    set @Fluffy_XmasCake,      getareadropitem("033-1.gat", 79, 29, 88, 42, "XmasCake", 1);
    set @Fluffy_Cake,          getareadropitem("033-1.gat", 79, 29, 88, 42, "Cake", 1);
    set @Fluffy_GreenApple,    getareadropitem("033-1.gat", 79, 29, 88, 42, "GreenApple", 1);
    if (@Fluffy_RedApple || @Fluffy_XmasCake || @Fluffy_Cake || @Fluffy_GreenApple)
        goto L_BeginHunting;
    goto L_ContinueTimer;

L_TooManyFluffies:
    if (@Fluffy_Toomany)
        goto L_ContinueTimer;
    message strcharinfo(0), "Wow, calm down, there are already too many fluffies around here.";
    set @Fluffy_Toomany, 1;
    goto L_ContinueTimer;

L_BeginHunting:
    set $@Fluffy_Spawn, @Fluffy_RedApple + 5 * @Fluffy_XmasCake + 3 * @Fluffy_Cake + @Fluffy_GreenApple;
    // limit the number of monsters that can be spawned, to prevent people creating lag with massive amount of monsters
    if ($@Fluffy_Spawn > 100)
        set $@Fluffy_Spawn, 100;

    areamonster "033-1.gat", 79, 29, 88, 42, "", 1020, $@Fluffy_Spawn, "Kimarr::OnFluffyDeath";

    // other monsters don't generate a real event
    set $@Fluffy_Extra, 5 * @Fluffy_XmasCake + 3 * @Fluffy_Cake + 10 * BaseLevel;
    if ((BaseLevel > 40) && (rand($@Fluffy_Extra) > 500)) // Ice Goblin
        areamonster "033-1.gat", 79, 29, 88, 42, "", 1058, 1, "Kimarr::OnOtherDeath";
    if ((BaseLevel > 60) && (rand($@Fluffy_Extra) > 550)) // Santa Slime
        areamonster "033-1.gat", 79, 29, 88, 42, "", 1015, 1, "Kimarr::OnOtherDeath";
    // TODO: add the wolvern as well when it has been added
    if ((BaseLevel > 70) && (rand($@Fluffy_Extra) > 600)) // Yeti
        areamonster "033-1.gat", 79, 29, 88, 42, "", 1072, 1, "Kimarr::OnOtherDeath";

    set $@Fluffy_Extra, 0;
    set @Fluffy_RedApple, 0;
    set @Fluffy_XmasCake, 0;
    set @Fluffy_Cake, 0;
    set @Fluffy_GreenApple, 0;
    set $@Fluffy_Alive, $@Fluffy_Alive + $@Fluffy_Spawn;
    goto L_ContinueTimer;

OnOtherDeath:
    // nothing happens
    end;

OnFluffyDeath:
    if ($@Fluffy_Hunting == 0)
        end;
    set $@Fluffy_Kills, $@Fluffy_Kills + 1;
    set $@Fluffy_Alive, $@Fluffy_Alive - 1;
    //TODO: remove announce after debugging
//  message strcharinfo(0), "Fluffies alive: " + $@Fluffy_Alive;
//  message strcharinfo(0), "Fluffies killed: " + $@Fluffy_Kills;
    if ($@Fluffy_Alive != 0)
        end;
    if (attachrid($@Fluffy_FighterID))
        goto L_Killedall;
    goto L_GotOut;
    end;

L_Killedall:
    message strcharinfo(0), "Good job, but you still have time to throw more food on the ground.";
    end;

S_Clean:
    stopnpctimer;
    set $@Fluffy_Hunting, 0;
    set $@Fluffy_Time, 0;
    set $@Fluffy_PC_Deaths, 0;
    set $@Fluffy_Fighter$, "";
    set $@Fluffy_FighterID, 0;
    set $@Fluffy_Kills, 0;
    set $@Fluffy_Spawn, 0;
    set $@Fluffy_Alive, 0;
    killmonster "033-1.gat", "Kimarr::OnOtherDeath";
    killmonster "033-1.gat", "Kimarr::OnFluffyDeath";
    return;

L_MaybeRecordScore:
    warp "033-1.gat", 77, 34;
    if ($@Fluffy_Kills < $@Fluffy_Min)
        goto L_NotGoodEnough;
    set @rank, 0;
L_MaybeInsertNext:
    if ($@Fluffy_Kills > $Record_Fluffy_Kills[@rank])
        goto L_InsertScore;
    // you already had a better score
    if (strcharinfo(0) == $Record_Fluffy_Name$[@rank])
        goto L_Reward1;
    set @rank, @rank + 1;
    if (@rank == MAX_HIGH_SCORES)
        goto L_Reward1;
    goto L_MaybeInsertNext;

L_InsertScore:
    set @loop, @rank;
L_FindLastScore:
    // comment this out to allow the player to be in the list more than once
    // though actually, it might be better just to assume the list is full
    if (strcharinfo(0) == $Record_Fluffy_Name$[@loop])
        goto L_MoveStuff;

    set @loop, @loop + 1;
    if (@loop == MAX_HIGH_SCORES)
        goto L_MoveStuff;
    goto L_FindLastScore;

L_MoveStuff:
    if (@loop == @rank)
        goto L_FinallyInsertMe;
    set $Record_Fluffy_Kills[@loop], $Record_Fluffy_Kills[@loop - 1];
    set $Record_Fluffy_Name$[@loop], $Record_Fluffy_Name$[@loop - 1];
    set $Record_Fluffy_Date$[@loop], $Record_Fluffy_Date$[@loop - 1];
    set @loop, @loop - 1;
    goto L_MoveStuff;

L_FinallyInsertMe:
    set $Record_Fluffy_Kills[@rank], $@Fluffy_Kills;
    set $Record_Fluffy_Name$[@rank], strcharinfo(0);
    callfunc "time_stamp";
    set $Record_Fluffy_Date$[@rank], @ts_date$ + " " + @ts_time$;
    set @ts_date$, "";
    set @ts_time$, "";
    goto L_Reward1;

L_NotGoodEnough:
    callsub S_Clean;

L_ShowRecord:
    set @rank, 0;
    set @loop, 0;
L_ShowNextRecord:
    if ($Record_Fluffy_Kills[@loop] == 0)
        goto L_Close;
    mes (@loop + 1) + " - " + $Record_Fluffy_Name$[@loop] + " - " + $Record_Fluffy_Kills[@loop] + " fluffies killed at " + $Record_Fluffy_Date$[@loop];
    set @loop, @loop + 1;
    goto L_ShowNextRecord;

L_Close:
    // clear all temporary player variables that are not otherwise cleared

    // it is not feasible to otherwise clear @loop
    // but, not all jumpers to L_Close have necessarily used it ...
    // still, I think it's a good precent to ALWAYS exit via L_Close
    set @loop, 0;

    // if you unset @state, @Q_Barbarians_MASK or @Q_Barbarians_SHIFT, it might break the script
    // If only we had the concept of "local constants" ...

    close;

S_Update_Mask:
    set QUEST_Barbarians,
        (QUEST_Barbarians & ~(@Q_Barbarians_MASK))
            | (@state << @Q_Barbarians_SHIFT);
    return;
}