summaryrefslogblamecommitdiff
path: root/npc/functions/weather.txt
blob: 75605749c7a797bc3bcc3952bc087c042c4a7bb5 (plain) (tree)

























                                                                               
                   












                                           




















                                                  
















                                                             
                 


                                                                       

































                                                                                                












                                                     



























                                                                                   
                                                     




                                          

                                                                       

                                                                 

















                                                                                 
     


                     
 
                                                                   










































                                                                                                 
                           








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

-	script	#WeatherCore	NPC_HIDDEN,{
    end;

OnInit:
    // This is weather startup
    .@init=true;
    // 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 should never snow on a desert, or happen a sandstorm on icelands.
    .wcore = htnew;
    .wtime = htnew;

    // Deserts
    htput(.wcore, "001-1", CLIMATE_DESERT);
    htput(.wcore, "002-1", CLIMATE_DESERT);
    htput(.wcore, "003-2", CLIMATE_DESERT);
    htput(.wcore, "004-1", CLIMATE_DESERT);
    htput(.wcore, "006-1", CLIMATE_DESERT);
    htput(.wcore, "023-1", CLIMATE_DESERT);
    htput(.wcore, "041-1", CLIMATE_DESERT);
    htput(.wcore, "042-1", CLIMATE_DESERT);
    htput(.wcore, "043-1", CLIMATE_DESERT);

    // Woodlands
    htput(.wcore, "007-1", CLIMATE_MODERATE);
    htput(.wcore, "008-1", CLIMATE_MODERATE);
    htput(.wcore, "009-1", CLIMATE_MODERATE);
    htput(.wcore, "010-1", CLIMATE_MODERATE);
    htput(.wcore, "011-1", CLIMATE_MODERATE);
    htput(.wcore, "012-1", CLIMATE_MODERATE);
    htput(.wcore, "013-1", CLIMATE_MODERATE);
    htput(.wcore, "014-1", CLIMATE_MODERATE);
    htput(.wcore, "015-1", CLIMATE_MODERATE);
    htput(.wcore, "016-1", CLIMATE_MODERATE);
    htput(.wcore, "017-1", CLIMATE_MODERATE);
    htput(.wcore, "018-1", CLIMATE_MODERATE);
    htput(.wcore, "025-1", CLIMATE_MODERATE);
    htput(.wcore, "026-1", CLIMATE_MODERATE);
    htput(.wcore, "027-1", CLIMATE_MODERATE);
    htput(.wcore, "028-1", CLIMATE_MODERATE);
    htput(.wcore, "029-1", CLIMATE_MODERATE);
    htput(.wcore, "051-1", CLIMATE_MODERATE); // ?
    htput(.wcore, "052-1", CLIMATE_MODERATE);
    htput(.wcore, "055-1", CLIMATE_MODERATE);
    htput(.wcore, "057-1", CLIMATE_MODERATE);

    // Icelands
    htput(.wcore, "019-1", CLIMATE_ICELAND);
    htput(.wcore, "020-1", CLIMATE_ICELAND);
    htput(.wcore, "030-1", CLIMATE_ICELAND);
    htput(.wcore, "031-1", CLIMATE_ICELAND);
    htput(.wcore, "033-1", CLIMATE_ICELAND);
    htput(.wcore, "034-1", CLIMATE_ICELAND);
    htput(.wcore, "045-1", CLIMATE_ICELAND);
    htput(.wcore, "046-1", CLIMATE_ICELAND);
    htput(.wcore, "047-1", CLIMATE_ICELAND);

    // Special
    htput(.wcore, "099-1", CLIMATE_NONE);


    debugmes("[Weather.sys] Total Maps = " + htsize(.wcore));
    initnpctimer;
    end;

    ///////////////////////////////////////////////////////////////////
    // Internal functions to check or change stuff
    // WeatherSwitch ( MASK )
    function WeatherSwitch {
        // Get map
        .@key$=getmap();

        // Sanitize
        .@m = htget(.wcore, .@key$, CLIMATE_NONE);

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

    // WeatherClear ( MAP )
    function WeatherClear {
        .@key$ = getarg(0);
        .@mk=getmapmask(.@key$);
        if (.@mk & MASK_NIGHT)
            .@mk=.@mk^MASK_NIGHT;
        if (.@mk & MASK_RAIN)
            .@mk=.@mk^MASK_RAIN;
        if (.@mk & MASK_SANDSTORM)
            .@mk=.@mk^MASK_SANDSTORM;
        if (.@mk & MASK_SNOW)
            .@mk=.@mk^MASK_SNOW;
        setmapmask(.@key$, .@mk);
        return;
    }

    ///////////////////////////////////////////////////////////////////
    // "#WeatherCore"::climate(mapid)
    public function climate {
        .@v = htget(.wcore, getarg(0), CLIMATE_NONE);
        return .@v;
    }

    // "#WeatherCore"::weather(weather{, mapid})
    public function weather {
        .@mk=getarg(0);
        .@m$=getarg(1, getmapname());
        return getmapmask(.@m$) & .@mk;
    }

    // "#WeatherCore"::weather_override(weather, duration{, mapid, override=false})
    public function weather_override {
        .@mk=getarg(0);
        .@tm=getarg(1);
        .@m$=getarg(2, getmapname());
        .@force=getarg(3, false);

        if (!.@force) {
            // Obtain map climate & validate
            .@cl = htget(.wcore, .@m$, CLIMATE_NONE);
            if (.@cl == CLIMATE_NONE)
                return false;

            // Forbidden changes (Disallowed by climate)
            if (.@cl == CLIMATE_DESERT && (.@mk == MASK_SNOW))
                return false;
            if (.@cl == CLIMATE_ICELAND && (.@mk == MASK_SANDSTORM))
                return false;
        }

        // Rain is not granted in desert or iceland
        // But "#WeatherCore"::climate() will have this handled
        // So we assume it is OK here and apply the changes

        // Maybe there's already a timer running?
        .@t = htget(.wtime, .@m$, 0);
        if (.@t <= 0) {
            addmapmask(.@m$, .@mk);
            htput(.wtime, .@m$, gettimetick(2)+.@tm);
        } else {
            htput(.wtime, .@m$, .@t+.@tm);
        }
        return true;
    }

    ///////////////////////////////////////////////////////////////////
    // Every 2.5 seconds, we clean up any ongoing weather effects
OnTimer2500:
    // No weather effect
    if (!htsize(.wtime)) {
        initnpctimer;
        end;
    }
    // We got a job to do
    .@hti = htiterator(.wtime);
    .@cur = gettimetick(2);
    for (.@key$ = htinextkey(.@hti); hticheck(.@hti); .@key$ = htinextkey(.@hti))
    {
        .@target=htget(.wtime, .@key$, 0);
        debugmes "Map %s (Time %d/%d)", .@key$, .@target, .@cur;
        // Not yet expired
        if (.@target > .@cur)
            continue;
        // Remove the effect
        htput(.wtime, .@key$, 0);
        WeatherClear(.@key$);
    }
    htidelete(.@hti);
    initnpctimer;
    end;

///////////////////////////////////////////////////////////////////
// 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:
    WeatherClear(getmap());
    end;

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

}