summaryrefslogtreecommitdiff
path: root/npc/functions/weather.txt
diff options
context:
space:
mode:
Diffstat (limited to 'npc/functions/weather.txt')
-rw-r--r--npc/functions/weather.txt244
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;
+
+}