// 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;
}