Пример #1
0
class Obstacles():
    def __init__(self, screen, obstacles, characters, items):
        self.screen = screen
        self.obstacles = obstacles
        self.characters = characters
        self.items = items
        
        self.layers = [[], []]
        self.rect_obstacles = []
        self.charactermap = []
        self.triggers = []
        self.item_map = []
        
        self.selected = None
        self.screen_offset = [0, 0]
        self.properties_frame = None
    def save(self, path):
        final_characters = [character.get_dict() for character in self.charactermap]
        final_items = [item.get_dict() for item in self.item_map]
        final_triggers = [trigger.get_dict() for trigger in self.triggers]
        final_obstacles = [[obstacle.get_dict() for obstacle in self.layers[0] + self.rect_obstacles], [obstacle.get_dict() for obstacle in self.layers[1]]]
        with open(os.path.join(path, "characters.py"), "w") as f:
            f.write("characters = " + repr(final_characters))
        with open(os.path.join(path, "items.py"), "w") as f:
            f.write("items = " + repr(final_items))
        with open(os.path.join(path, "triggers.py"), "w") as f:
            f.write("triggers = " + repr(final_triggers))
        with open(os.path.join(path, "obstacles.py"), "w") as f:
            f.write("layers = " + repr(final_obstacles))
    def gen_real_rect(self, mapsize):
        self.mapsize = mapsize
        real_height = mapsize[1] * (ISOHEIGHT // 2) + mapsize[0] * (ISOHEIGHT // 2)
        real_width = mapsize[1] * (ISOWIDTH // 2) + mapsize[0] * (ISOWIDTH // 2)
        startx = -(mapsize[1] * (ISOWIDTH // 2))
        starty = 0
        return Rect(startx, starty, real_width, real_height)
    def create_map(self, mapsize):
        self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5, 10, [], "realrect")
        self.floor_quadtree = QuadTree(Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10, [], "rect")
        self.layers = [[], []]
        self.rect_obstacles = []
        self.charactermap = []
        self.triggers = []
        self.item_map = []
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(math.sqrt(self.mapsize[0] ** 2 + self.mapsize[1] ** 2))
    def load_map(self, path, mapsize):
        self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5, 10, [], "realrect")
        self.floor_quadtree = QuadTree(Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10, [], "rect")
        self.load_obstaclemap(os.path.join(path, "obstacles.py"))
        self.load_charactermap(os.path.join(path, "characters.py"))
        self.load_triggermap(os.path.join(path, "triggers.py"))
        self.load_item_map(os.path.join(path, "items.py"))
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(math.sqrt(self.mapsize[0] ** 2 + self.mapsize[1] ** 2))
    def change_size(self, size):
        self.mapsize = size
        self.realrect_quadtree = QuadTree(self.gen_real_rect(self.mapsize), 0, 5, 10, [], "realrect")
        self.floor_quadtree = QuadTree(Rect(0, 0, self.mapsize[0] * WIDTH, self.mapsize[1] * TILEHEIGHT), 0, 5, 10, [], "rect")
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(math.sqrt(self.mapsize[0] ** 2 + self.mapsize[1] ** 2))
    def delete_item(self, item):
        self.item_map.remove(item)
    def add_item(self, item):
        self.item_map.append(self.create_item(item))
    def create_item(self, info):
        item_info = self.items[info["type"]].copy()
        temp = item_info.copy()
        temp.update(info)
        temp.update({"item_info": item_info.copy()})
        return Item(self.screen, **temp)
    def refresh_realrect_quadtree(self):
        self.realrect_quadtree.clear()
        self.realrect_quadtree.particles = [j for i in self.layers for j in i] + self.charactermap + self.item_map
        self.realrect_quadtree.update()
    def refresh_floor_quadtree(self):
        self.floor_quadtree.clear()
        self.floor_quadtree.particles = self.triggers + self.rect_obstacles
        self.floor_quadtree.update()
    def delete_obs(self, **kwargs):
        obs = kwargs.get("obstacle", None)
        for index, layer in enumerate(self.layers):
            try:
                layer.remove(obs)
                break
            except:
                continue
    def delete_trigger(self, trigger):
        try:
            self.triggers.remove(trigger)
        except:
            pass
    def delete_character(self, identifier):
        try:
            self.characters.remove(character)
        except:
            pass
    def create_obstacle(self, **info):
        if info["type"] == "RECT":
            return BasicObstacle(self.screen, x=info["x"], y=info["y"], width=info.get("width", 1), height=info.get("height", 1), type="RECT")
        else:
            tile_dict = self.obstacles[int(info["type"])]
            if type(tile_dict["images"]) == list:
                tile_dict["images"] = tile_dict["images"][0]
            complete_info = tile_dict.copy()
            complete_info.update(info)
            return Obstacle(self.screen, **complete_info)
    def spawn_character(self, **kwargs):
        if kwargs.get("info", None):
            self.charactermap.append(self.create_character(kwargs["info"]))
        else:
            self.charactermap.append(Character(self.screen, x=kwargs.get("x", 0), y=kwargs.get("y", 0), name=kwargs["name"]))
    def load_obstaclemap(self, path):
        self.layers = []
        temp = load_module(path)
        for layer in temp.layers:
            self.layers.append([])
            for obs in layer:
                new = self.create_obstacle(**obs)
                if type(new) == BasicObstacle:
                    self.rect_obstacles.append(new)
                else:
                    self.layers[-1].append(new)
        self.refresh_floor_quadtree()
        self.refresh_realrect_quadtree()
    def load_charactermap(self, path):
        self.charactermap = []
        temp = load_module(path)
        for character in temp.characters:
            self.charactermap.append(self.create_character(character))
        self.refresh_realrect_quadtree()
    def load_triggermap(self, path):
        self.triggers = []
        temp = load_module(path)
        for trigger in temp.triggers:
            self.triggers.append(Trigger(self.screen, **trigger))
        self.refresh_floor_quadtree()
    def load_item_map(self, path):
        self.item_map = []
        temp = load_module(path)
        for item in temp.items:
            self.item_map.append(self.create_item(item))
        self.refresh_realrect_quadtree()
    def create_character(self, info):
        temp = self.characters[info["name"]].copy()
        temp.update(info)
        temp.update({"orig_info": self.characters[info["name"]].copy()})
        return Character(self.screen, obstaclemap=self, **temp)
    def set_entry_value(self, entry, value):
        entry.delete(0, "end")
        entry.insert(0, value)
    def click(self, mouse_pos, tile_pos, mode, current_obs, current_layer, current_item, current_character, current_tab, properties_frame):
        for thing in [j for i in self.layers for j in i] + self.charactermap + self.item_map + self.rect_obstacles + self.triggers:
            thing.deselect()
        self.selected = None
        if mode == 0:
            selected = self.realrect_quadtree.collidepoint(mouse_pos)
            selected1 = self.floor_quadtree.collidepoint((tile_pos[0] * WIDTH, tile_pos[1] * HEIGHT))
            if selected or selected1:
                self.selected = max(selected + selected1, key=lambda x: (x.x, x.y))
                self.selected.select()
        elif mode == 1:
            if current_tab == "Obstacles":
                new_obs = self.create_obstacle(type=current_obs, x=tile_pos[0], y=tile_pos[1], width=1, height=1)
                if type(new_obs) == BasicObstacle:
                    self.rect_obstacles.append(new_obs)
                else:
                    self.layers[current_layer].append(new_obs)
            elif current_tab == "Items":
                new_obs = self.create_item({"type": current_item, "x": tile_pos[0], "y": tile_pos[1]})
                self.item_map.append(new_obs)
            elif current_tab == "Characters":
                new_obs = self.create_character({"name": current_character, "x": tile_pos[0], "y": tile_pos[1]})
                self.charactermap.append(new_obs)
            elif current_tab == "Triggers":
                new_obs = Trigger(self.screen, x=tile_pos[0], y=tile_pos[1], width=1, height=1)
                self.triggers.append(new_obs)
            self.selected = new_obs
            new_obs.select()
            self.refresh_realrect_quadtree()
            self.refresh_floor_quadtree()
        self.create_properties_widget(properties_frame)
        if self.selected:
            return True
        else:
            return False
    def destroy_properties_widget(self):
        if self.properties_frame:
            self.properties_frame.destroy()
            self.properties_frame = None
            self.widgets = {}
    def create_properties_widget(self, parent):
        self.destroy_properties_widget()
        if self.selected:
            obs_type = type(self.selected)
            if obs_type == BasicObstacle:
                possible_options = ["x", "y", "width", "height", "identifier"]
            elif obs_type == Trigger:
                possible_options = ["x", "y", "width", "height", "deactivate_after_use", "active", "identifier", "trigger"]
            elif obs_type == Obstacle:
                possible_options = ["x", "y", "identifier", "action", "after_looting", "items", "animation", "label", "onclick"]
            elif obs_type == Character:
                possible_options = ["x", "y", "dead", "weapon", "label", "identifier", "aggression_distance", "direction", "health", "random_walk_area", "waypoints", "ondeath"]
            elif obs_type == Item:
                possible_options = ["x", "y", "label", "identifier"]
            self.properties_frame = ttk.Frame(parent)
            self.widgets = {}
            for index, option in enumerate(possible_options):
                if option in ["x", "y", "width", "height", "aggression_distance", "health"]:
                    if option in ["x", "width"]:
                        self.widgets[option] = tk.Spinbox(self.properties_frame, from_=0, to=self.mapsize[0], increment=0.1)
                    elif option in ["y", "height"]:
                        self.widgets[option] = tk.Spinbox(self.properties_frame, from_=0, to=self.mapsize[1], increment=0.1)
                    elif option == "aggression_distance":
                        self.widgets[option] = tk.Spinbox(self.properties_frame, from_=0, to=self.map_diam, increment=0.1)
                    elif option == "health":
                        self.widgets[option] = tk.Spinbox(self.properties_frame, from_=0, to=1000)
                    self.set_entry_value(self.widgets[option], getattr(self.selected, option))
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                elif option in ["action", "weapon", "label", "identifier", "direction", "animation", "after_looting", "items"]:
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    attr = getattr(self.selected, option)
                    if option == "items" and attr is not None:
                        attr = ";".join(attr)
                    if attr is None:
                        attr = ""
                    self.set_entry_value(self.widgets[option], attr)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                elif option in ["active", "deactivate_after_use", "dead"]:
                    variable = tk.IntVar()
                    variable.set(int(getattr(self.selected, option)))
                    self.widgets[option] = {"widget": ttk.Checkbutton(self.properties_frame, text=option, variable=variable), "variable": variable}
                    self.widgets[option]["widget"].grid(row=index, column=1, sticky="w")
                elif option in ["onclick", "trigger", "ondeath"]:
                    self.widgets[option] = [ttk.Combobox(self.properties_frame, values=("REPLACE", "DELETE", "ADD", "KILL", "KILLALL", "SPAWN", "OPEN", "CLOSE", "DEACTIVATE", "ACTIVATE", "WINGAME", "TRYWINGAME", "CHANGEMAP")), ttk.Combobox(self.properties_frame, values=("obstacle", "character", "item", "trigger")), ttk.Entry(self.properties_frame), ttk.Entry(self.properties_frame), ttk.Entry(self.properties_frame)]
                    for widget_index, widget in enumerate(self.widgets[option]):
                        try:
                            if type(widget) == ttk.Combobox:
                                widget.set(getattr(self.selected, option)[widget_index])
                            else:
                                self.set_entry_value(widget, getattr(self.selected, option)[widget_index])
                        except:
                            pass
                        widget.grid(row=index + widget_index, column=1, sticky="w")
                elif option == "waypoints":
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                    self.set_entry_value(self.widgets[option], ";".join(",".join([str(y) for y in x]) for x in getattr(self.selected, option)))
                elif option == "random_walk_area":
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                    self.set_entry_value(self.widgets[option], ";".join(str(x) for x in getattr(self.selected, option)))
                if option not in ["deactivate_after_use", "dead", "active"]:
                    ttk.Label(self.properties_frame, text=option).grid(row=index, column=0, sticky="w")
            self.properties_frame.grid(row=1, column=0, sticky="nswe")
    def mousedrag(self, mouse_pos, pos_change):
        if self.selected:
            self.set_attributes(x=self.selected.x + pos_change[0], y=self.selected.y + pos_change[1])
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
    def delete(self, *args):
        if self.selected:
            if type(self.selected) == Character:
                self.charactermap.remove(self.selected)
            elif type(self.selected) == Obstacle:
                try:
                    self.layers[0].remove(self.selected)
                except:
                    self.layers[1].remove(self.selected)
            elif type(self.selected) == Item:
                self.item_map.remove(self.selected)
            elif type(self.selected) == BasicObstacle:
                self.rect_obstacles.remove(self.selected)
            elif type(self.selected) == Trigger:
                self.triggers.remove(self.selected)
            self.selected = None
            self.refresh_floor_quadtree()
            self.refresh_realrect_quadtree()
    def set_attributes(self, **kwargs):
        if self.selected:
            if self.properties_frame:
                final_dict = {}
                for key, item in self.widgets.items():
                    if type(item) == dict:
                        value = bool(item["variable"].get())
                    elif type(item) == list:
                        value = []
                        for part in item:
                            temp_val = part.get()
                            if temp_val:
                                value.append(temp_val)
                    else:
                        value = item.get()
                        try:
                            if key in ["after_looting", "health"]:
                                value = int(value)
                            else:
                                value = float(value)
                        except:
                            pass
                    if key in ["x", "y", "width", "height"]:
                        try:
                            final_dict[key] = float(value)
                        except:
                            pass
                    elif key == "direction":
                        if value in ["NW", "N", "NE", "E", "W", "SW", "SE", "S"]:
                            final_dict[key] = value
                    elif key == "items":
                        if value:
                            value = [x.strip() for x in value.split(";")]
                            final_dict[key] = value
                    elif key == "waypoints":
                        try:
                            if value:
                                value = [[float(y) for y in x.split(",")] for x in value.split(";")]
                            for x in value:
                                if len(x) < 2:
                                    break
                            else:
                                final_dict[key] = value
                        except:
                            pass
                    elif key == "random_walk_area":
                        try:
                            if value:
                                value = [float(x) for x in value.split(";")]
                            if len(value) == 4 or not value:
                                final_dict[key] = value
                        except:
                            pass
                    else:
                        final_dict[key] = value
                final_dict.update(kwargs)
                self.selected.set_values(**final_dict)
                for key, item in kwargs.items():
                    if key in ["x", "y"]:
                        self.set_entry_value(self.widgets[key], item)
    def draw_cursor(self, tile_pos, current_obs, current_item, current_char,  current_tab, screen_offset):
        if current_tab == "Obstacles":
            temp = self.create_obstacle(type=current_obs, x=tile_pos[0], y=tile_pos[1])
        elif current_tab == "Items":
            temp = self.create_item({"type": current_item, "x": tile_pos[0], "y": tile_pos[1]})
        elif current_tab == "Characters":
            temp = self.create_character({"name": current_char, "x": tile_pos[0], "y": tile_pos[1]})
        elif current_tab == "Triggers":
            temp = Trigger(self.screen, x=tile_pos[0], y=tile_pos[1])
        temp.draw(screen_offset)
    def draw(self, screen_offset):
        self.set_attributes()
        final = sorted(self.layers[1] + self.charactermap, key=lambda x: (x.x, x.y))
        ground = sorted(self.layers[0] + self.triggers + self.rect_obstacles + self.item_map, key=lambda x: (x.x, x.y))
        for ground_obs in ground:
            ground_obs.draw(screen_offset)
        for thing in final:
            thing.draw(screen_offset)
Пример #2
0
class Obstacles():
    def __init__(self, screen, obstacles, characters, items):
        self.screen = screen
        self.obstacles = obstacles
        self.characters = characters
        self.items = items

        self.layers = [[], []]
        self.rect_obstacles = []
        self.charactermap = []
        self.triggers = []
        self.item_map = []

        self.selected = None
        self.screen_offset = [0, 0]
        self.properties_frame = None

    def save(self, path):
        final_characters = [
            character.get_dict() for character in self.charactermap
        ]
        final_items = [item.get_dict() for item in self.item_map]
        final_triggers = [trigger.get_dict() for trigger in self.triggers]
        final_obstacles = [[
            obstacle.get_dict()
            for obstacle in self.layers[0] + self.rect_obstacles
        ], [obstacle.get_dict() for obstacle in self.layers[1]]]
        with open(os.path.join(path, "characters.py"), "w") as f:
            f.write("characters = " + repr(final_characters))
        with open(os.path.join(path, "items.py"), "w") as f:
            f.write("items = " + repr(final_items))
        with open(os.path.join(path, "triggers.py"), "w") as f:
            f.write("triggers = " + repr(final_triggers))
        with open(os.path.join(path, "obstacles.py"), "w") as f:
            f.write("layers = " + repr(final_obstacles))

    def gen_real_rect(self, mapsize):
        self.mapsize = mapsize
        real_height = mapsize[1] * (ISOHEIGHT //
                                    2) + mapsize[0] * (ISOHEIGHT // 2)
        real_width = mapsize[1] * (ISOWIDTH // 2) + mapsize[0] * (ISOWIDTH //
                                                                  2)
        startx = -(mapsize[1] * (ISOWIDTH // 2))
        starty = 0
        return Rect(startx, starty, real_width, real_height)

    def create_map(self, mapsize):
        self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5,
                                          10, [], "realrect")
        self.floor_quadtree = QuadTree(
            Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10,
            [], "rect")
        self.layers = [[], []]
        self.rect_obstacles = []
        self.charactermap = []
        self.triggers = []
        self.item_map = []
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(
            math.sqrt(self.mapsize[0]**2 + self.mapsize[1]**2))

    def load_map(self, path, mapsize):
        self.realrect_quadtree = QuadTree(self.gen_real_rect(mapsize), 0, 5,
                                          10, [], "realrect")
        self.floor_quadtree = QuadTree(
            Rect(0, 0, mapsize[0] * WIDTH, mapsize[1] * TILEHEIGHT), 0, 5, 10,
            [], "rect")
        self.load_obstaclemap(os.path.join(path, "obstacles.py"))
        self.load_charactermap(os.path.join(path, "characters.py"))
        self.load_triggermap(os.path.join(path, "triggers.py"))
        self.load_item_map(os.path.join(path, "items.py"))
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(
            math.sqrt(self.mapsize[0]**2 + self.mapsize[1]**2))

    def change_size(self, size):
        self.mapsize = size
        self.realrect_quadtree = QuadTree(self.gen_real_rect(self.mapsize), 0,
                                          5, 10, [], "realrect")
        self.floor_quadtree = QuadTree(
            Rect(0, 0, self.mapsize[0] * WIDTH, self.mapsize[1] * TILEHEIGHT),
            0, 5, 10, [], "rect")
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()
        self.map_diam = math.ceil(
            math.sqrt(self.mapsize[0]**2 + self.mapsize[1]**2))

    def delete_item(self, item):
        self.item_map.remove(item)

    def add_item(self, item):
        self.item_map.append(self.create_item(item))

    def create_item(self, info):
        item_info = self.items[info["type"]].copy()
        temp = item_info.copy()
        temp.update(info)
        temp.update({"item_info": item_info.copy()})
        return Item(self.screen, **temp)

    def refresh_realrect_quadtree(self):
        self.realrect_quadtree.clear()
        self.realrect_quadtree.particles = [
            j for i in self.layers for j in i
        ] + self.charactermap + self.item_map
        self.realrect_quadtree.update()

    def refresh_floor_quadtree(self):
        self.floor_quadtree.clear()
        self.floor_quadtree.particles = self.triggers + self.rect_obstacles
        self.floor_quadtree.update()

    def delete_obs(self, **kwargs):
        obs = kwargs.get("obstacle", None)
        for index, layer in enumerate(self.layers):
            try:
                layer.remove(obs)
                break
            except:
                continue

    def delete_trigger(self, trigger):
        try:
            self.triggers.remove(trigger)
        except:
            pass

    def delete_character(self, identifier):
        try:
            self.characters.remove(character)
        except:
            pass

    def create_obstacle(self, **info):
        if info["type"] == "RECT":
            return BasicObstacle(self.screen,
                                 x=info["x"],
                                 y=info["y"],
                                 width=info.get("width", 1),
                                 height=info.get("height", 1),
                                 type="RECT")
        else:
            tile_dict = self.obstacles[int(info["type"])]
            if type(tile_dict["images"]) == list:
                tile_dict["images"] = tile_dict["images"][0]
            complete_info = tile_dict.copy()
            complete_info.update(info)
            complete_info.update(
                {"orig_info": self.obstacles[int(info["type"])]})
            return Obstacle(self.screen, **complete_info)

    def spawn_character(self, **kwargs):
        if kwargs.get("info", None):
            self.charactermap.append(self.create_character(kwargs["info"]))
        else:
            self.charactermap.append(
                Character(self.screen,
                          x=kwargs.get("x", 0),
                          y=kwargs.get("y", 0),
                          name=kwargs["name"]))

    def load_obstaclemap(self, path):
        self.layers = []
        self.rect_obstacles = []
        temp = load_module(path)
        for layer in temp.layers:
            self.layers.append([])
            for obs in layer:
                new = self.create_obstacle(**obs)
                if type(new) == BasicObstacle:
                    self.rect_obstacles.append(new)
                else:
                    self.layers[-1].append(new)
        self.refresh_floor_quadtree()
        self.refresh_realrect_quadtree()

    def load_charactermap(self, path):
        self.charactermap = []
        temp = load_module(path)
        for character in temp.characters:
            self.charactermap.append(self.create_character(character))
        self.refresh_realrect_quadtree()

    def load_triggermap(self, path):
        self.triggers = []
        temp = load_module(path)
        for trigger in temp.triggers:
            self.triggers.append(Trigger(self.screen, **trigger))
        self.refresh_floor_quadtree()

    def load_item_map(self, path):
        self.item_map = []
        temp = load_module(path)
        for item in temp.items:
            self.item_map.append(self.create_item(item))
        self.refresh_realrect_quadtree()

    def create_character(self, info):
        temp = self.characters[info["name"]].copy()
        temp.update(info)
        temp.update({"orig_info": self.characters[info["name"]].copy()})
        return Character(self.screen, obstaclemap=self, **temp)

    def set_entry_value(self, entry, value):
        entry.delete(0, "end")
        entry.insert(0, value)

    def click(self, mouse_pos, tile_pos, mode, current_obs, current_layer,
              current_item, current_character, current_tab, properties_frame):
        for thing in [
                j for i in self.layers for j in i
        ] + self.charactermap + self.item_map + self.rect_obstacles + self.triggers:
            thing.deselect()
        self.selected = None
        if mode == 0:
            selected = self.realrect_quadtree.collidepoint(mouse_pos)
            selected1 = self.floor_quadtree.collidepoint(
                (tile_pos[0] * WIDTH, tile_pos[1] * HEIGHT))
            if selected or selected1:
                self.selected = max(selected + selected1,
                                    key=lambda x: (x.x, x.y))
                self.selected.select()
        elif mode == 1:
            if current_tab == "Obstacles":
                new_obs = self.create_obstacle(type=current_obs,
                                               x=tile_pos[0],
                                               y=tile_pos[1],
                                               width=1,
                                               height=1)
                if type(new_obs) == BasicObstacle:
                    self.rect_obstacles.append(new_obs)
                else:
                    self.layers[current_layer].append(new_obs)
            elif current_tab == "Items":
                new_obs = self.create_item({
                    "type": current_item,
                    "x": tile_pos[0],
                    "y": tile_pos[1]
                })
                self.item_map.append(new_obs)
            elif current_tab == "Characters":
                new_obs = self.create_character({
                    "name": current_character,
                    "x": tile_pos[0],
                    "y": tile_pos[1]
                })
                self.charactermap.append(new_obs)
            elif current_tab == "Triggers":
                new_obs = Trigger(self.screen,
                                  x=tile_pos[0],
                                  y=tile_pos[1],
                                  width=1,
                                  height=1)
                self.triggers.append(new_obs)
            self.selected = new_obs
            new_obs.select()
            self.refresh_realrect_quadtree()
            self.refresh_floor_quadtree()
        self.create_properties_widget(properties_frame)
        if self.selected:
            return True
        else:
            return False

    def destroy_properties_widget(self):
        if self.properties_frame:
            self.properties_frame.destroy()
            self.properties_frame = None
            self.widgets = {}

    def create_properties_widget(self, parent):
        self.destroy_properties_widget()
        if self.selected:
            obs_type = type(self.selected)
            if obs_type == BasicObstacle:
                possible_options = ["x", "y", "width", "height", "identifier"]
            elif obs_type == Trigger:
                possible_options = [
                    "x", "y", "width", "height", "deactivate_after_use",
                    "active", "identifier", "trigger"
                ]
            elif obs_type == Obstacle:
                possible_options = [
                    "x", "y", "identifier", "action", "after_looting", "items",
                    "animation", "label", "onclick"
                ]
            elif obs_type == Character:
                possible_options = [
                    "x", "y", "dead", "weapon", "label", "identifier",
                    "aggression_distance", "direction", "health",
                    "random_walk_area", "waypoints", "ondeath"
                ]
            elif obs_type == Item:
                possible_options = [
                    "x", "y", "label", "identifier", "onpickup"
                ]
            self.properties_frame = ttk.Frame(parent)
            self.widgets = {}
            for index, option in enumerate(possible_options):
                if option in [
                        "x", "y", "width", "height", "aggression_distance",
                        "health"
                ]:
                    if option in ["x", "width"]:
                        self.widgets[option] = tk.Spinbox(
                            self.properties_frame,
                            from_=0,
                            to=self.mapsize[0],
                            increment=0.1)
                    elif option in ["y", "height"]:
                        self.widgets[option] = tk.Spinbox(
                            self.properties_frame,
                            from_=0,
                            to=self.mapsize[1],
                            increment=0.1)
                    elif option == "aggression_distance":
                        self.widgets[option] = tk.Spinbox(
                            self.properties_frame,
                            from_=0,
                            to=self.map_diam,
                            increment=0.1)
                    elif option == "health":
                        self.widgets[option] = tk.Spinbox(
                            self.properties_frame, from_=0, to=1000)
                    self.set_entry_value(self.widgets[option],
                                         getattr(self.selected, option))
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                elif option in [
                        "action", "weapon", "label", "identifier", "direction",
                        "animation", "after_looting", "items"
                ]:
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    attr = getattr(self.selected, option)
                    if option == "items" and attr is not None:
                        attr = ";".join(attr)
                    if attr is None:
                        attr = ""
                    self.set_entry_value(self.widgets[option], attr)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                elif option in ["active", "deactivate_after_use", "dead"]:
                    variable = tk.IntVar()
                    variable.set(int(getattr(self.selected, option)))
                    self.widgets[option] = {
                        "widget":
                        ttk.Checkbutton(self.properties_frame,
                                        text=option,
                                        variable=variable),
                        "variable":
                        variable
                    }
                    self.widgets[option]["widget"].grid(row=index,
                                                        column=1,
                                                        sticky="w")
                elif option in ["onclick", "trigger", "ondeath", "onpickup"]:
                    self.widgets[option] = [
                        ttk.Combobox(self.properties_frame,
                                     values=("REPLACE", "DELETE", "ADD",
                                             "KILL", "KILLALL", "SPAWN",
                                             "OPEN", "CLOSE", "DEACTIVATE",
                                             "ACTIVATE", "WINGAME",
                                             "TRYWINGAME", "CHANGEMAP",
                                             "TRYCHANGEMAP")),
                        ttk.Combobox(self.properties_frame,
                                     values=("obstacle", "character", "item",
                                             "trigger")),
                        ttk.Entry(self.properties_frame),
                        ttk.Entry(self.properties_frame),
                        ttk.Entry(self.properties_frame)
                    ]
                    for widget_index, widget in enumerate(
                            self.widgets[option]):
                        try:
                            if type(widget) == ttk.Combobox:
                                widget.set(
                                    getattr(self.selected,
                                            option)[widget_index])
                            else:
                                self.set_entry_value(
                                    widget,
                                    getattr(self.selected,
                                            option)[widget_index])
                        except:
                            pass
                        widget.grid(row=index + widget_index,
                                    column=1,
                                    sticky="w")
                elif option == "waypoints":
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                    self.set_entry_value(
                        self.widgets[option],
                        ";".join(",".join([str(y) for y in x])
                                 for x in getattr(self.selected, option)))
                elif option == "random_walk_area":
                    self.widgets[option] = ttk.Entry(self.properties_frame)
                    self.widgets[option].grid(row=index, column=1, sticky="w")
                    self.set_entry_value(
                        self.widgets[option], ";".join(
                            str(x) for x in getattr(self.selected, option)))
                if option not in ["deactivate_after_use", "dead", "active"]:
                    ttk.Label(self.properties_frame,
                              text=option).grid(row=index,
                                                column=0,
                                                sticky="w")
            self.properties_frame.grid(row=1, column=0, sticky="nswe")

    def mousedrag(self, mouse_pos, pos_change):
        if self.selected:
            self.set_attributes(x=self.selected.x + pos_change[0],
                                y=self.selected.y + pos_change[1])
        self.refresh_realrect_quadtree()
        self.refresh_floor_quadtree()

    def delete(self, *args):
        if self.selected:
            if type(self.selected) == Character:
                self.charactermap.remove(self.selected)
            elif type(self.selected) == Obstacle:
                try:
                    self.layers[0].remove(self.selected)
                except:
                    self.layers[1].remove(self.selected)
            elif type(self.selected) == Item:
                self.item_map.remove(self.selected)
            elif type(self.selected) == BasicObstacle:
                self.rect_obstacles.remove(self.selected)
            elif type(self.selected) == Trigger:
                self.triggers.remove(self.selected)
            self.selected = None
            self.refresh_floor_quadtree()
            self.refresh_realrect_quadtree()

    def set_attributes(self, **kwargs):
        if self.selected:
            if self.properties_frame:
                final_dict = {}
                for key, item in self.widgets.items():
                    if type(item) == dict:
                        value = bool(item["variable"].get())
                    elif type(item) == list:
                        value = []
                        for part in item:
                            temp_val = part.get()
                            if temp_val:
                                value.append(temp_val)
                    else:
                        value = item.get()
                        try:
                            if key in ["after_looting", "health"]:
                                value = int(value)
                            elif key in ["x", "y", "width", "height"]:
                                value = float(value)
                        except:
                            pass
                    if key in [
                            "x", "y", "width", "height", "aggression_distance"
                    ]:
                        try:
                            final_dict[key] = float(value)
                        except:
                            pass
                    elif key == "direction":
                        if value in [
                                "NW", "N", "NE", "E", "W", "SW", "SE", "S"
                        ]:
                            final_dict[key] = value
                    elif key == "items":
                        if value:
                            value = [x.strip() for x in value.split(";")]
                            final_dict[key] = value
                    elif key == "waypoints":
                        try:
                            if value:
                                value = [[float(y) for y in x.split(",")]
                                         for x in value.split(";")]
                            for x in value:
                                if len(x) < 2:
                                    break
                            else:
                                final_dict[key] = value
                        except:
                            pass
                    elif key == "random_walk_area":
                        try:
                            if value:
                                value = [float(x) for x in value.split(";")]
                            if len(value) == 4 or not value:
                                final_dict[key] = value
                        except:
                            pass
                    else:
                        final_dict[key] = value
                final_dict.update(kwargs)
                self.selected.set_values(**final_dict)
                for key, item in kwargs.items():
                    if key in ["x", "y"]:
                        self.set_entry_value(self.widgets[key], item)

    def draw_cursor(self, tile_pos, current_obs, current_item, current_char,
                    current_tab, screen_offset):
        if current_tab == "Obstacles":
            temp = self.create_obstacle(type=current_obs,
                                        x=tile_pos[0],
                                        y=tile_pos[1])
        elif current_tab == "Items":
            temp = self.create_item({
                "type": current_item,
                "x": tile_pos[0],
                "y": tile_pos[1]
            })
        elif current_tab == "Characters":
            temp = self.create_character({
                "name": current_char,
                "x": tile_pos[0],
                "y": tile_pos[1]
            })
        elif current_tab == "Triggers":
            temp = Trigger(self.screen, x=tile_pos[0], y=tile_pos[1])
        temp.draw(screen_offset)

    def draw(self, screen_offset):
        self.set_attributes()
        final = sorted(self.layers[1] + self.charactermap,
                       key=lambda x: (x.x, x.y))
        ground = sorted(self.layers[0] + self.triggers + self.rect_obstacles +
                        self.item_map,
                        key=lambda x: (x.x, x.y))
        for ground_obs in ground:
            ground_obs.draw(screen_offset)
        for thing in final:
            thing.draw(screen_offset)