def read(self, s): s = preprocess(s) d = self._dict for line in s.split("\n"): words = line.split() if not words: continue if words[0] == "clear": d.clear() elif words[0] == "def": name = words[1] if name not in d: d[name] = {} elif words[0] in self.string_properties: d[name][words[0]] = words[1] elif words[0] in self.int_properties: d[name][words[0]] = int(words[1]) elif words[0] in self.precision_properties: d[name][words[0]] = to_int(words[1]) elif words[0] in self.int_list_properties: d[name][words[0]] = [int(x) for x in words[1:]] elif words[0] in self.precision_list_properties: d[name][words[0]] = [to_int(x) for x in words[1:]] else: if words[0] == "effect" and words[1] == "bonus" and words[2] in self.precision_properties: words[3] = to_int(words[3]) if len(words) > 4: # apparently this case doesn't happen at the moment words[4] = to_int(words[4]) d[name][words[0]] = words[1:]
def __init__(self, prototype, square, qty): prototype.init_dict(self) self.qty = to_int(qty) # XXX does the value come from the map? (already done in rules) self.qty_max = self.qty if self.resource_type == 1: # wood self.resource_regen = to_int(".01") Entity.__init__(self, square)
def __init__(self, prototype, square, qty): prototype.init_dict(self) self.qty = to_int( qty ) # XXX does the value come from the map? (already done in rules) self.qty_max = self.qty if self.resource_type == 1: # wood self.resource_regen = to_int(".01") Entity.__init__(self, square)
def _add_start(self, w, words, line): # get start type if w == "player": n = "players_starts" else: n = "computers_starts" # get resources starting_resources = [] for c in words[1:1+self.nb_res]: try: starting_resources.append(to_int(c)) except: map_error(line, "expected an integer but found %s" % c) # build start self._add_start_to(getattr(self, n), starting_resources, words[1+self.nb_res:])
def _add_start(self, w, words, line): # get start type if w == "player": n = "players_starts" else: n = "computers_starts" # get resources starting_resources = [] for c in words[1:1 + self.nb_res]: try: starting_resources.append(to_int(c)) except: map_error(line, "expected an integer but found %s" % c) # build start self._add_start_to(getattr(self, n), starting_resources, words[1 + self.nb_res:])
def _load_map(self, map): def random_choice_repl(matchobj): return worldrandom.choice( matchobj.group(1).split("\n#end_choice\n")) def check_squares(squares): for sq in squares: if re.match("^[a-z]+[0-9]+$", sq) is None: map_error(line, "%s is not a square" % sq) self.objective = [] self.intro = [] self.timer_coefficient = 1 triggers = [] self.map_objects = [] self.computers_starts = [] self.players_starts = [] self.starting_units = [] squares_words = [ "starting_squares", "additional_meadows", "remove_meadows", "high_grounds" ] self.square_width = 12 # default value self.nb_lines = 0 self.nb_columns = 0 self.nb_rows = 0 # deprecated (was incorrectly used for columns instead of lines) self.nb_meadows_by_square = 0 self.west_east = [] self.south_north = [] # "squares words" self.starting_squares = [] self.additional_meadows = [] self.remove_meadows = [] self.high_grounds = [] self.starting_resources = [0 for _ in range(self.nb_res)] self.nb_players_min = 1 self.nb_players_max = 1 s = map.read() # "universal newlines" s = re.sub("(?m);.*$", "", s) # remove comments s = re.sub("(?m)^[ \t]*$\n", "", s) # remove empty lines s = re.sub(r"(?m)\\[ \t]*$\n", " ", s) # join lines ending with "\" s = s.replace("(", " ( ") s = s.replace(")", " ) ") s = re.sub(r"\s*\n\s*", r"\n", s) # strip lines s = re.sub(r"(?ms)^#random_choice\n(.*?)\n#end_random_choice$", random_choice_repl, s) s = re.sub(r"(?m)^(goldmine|wood)s\s+([0-9]+)\s+(.*)$", r"\1 \2 \3", s) s = re.sub(r"(south_north|west_east)_paths", r"\1 path", s) s = re.sub(r"(south_north|west_east)_bridges", r"\1 bridge", s) for line in s.split("\n"): # TODO: error msg words = line.strip().split() if not words: continue # empty line w = words[0] if w[0:1] == ";": continue # comment for _w in words[1:]: if w in ["south_north", "west_east"]: continue # TODO: check that the exit type_name is defined in style for _w in _w.split(","): if _w and _w[0] == "-": _w = _w[1:] if re.match("^([a-z]+[0-9]+|[0-9]+(.[0-9]*)?|.[0-9]+)$", _w) is None and \ not hasattr(Player, "lang_" + _w) and \ _w not in rules.classnames() and \ _w not in get_ai_names() and \ _w not in ["(", ")", "all", "players", "computers"] and \ _w not in ORDERS_DICT: map_error(line, "unknown: %s" % _w) if w in ["title", "objective", "intro"]: setattr(self, w, [int(x) for x in words[1:]]) # TODO: error msg (sounds) elif w in [ "square_width", "nb_rows", "nb_columns", "nb_lines", "nb_players_min", "nb_players_max", "scenario", "nb_meadows_by_square", "global_food_limit", "timer_coefficient" ]: try: setattr(self, w, int(words[1])) if w == "nb_rows": self.nb_columns = self.nb_rows warning( "nb_rows is deprecated, use nb_columns instead") except: map_error(line, "%s must be an integer" % w) elif w in ["south_north", "west_east"]: squares = words[2:] check_squares(squares) getattr(self, w).append((words[1], squares)) elif w in squares_words: squares = words[1:] check_squares(squares) getattr(self, w).extend(squares) elif w in ["starting_resources"]: self.starting_resources = [] for c in words[1:]: try: self.starting_resources.append(to_int(c)) except: map_error(line, "expected an integer but found %s" % c) elif rules.get(w, "class") == ["deposit"]: for sq in words[2:]: # TODO: error msg (squares) self.map_objects.append([sq, w, words[1]]) elif w in ["starting_units"]: getattr(self, w).extend(words[1:]) # TODO: error msg (types) elif w in ["player", "computer_only", "computer"]: self._add_start(w, words, line) elif w == "trigger": triggers.append(words[1:]) else: map_error(line, "unknown command: %s" % w) # build self.players_starts for sq in self.starting_squares: self._add_start_to(self.players_starts, self.starting_resources, self.starting_units, sq) if self.nb_players_min > self.nb_players_max: map_error("", "nb_players_min > nb_players_max") if len(self.players_starts) < self.nb_players_max: map_error("", "not enough starting places for nb_players_max") # 2 multiplayer map types: with or without standard triggers # TODO: select in a menu: User Map Settings, melee, free for all, etc if not triggers and self.default_triggers: triggers = self.default_triggers for t in triggers: self._add_trigger(t)
def _load_map(self, map): def random_choice_repl(matchobj): return worldrandom.choice(matchobj.group(1).split("\n#end_choice\n")) def check_squares(squares): for sq in squares: if re.match("^[a-z]+[0-9]+$", sq) is None: map_error(line, "%s is not a square" % sq) self.objective = [] self.intro = [] self.timer_coefficient = 1 triggers = [] self.map_objects = [] self.computers_starts = [] self.players_starts = [] self.starting_units = [] squares_words = ["starting_squares", "additional_meadows", "remove_meadows", "high_grounds"] self.square_width = 12 # default value self.nb_lines = 0 self.nb_columns = 0 self.nb_rows = 0 # deprecated (was incorrectly used for columns instead of lines) self.nb_meadows_by_square = 0 self.west_east = [] self.south_north = [] # "squares words" self.starting_squares = [] self.additional_meadows = [] self.remove_meadows = [] self.high_grounds = [] self.starting_resources = [0 for _ in range(self.nb_res)] self.nb_players_min = 1 self.nb_players_max = 1 s = map.read() # "universal newlines" s = re.sub("(?m);.*$", "", s) # remove comments s = re.sub("(?m)^[ \t]*$\n", "", s) # remove empty lines s = re.sub(r"(?m)\\[ \t]*$\n", " ", s) # join lines ending with "\" s = s.replace("(", " ( ") s = s.replace(")", " ) ") s = re.sub(r"\s*\n\s*", r"\n", s) # strip lines s = re.sub(r"(?ms)^#random_choice\n(.*?)\n#end_random_choice$", random_choice_repl, s) s = re.sub(r"(?m)^(goldmine|wood)s\s+([0-9]+)\s+(.*)$", r"\1 \2 \3", s) s = re.sub(r"(south_north|west_east)_paths", r"\1 path", s) s = re.sub(r"(south_north|west_east)_bridges", r"\1 bridge", s) for line in s.split("\n"): # TODO: error msg words = line.strip().split() if not words: continue # empty line w = words[0] if w[0:1] == ";": continue # comment for _w in words[1:]: if w in ["south_north", "west_east"]: continue # TODO: check that the exit type_name is defined in style for _w in _w.split(","): if _w and _w[0] == "-": _w = _w[1:] if re.match("^([a-z]+[0-9]+|[0-9]+(.[0-9]*)?|.[0-9]+)$", _w) is None and \ not hasattr(Player, "lang_" + _w) and \ _w not in rules.classnames() and \ _w not in get_ai_names() and \ _w not in ["(", ")", "all", "players", "computers"] and \ _w not in ORDERS_DICT: map_error(line, "unknown: %s" % _w) if w in ["title", "objective", "intro"]: setattr(self, w, [int(x) for x in words[1:]]) # TODO: error msg (sounds) elif w in ["square_width", "nb_rows", "nb_columns", "nb_lines", "nb_players_min", "nb_players_max", "scenario", "nb_meadows_by_square", "global_food_limit", "timer_coefficient"]: try: setattr(self, w, int(words[1])) if w == "nb_rows": self.nb_columns = self.nb_rows warning("nb_rows is deprecated, use nb_columns instead") except: map_error(line, "%s must be an integer" % w) elif w in ["south_north", "west_east"]: squares = words[2:] check_squares(squares) getattr(self, w).append((words[1], squares)) elif w in squares_words: squares = words[1:] check_squares(squares) getattr(self, w).extend(squares) elif w in ["starting_resources"]: self.starting_resources = [] for c in words[1:]: try: self.starting_resources.append(to_int(c)) except: map_error(line, "expected an integer but found %s" % c) elif rules.get(w, "class") == ["deposit"]: for sq in words[2:]: # TODO: error msg (squares) self.map_objects.append([sq, w, words[1]]) elif w in ["starting_units"]: getattr(self, w).extend(words[1:]) # TODO: error msg (types) elif w in ["player", "computer_only", "computer"]: self._add_start(w, words, line) elif w == "trigger": triggers.append(words[1:]) else: map_error(line, "unknown command: %s" % w) # build self.players_starts for sq in self.starting_squares: self._add_start_to(self.players_starts, self.starting_resources, self.starting_units, sq) if self.nb_players_min > self.nb_players_max: map_error("", "nb_players_min > nb_players_max") if len(self.players_starts) < self.nb_players_max: map_error("", "not enough starting places for nb_players_max") # 2 multiplayer map types: with or without standard triggers # TODO: select in a menu: User Map Settings, melee, free for all, etc if not triggers and self.default_triggers: triggers = self.default_triggers for t in triggers: self._add_trigger(t)
def execute_raise_dead(self): self.unit.player.lang_add_units([self.target.name] + self.type.effect[2:], decay=to_int(self.type.effect[1]), from_corpse=True, notify=False)
def execute_summon(self): self.unit.player.lang_add_units([self.target.name] + self.type.effect[2:], decay=to_int(self.type.effect[1]), notify=False)
def execute_raise_dead(self): self.unit.player.lang_add_units( [self.target.name] + self.type.effect[2:], decay=to_int(self.type.effect[1]), from_corpse=True, notify=False)
def execute_summon(self): self.unit.player.lang_add_units( [self.target.name] + self.type.effect[2:], decay=to_int(self.type.effect[1]), notify=False)