From 8dc05bd26ad7f7e8f00f2a0e476ba775cda16b3d Mon Sep 17 00:00:00 2001 From: Zukero Date: Mon, 28 Aug 2017 01:05:19 +0200 Subject: [PATCH] Updated UI and model to support Actor Condition Immunity. Overall, a much better UI to tune Actor Condition-based effects on Dialogues, Items and NPCs. --- .../model/gamedata/ActorCondition.java | 5 +- .../model/gamedata/Dialogue.java | 2 + .../ui/gamedataeditors/DialogueEditor.java | 55 ++- .../ui/gamedataeditors/ItemEditor.java | 423 ++++++++++++++---- .../ui/gamedataeditors/NPCEditor.java | 271 ++++++++++- 5 files changed, 643 insertions(+), 113 deletions(-) diff --git a/src/com/gpl/rpg/atcontentstudio/model/gamedata/ActorCondition.java b/src/com/gpl/rpg/atcontentstudio/model/gamedata/ActorCondition.java index 12f4596..6b69fed 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/gamedata/ActorCondition.java +++ b/src/com/gpl/rpg/atcontentstudio/model/gamedata/ActorCondition.java @@ -21,8 +21,9 @@ public class ActorCondition extends JSONElement { private static final long serialVersionUID = -3969824899972048507L; - public static final Integer CLEAR_AC_MAGNITUDE = -99; - public static final Integer FOREVER_DURATION = 999; + public static final Integer MAGNITUDE_CLEAR = -99; + public static final Integer DURATION_FOREVER = 999;; + public static final Integer DURATION_NONE = 0; // Available from init state //public String id; inherited. diff --git a/src/com/gpl/rpg/atcontentstudio/model/gamedata/Dialogue.java b/src/com/gpl/rpg/atcontentstudio/model/gamedata/Dialogue.java index d28c4e2..2cc77c7 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/gamedata/Dialogue.java +++ b/src/com/gpl/rpg/atcontentstudio/model/gamedata/Dialogue.java @@ -58,6 +58,7 @@ public class Dialogue extends JSONElement { dropList, skillIncrease, actorCondition, + actorConditionImmunity, alignmentChange, giveItem, createTimer, @@ -250,6 +251,7 @@ public class Dialogue extends JSONElement { reward.map = reward.map_name != null ? proj.getMap(reward.map_name) : null; break; case actorCondition: + case actorConditionImmunity: reward.reward_obj = proj.getActorCondition(reward.reward_obj_id); break; case alignmentChange: diff --git a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/DialogueEditor.java b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/DialogueEditor.java index 2b90313..060dbaf 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/DialogueEditor.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/DialogueEditor.java @@ -100,6 +100,7 @@ public class DialogueEditor extends JSONElementEditor { private JComponent rewardValue; private JRadioButton rewardConditionTimed; private JRadioButton rewardConditionForever; + private JRadioButton rewardConditionClear; private RepliesListModel repliesListModel; @SuppressWarnings("rawtypes") @@ -362,6 +363,7 @@ public class DialogueEditor extends JSONElementEditor { if (rewardObj != null) { removeElementListener(rewardObj); } + boolean immunity = false; if (reward.type != null) { switch (reward.type) { case activateMapObjectGroup: @@ -388,6 +390,8 @@ public class DialogueEditor extends JSONElementEditor { rewardObj = null; rewardValue = null; break; + case actorConditionImmunity: + immunity = true; case actorCondition: rewardMap = null; @@ -399,13 +403,25 @@ public class DialogueEditor extends JSONElementEditor { rewardValue = addIntegerField(pane, "Duration: ", reward.reward_value, false, writable, listener); rewardConditionForever = new JRadioButton("Forever"); pane.add(rewardConditionForever, JideBoxLayout.FIX); - + if (!immunity) { + rewardConditionClear = new JRadioButton("Clear actor condition"); + pane.add(rewardConditionClear, JideBoxLayout.FIX); + } + ButtonGroup radioGroup = new ButtonGroup(); radioGroup.add(rewardConditionTimed); radioGroup.add(rewardConditionForever); + if (!immunity) radioGroup.add(rewardConditionClear); - rewardConditionTimed.setSelected(reward.reward_value == null || reward.reward_value != ActorCondition.FOREVER_DURATION); - rewardConditionForever.setSelected(!rewardConditionTimed.isSelected()); + if (immunity) { + rewardConditionTimed.setSelected(reward.reward_value == null || (reward.reward_value != ActorCondition.DURATION_FOREVER && reward.reward_value != ActorCondition.MAGNITUDE_CLEAR)); + rewardConditionForever.setSelected(reward.reward_value != null && reward.reward_value != ActorCondition.DURATION_FOREVER); + rewardConditionClear.setSelected(reward.reward_value != null && reward.reward_value != ActorCondition.MAGNITUDE_CLEAR); + } else { + rewardConditionTimed.setSelected(reward.reward_value != null && reward.reward_value != ActorCondition.DURATION_FOREVER); + rewardConditionForever.setSelected(reward.reward_value == null || reward.reward_value == ActorCondition.DURATION_FOREVER); + } + rewardValue.setEnabled(rewardConditionTimed.isSelected()); rewardConditionTimed.addActionListener(new ActionListener() { @Override @@ -419,7 +435,14 @@ public class DialogueEditor extends JSONElementEditor { listener.valueChanged(rewardConditionForever, new Boolean(rewardConditionForever.isSelected())); } }); - + if (!immunity) { + rewardConditionClear.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(rewardConditionClear, new Boolean(rewardConditionClear.isSelected())); + } + }); + } break; case alignmentChange: rewardMap = null; @@ -843,8 +866,18 @@ public class DialogueEditor extends JSONElementEditor { label.setIcon(new ImageIcon(DefaultIcons.getObjectLayerIcon())); break; case actorCondition: - boolean rewardForever = reward.reward_value != null && reward.reward_value == ActorCondition.FOREVER_DURATION; - label.setText("Give actor condition "+rewardObjDesc+(rewardForever ? " forever" : " for "+reward.reward_value+" turns")); + boolean rewardClear = reward.reward_value != null && reward.reward_value.intValue() == ActorCondition.MAGNITUDE_CLEAR; + if (rewardClear) { + label.setText("Clear actor condition "+rewardObjDesc); + } else { + boolean rewardForever = reward.reward_value != null && reward.reward_value.intValue() == ActorCondition.DURATION_FOREVER; + label.setText("Give actor condition "+rewardObjDesc+(rewardForever ? " forever" : " for "+reward.reward_value+" turns")); + } + if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon())); + break; + case actorConditionImmunity: + boolean rewardForever = reward.reward_value == null || reward.reward_value.intValue() == ActorCondition.DURATION_FOREVER; + label.setText("Give immunity to actor condition "+rewardObjDesc+(rewardForever ? " forever" : " for "+reward.reward_value+" turns")); if (reward.reward_obj != null) label.setIcon(new ImageIcon(reward.reward_obj.getIcon())); break; case alignmentChange: @@ -1231,11 +1264,15 @@ public class DialogueEditor extends JSONElementEditor { if (stage != null) stage.addBacklink(dialogue); } rewardsListModel.itemChanged(selectedReward); - } else if (source == rewardConditionForever) { - selectedReward.reward_value = ActorCondition.FOREVER_DURATION; + } else if (source == rewardConditionClear) { + selectedReward.reward_value = ActorCondition.MAGNITUDE_CLEAR; rewardValue.setEnabled(false); rewardsListModel.itemChanged(selectedReward); - } else if (source == rewardConditionTimed) { + } else if (source == rewardConditionForever) { + selectedReward.reward_value = ActorCondition.DURATION_FOREVER; + rewardValue.setEnabled(false); + rewardsListModel.itemChanged(selectedReward); + } else if (source == rewardConditionTimed) { selectedReward.reward_value = (Integer) ((JSpinner)rewardValue).getValue(); rewardValue.setEnabled(true); rewardsListModel.itemChanged(selectedReward); diff --git a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/ItemEditor.java b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/ItemEditor.java index f959c89..5672a59 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/ItemEditor.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/ItemEditor.java @@ -88,6 +88,8 @@ public class ItemEditor extends JSONElementEditor { @SuppressWarnings("rawtypes") private JList equipConditionsList; private MyComboBox equipConditionBox; + private JRadioButton equipConditionWithMagnitude; + private JRadioButton equipConditionImmunity; private JSpinner equipConditionMagnitude; private CollapsiblePanel hitEffectPane; @@ -100,20 +102,26 @@ public class ItemEditor extends JSONElementEditor { @SuppressWarnings("rawtypes") private JList hitSourceConditionsList; private MyComboBox hitSourceConditionBox; + private JSpinner hitSourceConditionChance; private JRadioButton hitSourceConditionClear; private JRadioButton hitSourceConditionApply; + private JRadioButton hitSourceConditionImmunity; private JSpinner hitSourceConditionMagnitude; + private JRadioButton hitSourceConditionTimed; + private JRadioButton hitSourceConditionForever; private JSpinner hitSourceConditionDuration; - private JSpinner hitSourceConditionChance; private TargetTimedConditionsListModel hitTargetConditionsModel; @SuppressWarnings("rawtypes") private JList hitTargetConditionsList; private MyComboBox hitTargetConditionBox; + private JSpinner hitTargetConditionChance; private JRadioButton hitTargetConditionClear; private JRadioButton hitTargetConditionApply; + private JRadioButton hitTargetConditionImmunity; private JSpinner hitTargetConditionMagnitude; + private JRadioButton hitTargetConditionTimed; + private JRadioButton hitTargetConditionForever; private JSpinner hitTargetConditionDuration; - private JSpinner hitTargetConditionChance; private CollapsiblePanel killEffectPane; private Item.KillEffect killEffect; @@ -125,11 +133,14 @@ public class ItemEditor extends JSONElementEditor { @SuppressWarnings("rawtypes") private JList killSourceConditionsList; private MyComboBox killSourceConditionBox; + private JSpinner killSourceConditionChance; private JRadioButton killSourceConditionClear; private JRadioButton killSourceConditionApply; + private JRadioButton killSourceConditionImmunity; private JSpinner killSourceConditionMagnitude; + private JRadioButton killSourceConditionTimed; + private JRadioButton killSourceConditionForever; private JSpinner killSourceConditionDuration; - private JSpinner killSourceConditionChance; public ItemEditor(Item item) { @@ -485,28 +496,31 @@ public class ItemEditor extends JSONElementEditor { hitSourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); hitSourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); - hitSourceConditionApply = new JRadioButton("Apply new condition"); - pane.add(hitSourceConditionApply, JideBoxLayout.FIX); - hitSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); - hitSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener); + hitSourceConditionClear = new JRadioButton("Clear active condition"); pane.add(hitSourceConditionClear, JideBoxLayout.FIX); + hitSourceConditionApply = new JRadioButton("Apply condition with magnitude"); + pane.add(hitSourceConditionApply, JideBoxLayout.FIX); + hitSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); + hitSourceConditionImmunity = new JRadioButton("Give immunity to condition"); + pane.add(hitSourceConditionImmunity, JideBoxLayout.FIX); - ButtonGroup radioGroup = new ButtonGroup(); - radioGroup.add(hitSourceConditionApply); - radioGroup.add(hitSourceConditionClear); + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(hitSourceConditionApply); + radioEffectGroup.add(hitSourceConditionClear); + radioEffectGroup.add(hitSourceConditionImmunity); - if (condition != null && condition.magnitude != null && condition.magnitude == ActorCondition.CLEAR_AC_MAGNITUDE) { - hitSourceConditionClear.setSelected(true); - hitSourceConditionApply.setSelected(false); - hitSourceConditionMagnitude.setEnabled(false); - hitSourceConditionDuration.setEnabled(false); - } else { - hitSourceConditionClear.setSelected(false); - hitSourceConditionApply.setSelected(true); - hitSourceConditionMagnitude.setEnabled(true); - hitSourceConditionDuration.setEnabled(true); - } + hitSourceConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(hitSourceConditionTimed, JideBoxLayout.FIX); + hitSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener); + hitSourceConditionForever = new JRadioButton("Forever"); + pane.add(hitSourceConditionForever, JideBoxLayout.FIX); + + ButtonGroup radioDurationGroup = new ButtonGroup(); + radioDurationGroup.add(hitSourceConditionTimed); + radioDurationGroup.add(hitSourceConditionForever); + + updateHitSourceTimedConditionWidgets(condition); hitSourceConditionClear.addActionListener(new ActionListener() { @Override @@ -520,10 +534,47 @@ public class ItemEditor extends JSONElementEditor { listener.valueChanged(hitSourceConditionApply, new Boolean(hitSourceConditionApply.isSelected())); } }); + hitSourceConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitSourceConditionImmunity, new Boolean(hitSourceConditionImmunity.isSelected())); + } + }); + + hitSourceConditionTimed.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitSourceConditionTimed, new Boolean(hitSourceConditionTimed.isSelected())); + } + }); + hitSourceConditionForever.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitSourceConditionForever, new Boolean(hitSourceConditionForever.isSelected())); + } + }); pane.revalidate(); pane.repaint(); } + + public void updateHitSourceTimedConditionWidgets(Item.TimedConditionEffect condition) { + + boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); + boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); + boolean forever = condition.duration != null && condition.duration == ActorCondition.DURATION_FOREVER; + + hitSourceConditionClear.setSelected(clear); + hitSourceConditionApply.setSelected(!clear && !immunity); + hitSourceConditionMagnitude.setEnabled(!clear && !immunity); + hitSourceConditionImmunity.setSelected(immunity); + + hitSourceConditionTimed.setSelected(!forever); + hitSourceConditionTimed.setEnabled(!clear); + hitSourceConditionDuration.setEnabled(!clear && !forever); + hitSourceConditionForever.setSelected(forever); + hitSourceConditionForever.setEnabled(!clear); + } public void updateHitTargetTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) { pane.removeAll(); @@ -541,28 +592,31 @@ public class ItemEditor extends JSONElementEditor { hitTargetConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); hitTargetConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); - hitTargetConditionApply = new JRadioButton("Apply new condition"); - pane.add(hitTargetConditionApply, JideBoxLayout.FIX); - hitTargetConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); - hitTargetConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener); + hitTargetConditionClear = new JRadioButton("Clear active condition"); pane.add(hitTargetConditionClear, JideBoxLayout.FIX); + hitTargetConditionApply = new JRadioButton("Apply condition with magnitude"); + pane.add(hitTargetConditionApply, JideBoxLayout.FIX); + hitTargetConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); + hitTargetConditionImmunity = new JRadioButton("Give immunity to condition"); + pane.add(hitTargetConditionImmunity, JideBoxLayout.FIX); - ButtonGroup radioGroup = new ButtonGroup(); - radioGroup.add(hitTargetConditionApply); - radioGroup.add(hitTargetConditionClear); + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(hitTargetConditionApply); + radioEffectGroup.add(hitTargetConditionClear); + radioEffectGroup.add(hitTargetConditionImmunity); - if (condition != null && condition.magnitude != null && condition.magnitude == ActorCondition.CLEAR_AC_MAGNITUDE) { - hitTargetConditionClear.setSelected(true); - hitTargetConditionApply.setSelected(false); - hitTargetConditionMagnitude.setEnabled(false); - hitTargetConditionDuration.setEnabled(false); - } else { - hitTargetConditionClear.setSelected(false); - hitTargetConditionApply.setSelected(true); - hitTargetConditionMagnitude.setEnabled(true); - hitTargetConditionDuration.setEnabled(true); - } + hitTargetConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(hitTargetConditionTimed, JideBoxLayout.FIX); + hitTargetConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener); + hitTargetConditionForever = new JRadioButton("Forever"); + pane.add(hitTargetConditionForever, JideBoxLayout.FIX); + + ButtonGroup radioDurationGroup = new ButtonGroup(); + radioDurationGroup.add(hitTargetConditionTimed); + radioDurationGroup.add(hitTargetConditionForever); + + updateHitTargetTimedConditionWidgets(condition); hitTargetConditionClear.addActionListener(new ActionListener() { @Override @@ -576,11 +630,48 @@ public class ItemEditor extends JSONElementEditor { listener.valueChanged(hitTargetConditionApply, new Boolean(hitTargetConditionApply.isSelected())); } }); + hitTargetConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitTargetConditionImmunity, new Boolean(hitTargetConditionImmunity.isSelected())); + } + }); + + hitTargetConditionTimed.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitTargetConditionTimed, new Boolean(hitTargetConditionTimed.isSelected())); + } + }); + hitTargetConditionForever.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitTargetConditionForever, new Boolean(hitTargetConditionForever.isSelected())); + } + }); pane.revalidate(); pane.repaint(); } + public void updateHitTargetTimedConditionWidgets(Item.TimedConditionEffect condition) { + + boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); + boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); + boolean forever = condition.duration != null && condition.duration == ActorCondition.DURATION_FOREVER; + + hitTargetConditionClear.setSelected(clear); + hitTargetConditionApply.setSelected(!clear && !immunity); + hitTargetConditionMagnitude.setEnabled(!clear && !immunity); + hitTargetConditionImmunity.setSelected(immunity); + + hitTargetConditionTimed.setSelected(!forever); + hitTargetConditionTimed.setEnabled(!clear); + hitTargetConditionDuration.setEnabled(!clear && !forever); + hitTargetConditionForever.setSelected(forever); + hitTargetConditionForever.setEnabled(!clear); + } + public void updateKillSourceTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) { pane.removeAll(); if (killSourceConditionBox != null) { @@ -597,28 +688,31 @@ public class ItemEditor extends JSONElementEditor { killSourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); killSourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); - killSourceConditionApply = new JRadioButton("Apply new condition"); - pane.add(killSourceConditionApply, JideBoxLayout.FIX); - killSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); - killSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener); + killSourceConditionClear = new JRadioButton("Clear active condition"); pane.add(killSourceConditionClear, JideBoxLayout.FIX); + killSourceConditionApply = new JRadioButton("Apply condition with magnitude"); + pane.add(killSourceConditionApply, JideBoxLayout.FIX); + killSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); + killSourceConditionImmunity = new JRadioButton("Give immunity to condition"); + pane.add(killSourceConditionImmunity, JideBoxLayout.FIX); - ButtonGroup radioGroup = new ButtonGroup(); - radioGroup.add(killSourceConditionApply); - radioGroup.add(killSourceConditionClear); + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(killSourceConditionApply); + radioEffectGroup.add(killSourceConditionClear); + radioEffectGroup.add(killSourceConditionImmunity); - if (condition != null && condition.magnitude != null && condition.magnitude == ActorCondition.CLEAR_AC_MAGNITUDE) { - killSourceConditionClear.setSelected(true); - killSourceConditionApply.setSelected(false); - killSourceConditionMagnitude.setEnabled(false); - killSourceConditionDuration.setEnabled(false); - } else { - killSourceConditionClear.setSelected(false); - killSourceConditionApply.setSelected(true); - killSourceConditionMagnitude.setEnabled(true); - killSourceConditionDuration.setEnabled(true); - } + killSourceConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(killSourceConditionTimed, JideBoxLayout.FIX); + killSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener); + killSourceConditionForever = new JRadioButton("Forever"); + pane.add(killSourceConditionForever, JideBoxLayout.FIX); + + ButtonGroup radioDurationGroup = new ButtonGroup(); + radioDurationGroup.add(killSourceConditionTimed); + radioDurationGroup.add(killSourceConditionForever); + + updateKillSourceTimedConditionWidgets(condition); killSourceConditionClear.addActionListener(new ActionListener() { @Override @@ -632,11 +726,49 @@ public class ItemEditor extends JSONElementEditor { listener.valueChanged(killSourceConditionApply, new Boolean(killSourceConditionApply.isSelected())); } }); + killSourceConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(killSourceConditionImmunity, new Boolean(killSourceConditionImmunity.isSelected())); + } + }); + + killSourceConditionTimed.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(killSourceConditionTimed, new Boolean(killSourceConditionTimed.isSelected())); + } + }); + killSourceConditionForever.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(killSourceConditionForever, new Boolean(killSourceConditionForever.isSelected())); + } + }); + pane.revalidate(); pane.repaint(); } - public void updateEquipConditionEditorPane(JPanel pane, Item.ConditionEffect condition, FieldUpdateListener listener) { + public void updateKillSourceTimedConditionWidgets(Item.TimedConditionEffect condition) { + + boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); + boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); + boolean forever = condition.duration != null && condition.duration == ActorCondition.DURATION_FOREVER; + + killSourceConditionClear.setSelected(clear); + killSourceConditionApply.setSelected(!clear && !immunity); + killSourceConditionMagnitude.setEnabled(!clear && !immunity); + killSourceConditionImmunity.setSelected(immunity); + + killSourceConditionTimed.setSelected(!forever); + killSourceConditionTimed.setEnabled(!clear); + killSourceConditionDuration.setEnabled(!clear && !forever); + killSourceConditionForever.setSelected(forever); + killSourceConditionForever.setEnabled(!clear); + } + + public void updateEquipConditionEditorPane(JPanel pane, Item.ConditionEffect condition, final FieldUpdateListener listener) { pane.removeAll(); if (equipConditionBox != null) { removeElementListener(equipConditionBox); @@ -651,7 +783,34 @@ public class ItemEditor extends JSONElementEditor { Project proj = ((Item)target).getProject(); equipConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); + equipConditionWithMagnitude = new JRadioButton("Apply condition with magnitude."); + pane.add(equipConditionWithMagnitude, JideBoxLayout.FIX); equipConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude, 1, false, writable, listener); + equipConditionImmunity = new JRadioButton("Give immunity to condition."); + pane.add(equipConditionImmunity, JideBoxLayout.FIX); + + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(equipConditionWithMagnitude); + radioEffectGroup.add(equipConditionImmunity); + + boolean immunity = condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR; + equipConditionImmunity.setSelected(immunity); + equipConditionWithMagnitude.setSelected(!immunity); + equipConditionMagnitude.setEnabled(!immunity); + + equipConditionWithMagnitude.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(equipConditionWithMagnitude, new Boolean(equipConditionWithMagnitude.isSelected())); + } + }); + equipConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(equipConditionImmunity, new Boolean(equipConditionImmunity.isSelected())); + } + }); + pane.revalidate(); pane.repaint(); @@ -793,10 +952,17 @@ public class ItemEditor extends JSONElementEditor { if (effect.condition != null) { label.setIcon(new ImageIcon(effect.condition.getIcon())); - if (effect.magnitude == ActorCondition.CLEAR_AC_MAGNITUDE) { - label.setText(effect.chance+"% chances to clear "+effect.condition.getDesc()); + + boolean immunity = (effect.magnitude == null || effect.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (effect.duration != null && effect.duration > ActorCondition.DURATION_NONE); + boolean clear = (effect.magnitude == null || effect.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (effect.duration == null || effect.duration == ActorCondition.DURATION_NONE); + boolean forever = effect.duration != null && effect.duration == ActorCondition.DURATION_FOREVER; + + if (clear) { + label.setText(effect.chance+"% chances to clear actor condition "+effect.condition.getDesc()); + } else if (immunity) { + label.setText(effect.chance+"% chances to give immunity to "+effect.condition.getDesc()+(forever ? " forever" : " for "+effect.duration+" rounds")); } else { - label.setText(effect.chance+"% chances to give "+effect.duration+" rounds of "+effect.condition.getDesc()+" x"+effect.magnitude); + label.setText(effect.chance+"% chances to give actor condition "+effect.condition.getDesc()+" x"+effect.magnitude+(forever ? " forever" : " for "+effect.duration+" rounds")); } } else { label.setText("New, undefined actor condition effect."); @@ -880,7 +1046,11 @@ public class ItemEditor extends JSONElementEditor { if (effect.condition != null) { label.setIcon(new ImageIcon(effect.condition.getIcon())); - label.setText("Applies "+effect.condition.getDesc()+" x"+effect.magnitude); + if (effect.magnitude == ActorCondition.MAGNITUDE_CLEAR) { + label.setText("Immune to actor condition "+effect.condition.getDesc()); + } else { + label.setText("Give actor condition "+effect.condition.getDesc()+" x"+effect.magnitude); + } } else { label.setText("New, undefined actor condition effect."); } @@ -1096,6 +1266,12 @@ public class ItemEditor extends JSONElementEditor { } else if (source == equipConditionMagnitude) { selectedEquipEffectCondition.magnitude = (Integer) value; equipConditionsModel.itemChanged(selectedEquipEffectCondition); + } else if (source == equipConditionImmunity && (Boolean) value) { + selectedEquipEffectCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + equipConditionMagnitude.setEnabled(false); + } else if (source == equipConditionWithMagnitude && (Boolean) value) { + selectedEquipEffectCondition.magnitude = (Integer) equipConditionMagnitude.getValue(); + equipConditionMagnitude.setEnabled(true); } else if (source == hitHPMin) { hitEffect.hp_boost_min = (Integer) value; updatePrice = true; @@ -1127,24 +1303,47 @@ public class ItemEditor extends JSONElementEditor { } hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition); updateHit = true; - } else if (source == hitSourceConditionClear) { - selectedHitEffectSourceCondition.magnitude = ActorCondition.CLEAR_AC_MAGNITUDE; + } else if (source == hitSourceConditionClear && (Boolean) value) { + selectedHitEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; selectedHitEffectSourceCondition.duration = null; - hitSourceConditionMagnitude.setEnabled(false); - hitSourceConditionDuration.setEnabled(false); + updateHitSourceTimedConditionWidgets(selectedHitEffectSourceCondition); hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition); updateHit = true; - } else if (source == hitSourceConditionApply) { - selectedHitEffectSourceCondition.magnitude = 0; - selectedHitEffectSourceCondition.duration = 0; - hitSourceConditionMagnitude.setEnabled(true); - hitSourceConditionDuration.setEnabled(true); + } else if (source == hitSourceConditionApply && (Boolean) value) { + selectedHitEffectSourceCondition.magnitude = (Integer) hitSourceConditionMagnitude.getValue(); + selectedHitEffectSourceCondition.duration = hitSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitSourceConditionDuration.getValue(); + if (selectedHitEffectSourceCondition.duration == null) { + selectedHitEffectSourceCondition.duration = 1; + } + updateHitSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition); + updateHit = true; + } else if (source == hitSourceConditionImmunity && (Boolean) value) { + selectedHitEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitEffectSourceCondition.duration = hitSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitSourceConditionDuration.getValue(); + if (selectedHitEffectSourceCondition.duration == null || selectedHitEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitEffectSourceCondition.duration = 1; + } + updateHitSourceTimedConditionWidgets(selectedHitEffectSourceCondition); hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition); updateHit = true; } else if (source == hitSourceConditionMagnitude) { selectedHitEffectSourceCondition.magnitude = (Integer) value; hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition); updateHit = true; + } else if (source == hitSourceConditionTimed && (Boolean) value) { + selectedHitEffectSourceCondition.duration = (Integer) hitSourceConditionDuration.getValue(); + if (selectedHitEffectSourceCondition.duration == null || selectedHitEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitEffectSourceCondition.duration = 1; + } + updateHitSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition); + updateHit = true; + } else if (source == hitSourceConditionForever && (Boolean) value) { + selectedHitEffectSourceCondition.duration = ActorCondition.DURATION_FOREVER; + updateHitSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition); + updateHit = true; } else if (source == hitSourceConditionDuration) { selectedHitEffectSourceCondition.duration = (Integer) value; hitSourceConditionsModel.itemChanged(selectedHitEffectSourceCondition); @@ -1168,24 +1367,47 @@ public class ItemEditor extends JSONElementEditor { } hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition); updateHit = true; - } else if (source == hitTargetConditionClear) { - selectedHitEffectTargetCondition.magnitude = ActorCondition.CLEAR_AC_MAGNITUDE; + } else if (source == hitTargetConditionClear && (Boolean) value) { + selectedHitEffectTargetCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; selectedHitEffectTargetCondition.duration = null; - hitTargetConditionMagnitude.setEnabled(false); - hitTargetConditionDuration.setEnabled(false); + updateHitTargetTimedConditionWidgets(selectedHitEffectTargetCondition); hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition); updateHit = true; - } else if (source == hitTargetConditionApply) { - selectedHitEffectTargetCondition.magnitude = 0; - selectedHitEffectTargetCondition.duration = 0; - hitTargetConditionMagnitude.setEnabled(true); - hitTargetConditionDuration.setEnabled(true); + } else if (source == hitTargetConditionApply && (Boolean) value) { + selectedHitEffectTargetCondition.magnitude = (Integer) hitTargetConditionMagnitude.getValue(); + selectedHitEffectTargetCondition.duration = hitTargetConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitTargetConditionDuration.getValue(); + if (selectedHitEffectTargetCondition.duration == null || selectedHitEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitEffectTargetCondition.duration = 1; + } + updateHitTargetTimedConditionWidgets(selectedHitEffectTargetCondition); + hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition); + updateHit = true; + } else if (source == hitTargetConditionImmunity && (Boolean) value) { + selectedHitEffectTargetCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitEffectTargetCondition.duration = hitTargetConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitTargetConditionDuration.getValue(); + if (selectedHitEffectTargetCondition.duration == null || selectedHitEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitEffectTargetCondition.duration = 1; + } + updateHitTargetTimedConditionWidgets(selectedHitEffectTargetCondition); hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition); updateHit = true; } else if (source == hitTargetConditionMagnitude) { selectedHitEffectTargetCondition.magnitude = (Integer) value; hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition); updateHit = true; + } else if (source == hitTargetConditionTimed && (Boolean) value) { + selectedHitEffectTargetCondition.duration = (Integer) hitTargetConditionDuration.getValue(); + if (selectedHitEffectTargetCondition.duration == null) { + selectedHitEffectTargetCondition.duration = 1; + } + updateHitTargetTimedConditionWidgets(selectedHitEffectTargetCondition); + hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition); + updateHit = true; + } else if (source == hitTargetConditionForever && (Boolean) value) { + selectedHitEffectTargetCondition.duration = ActorCondition.DURATION_FOREVER; + updateHitTargetTimedConditionWidgets(selectedHitEffectTargetCondition); + hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition); + updateHit = true; } else if (source == hitTargetConditionDuration) { selectedHitEffectTargetCondition.duration = (Integer) value; hitTargetConditionsModel.itemChanged(selectedHitEffectTargetCondition); @@ -1225,24 +1447,47 @@ public class ItemEditor extends JSONElementEditor { } killSourceConditionsModel.itemChanged(selectedKillEffectCondition); updateKill = true; - } else if (source == killSourceConditionClear) { - selectedKillEffectCondition.magnitude = ActorCondition.CLEAR_AC_MAGNITUDE; + } else if (source == killSourceConditionClear && (Boolean) value) { + selectedKillEffectCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; selectedKillEffectCondition.duration = null; - killSourceConditionMagnitude.setEnabled(false); - killSourceConditionDuration.setEnabled(false); + updateKillSourceTimedConditionWidgets(selectedKillEffectCondition); killSourceConditionsModel.itemChanged(selectedKillEffectCondition); updateKill = true; - } else if (source == killSourceConditionApply) { - selectedKillEffectCondition.magnitude = 0; - selectedKillEffectCondition.duration = 0; - killSourceConditionMagnitude.setEnabled(true); - killSourceConditionDuration.setEnabled(true); + } else if (source == killSourceConditionApply && (Boolean) value) { + selectedKillEffectCondition.magnitude = (Integer) killSourceConditionMagnitude.getValue(); + selectedKillEffectCondition.duration = killSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) killSourceConditionDuration.getValue(); + if (selectedKillEffectCondition.duration == null || selectedKillEffectCondition.duration == ActorCondition.DURATION_NONE) { + selectedKillEffectCondition.duration = 1; + } + updateKillSourceTimedConditionWidgets(selectedKillEffectCondition); + killSourceConditionsModel.itemChanged(selectedKillEffectCondition); + updateKill = true; + } else if (source == killSourceConditionImmunity && (Boolean) value) { + selectedKillEffectCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedKillEffectCondition.duration = killSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) killSourceConditionDuration.getValue(); + if (selectedKillEffectCondition.duration == null || selectedKillEffectCondition.duration == ActorCondition.DURATION_NONE) { + selectedKillEffectCondition.duration = 1; + } + updateKillSourceTimedConditionWidgets(selectedKillEffectCondition); killSourceConditionsModel.itemChanged(selectedKillEffectCondition); updateKill = true; } else if (source == killSourceConditionMagnitude) { selectedKillEffectCondition.magnitude = (Integer) value; killSourceConditionsModel.itemChanged(selectedKillEffectCondition); updateKill = true; + } else if (source == killSourceConditionTimed && (Boolean) value) { + selectedKillEffectCondition.duration = (Integer) killSourceConditionDuration.getValue(); + if (selectedKillEffectCondition.duration == null) { + selectedKillEffectCondition.duration = 1; + } + updateKillSourceTimedConditionWidgets(selectedKillEffectCondition); + killSourceConditionsModel.itemChanged(selectedKillEffectCondition); + updateKill = true; + } else if (source == killSourceConditionForever && (Boolean) value) { + selectedKillEffectCondition.duration = ActorCondition.DURATION_FOREVER; + updateKillSourceTimedConditionWidgets(selectedKillEffectCondition); + killSourceConditionsModel.itemChanged(selectedKillEffectCondition); + updateKill = true; } else if (source == killSourceConditionDuration) { selectedKillEffectCondition.duration = (Integer) value; killSourceConditionsModel.itemChanged(selectedKillEffectCondition); diff --git a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/NPCEditor.java b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/NPCEditor.java index 9daace3..137aeb1 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/NPCEditor.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/NPCEditor.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import javax.swing.ButtonGroup; import javax.swing.DefaultListCellRenderer; import javax.swing.ImageIcon; import javax.swing.JButton; @@ -16,6 +17,7 @@ import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; +import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.JTextField; @@ -90,17 +92,27 @@ public class NPCEditor extends JSONElementEditor { @SuppressWarnings("rawtypes") private JList hitSourceConditionsList; private MyComboBox sourceConditionBox; - private JSpinner sourceConditionMagnitude; - private JSpinner sourceConditionDuration; private JSpinner sourceConditionChance; + private JRadioButton sourceConditionClear; + private JRadioButton sourceConditionApply; + private JRadioButton sourceConditionImmunity; + private JSpinner sourceConditionMagnitude; + private JRadioButton sourceConditionTimed; + private JRadioButton sourceConditionForever; + private JSpinner sourceConditionDuration; private TargetTimedConditionsListModel hitTargetConditionsListModel; @SuppressWarnings("rawtypes") private JList hitTargetConditionsList; private MyComboBox targetConditionBox; - private JSpinner targetConditionMagnitude; - private JSpinner targetConditionDuration; private JSpinner targetConditionChance; + private JRadioButton targetConditionClear; + private JRadioButton targetConditionApply; + private JRadioButton targetConditionImmunity; + private JSpinner targetConditionMagnitude; + private JRadioButton targetConditionTimed; + private JRadioButton targetConditionForever; + private JSpinner targetConditionDuration; private JPanel dialogueGraphPane; private DialogueGraphView dialogueGraphView; @@ -313,7 +325,7 @@ public class NPCEditor extends JSONElementEditor { pane.add(combatTraitPane, JideBoxLayout.FIX); } - public void updateSourceTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, FieldUpdateListener listener) { + public void updateSourceTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) { pane.removeAll(); if (sourceConditionBox != null) { removeElementListener(sourceConditionBox); @@ -323,15 +335,88 @@ public class NPCEditor extends JSONElementEditor { Project proj = ((NPC)target).getProject(); sourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); - sourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude, 1, false, writable, listener); - sourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener); sourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); - + + sourceConditionClear = new JRadioButton("Clear active condition"); + pane.add(sourceConditionClear, JideBoxLayout.FIX); + sourceConditionApply = new JRadioButton("Apply condition with magnitude"); + pane.add(sourceConditionApply, JideBoxLayout.FIX); + sourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); + sourceConditionImmunity = new JRadioButton("Give immunity to condition"); + pane.add(sourceConditionImmunity, JideBoxLayout.FIX); + + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(sourceConditionApply); + radioEffectGroup.add(sourceConditionClear); + radioEffectGroup.add(sourceConditionImmunity); + + sourceConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(sourceConditionTimed, JideBoxLayout.FIX); + sourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener); + sourceConditionForever = new JRadioButton("Forever"); + pane.add(sourceConditionForever, JideBoxLayout.FIX); + + ButtonGroup radioDurationGroup = new ButtonGroup(); + radioDurationGroup.add(sourceConditionTimed); + radioDurationGroup.add(sourceConditionForever); + + updateSourceTimedConditionWidgets(condition); + + sourceConditionClear.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(sourceConditionClear, new Boolean(sourceConditionClear.isSelected())); + } + }); + sourceConditionApply.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(sourceConditionApply, new Boolean(sourceConditionApply.isSelected())); + } + }); + sourceConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(sourceConditionImmunity, new Boolean(sourceConditionImmunity.isSelected())); + } + }); + + sourceConditionTimed.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(sourceConditionTimed, new Boolean(sourceConditionTimed.isSelected())); + } + }); + sourceConditionForever.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(sourceConditionForever, new Boolean(sourceConditionForever.isSelected())); + } + }); pane.revalidate(); pane.repaint(); } - public void updateTargetTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, FieldUpdateListener listener) { + public void updateSourceTimedConditionWidgets(NPC.TimedConditionEffect condition) { + + boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); + boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); + boolean forever = condition.duration != null && condition.duration == ActorCondition.DURATION_FOREVER; + + sourceConditionClear.setSelected(clear); + sourceConditionApply.setSelected(!clear && !immunity); + sourceConditionMagnitude.setEnabled(!clear && !immunity); + sourceConditionImmunity.setSelected(immunity); + + sourceConditionTimed.setSelected(!forever); + sourceConditionTimed.setEnabled(!clear); + sourceConditionDuration.setEnabled(!clear && !forever); + sourceConditionForever.setSelected(forever); + sourceConditionForever.setEnabled(!clear); + } + + + public void updateTargetTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) { pane.removeAll(); if (targetConditionBox != null) { removeElementListener(targetConditionBox); @@ -341,14 +426,85 @@ public class NPCEditor extends JSONElementEditor { Project proj = ((NPC)target).getProject(); targetConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); - targetConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude, 1, false, writable, listener); - targetConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener); targetConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); - + targetConditionClear = new JRadioButton("Clear active condition"); + pane.add(targetConditionClear, JideBoxLayout.FIX); + targetConditionApply = new JRadioButton("Apply condition with magnitude"); + pane.add(targetConditionApply, JideBoxLayout.FIX); + targetConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); + targetConditionImmunity = new JRadioButton("Give immunity to condition"); + pane.add(targetConditionImmunity, JideBoxLayout.FIX); + + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(targetConditionApply); + radioEffectGroup.add(targetConditionClear); + radioEffectGroup.add(targetConditionImmunity); + + targetConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(targetConditionTimed, JideBoxLayout.FIX); + targetConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, false, writable, listener); + targetConditionForever = new JRadioButton("Forever"); + pane.add(targetConditionForever, JideBoxLayout.FIX); + + ButtonGroup radioDurationGroup = new ButtonGroup(); + radioDurationGroup.add(targetConditionTimed); + radioDurationGroup.add(targetConditionForever); + + updateTargetTimedConditionWidgets(condition); + + targetConditionClear.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(targetConditionClear, new Boolean(targetConditionClear.isSelected())); + } + }); + targetConditionApply.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(targetConditionApply, new Boolean(targetConditionApply.isSelected())); + } + }); + targetConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(targetConditionImmunity, new Boolean(targetConditionImmunity.isSelected())); + } + }); + + targetConditionTimed.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(targetConditionTimed, new Boolean(targetConditionTimed.isSelected())); + } + }); + targetConditionForever.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(targetConditionForever, new Boolean(targetConditionForever.isSelected())); + } + }); pane.revalidate(); pane.repaint(); } + public void updateTargetTimedConditionWidgets(NPC.TimedConditionEffect condition) { + + boolean immunity = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration != null && condition.duration > ActorCondition.DURATION_NONE); + boolean clear = (condition.magnitude == null || condition.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (condition.duration == null || condition.duration == ActorCondition.DURATION_NONE); + boolean forever = condition.duration != null && condition.duration == ActorCondition.DURATION_FOREVER; + + targetConditionClear.setSelected(clear); + targetConditionApply.setSelected(!clear && !immunity); + targetConditionMagnitude.setEnabled(!clear && !immunity); + targetConditionImmunity.setSelected(immunity); + + targetConditionTimed.setSelected(!forever); + targetConditionTimed.setEnabled(!clear); + targetConditionDuration.setEnabled(!clear && !forever); + targetConditionForever.setSelected(forever); + targetConditionForever.setEnabled(!clear); + } + public static class TargetTimedConditionsListModel implements ListModel { NPC.HitEffect source; @@ -485,7 +641,18 @@ public class NPCEditor extends JSONElementEditor { if (effect.condition != null) { label.setIcon(new ImageIcon(effect.condition.getIcon())); - label.setText(effect.chance+"% chances to give "+effect.duration+" rounds of "+effect.condition.getDesc()+" x"+effect.magnitude); + + boolean immunity = (effect.magnitude == null || effect.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (effect.duration != null && effect.duration > ActorCondition.DURATION_NONE); + boolean clear = (effect.magnitude == null || effect.magnitude == ActorCondition.MAGNITUDE_CLEAR) && (effect.duration == null || effect.duration == ActorCondition.DURATION_NONE); + boolean forever = effect.duration != null && effect.duration == ActorCondition.DURATION_FOREVER; + + if (clear) { + label.setText(effect.chance+"% chances to clear actor condition "+effect.condition.getDesc()); + } else if (immunity) { + label.setText(effect.chance+"% chances to give immunity to "+effect.condition.getDesc()+(forever ? " forever" : " for "+effect.duration+" rounds")); + } else { + label.setText(effect.chance+"% chances to give actor condition "+effect.condition.getDesc()+" x"+effect.magnitude+(forever ? " forever" : " for "+effect.duration+" rounds")); + } } else { label.setText("New, undefined actor condition effect."); } @@ -619,12 +786,51 @@ public class NPCEditor extends JSONElementEditor { selectedHitEffectSourceCondition.condition_id = null; } hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); + } else if (source == sourceConditionClear && (Boolean) value) { + selectedHitEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitEffectSourceCondition.duration = null; + updateSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); + updateHit = true; + } else if (source == sourceConditionApply && (Boolean) value) { + selectedHitEffectSourceCondition.magnitude = (Integer) sourceConditionMagnitude.getValue(); + selectedHitEffectSourceCondition.duration = sourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) sourceConditionDuration.getValue(); + if (selectedHitEffectSourceCondition.duration == null) { + selectedHitEffectSourceCondition.duration = 1; + } + updateSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); + updateHit = true; + } else if (source == sourceConditionImmunity && (Boolean) value) { + selectedHitEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitEffectSourceCondition.duration = sourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) sourceConditionDuration.getValue(); + if (selectedHitEffectSourceCondition.duration == null || selectedHitEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitEffectSourceCondition.duration = 1; + } + updateSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); + updateHit = true; } else if (source == sourceConditionMagnitude) { selectedHitEffectSourceCondition.magnitude = (Integer) value; hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); + updateHit = true; + } else if (source == sourceConditionTimed && (Boolean) value) { + selectedHitEffectSourceCondition.duration = (Integer) sourceConditionDuration.getValue(); + if (selectedHitEffectSourceCondition.duration == null || selectedHitEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitEffectSourceCondition.duration = 1; + } + updateSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); + updateHit = true; + } else if (source == sourceConditionForever && (Boolean) value) { + selectedHitEffectSourceCondition.duration = ActorCondition.DURATION_FOREVER; + updateSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); + updateHit = true; } else if (source == sourceConditionDuration) { selectedHitEffectSourceCondition.duration = (Integer) value; hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); + updateHit = true; } else if (source == sourceConditionChance) { selectedHitEffectSourceCondition.chance = (Double) value; hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); @@ -642,12 +848,51 @@ public class NPCEditor extends JSONElementEditor { selectedHitEffectTargetCondition.condition_id = null; } hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); + } else if (source == targetConditionClear && (Boolean) value) { + selectedHitEffectTargetCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitEffectTargetCondition.duration = null; + updateSourceTimedConditionWidgets(selectedHitEffectTargetCondition); + hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); + updateHit = true; + } else if (source == targetConditionApply && (Boolean) value) { + selectedHitEffectTargetCondition.magnitude = (Integer) targetConditionMagnitude.getValue(); + selectedHitEffectTargetCondition.duration = targetConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) targetConditionDuration.getValue(); + if (selectedHitEffectTargetCondition.duration == null) { + selectedHitEffectTargetCondition.duration = 1; + } + updateSourceTimedConditionWidgets(selectedHitEffectTargetCondition); + hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); + updateHit = true; + } else if (source == targetConditionImmunity && (Boolean) value) { + selectedHitEffectTargetCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitEffectTargetCondition.duration = targetConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) targetConditionDuration.getValue(); + if (selectedHitEffectTargetCondition.duration == null || selectedHitEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitEffectTargetCondition.duration = 1; + } + updateSourceTimedConditionWidgets(selectedHitEffectTargetCondition); + hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); + updateHit = true; } else if (source == targetConditionMagnitude) { selectedHitEffectTargetCondition.magnitude = (Integer) value; hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); + updateHit = true; + } else if (source == targetConditionTimed && (Boolean) value) { + selectedHitEffectTargetCondition.duration = (Integer) targetConditionDuration.getValue(); + if (selectedHitEffectTargetCondition.duration == null || selectedHitEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitEffectTargetCondition.duration = 1; + } + updateSourceTimedConditionWidgets(selectedHitEffectTargetCondition); + hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); + updateHit = true; + } else if (source == targetConditionForever && (Boolean) value) { + selectedHitEffectTargetCondition.duration = ActorCondition.DURATION_FOREVER; + updateSourceTimedConditionWidgets(selectedHitEffectTargetCondition); + hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); + updateHit = true; } else if (source == targetConditionDuration) { selectedHitEffectTargetCondition.duration = (Integer) value; hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); + updateHit = true; } else if (source == targetConditionChance) { selectedHitEffectTargetCondition.chance = (Double) value; hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition);