diff options
Diffstat (limited to 'npc/functions/weather.txt')
-rw-r--r-- | npc/functions/weather.txt | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/npc/functions/weather.txt b/npc/functions/weather.txt new file mode 100644 index 00000000..75605749 --- /dev/null +++ b/npc/functions/weather.txt @@ -0,0 +1,244 @@ +// 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; + +} |