// TMW2 scripts. // Authors: // Jesusalva // Description: // Controls world seasons. RESPECT MASK_* VARS ON CONSTANTS DB // is_night(set=False) function script is_night { // If we're not configuring, retrieve the variable (cache) // It is more efficient this way .@set=getarg(0, false); if (!.@set) return $@WEATHER_NIGHT; /* // Night time depends on season. // Summer: Day > Night // Winter: Night > Day // Autumn/Spring: Day = Night // // But we have TWO SUNS, meaning night is always smaller. // // 2 = GETTIME_MINUTE // 3 = GETTIME_HOUR // Summer: 5h day. 1h night. (4 cycles, 8 updates) // Others: 3h day. 1h night. (6 cycles, 12 updates) // Winter: 2h day. 1h night. (8 cycles, 16 updates) */ // NEW Unified Rule: Day last 3 hours. Night lasts 1 hour. Always. .@t=(season() == SUMMER ? 6 : (season() == WINTER ? 3 : 4)); return (gettime(3) % .@t == 1); } 000-0,0,0,0 script #WeatherCore NPC_HIDDEN,{ end; /* * removemapflag("", ) * setmapflag("", {, }) * getmapflag("", ) mf_snow: 16 mf_jexp: 39 mf_bexp: 40 */ OnInit: // This is weather startup .@init=true; $@WEATHER_NIGHT=is_night(true); .tpc=0; .tcl=0; // 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 will never snow on a desert, or a sandstorm on icelands. .wcore = htnew; // Deserts //htput(.wcore, "032-1", "desert"); // Woodlands htput(.wcore, "001-4", "woodland"); htput(.wcore, "001-11", "woodland"); htput(.wcore, "001-12", "woodland"); htput(.wcore, "018-2", "woodland"); // Icelands htput(.wcore, "031-1", "iceland"); htput(.wcore, "033-1", "iceland"); // Special //htput(.wcore, "011-3", "special"); consoleinfo "[Weather.sys] Total Maps = " + htsize(.wcore); // No "end" here, so server starts with weather OnMinute00: OnMinute15: OnMinute30: OnMinute45: // There is no weather in test servers if (debug && !$@GM_OVERRIDE) end; //debugmes "[Weather.sys] Starting to regen"; .tpc+=getusers(1); .tcl+=1; .@hti = htiterator(.wcore); for(.@key$ = htinextkey(.@hti); hticheck(.@hti); .@key$ = htinextkey(.@hti)) { // Local variables: .@key$ .@type .@r .@type$=htget(.wcore, .@key$); .@r=rand(0,10000); // Clear weather map masks .@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; if (.@mk & MASK_EVILSANCTUM) .@mk=.@mk^MASK_EVILSANCTUM; // Monster King Sieges (can be weird, siege last 10mn and mask last 15) if ($@MK_SCENE) .@mk=.@mk|MASK_EVILSANCTUM; if (.@mk & (MASK_MATTACK|MASK_EVILSANCTUM)) .@mk=.@mk^MASK_EVILSANCTUM; // Remove all current masks, and add rain/snow/sand if (.@type$ == "desert") { if (.@r < 10) .@mk=.@mk|MASK_RAIN; else if (.@r < 300) .@mk=.@mk|MASK_SANDSTORM; } else if (.@type$ == "woodland") { if (.@r < 300) .@mk=.@mk|MASK_RAIN; if ($EVENT$ == "Christmas") .@mk=.@mk|MASK_SNOW; else if (season() == WINTER && .@r >= 9250) .@mk=.@mk|MASK_SNOW; } else if (.@type$ == "iceland") { if (.@r < 30) .@mk=.@mk|MASK_RAIN; else if (.@r < 300) .@mk=.@mk|MASK_SNOW; } else if (.@type$ == "special") { // This biom is too hot for snow. But it may rain. if (.@r < 300) .@mk=.@mk|MASK_RAIN; // Fog? (Evil Sanctum and Monster Attack) Or Sandstorm? if (.@r % 4 == 2) .@mk=.@mk|MASK_EVILSANCTUM; else if (.@r % 4 == 1) .@mk=.@mk|MASK_SANDSTORM; else if (.@r % 4 == 3) .@mk=.@mk|MASK_MATTACK; } else { consolebug "Warning warning, blame Saulc! Weather system error on map "+.@key$; announce("ERROR BLAME SAULC! WEATHER SYSTEM CORRUPTED.", bc_all); } // Bugfix if (!(.@mk & MASK_NONE)) .@mk=.@mk|MASK_NONE; setmapmask .@key$, .@mk; // Is it night time? if (is_night()) { setmapflag(.@key$, mf_nightenabled); addmapmask .@key$, MASK_NIGHT; } else if (getmapmask(.@key$) & MASK_NIGHT) { removemapflag(.@key$, mf_nightenabled); removemapmask .@key$, MASK_NIGHT; } } htidelete(.@hti); //debugmes "[Weather.sys] Regenerated"; // Hardcore: Skip day/night cycles if ($HARDCORE || $@GM_OVERRIDE) { $@WEATHER_NIGHT=is_night(true); end; } // Crossroads has no changes between day/night (cosmetic only) (skill only) callfunc "FYE_Normalize"; debugmes "[Weather.sys] Weather reloaded"; end; // 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; } // 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: 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); end; // Reset the whole map, including season, event and weather masks OnReset: getmapxy(.@key$,.@a,.@b,0); setmapmask(.@key$, MASK_NONE); end; }