Source code for BaseMod.effects.effectHistory

from copy import deepcopy

import numpy as np
from PySide6.QtCore import QPoint, QLineF, QRect

from RWS.Modify import HistoryElement
from RWS.Loaders import Effect
from RWS.Utils import draw_line


[docs] def copy_effect(effect): return deepcopy(effect) # i should come up with better solution at sometime
[docs] class EffectBrush(HistoryElement):
[docs] def __init__(self, history, index, start: QPoint, size: int, remove: bool, ultra: bool): super().__init__(history) self.changes = {} self.start = start self.size = size self.remove = remove self.ultra = ultra # kill self.effect = history.level.manager.effects.find_effect(self.history.level.l_effects[index]["nm"]) self.index = index self.lastpos = start self.paintapoint(start) self.redraw()
[docs] def redraw(self): self.history.level.manager.basemod.effecteditor.elayer.redraw()
[docs] def add_move(self, position): points = [] draw_line(self.lastpos, position, lambda p: points.append(p)) points.pop(0) for point in points: self.paintapoint(point) self.lastpos = position self.redraw()
[docs] def paintapoint(self, point): strength = 10 + (90 if self.ultra else 0) if self.effect.ultrablack: strength = 10000 rect = QRect(point - QPoint(self.size, self.size), point + QPoint(self.size, self.size)) for xp in range(rect.x(), rect.topRight().x()): for yp in range(rect.y(), rect.bottomLeft().y()): newpoint = QPoint(xp, yp) if not self.history.level.inside(newpoint): continue cellval = int(self.history.level.l_effects[self.index, xp, yp]) val = cellval dist = self.size - QLineF(newpoint, point).length() if dist > 0: val = round(min(max(val + strength * dist * (-1 if self.remove else 1), 0), 100), 4) if val == cellval: continue if self.changes.get(newpoint): self.changes[newpoint] = [self.changes[newpoint][0], val] else: self.changes[newpoint] = [cellval, val] self.history.level.l_effects[self.index, xp, yp] = val self.history.level.manager.basemod.effecteditor.elayer.draw_pixel(newpoint, True)
[docs] def undo_changes(self): for point, v in self.changes.items(): before, _ = v self.history.level.l_effects[self.index, point.x(), point.y()] = before self.history.level.manager.basemod.effecteditor.elayer.draw_pixel(point, True) self.redraw()
[docs] def redo_changes(self): for point, v in self.changes.items(): _, after = v self.history.level.l_effects[self.index, point.x(), point.y()] = after self.history.level.manager.basemod.effecteditor.elayer.draw_pixel(point, True) self.redraw()
[docs] class EffectAdd(HistoryElement):
[docs] def __init__(self, history, effect: Effect): super().__init__(history) self.effect = effect self.add_effect()
[docs] def add_effect(self): self.level.l_effects.append(self.effect.todict(self.level.level_size_qsize)) self.basemod.effectui.add_effects() self.basemod.effecteditor.effectindex.update_value(len(self.level.l_effects) - 1)
[docs] def undo_changes(self): self.level.l_effects.pop() self.basemod.effectui.add_effects()
[docs] def redo_changes(self): self.add_effect()
[docs] class EffectRemove(HistoryElement):
[docs] def __init__(self, history, index): super().__init__(history) self.index = index self.savedeffect = self.history.level.l_effects.pop(index) self.remove_effect()
[docs] def remove_effect(self): self.basemod.effectui.add_effects() self.basemod.effecteditor.effectindex.update_value(max(0, self.index - 1))
[docs] def undo_changes(self): self.history.level.l_effects.insert(self.index, self.savedeffect) self.basemod.effectui.add_effects() self.basemod.effecteditor.effectindex.update_value(max(0, self.index))
[docs] def redo_changes(self): self.history.level.l_effects.pop(self.index) self.remove_effect()
[docs] class EffectOptionChange(HistoryElement):
[docs] def __init__(self, history, index, option, value): super().__init__(history) self.prevvalue = history.level.l_effects[index]["options"][option][2] self.index = index self.option = option self.value = value self.redo_changes()
[docs] def undo_changes(self): self.level.l_effects[self.index]["options"][self.option][2] = self.prevvalue self.basemod.effectui.effect_settings()
[docs] def redo_changes(self): self.level.l_effects[self.index]["options"][self.option][2] = self.value self.basemod.effectui.effect_settings()
[docs] class EffectMove(HistoryElement):
[docs] def __init__(self, history, index, dir): super().__init__(history) self.index = index self.newindex = index + dir self.redo_changes()
[docs] def redo_changes(self): self.level.l_effects.insert(self.newindex, self.level.l_effects.pop(self.index)) self.basemod.effectui.add_effects() self.basemod.effecteditor.effectindex.update_value(self.newindex)
[docs] def undo_changes(self): self.level.l_effects.insert(self.index, self.level.l_effects.pop(self.newindex)) self.basemod.effectui.add_effects() self.basemod.effecteditor.effectindex.update_value(self.index)
[docs] class EffectDuplicate(HistoryElement):
[docs] def __init__(self, history, index): super().__init__(history) self.index = index self.duplicate = deepcopy(self.level.l_effects[index]) self.redo_changes()
[docs] def redo_changes(self): self.level.l_effects.insert(self.index+1, self.duplicate) self.basemod.effectui.add_effects() self.basemod.effecteditor.effectindex.update_value(self.index+1)
[docs] def undo_changes(self): self.level.l_effects.pop(self.index+1) self.basemod.effectui.add_effects() self.basemod.effecteditor.effectindex.update_value(self.index)
[docs] class LevelResizedEffects(HistoryElement):
[docs] def __init__(self, history, newrect): super().__init__(history) self.newrect = newrect self.preveffects = [] self.redo_changes()
[docs] def undo_changes(self): for i, v in enumerate(self.level.l_effects.effects): v["mtrx"] = np.copy(self.preveffects[i])
[docs] def redo_changes(self): for i, v in enumerate(self.level.l_effects.effects): newshape = np.zeros((self.newrect.width(), self.newrect.height()), np.float16) self.preveffects.append(np.copy(v["mtrx"])) with np.nditer(newshape, flags=['multi_index'], op_flags=['writeonly']) as it: for x in it: if it.multi_index[0] < -self.newrect.x() or it.multi_index[1] < -self.newrect.y(): x[...] = 0 continue newpoints = [it.multi_index[0] + self.newrect.x(), it.multi_index[1] + self.newrect.y()] if newpoints[0] >= v["mtrx"].shape[0] or newpoints[1] >= v["mtrx"].shape[1]: x[...] = 0 continue x[...] = v["mtrx"][newpoints[0], newpoints[1]] v["mtrx"] = newshape