summaryrefslogblamecommitdiff
path: root/npc/functions/weather.txt
blob: 561c6b596d0617443728941b6b36ea43fa705b72 (plain) (tree)
1
2
3
4
5
6
7
8





                                                                 
                      
                                         





                                                      




                                    

                                                             
                                                                              
                         
                       
                              


                                       
                                                                                             
                     
                 
            

                 

 


                                                    








                                            
  
 







                                                           
                                                           
                                                            














                                                                          
                                       
                                        
                                        




                                       
                                       
                                       



                                       
                                       
                                       


                                      
                                      
                                      
                                      
                                      
                                      
                                      
                                      
 



                                      
                                                            





                                                   

                                                                                  


                                             









                                     

                                 


                                       
                                                                               



                                                   



                                                           
                                    
                               
                                         

                                           
                          
                                    



                                                       
                                    

                                          
                         
                                    
                               
                                    
 












                                                                   

                                                                                         
                                                                             

         



                                

                                
                            
                         
                                                
                                          

                                                     
                                             
         

                     
 
                                                                                     
      




                                                                      
                                                       


                                                        

                                                       
                                                       

                                          
                                                
                                                       


                                                      

                                                       
                                                       

                                          
     
                                   
 
                                                

        
                              
                                  










                                                                                                
                                          


               

                                                   
                             


        
                                  


        
                             


        
                              


        
                                    

        



















                                                                                                 
                         

                               














                                                                 
                                  


        
// TMW2 scripts.
// Authors:
//    Jesusalva
// Description:
//    Controls world seasons. RESPECT MASK_* VARS ON CONSTANTS DB

// is_night(set=False)
function	script	is_night	{
    // If we're not configuring, retrieve the variable
    // It is more efficient this way
    .@set=getarg(0, false);
    if (!.@set)
        return $@WEATHER_NIGHT;

    // Night time depends on season.
    // Summer: Day > Night
    // Winter: Night > Day
    // Autumn/Spring: Day = Night
    //
    // But we have TWO SUNS, meaning night is always smaller.
    //
    // By default, each period lasts a whole hour, give or take 15 minutes (?)
    // 2 = GETTIME_MINUTE
    // 3 = GETTIME_HOUR
    if (gettime(3) % 3 == 1) {
        // Summer: 2h30 day. 30m night.
        // Others: 2h15 day. 45m night.
        // Winter: 2h   day.  1h night.
        if (season() == SUMMER && gettime(2) <= 30 || season() != WINTER && gettime(2) <= 15)
            return 0;
        return 1;
    } else {
        return 0;
    }
}

000-0,0,0,0	script	#WeatherCore	NPC_HIDDEN,{
    end;

/*
 * removemapflag("<map name>", <flag>)
 * setmapflag("<map name>", <flag>{, <val>})
 * getmapflag("<map name>", <flag>)

	mf_snow:               16

	mf_jexp:               39
	mf_bexp:               40
*/

OnInit:
    // Bind commands
    bindatcmd "wsnow", "#WeatherCore::OnSnow", 80, 80, 1;
    bindatcmd "wrain", "#WeatherCore::OnRain", 80, 80, 1;
    bindatcmd "wsand", "#WeatherCore::OnSand", 80, 80, 1;
    bindatcmd "wevil", "#WeatherCore::OnEvil", 80, 80, 1;
    bindatcmd "wnight", "#WeatherCore::OnNight", 80, 80, 1;
    bindatcmd "wclear", "#WeatherCore::OnClear", 80, 80, 1;
    bindatcmd "wreset", "#WeatherCore::OnReset", 99, 99, 1;
    bindatcmd "wset",   "#WeatherCore::OnManual", 99, 99, 1;


    // Determine which maps are subject to weather, and how weather works:
    // eg. it will never snow on a desert, or a sandstorm on icelands.
    .wcore = htnew;

    // Deserts
    htput(.wcore, "003-1", "desert");
    htput(.wcore, "004-1", "desert");
    htput(.wcore, "004-2", "desert");
    htput(.wcore, "009-1", "desert");
    htput(.wcore, "010-1", "desert");
    htput(.wcore, "010-2", "desert");

    // Woodlands
    htput(.wcore, "001-4", "woodland");
    htput(.wcore, "001-11", "woodland");
    htput(.wcore, "001-12", "woodland");
    htput(.wcore, "005-1", "woodland");
    htput(.wcore, "012-1", "woodland");
    htput(.wcore, "014-1", "woodland");
    htput(.wcore, "014-2", "woodland");
    htput(.wcore, "014-3", "woodland");
    htput(.wcore, "014-4", "woodland");
    htput(.wcore, "014-5", "woodland");
    htput(.wcore, "017-1", "woodland");
    htput(.wcore, "018-1", "woodland");
    htput(.wcore, "018-2", "woodland");
    htput(.wcore, "018-4", "woodland");
    htput(.wcore, "018-5", "woodland");
    htput(.wcore, "027-1", "woodland");

    // Icelands
    htput(.wcore, "001-7", "iceland");
    htput(.wcore, "019-1", "iceland");
    htput(.wcore, "019-2", "iceland");
    htput(.wcore, "019-3", "iceland");
    htput(.wcore, "019-4", "iceland");
    htput(.wcore, "020-1", "iceland");
    htput(.wcore, "022-1", "iceland");
    htput(.wcore, "024-1", "iceland");

    // Special
    htput(.wcore, "011-3", "special");


    debugmes "[Weather.sys] Total Maps = " + htsize(.wcore);
    // No "end" here, so server starts with weather
OnMinute00:
OnMinute15:
OnMinute30:
OnMinute45:

    .@hti = htiterator(.wcore);
    for(.@key$ = htinextkey(.@hti); hticheck(.@hti); .@key$ = htinextkey(.@hti)) {
        // Local variables: .@key$ .@type .@r
        .@type$=htget(.wcore, .@key$);
        .@r=rand(0,10000);

        // Clear weather map masks
        .@mk=getmapmask(.@key$);

        if (.@mk & MASK_RAIN)
            .@mk=.@mk^MASK_RAIN;
        if (.@mk & MASK_SANDSTORM)
            .@mk=.@mk^MASK_SANDSTORM;
        if (.@mk & MASK_SNOW)
            .@mk=.@mk^MASK_SNOW;
        if (.@mk & MASK_NIGHT)
            .@mk=.@mk^MASK_NIGHT;
        if (.@mk & MASK_EVILSANCTUM)
            .@mk=.@mk^MASK_EVILSANCTUM;

        // Monster King Sieges (can be weird, siege last 10mn and mask last 15)
        if ($@MK_SCENE)
            .@mk=.@mk|MASK_EVILSANCTUM;
        if (.@mk & (MASK_MATTACK|MASK_EVILSANCTUM))
            .@mk=.@mk^MASK_EVILSANCTUM;

        // Remove all current masks, and add rain/snow/sand
        if (.@type$ == "desert") {
            if (.@r < 10)
                .@mk=.@mk|MASK_RAIN;
            else if (.@r < 300)
                .@mk=.@mk|MASK_SANDSTORM;

        } else if (.@type$ == "woodland") {
            if (.@r < 300)
                .@mk=.@mk|MASK_RAIN;

            if ($EVENT$ == "Christmas")
                .@mk=.@mk|MASK_SNOW;
            else if (season() == WINTER && .@r >= 9250)
                .@mk=.@mk|MASK_SNOW;

        } else if (.@type$ == "iceland") {
            if (.@r < 30)
                .@mk=.@mk|MASK_RAIN;
            else if (.@r < 300)
                .@mk=.@mk|MASK_SNOW;

        } else if (.@type$ == "special") {
            // This biom is too hot for snow. But it may rain.
            if (.@r < 300)
                .@mk=.@mk|MASK_RAIN;

            // Fog? (Evil Sanctum and Monster Attack) Or Sandstorm?
            if (.@r % 4 == 2)
                .@mk=.@mk|MASK_EVILSANCTUM;
            else if (.@r % 4 == 1)
                .@mk=.@mk|MASK_SANDSTORM;
            else if (.@r % 4 == 3)
                .@mk=.@mk|MASK_MATTACK;

        } else {
            debugmes "Warning warning, blame Saulc! Weather system error on map "+.@key$;
            announce("ERROR BLAME SAULC! WEATHER SYSTEM CORRUPTED.", bc_all);
        }

        // Bugfix
        if (!(.@mk & MASK_NONE))
            .@mk=.@mk|MASK_NONE;

        setmapmask .@key$, .@mk;

        // Is it night time?
        if (is_night()) {
            setmapflag(.@key$, mf_nightenabled);
            addmapmask .@key$, MASK_NIGHT;
        } else if (getmapmask(.@key$) & MASK_NIGHT) {
            removemapflag(.@key$, mf_nightenabled);
            removemapmask .@key$, MASK_NIGHT;
        }
    }
    htidelete(.@hti);

    // During night, normal monsters respawn 30% faster. (Bifs and Bosses are immune)
    //
    // Also, announce to players about day/night cycle changes
    // The fastest you'll get is 30 minutes for night cycle.
    // It's 2 messages every 3 hours. (r7.5)
    // Player might be on cave, and this will help them tracking time.
    if (is_night() && !$@WEATHER_NIGHT) {
        .@c = getunits(BL_PC, .@players, MAX_CYCLE_PC);
        for (.@i = 0; .@i < .@c; .@i++) {
            message(.@players[.@i], "The night falls.");
        }
        setbattleflag("mob_spawn_delay", BCONFN_SPAWN);
        setbattleflag("monster_hp_rate", BCONFN_MOBHP);
        //charcommand("@reloadbattleconf"); // Careful!
        donpcevent("@exprate::OnReload");
        donpcevent("@droprate::OnReload");
    } else if (!is_night() && $@WEATHER_NIGHT) {
        .@c = getunits(BL_PC, .@players, MAX_CYCLE_PC);
        for (.@i = 0; .@i < .@c; .@i++) {
            message(.@players[.@i], "The day rises.");
        }
        setbattleflag("mob_spawn_delay", BCONFD_SPAWN);
        setbattleflag("monster_hp_rate", BCONFD_MOBHP);
        //charcommand("@reloadbattleconf"); // Careful!
        donpcevent("@exprate::OnReload");
        donpcevent("@droprate::OnReload");
    }
    $@WEATHER_NIGHT=is_night(true);

    //debugmes "[Weather.sys] Weather reloaded";
    end;

    // Function to check stuff
    // WeatherSwitch ( MASK, MAP )
    function WeatherSwitch {
        // Get map
        getmapxy(.@key$,.@a,.@b,0);

        // Sanitize
        .@m$ = htget(.wcore, .@key$, "Not found");

        // Change Weather or abort
        if (.@m$ == "Not found")
            dispbottom l("Command not permitted on this map! Check npc/functions/weather.conf");
        else
            addmapmask(.@key$, getarg(0));
        return;
    }

// Some commands, for GMs manually override weather
OnRain:
    WeatherSwitch(MASK_RAIN);
    end;

OnSand:
    WeatherSwitch(MASK_SANDSTORM);
    end;

OnSnow:
    WeatherSwitch(MASK_SNOW);
    end;

OnNight:
    WeatherSwitch(MASK_NIGHT);
    end;

OnEvil:
    WeatherSwitch(MASK_EVILSANCTUM);
    end;

OnManual:
    if (!.@atcmd_numparameters) {
        dispbottom l("Syntax: @wset <map_mask>");
        end;
    }

    // Never allow negative numbers, or to disable map mask 1 (never, EVER, do such insane thing)
	.@rq = atoi(.@atcmd_parameters$[0]);
    if (.@rq <= 1 || .@rq % 2 == 1) {
        dispbottom l("Invalid map mask");
        end;
    }

    // <Insert a helpful comment here>
    getmapxy(.@key$,.@a,.@b,0);
    .@mk=getmapmask(.@key$);
    .@mk=.@mk^.@rq;
    setmapmask(.@key$, .@mk);
    end;

// Clear works on any map
OnClear:
    getmapxy(.@key$,.@a,.@b,0);
    .@mk=getmapmask(.@key$);
    if (.@mk & MASK_RAIN)
        .@mk=.@mk^MASK_RAIN;
    if (.@mk & MASK_SANDSTORM)
        .@mk=.@mk^MASK_SANDSTORM;
    if (.@mk & MASK_SNOW)
        .@mk=.@mk^MASK_SNOW;
    if (.@mk & MASK_NIGHT)
        .@mk=.@mk^MASK_NIGHT;
    setmapmask(.@key$, .@mk);
    end;

// Reset the whole map, including season, event and weather masks
OnReset:
    getmapxy(.@key$,.@a,.@b,0);
    setmapmask(.@key$, MASK_NONE);
    end;

}