// 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_WOODLAND); htput(.wcore, "008-1", CLIMATE_WOODLAND); htput(.wcore, "009-1", CLIMATE_WOODLAND); htput(.wcore, "010-1", CLIMATE_WOODLAND); htput(.wcore, "011-1", CLIMATE_WOODLAND); htput(.wcore, "012-1", CLIMATE_WOODLAND); htput(.wcore, "013-1", CLIMATE_WOODLAND); htput(.wcore, "014-1", CLIMATE_WOODLAND); htput(.wcore, "015-1", CLIMATE_WOODLAND); htput(.wcore, "016-1", CLIMATE_WOODLAND); htput(.wcore, "017-1", CLIMATE_WOODLAND); htput(.wcore, "018-1", CLIMATE_WOODLAND); htput(.wcore, "025-1", CLIMATE_WOODLAND); htput(.wcore, "026-1", CLIMATE_WOODLAND); htput(.wcore, "027-1", CLIMATE_WOODLAND); htput(.wcore, "028-1", CLIMATE_WOODLAND); htput(.wcore, "029-1", CLIMATE_WOODLAND); htput(.wcore, "051-1", CLIMATE_WOODLAND); // ? htput(.wcore, "052-1", CLIMATE_WOODLAND); htput(.wcore, "055-1", CLIMATE_WOODLAND); htput(.wcore, "057-1", CLIMATE_WOODLAND); // 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$, .@tm); } else { htput(.wtime, .@m$, .@t+.@tm); } return true; } /////////////////////////////////////////////////////////////////// // 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); 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 "); 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; } // 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; }