new object $climate: $has_commands, $weather_system; var $climate daylengths = 0; var $climate seasons = 0; var $climate weathers = 0; var $has_commands local = #[]; var $has_commands remote = #[["@list-climate", [["@list-climate", "*", "@list-climate <this>", 'show_cmd, #[[1, ['this, []]]]]]], ["@setup", [["@setup", "* seasons * daylengths *", "@setup <this> seasons <any> daylengths <any>", 'setup_cmd, #[[1, ['this, []]], [3, ['any, []]], [5, ['any, []]]]]]], ["@add-weather", [["@add-weather", "* type * prob?abilities *", "@add-weather <this> type <descendant of $weather> prob?abilities <any>", 'add_weather_cmd, #[[1, ['this, []]], [3, ['descendant, [$weather]]], [5, ['any, []]]]]]], ["@del-weather", [["@del-weather", "* type *", "@del-weather <this> type <descendant of $weather>", 'del_weather_cmd, #[[1, ['this, []]], [3, ['descendant, [$weather]]]]]]]]; var $has_commands shortcuts = #[]; var $root created_on = 839895133; var $root flags = ['variables, 'methods, 'code, 'core]; var $root help_node = $help_sys_climate; var $root inited = 1; var $root managed = [$climate]; var $root manager = $climate; public method ._probabilities() { arg from, season, fuzz; var i, j, attr, refattr, dists, sum, t; season = season in seasons; refattr = from.attributes(); dists = map i in (weathers.keys()) to (refresh() && [i, (100 * ((weathers[i])[season])) / (fuzz + ((type((t = (| map j in [1 .. (attr = i.attributes()).length()] to (abs((attr[j]) - (refattr[j]))).sum() |))) == 'error) ? 1000000 : t))]); // normalize the list - the sum should be around 10,000 sum = (dists.slice(2)).sum(); return map i in (dists) to ([i[1], ((i[2]) * 10000) / sum]); }; public method .add_weather_cmd() { arg cmdstr, cmd, this, p1, weather, p2, probs; var i; (> .perms(sender()) <); probs = map i in (probs.explode()) to (toint(i)); if ((probs.length()) != (seasons.length())) throw(~parse, "Wrong number of probabilities."); weathers = weathers.add(weather, probs); return ("Weather `" + (weather.name())) + "' added."; }; public method .advance() { arg current, season, dependancies; var dists, i, w, d, fuzz; fuzz = 10; dists = ._probabilities(current, season, fuzz); dists = dists.sort(dists.slice(2)); for i in (dependancies) { d = (i[1]).get_setting("weather-time", $realm); dists += ((i[2]) * ((d[3])._probabilities(d[1], d[2], fuzz))) / 100; } w = random(10000); i = 1; d = 0; while ((i <= (dists.length())) && ((d += (dists[i])[2]) < w)) i++; if (i > (dists.length())) i--; return (dists[i])[1]; }; public method .ctext_variables() { arg current, season; var vars; vars = #[["weather", current.name()], ["weather_desc", current.prose()], ["season", season]]; vars = vars.union(current.attribute_vars()); return vars; }; public method .daylength() { arg season; return daylengths[season in seasons]; }; public method .del_weather_cmd() { arg cmdstr, cmd, this, p1, weather; var i; (> .perms(sender()) <); if (!(weathers.contains(weather))) return "That weather doesn't belong to this climate."; weathers = weathers.del(weather); return ("Weather `" + (weather.name())) + "' removed."; }; public method .match_weather() { arg weather_str; var i, out; if ((out = find i in (weathers.keys()) where ((i.name()) == weather_str))) return (weathers.keys())[out]; if ((out = find i in (weathers.keys()) where (weather_str.match_begin(i.name())))) return (weathers.keys())[out]; throw(~keynf, "No such weather in this climate."); }; public method .setup_cmd() { arg cmdstr, cmd, this, p, vals, p, dls; var s, line, attrs, att2, extras, ex2, i; (> .perms(sender()) <); seasons = vals.explode(); daylengths = map i in (dls.explode()) to (toint(i)); weathers = #[]; return ("Seasons: " + (seasons.to_english())) + ". The weather list has been wiped."; }; public method .show_cmd() { arg cmdstr, cmd, this; var out, x, i; return ((map i in (weathers) to ([(i[1]).name(), @i[2]]).transpose()).tabulate([["Weather type", "------------"], @map i in (seasons) to ([i, "".pad(i.length(), "-")])])) + ["---"]; };