summaryrefslogblamecommitdiff
path: root/npc/functions/util.txt
blob: 4e12e5fed5a0d3ed54fadf6e2628e53f0bcf2dc9 (plain) (tree)
1
2
3
4
5
6
               
           
               


                    






                                                                                         
 







                                                                        
 



                                                                                     
                                      

               

                                                                          













                                                                                       




                                                         
                                                                                  








                                                                                                

                                                                                 
                                        
                                 


















                                         
                                     
                                          

                    











                                       




                                     








                                       
                                    

                    
                       



                                           











                                                
                                        



                
                                                                                  
                                                    
                                         

                              
                                   
                               

                                               

                        

                                            





                                                    



                                                  

                                               











                                                



                                            



                                             



                                              



                                                    
                               
                                                  
                        
 



                                           



                                         





                                          

                        




                                                  
                         
 
 




 
                                  


                                      
                                                









                                               






                                                                           







                                              


                                                     
 



                                                 



                                            



                                                  
                                     
                        

 




 
                                     

                                    




                                        
                                        









                                       



                                       
                                        
                        
 




 
                                





                                         
                                       


                                          















                                                        
                                   
                        
 
 































                                                  



















                                          
























                                            
                                              






                                           
                                          









                                         



                                          
                                  
                         

 
            

     
                                        




                




                                                                 
                  

                                 
                         

     
                     

                                  
                         
                                 
                         
                                 
                         






                                  
                         
                                 
                         

     




                                  
                         
                                 
                         

     




                                                                          
                   
 
 














                                              





                                                                                                          
 





                                                                          
 







                                                                  
           
            
            








                                                       
  







                                                
                                      













                                   




                                                 

  

                                                        






                                         

 
                                             
                                                            
                             
                                         
                                                




                              
                                                     


                                 
                           



                                    
  





































                                                                                                                            
  
 




                                                                                                
                                    

 























                                                                         

































                                                                                   
 
 






                                                      
                                                                                              
                                      
                                                                        




                   
// TMW2 Script.
// Authors:
//    Jesusalva
// Description:
//    Util functions

/////////////////////////////////////////////////////////////////////////////////
// Delete item ID on inventories, storages, guild storages and carts. Also affects mails.
// WARNING, irreversible and dangerous!
// DelItemFromEveryPlayer( ID )
function	script	DelItemFromEveryPlayer	{
    if (getarg(0, -1) < 0)
        return;

    query_sql("DELETE FROM `inventory` WHERE `nameid`="+getarg(0));
    query_sql("DELETE FROM `cart_inventory` WHERE `nameid`="+getarg(0));
    query_sql("DELETE FROM `storage` WHERE `nameid`="+getarg(0));
    query_sql("DELETE FROM `guild_storage` WHERE `nameid`="+getarg(0));
    query_sql("DELETE FROM `rodex_items` WHERE `nameid`="+getarg(0));
    query_sql("DELETE FROM `auction` WHERE `nameid`="+getarg(0));
    return;
}

// Delete an acc_reg entry from all players. Full arrays only. Affect num and str db.
// WARNING, irreversible and dangerous!
// DelAccRegFromEveryPlayer( KEY )
function	script	DelAccRegFromEveryPlayer	{
    if (getarg(0, "error") == "error")
        return;

    query_sql("DELETE FROM `acc_reg_num_db` WHERE `key`='"+getarg(0)+"'");
    query_sql("DELETE FROM `acc_reg_str_db` WHERE `key`='"+getarg(0)+"'");
    return;
}

// Delete a quest entry from all players. This includes all counters. Use with caution.
// WARNING, irreversible and dangerous!
// DelQuestFromEveryPlayer( ID )
function	script	DelQuestFromEveryPlayer	{
    if (getarg(0, -1) < 0)
        return;

    query_sql("DELETE FROM `quest` WHERE `quest_id`="+getarg(0));
    return;
}

// Transforms an item in something else.
// ReplaceItemFromEveryPlayer( OldID, NewID )
function	script	ReplaceItemFromEveryPlayer	{
    if (getarg(0, -1) < 0)
        return;
    debugmes("* Server update: %d item was replaced by %d", getarg(0), getarg(1));
    query_sql("UPDATE `inventory` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
    query_sql("UPDATE `cart_inventory` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
    query_sql("UPDATE `storage` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
    query_sql("UPDATE `guild_storage` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
    query_sql("UPDATE `rodex_items` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
    query_sql("UPDATE `auction` SET `nameid`='"+getarg(1)+"' WHERE `nameid`="+getarg(0));
    return;
}


/////////////////////////////////////////////////////////////////////////////////
// Returns Nard reputation for discounts
// Currently ranges from 0 to 16.
function	script	nard_reputation	{
    .@nr=0; // Base reputation

    // Valon Quest (+1 rep)
    if (getq(CandorQuest_Trainer) >= 14)
        .@nr=.@nr+1;

    // Zegas Quest (+1 rep)
    if (getq(CandorQuest_Barrel) >= 4)
        .@nr=.@nr+1;

    // Hide And Seek Quest (+1 rep)
    if (getq(CandorQuest_HAS) >= 4)
        .@nr=.@nr+1;

    // Sailors Quest (+1 rep)
    if (getq(CandorQuest_Sailors) >= 3)
        .@nr=.@nr+1;

    // Sailors Quest, part 2 (+1 rep)
    if (getq(CandorQuest_SailorCure) >= 1)
        .@nr=.@nr+1;

    // Vincent Quest (+1 rep)
    if (getq(CandorQuest_Vincent) >= 2)
        .@nr=.@nr+1;

    // Tolchi Quest (+1 rep)
    if (getq(CandorQuest_Tolchi) >= 4)
        .@nr=.@nr+1;

    // Maya Quest (+1 rep)
    if (getq(CandorQuest_Maya) >= 4)
        .@nr=.@nr+1;

    // Rosen Quest (+1 rep)
    if (getq(CandorQuest_Rosen) >= 3)
        .@nr=.@nr+1;

    // Ship Crew Quests
    // Dan Quest (+1 rep)
    if (getq(ShipQuests_Dan) >= 3)
        .@nr=.@nr+1;

    // Chef Gado Quest (+1 rep)
    if (getq(ShipQuests_ChefGado) >= 2)
        .@nr=.@nr+1;

    // Peter Quest (+1 rep)
    if (getq(ShipQuests_Peter) >= 7)
        .@nr=.@nr+1;

    // Tulimshar Quests
    // Swezanne Quest (+1 rep)
    if (getq(TulimsharQuest_Swezanne) >= 1)
        .@nr=.@nr+1;

    // Sailors Quest (+1 rep)
    if (getq(TulimsharQuest_Sailors) >= 2)
        .@nr=.@nr+1;

    // Hasan Quest (+1 rep)
    if (getq(TulimsharQuest_Hasan) >= 5)
        .@nr=.@nr+1;

    // Dausen Quest (+1 rep)
    if (getq(TulimsharQuest_WaterForGuard) >= 3)
        .@nr=.@nr+1;

    //debugmes "Reputation: "+str(.@nr);
    return .@nr;

}

// Returns reputation based on quests completion for discounts. Returns 0~100 int.
// Takes one argument (PC_DEST$). Grep for "getarg".
function	script	reputation	{
    .@nr=0; // Base reputation

    // Tulimshar Quests (14 points)
    if (getarg(0) == "Tulim") {
        // Eugene Quest (+1 rep)
        if (getq(TulimsharQuests_Fishman) >= 2)
            .@nr=.@nr+1;

        // Sarah Quest (+1 rep)
        if (getq(TulimsharQuest_Sarah) >= 1)
            .@nr=.@nr+1;

        // Dausen Quest (+1 rep)
        if (getq(TulimsharQuest_WaterForGuard) >= 3)
            .@nr=.@nr+1;

        // Dausen Quest II (+1 rep)
        if (getq(TulimsharQuest_MobTutorial) >= 8)
            .@nr=.@nr+1;

        // Swezanne Quest (+1 rep)
        if (getq(TulimsharQuest_Swezanne) >= 1)
            .@nr=.@nr+1;

        // Silvia Quest (+1 rep)
        if (getq(TulimsharQuest_Lifestone) >= 2)
            .@nr=.@nr+1;

        /*
        // Eisten Quest (+1 rep)
        if (getq(TulimsharQuest_Eistein) >= 6)
            .@nr=.@nr+1;
        */

        // Hasan Quest (+1 rep)
        if (getq(TulimsharQuest_Hasan) >= 5)
            .@nr=.@nr+1;

        // Devoir Quest (+1 rep)
        if (getq(TulimsharQuest_Devoir) >= 1)
            .@nr=.@nr+1;

        // Sailors Quest (+1 rep)
        if (getq(TulimsharQuest_Sailors) >= 2)
            .@nr=.@nr+1;

        // Zarkor Quest (+1 rep)
        if (getq(TulimsharQuest_DarkInvocator) >= 7)
            .@nr=.@nr+1;

        // Anwar Quest (+1 rep)
        if (getq(TulimsharQuest_AnwarField) >= 10)
            .@nr=.@nr+1;

        // Neko Quest (+1 rep)
        if (getq(TulimsharQuest_Neko) >= 2)
            .@nr=.@nr+1;

        // Tycoon Quest (+1 rep)
        if (getq(MineQuest_Tycoon) >= 15)
            .@nr=.@nr+1;

        // Dracoula Quest (+1 rep)
        if (getq(MineQuest_Dracoula) >= 1)
            .@nr=.@nr+1;

        // Caelum Quest (+1 rep)
        if (getq(MineQuest_Caelum) >= 2)
            .@nr=.@nr+1;

        // Veteran Officer Quest (+1 rep)
        if (getq(TulimsharQuest_WoodenSword) >= 2)
            .@nr=.@nr+1;

        // TULIMSHAR Magical Forumula
        .@nr=.@nr*100/16;







    // Hurnscald Quests (9 points)
    } else if (getarg(0) == "Hurns") {

        // Alan Quest (+1 rep)
        if (getq(HurnscaldQuest_ForestBow) >= 2)
            .@nr=.@nr+1;

        // Gwendolyn Quest (+1 rep)
        if (getq(HurnscaldQuest_HarkEye) >= 6)
            .@nr=.@nr+1;

        // Celestia Quest (+1 rep)
        if (getq(HurnscaldQuest_TeaParty) >= 2)
            .@nr=.@nr+1;

        /*
        // Yeti King Quest (+1 rep)
        // Please note that if you challenge it again and lose, it'll reset
        if (getq(HurnscaldQuest_Celestia) == 6)
            .@nr=.@nr+1;
        */

        // Farmers Quest (+1 rep)
        if (getq(HurnscaldQuest_Farmers) >= 5)
            .@nr=.@nr+1;

        // Helena Quest (+1 rep)
        if (getq(HurnscaldQuest_Bandits) >= 8)
            .@nr=.@nr+1;

        // Injuried Mouboo Quest (+1 rep)
        if (getq(HurnscaldQuest_InjuriedMouboo) >= 2)
            .@nr=.@nr+1;

        // Blood Donor Quest (+1 rep)
        if (getq(HurnscaldQuest_BloodDonor) >= 1)
            .@nr=.@nr+1;

        // Woody Quest (+1 rep)
        if (getq(HurnscaldQuest_Woody) >= 5)
            .@nr=.@nr+1;

        // Lieutenant Quest (+1 rep)
        if (getq(HurnscaldQuest_Lieutenant) >= 10)
            .@nr=.@nr+1;

        // HURNSCALD Magical Forumula
        .@nr=.@nr*100/9;







    // Land Of Fire Quests (5 points)
    } else if (getarg(0) == "LoF") {

        // The EPISODE
        //// Tea For Two (+1 rep)
        if (getq(LoFQuest_EPISODE) >= 2)
            .@nr=.@nr+1;
        //// Early Christmas (+1 rep)
        if (getq(LoFQuest_EPISODE) >= 6)
            .@nr=.@nr+1;

        // George Quest (+1 rep)
        if (getq(LoFQuest_George) >= 3)
            .@nr=.@nr+1;

        // Fairy Quest (+1 rep)
        if (getq(LoFQuest_Fairy) >= 3)
            .@nr=.@nr+1;

        // Pet Detective Quest (+1 rep)
        if (getq(LoFQuest_Pets) >= 1)
            .@nr=.@nr+1;

        // LAND OF FIRE Magical Forumula
        .@nr=.@nr*100/5;






    // Nivalis Quests (2 points)
    } else if (getarg(0) == "Nival") {

        // Nivalis Well Quest (+1 rep)
        if (getq(NivalisQuest_Well) >= 2)
            .@nr=.@nr+1;

        // Nivalis Cindy Quest (+1 rep)
        if (getq(NivalisQuest_Cindy) >= 5)
            .@nr=.@nr+1;

        // Blue Sage: Investigation Quest (+1 rep)
        if (getq(NivalisQuest_BlueSage) >= 12)
            .@nr=.@nr+1;

        // Blue Sage: Slime Hunting Quest (+1 rep)
        if (getq(NivalisQuest_BlueSageSlimes) >= 12)
            .@nr=.@nr+1;

        // Blue Sage: Page Makers Quest (+1 rep)
        if (getq(NivalisQuest_BlueSagePagemaker) >= 12)
            .@nr=.@nr+1;

        // Blue Sage: Page Finders Quest (+1 rep)
        if (getq(NivalisQuest_BlueSagePagefinder) >= 12)
            .@nr=.@nr+1;

        // NIVALIS Magical Forumula
        .@nr=.@nr*100/6;







    // Halinarzo Quests (5 points)
    } else if (getarg(0) == "Halin") {

        // Foxhound Famine Quest (+1 rep)
        if (getq(HalinarzoQuest_Foxhound) >= 6)
            .@nr=.@nr+1;

        // Charles Quest (+1 rep)
        if (getq(HalinarzoQuest_TraderKing) >= 2)
            .@nr=.@nr+1;

        // Joaquim & Yumi Quest (+1 rep)
        if (getq(HalinarzoQuest_SickWife) >= 5)
            .@nr=.@nr+1;

        // Life Delight Quest (+1 rep)
        if (getq(HalinarzoQuest_LifeDelight) >= 2)
            .@nr=.@nr+1;

        // Sawis Quest (+1 rep)
        if (getq(HalinarzoQuest_Sawis) >= 2)
            .@nr=.@nr+1;

        // HALINARZO Magical Forumula
        .@nr=.@nr*100/5;







    // Frostia Quests (2 points)
    } else if (getarg(0) == "Frostia") {

        // Rescue Yeti Quest (+1 rep)
        if (getq(NivalisQuest_Well) >= 2)
            .@nr=.@nr+1;

        // Rescue Cindy Quest (+1 rep)
        if (getq(NivalisQuest_Cindy) >= 5)
            .@nr=.@nr+1;

        // FROSTIA Magical Forumula
        .@nr=.@nr*100/2;







    // Candor Quests (9 points)
    } else if (getarg(0) == "Candor") {

        // Valon Quest (+1 rep)
        if (getq(CandorQuest_Trainer) >= 14)
            .@nr=.@nr+1;

        // Zegas Quest (+1 rep)
        if (getq(CandorQuest_Barrel) >= 4)
            .@nr=.@nr+1;

        // Hide And Seek Quest (+1 rep)
        if (getq(CandorQuest_HAS) >= 4)
            .@nr=.@nr+1;

        // Sailors Quest (+1 rep)
        if (getq(CandorQuest_Sailors) >= 3)
            .@nr=.@nr+1;

        // Sailors Quest, part 2 (+1 rep)
        if (getq(CandorQuest_SailorCure) >= 1)
            .@nr=.@nr+1;

        // Vincent Quest (+1 rep)
        if (getq(CandorQuest_Vincent) >= 2)
            .@nr=.@nr+1;

        // Tolchi Quest (+1 rep)
        if (getq(CandorQuest_Tolchi) >= 3)
            .@nr=.@nr+1;

        // Maya Quest (+1 rep)
        if (getq(CandorQuest_Maya) >= 4)
            .@nr=.@nr+1;

        // Rosen Quest (+1 rep)
        if (getq(CandorQuest_Rosen) >= 3)
            .@nr=.@nr+1;

        // Marggo Quest (+1 rep)
        if (getq(CandorQuest_Marggo) >= 1)
            .@nr=.@nr+1;

        // CANDOR Magical Forumula
        .@nr=.@nr*100/10;


    // Final
    }

    //debugmes "Reputation: "+str(.@nr);
    return .@nr;

}


// Returns time for ship travel.
// Can be modified by a factor.
function	script	nard_time	{
    // Estimates time to move by ship from LOCATION$ to getarg(0)

    // From Candor
    if (LOCATION$ == "Candor") {
        if (getarg(0) == "Tulim")
            return 22000;

    }
    // From Tulimshar
    if (LOCATION$ == "Tulim") {
        if (getarg(0) == "Candor")
            return 22000;
        if (getarg(0) == "Hurns")
            return 28000;
        if (getarg(0) == "Nival")
            return 52000;

    }
    // From Hurnscald
    if (LOCATION$ == "Hurns") {
        if (getarg(0) == "Candor")
            return 22000;
        if (getarg(0) == "Tulim")
            return 28000;
        if (getarg(0) == "Nival")
            return 28000;

    }
    // From Nivalis
    if (LOCATION$ == "Nival") {
        if (getarg(0) == "Candor")
            return 46000;
        if (getarg(0) == "Tulim")
            return 52000;
        if (getarg(0) == "Hurns")
            return 28000;

    }

    // Error
    debugmes "ERROR, INVALID LOCATION AND DESTINATION";
    debugmes l("@@ -> @@", LOCATION$, getarg(0));
    dispbottom l("An error on your travel time happened. Please report.");
    return INT_MAX;
}

// Determines if player is still in range.
// eg.
// if (reachable(.x, .y, .distance)) {
function	script	reachable	{
    .@x=getarg(0);
    .@y=getarg(1);
    .@z=getarg(2);
    getmapxy(.@mp$, .@xp, .@yp, 0);

    if (distance(.@x, .@y, .@xp, .@yp) <= .@z)
        return 1;
    else
        return 0;
}

// Determines if party exp sharing is enabled
// ( Party ID )
function	script	party_expon	{
    .@nb = query_sql("SELECT exp FROM `party` WHERE party_id="+escape_sql(getarg(0))+" LIMIT 2", .@value);
    return .@value[0];
}

// Special rif for books
// rif2(<menu_id>, <condition>, <text>)
function	script	rif2	{
    return rif( getarg(1)   ,rif(@menu == getarg(0), "► ") + getarg(2));
}


// Prepare Mana Stone
// mstone( lvl )
function	script	mstone	{
    // Fill variable
    .@v=getarg(0);

    // Determine how much stats you need, this is based on players
    // and change based on $Global Variables
    .int=5;
    .lvl=15;
    .jlv=10;

    return (
            MAGIC_LVL == .@v &&
            readparam(bInt) >= $MANA_BINT+(.int*.@v) &&
            BaseLevel >= $MANA_BLVL+(.lvl*.@v) &&
            JobLevel >= $MANA_JLVL+(.jlv*.@v) &&
            readparam(Sp) == readparam(MaxSp));
}

/*
// Gets how many subclasses were actually filled
// total_subclass(  )
function	script	total_subclass	{
    .@i=0;
    if (MAGIC_SUBCLASS & CL_PALADIN)
        .@i+=1;
    if (MAGIC_SUBCLASS & CL_TANKER)
        .@i+=1;
    if (MAGIC_SUBCLASS & CL_BERSERKER)
        .@i+=1;
    if (MAGIC_SUBCLASS & CL_RANGER)
        .@i+=1;
    if (MAGIC_SUBCLASS & CL_SNIPER)
        .@i+=1;
    if (MAGIC_SUBCLASS & CL_WIZARD)
        .@i+=1;
    if (MAGIC_SUBCLASS & CL_SAGE)
        .@i+=1;
    if (MAGIC_SUBCLASS & CL_PRIEST)
        .@i+=1;
    return .@i;
}

// Gets how many subclasses were actually allowed
// max_subclass()
function	script	max_subclass	{
    return (MAGIC_LVL/2);
}
*/

// MAGIC_PTS → Amount of used Magic Skill Points
// sk_maxpoints() → Max Magic Skill Points you may use
// Returns how many points you can use
function	script	sk_maxpoints	{
    // 2 points per magic level
    .@val=(MAGIC_LVL)*2;
    // 1 point per skill permit level
    .@val+=getskilllv(TMW2_SKILLPERMIT);
    return .@val;
}

// Returns true if a skill can be leveled up.
// TODO: Ideally, we would also check for skill max level...
// sk_canlvup( sk, {cost=1} )
function	script	sk_canlvup	{
    if (MAGIC_PTS+getarg(1,1) >= sk_maxpoints())
        return 1;
    return 0;
}

// Level up a skill in 1 level
// TODO: Return the point if leveling about Max Level
// sk_lvup( sk )
function	script	sk_lvup	{
    .@lvl=getskilllv(getarg(0));
    getexp 0, 50*(.@lvl+1);
    addtoskill(getarg(0),.@lvl+1,0);
    return;
}

/*
// Magic School Learning Interface
// mlearn( skill, {item 1, amount 1}, {item 2, amount 2}... )
// returns false if cheater
function	script	mlearn	{
    if (getargcount() < 2 || getargcount() % 2 != 1)
        return Exception("Faulty learning skill command invoked - error");

    .@sk=getarg(0);

    // List required ingredients
    mesq l("This useful skill will only require:");
    for (.@i=1;.@i < getargcount(); .@i++) {
        mesc l("@@/@@ @@", countitem(getarg(.@i)),            (getskilllv(.@sk)+1)*getarg(.@i+1), getitemlink(getarg(.@i)));
        .@i++;
    }
    // getarg(.@i)
    next;
    if (askyesno() == ASK_NO)
        return true;

    // Count items
    for (.@i=1;.@i < getargcount(); .@i++) {
        if (countitem(getarg(.@i))         < (getskilllv(.@sk)+1)*getarg(.@i+1))
            return false;
        .@i++;
    }

    // Delete Items
    for (.@i=1;.@i < getargcount(); .@i++) {
        delitem getarg(.@i),          (getskilllv(.@sk)+1)*getarg(.@i+1);
        .@i++;
    }

    sk_lvup(.@sk);
    next;

    return true;
}
*/

// Returns a value defining your current magic control (affects success ratio, higher is better)
// A value of '5' means perfect control, and a value of '0' means overwhelm.
// abizit()
function	script	abizit	{
    .@base=(MAGIC_LVL**3);
    return min(MAGIC_EXP/.@base, 5);
}


// Returns, based on a 1-5 range, the title for both thief and merc ranks
// thiefrank() / mercrank()
function	script	thiefrank	{
    switch (THIEF_RANK) {
        case 5: return l("Bandit Lord");
        case 4: return l("Assassin");
        case 3: return l("Rogue");
        case 2: return l("Bandit");
        case 1: return l("Thief");
        default: return l("Error");
    }
}
function	script	mercrank	{
    switch (MERC_RANK) {
        case 5: return l("Constable");
        case 4: return l("Guardian");
        case 3: return l("Merchant");
        case 2: return l("Trader");
        case 1: return l("Fair Person");
        default: return l("Error");
    }
}

// gettimeparam(GETTIME_X)
//   Returns the number of seconds/minutes/hours/days/months/years since 01/01/1970
function	script	gettimeparam	{
    .@p=getarg(0, GETTIME_MINUTE);

    // Seconds
    .@t=gettimetick(2);
    if (.@p == GETTIME_SECOND)
        return .@t;

    // Minutes (default)
    .@t=.@t/60;
    if (.@p == GETTIME_MINUTE)
        return .@t;

    // Hours
    .@t=.@t/60;
    if (.@p == GETTIME_HOUR)
        return .@t;

    // Days
    .@t=.@t/24;
    if (.@p == GETTIME_DAYOFMONTH)
        return .@t;

    // Months (estimative)
    .@t=.@t/30;
    if (.@p == GETTIME_MONTH)
        return .@t;

    // Years (estimative, unused, fallback)
    .@t=.@t/12;
    return .@t;
}


// Upon entering a town
// EnterTown( LocName )
function	script	EnterTown	{
    // Fill variable
    .@v$=getarg(0);

    // Validade variable, see npc/000-1/exit.txt first
    setarray .@locs$, "Candor", "Tulim", "Halin", "Hurns", "LoF", "Lilit", "Nival", "Frostia";
    if (array_find(.@locs$, .@v$) < 0)
        return Exception("Invalid location passed to EnterTown: "+.@v$);

    LOCATION$=.@v$;
    return;
}