summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesusaves <cpntb1@ymail.com>2021-04-14 21:56:42 -0300
committerJesusaves <cpntb1@ymail.com>2021-04-14 21:56:42 -0300
commit9ed3fc1f95fe28741686280b1ae7da3b9f9ca403 (patch)
tree7bf34269837c83026f6a57aaae2300fbed806937
parent3f3280f8a70d9fd73e135ac224dbe5e6ee69a606 (diff)
downloadserverdata-9ed3fc1f95fe28741686280b1ae7da3b9f9ca403.tar.gz
serverdata-9ed3fc1f95fe28741686280b1ae7da3b9f9ca403.tar.bz2
serverdata-9ed3fc1f95fe28741686280b1ae7da3b9f9ca403.tar.xz
serverdata-9ed3fc1f95fe28741686280b1ae7da3b9f9ca403.zip
Rewrite weather code for its greatest challenge: Kaflosh
-rw-r--r--db/constants.conf8
-rw-r--r--npc/functions/weather.txt121
2 files changed, 99 insertions, 30 deletions
diff --git a/db/constants.conf b/db/constants.conf
index 97572495..c9e500ee 100644
--- a/db/constants.conf
+++ b/db/constants.conf
@@ -4082,15 +4082,15 @@ more than one separator can be used in a row (so 12_3___456 is illegal).
comment__: "map masks"
MASK_NONE: 1
- MASK_MATTACK: 2
- MASK_EVILSANCTUM: 4
+ MASK_UNUSED1: 2
+ MASK_UNUSED2: 4
MASK_NIGHT: 8
MASK_RAIN: 16
MASK_SANDSTORM: 32
MASK_SNOW: 64
MASK_CHRISTMAS: 128
- MASK_AUTUMN: 256
- MASK_UNUSED: 512
+ MASK_UNUSED3: 256
+ MASK_UNUSED4: 512
MASK_SPECIAL: 1024 // Usually a warning sign
MASK_SPECIAL2: 2048
MASK_SPECIAL3: 4096
diff --git a/npc/functions/weather.txt b/npc/functions/weather.txt
index 3cf872c8..1d384a04 100644
--- a/npc/functions/weather.txt
+++ b/npc/functions/weather.txt
@@ -24,6 +24,7 @@ OnInit:
// 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);
@@ -75,9 +76,44 @@ OnInit:
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);
@@ -91,25 +127,68 @@ OnInit:
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$, .@tm);
+ } else {
+ htput(.wtime, .@m$, .@t+.@tm);
+ }
+ return true;
+ }
///////////////////////////////////////////////////////////////////
- // 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;
+ // Every 5 seconds, we clean up any ongoing weather effects
+OnTimer5000:
+ // 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);
@@ -153,17 +232,7 @@ OnManual:
// 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);
+ WeatherClear(getmap());
end;
// Reset the whole map, including season, event and weather masks