# HG changeset patch # User Neil Muller # Date 1378481545 -7200 # Node ID 9589e1db443330f2e9329ddaa25fdb8e52a8678e # Parent 55752fc7b75378b327284b5fe25cf92aa017bf83 Allow copying polygon 6 into terrain objects diff -r 55752fc7b753 -r 9589e1db4433 tools/area_editor.py --- a/tools/area_editor.py Fri Sep 06 17:29:50 2013 +0200 +++ b/tools/area_editor.py Fri Sep 06 17:32:25 2013 +0200 @@ -49,10 +49,17 @@ MENU_BUTTON_HEIGHT // 2) +class TestWorld(object): + + def __init__(self): + self.level_state = {} + + class EditorLevel(Level): def __init__(self, name, x=800, y=600): - super(EditorLevel, self).__init__(name, None) + world = TestWorld() + super(EditorLevel, self).__init__(name, world) self.x = x self.y = y # Lookup initiliasition info from the objects @@ -262,10 +269,12 @@ class EditClassDialog(Dialog): - def __init__(self, classname, cls, data, delete=False): + def __init__(self, classname, cls, data, level_widget, + delete=False): super(EditClassDialog, self).__init__() + self.level_widget = level_widget self.classname = classname - self.rect = pygame.rect.Rect(0, 0, 800, 550) + self.rect = pygame.rect.Rect(0, 0, 900, 550) title = Label("Editing %s" % classname) title.rect = pygame.rect.Rect(100, 10, 600, 25) self.add(title) @@ -273,6 +282,8 @@ y = 40 self.fields = {} index = 0 + self.poly_field = None + self.needs_cleanup = False for requirement, hint in self.requires: label = Label(requirement) label.rect = pygame.rect.Rect(40, y, 200, 25) @@ -292,11 +303,18 @@ except IndexError: # Assumed to be arguments with the default value pass + if hint.startswith('polygon'): + self.poly_field = field self.fields[requirement] = field hintlabel = Label(hint) - hintlabel.rect = pygame.rect.Rect(640, y, 100, 25) + hintlabel.rect = pygame.rect.Rect(640, y, 250, 25) self.add(hintlabel) y += 30 + if self.poly_field: + y += 20 + button = Button('Use Polygon 6', action=self.get_poly) + button.rect = pygame.rect.Rect(350, y, 250, 30) + self.add(button) buttons = [] if delete: labels = ['OK', 'Delete', 'Cancel'] @@ -309,6 +327,25 @@ row.rect = pygame.rect.Rect(250, 500, 700, 50) self.add(row) + def get_poly(self): + try: + data = self.level_widget.level.polygons[6][:] + except KeyError: + data = [] + if data: + # We unclose the polygon, because that's what pymunk + # wants + if data[0] == data[-1] and len(data) > 1: + data.pop() + data = [list(x) for x in data] + self.needs_cleanup = True + self.poly_field.set_text('%s' % data) + + def cleanup(self): + if self.needs_cleanup: + self.level_widget.level.polygons[6] = [] + self.level_widget.invalidate() + def get_data(self): result = {} result['classname'] = self.classname @@ -322,6 +359,22 @@ continue if val == 'name': result['name'] = text + elif self.fields[val] == self.poly_field and text: + # Evil, but faster than good + try: + l = eval(text) + args.append(' - - %s' % l[0]) + for coord in l[1:]: + args.append(' - %s' % coord) + except Exception: + alert("Invalid polygon %s" % text) + self.needs_cleanup = False + return None + # Check for convexity + hull = pymunk.util.convex_hull(l) + if hull != l: + alert("Invalid polygon %s - not convex" % text) + return None else: args.append(' - ' + text) data = "args:\n" + '\n'.join(args) @@ -504,24 +557,25 @@ def _edit_class(self, classname, cls, data): # Dialog for class properties - dialog = EditClassDialog(classname, cls, data) + dialog = EditClassDialog(classname, cls, data, self) if dialog.present() == 'OK': - return dialog.get_data() + return dialog return None def _edit_selected(self, obj): data = self.level.lookup[obj] cls = obj.__class__ classname = obj.__class__.__name__ - dialog = EditClassDialog(classname, cls, data, True) + dialog = EditClassDialog(classname, cls, data, self, True) res = dialog.present() if res == 'OK': edited = dialog.get_data() if edited is not None: for target in [self.level._game_objects, self.level._enemies]: if data in target: - self.level.try_new_object(classname, target, - edited, data) + if self.level.try_new_object(classname, target, + edited, data): + dialog.cleanup() break elif res == 'Delete': for target in [self.level._game_objects, self.level._enemies]: @@ -554,11 +608,13 @@ return if res == 'OK': cls = self.level.get_class(choice['classname']) - edited = self._edit_class(choice['classname'], cls, choice) - if edited is not None: - self.level.try_new_object(choice["classname"], - self.level._game_objects, - edited, choice) + edit_dlg = self._edit_class(choice['classname'], cls, choice) + if edit_dlg is not None: + edited = edit_dlg.get_data() + if self.level.try_new_object(choice["classname"], + self.level._game_objects, + edited, choice): + edit_dlg.cleanup() elif res == 'Delete': self.level._game_objects.remove(choice) self.level.reset_objs() @@ -571,10 +627,13 @@ return if res == 'OK': cls = self.level.get_class(choice['classname'], ne) - edited = self._edit_class(choice['classname'], cls, choice) - if edited is not None: - self.level.try_new_object(choice["classname"], - self.level._enemies, edited, choice) + edit_dlg = self._edit_class(choice['classname'], cls, choice) + if edit_dlg is not None: + edited = edit_dlg.get_data() + if self.level.try_new_object(choice["classname"], + self.level._enemies, + edited, choice): + edit_dlg.cleanup() elif res == 'Delete': self.level._enemies.remove(choice) self.level.reset_objs() @@ -606,10 +665,13 @@ if res == 'OK' and choice is not None: classname = choice['classname'] cls = choice['class'] - new_cls = self._edit_class(classname, cls, None) - if new_cls is not None: - self.level.try_new_object(classname, self.level._game_objects, - new_cls, None) + edit_dlg = self._edit_class(classname, cls, None) + if edit_dlg is not None: + new_cls = edit_dlg.get_data() + if self.level.try_new_object(classname, + self.level._game_objects, + new_cls, None): + edit_dlg.cleanup() def add_enemy(self): classes = ne.get_editable_enemies() @@ -619,10 +681,12 @@ if res == 'OK' and choice is not None: classname = choice['classname'] cls = choice['class'] - new_cls = self._edit_class(classname, cls, None) - if new_cls is not None: - self.level.try_new_object(classname, self.level._enemies, - new_cls, None) + edit_dlg = self._edit_class(classname, cls, None) + if edit_dlg is not None: + new_cls = edit_dlg.get_data() + if self.level.try_new_object(classname, self.level._enemies, + new_cls, None): + edit_dlg.cleanup() def add_puzzler(self): classes = np.get_editable_puzzlers() @@ -632,10 +696,13 @@ if res == 'OK' and choice is not None: classname = choice['classname'] cls = choice['class'] - new_cls = self._edit_class(classname, cls, None) - if new_cls is not None: - self.level.try_new_object(classname, self.level._game_objects, - new_cls, None) + edit_dlg = self._edit_class(classname, cls, None) + if edit_dlg is not None: + new_cls = edit_dlg.get_data() + if self.level.try_new_object(classname, + self.level._game_objects, + new_cls, None): + edit_dlg.cleanup() class HighLightButton(Button):