diff --git a/src/com/gpl/rpg/atcontentstudio/model/gamedata/Item.java b/src/com/gpl/rpg/atcontentstudio/model/gamedata/Item.java index bda85e4..03d0e6f 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/gamedata/Item.java +++ b/src/com/gpl/rpg/atcontentstudio/model/gamedata/Item.java @@ -34,6 +34,7 @@ public class Item extends JSONElement { public String category_id = null; public String description = null; public HitEffect hit_effect = null; + public HitReceivedEffect hit_received_effect = null; public KillEffect kill_effect = null; public EquipEffect equip_effect = null; @@ -58,6 +59,14 @@ public class Item extends JSONElement { public List conditions_target = null; } + public static class HitReceivedEffect extends HitEffect { + //Available from parsed state + public Integer hp_boost_min_target = null; + public Integer hp_boost_max_target = null; + public Integer ap_boost_min_target = null; + public Integer ap_boost_max_target = null; + } + public static class EquipEffect { //Available from parsed state public Integer damage_boost_min = null; @@ -246,6 +255,53 @@ public class Item extends JSONElement { } } + Map hitReceivedEffect = (Map) itemJson.get("hitReceivedEffect"); + if (hitReceivedEffect != null) { + this.hit_received_effect = new HitReceivedEffect(); + if (hitReceivedEffect.get("increaseCurrentHP") != null) { + this.hit_received_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentHP")).get("min"))); + this.hit_received_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentHP")).get("max"))); + } + if (hitReceivedEffect.get("increaseCurrentAP") != null) { + this.hit_received_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentAP")).get("min"))); + this.hit_received_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentAP")).get("max"))); + } + if (hitReceivedEffect.get("increaseAttackerCurrentHP") != null) { + this.hit_received_effect.hp_boost_min_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentHP")).get("min"))); + this.hit_received_effect.hp_boost_max_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentHP")).get("max"))); + } + if (hitReceivedEffect.get("increaseAttackerCurrentAP") != null) { + this.hit_received_effect.ap_boost_min_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentAP")).get("min"))); + this.hit_received_effect.ap_boost_max_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentAP")).get("max"))); + } + List conditionsSourceJson = (List) hitReceivedEffect.get("conditionsSource"); + if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) { + this.hit_received_effect.conditions_source = new ArrayList(); + for (Object conditionJsonObj : conditionsSourceJson) { + Map conditionJson = (Map)conditionJsonObj; + TimedConditionEffect condition = new TimedConditionEffect(); + condition.condition_id = (String) conditionJson.get("condition"); + condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude")); + condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration")); + if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString()); + this.hit_received_effect.conditions_source.add(condition); + } + } + List conditionsTargetJson = (List) hitReceivedEffect.get("conditionsTarget"); + if (conditionsTargetJson != null && !conditionsTargetJson.isEmpty()) { + this.hit_received_effect.conditions_target = new ArrayList(); + for (Object conditionJsonObj : conditionsTargetJson) { + Map conditionJson = (Map)conditionJsonObj; + TimedConditionEffect condition = new TimedConditionEffect(); + condition.condition_id = (String) conditionJson.get("condition"); + condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude")); + condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration")); + if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString()); + this.hit_received_effect.conditions_target.add(condition); + } + } + } + Map killEffect = (Map) itemJson.get("killEffect"); if (killEffect == null) { killEffect = (Map) itemJson.get("useEffect"); @@ -321,6 +377,18 @@ public class Item extends JSONElement { if (ce.condition != null) ce.condition.addBacklink(this); } } + if (this.hit_received_effect != null && this.hit_received_effect.conditions_source != null) { + for (TimedConditionEffect ce : this.hit_received_effect.conditions_source) { + if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id); + if (ce.condition != null) ce.condition.addBacklink(this); + } + } + if (this.hit_received_effect != null && this.hit_received_effect.conditions_target != null) { + for (TimedConditionEffect ce : this.hit_received_effect.conditions_target) { + if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id); + if (ce.condition != null) ce.condition.addBacklink(this); + } + } if (this.kill_effect != null && this.kill_effect.conditions_source != null) { for (TimedConditionEffect ce : this.kill_effect.conditions_source) { if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id); @@ -422,6 +490,47 @@ public class Item extends JSONElement { } } } + if (this.hit_received_effect != null) { + clone.hit_received_effect = new HitReceivedEffect(); + clone.hit_received_effect.ap_boost_max = this.hit_received_effect.ap_boost_max; + clone.hit_received_effect.ap_boost_min = this.hit_received_effect.ap_boost_min; + clone.hit_received_effect.hp_boost_max = this.hit_received_effect.hp_boost_max; + clone.hit_received_effect.hp_boost_min = this.hit_received_effect.hp_boost_min; + clone.hit_received_effect.ap_boost_max_target = this.hit_received_effect.ap_boost_max_target; + clone.hit_received_effect.ap_boost_min_target = this.hit_received_effect.ap_boost_min_target; + clone.hit_received_effect.hp_boost_max_target = this.hit_received_effect.hp_boost_max_target; + clone.hit_received_effect.hp_boost_min_target = this.hit_received_effect.hp_boost_min_target; + if (this.hit_received_effect.conditions_source != null) { + clone.hit_received_effect.conditions_source = new ArrayList(); + for (TimedConditionEffect c : this.hit_received_effect.conditions_source) { + TimedConditionEffect cclone = new TimedConditionEffect(); + cclone.magnitude = c.magnitude; + cclone.condition_id = c.condition_id; + cclone.condition = c.condition; + cclone.chance = c.chance; + cclone.duration = c.duration; + if (cclone.condition != null) { + cclone.condition.addBacklink(clone); + } + clone.hit_received_effect.conditions_source.add(cclone); + } + } + if (this.hit_received_effect.conditions_target != null) { + clone.hit_received_effect.conditions_target = new ArrayList(); + for (TimedConditionEffect c : this.hit_received_effect.conditions_target) { + TimedConditionEffect cclone = new TimedConditionEffect(); + cclone.magnitude = c.magnitude; + cclone.condition_id = c.condition_id; + cclone.condition = c.condition; + cclone.chance = c.chance; + cclone.duration = c.duration; + if (cclone.condition != null) { + cclone.condition.addBacklink(clone); + } + clone.hit_received_effect.conditions_target.add(cclone); + } + } + } if (this.kill_effect != null) { clone.kill_effect = new KillEffect(); clone.kill_effect.ap_boost_max = this.kill_effect.ap_boost_max; @@ -600,6 +709,74 @@ public class Item extends JSONElement { } } } + if (this.hit_received_effect != null) { + Map hitReceivedEffectJson = new LinkedHashMap(); + itemJson.put("hitReceivedEffect", hitReceivedEffectJson); + if (this.hit_received_effect.hp_boost_min != null || this.hit_received_effect.hp_boost_max != null) { + Map hpJson = new LinkedHashMap(); + hitReceivedEffectJson.put("increaseCurrentHP", hpJson); + if (this.hit_received_effect.hp_boost_min != null) hpJson.put("min", this.hit_received_effect.hp_boost_min); + else hpJson.put("min", 0); + if (this.hit_received_effect.hp_boost_max != null) hpJson.put("max", this.hit_received_effect.hp_boost_max); + else hpJson.put("max", 0); + } + if (this.hit_received_effect.ap_boost_min != null || this.hit_received_effect.ap_boost_max != null) { + Map apJson = new LinkedHashMap(); + hitReceivedEffectJson.put("increaseCurrentAP", apJson); + if (this.hit_received_effect.ap_boost_min != null) apJson.put("min", this.hit_received_effect.ap_boost_min); + else apJson.put("min", 0); + if (this.hit_received_effect.ap_boost_max != null) apJson.put("max", this.hit_received_effect.ap_boost_max); + else apJson.put("max", 0); + } + if (this.hit_received_effect.hp_boost_min_target != null || this.hit_received_effect.hp_boost_max_target != null) { + Map hpJson = new LinkedHashMap(); + hitReceivedEffectJson.put("increaseAttackerCurrentHP", hpJson); + if (this.hit_received_effect.hp_boost_min_target != null) hpJson.put("min", this.hit_received_effect.hp_boost_min_target); + else hpJson.put("min", 0); + if (this.hit_received_effect.hp_boost_max_target != null) hpJson.put("max", this.hit_received_effect.hp_boost_max_target); + else hpJson.put("max", 0); + } + if (this.hit_received_effect.ap_boost_min_target != null || this.hit_received_effect.ap_boost_max_target != null) { + Map apJson = new LinkedHashMap(); + hitReceivedEffectJson.put("increaseAttackerCurrentAP", apJson); + if (this.hit_received_effect.ap_boost_min_target != null) apJson.put("min", this.hit_received_effect.ap_boost_min_target); + else apJson.put("min", 0); + if (this.hit_received_effect.ap_boost_max_target != null) apJson.put("max", this.hit_received_effect.ap_boost_max_target); + else apJson.put("max", 0); + } + if (this.hit_received_effect.conditions_source != null) { + List conditionsSourceJson = new ArrayList(); + hitReceivedEffectJson.put("conditionsSource", conditionsSourceJson); + for (TimedConditionEffect condition : this.hit_received_effect.conditions_source) { + Map conditionJson = new LinkedHashMap(); + conditionsSourceJson.add(conditionJson); + if (condition.condition != null) { + conditionJson.put("condition", condition.condition.id); + } else if (condition.condition_id != null) { + conditionJson.put("condition", condition.condition_id); + } + if (condition.magnitude != null) conditionJson.put("magnitude", condition.magnitude); + if (condition.duration != null) conditionJson.put("duration", condition.duration); + if (condition.chance != null) conditionJson.put("chance", JSONElement.printJsonChance(condition.chance)); + } + } + if (this.hit_received_effect.conditions_target != null) { + List conditionsTargetJson = new ArrayList(); + hitReceivedEffectJson.put("conditionsTarget", conditionsTargetJson); + for (TimedConditionEffect condition : this.hit_received_effect.conditions_target) { + Map conditionJson = new LinkedHashMap(); + conditionsTargetJson.add(conditionJson); + if (condition.condition != null) { + conditionJson.put("condition", condition.condition.id); + } else if (condition.condition_id != null) { + conditionJson.put("condition", condition.condition_id); + } + if (condition.magnitude != null) conditionJson.put("magnitude", condition.magnitude); + if (condition.duration != null) conditionJson.put("duration", condition.duration); + if (condition.chance != null) conditionJson.put("chance", JSONElement.printJsonChance(condition.chance)); + } + } + } if (this.kill_effect != null) { Map killEffectJson = new LinkedHashMap(); if (this.category != null && this.category.action_type != null && this.category.action_type == ItemCategory.ActionType.equip) { diff --git a/src/com/gpl/rpg/atcontentstudio/model/gamedata/NPC.java b/src/com/gpl/rpg/atcontentstudio/model/gamedata/NPC.java index 753f8e6..aa39ee1 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/gamedata/NPC.java +++ b/src/com/gpl/rpg/atcontentstudio/model/gamedata/NPC.java @@ -47,6 +47,8 @@ public class NPC extends JSONElement { public Integer block_chance = null; public Integer damage_resistance = null; public HitEffect hit_effect = null; + public HitReceivedEffect hit_received_effect = null; + public DeathEffect death_effect = null; //Available from linked state public Dialogue dialogue = null; @@ -70,17 +72,29 @@ public class NPC extends JSONElement { protectSpawn, wholeMap } - - public static class HitEffect { + + public static class DeathEffect { //Available from parsed state public Integer hp_boost_min = null; public Integer hp_boost_max = null; public Integer ap_boost_min = null; public Integer ap_boost_max = null; public List conditions_source = null; + } + + public static class HitEffect extends DeathEffect { + //Available from parsed state public List conditions_target = null; } + public static class HitReceivedEffect extends HitEffect { + //Available from parsed state + public Integer hp_boost_min_target = null; + public Integer hp_boost_max_target = null; + public Integer ap_boost_min_target = null; + public Integer ap_boost_max_target = null; + } + public static class TimedConditionEffect { //Available from parsed state public Integer magnitude = null; @@ -224,6 +238,79 @@ public class NPC extends JSONElement { } } + Map hitReceivedEffect = (Map) npcJson.get("hitReceivedEffect"); + if (hitReceivedEffect != null) { + this.hit_received_effect = new HitReceivedEffect(); + if (hitReceivedEffect.get("increaseCurrentHP") != null) { + this.hit_received_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentHP")).get("max"))); + this.hit_received_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentHP")).get("min"))); + } + if (hitReceivedEffect.get("increaseCurrentAP") != null) { + this.hit_received_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentAP")).get("max"))); + this.hit_received_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseCurrentAP")).get("min"))); + } + if (hitReceivedEffect.get("increaseAttackerCurrentHP") != null) { + this.hit_received_effect.hp_boost_max_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentHP")).get("max"))); + this.hit_received_effect.hp_boost_min_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentHP")).get("min"))); + } + if (hitReceivedEffect.get("increaseAttackerCurrentAP") != null) { + this.hit_received_effect.ap_boost_max_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentAP")).get("max"))); + this.hit_received_effect.ap_boost_min_target = JSONElement.getInteger((Number) (((Map)hitReceivedEffect.get("increaseAttackerCurrentAP")).get("min"))); + } + List conditionsSourceJson = (List) hitReceivedEffect.get("conditionsSource"); + if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) { + this.hit_received_effect.conditions_source = new ArrayList(); + for (Object conditionJsonObj : conditionsSourceJson) { + Map conditionJson = (Map)conditionJsonObj; + TimedConditionEffect condition = new TimedConditionEffect(); + condition.condition_id = (String) conditionJson.get("condition"); + condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude")); + condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration")); + if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString()); + this.hit_received_effect.conditions_source.add(condition); + } + } + List conditionsTargetJson = (List) hitReceivedEffect.get("conditionsTarget"); + if (conditionsTargetJson != null && !conditionsTargetJson.isEmpty()) { + this.hit_received_effect.conditions_target = new ArrayList(); + for (Object conditionJsonObj : conditionsTargetJson) { + Map conditionJson = (Map)conditionJsonObj; + TimedConditionEffect condition = new TimedConditionEffect(); + condition.condition_id = (String) conditionJson.get("condition"); + condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude")); + condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration")); + if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString()); + this.hit_received_effect.conditions_target.add(condition); + } + } + } + + Map deathEffect = (Map) npcJson.get("deathEffect"); + if (deathEffect != null) { + this.death_effect = new HitEffect(); + if (deathEffect.get("increaseCurrentHP") != null) { + this.death_effect.hp_boost_max = JSONElement.getInteger((Number) (((Map)deathEffect.get("increaseCurrentHP")).get("max"))); + this.death_effect.hp_boost_min = JSONElement.getInteger((Number) (((Map)deathEffect.get("increaseCurrentHP")).get("min"))); + } + if (deathEffect.get("increaseCurrentAP") != null) { + this.death_effect.ap_boost_max = JSONElement.getInteger((Number) (((Map)deathEffect.get("increaseCurrentAP")).get("max"))); + this.death_effect.ap_boost_min = JSONElement.getInteger((Number) (((Map)deathEffect.get("increaseCurrentAP")).get("min"))); + } + List conditionsSourceJson = (List) deathEffect.get("conditionsSource"); + if (conditionsSourceJson != null && !conditionsSourceJson.isEmpty()) { + this.death_effect.conditions_source = new ArrayList(); + for (Object conditionJsonObj : conditionsSourceJson) { + Map conditionJson = (Map)conditionJsonObj; + TimedConditionEffect condition = new TimedConditionEffect(); + condition.condition_id = (String) conditionJson.get("condition"); + condition.magnitude = JSONElement.getInteger((Number) conditionJson.get("magnitude")); + condition.duration = JSONElement.getInteger((Number) conditionJson.get("duration")); + if (conditionJson.get("chance") != null) condition.chance = JSONElement.parseChance(conditionJson.get("chance").toString()); + this.death_effect.conditions_source.add(condition); + } + } + } + } @Override @@ -267,6 +354,24 @@ public class NPC extends JSONElement { if (ce.condition != null) ce.condition.addBacklink(this); } } + if (this.hit_received_effect != null && this.hit_received_effect.conditions_source != null) { + for (TimedConditionEffect ce : this.hit_received_effect.conditions_source) { + if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id); + if (ce.condition != null) ce.condition.addBacklink(this); + } + } + if (this.hit_received_effect != null && this.hit_received_effect.conditions_target != null) { + for (TimedConditionEffect ce : this.hit_received_effect.conditions_target) { + if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id); + if (ce.condition != null) ce.condition.addBacklink(this); + } + } + if (this.death_effect != null && this.death_effect.conditions_source != null) { + for (TimedConditionEffect ce : this.death_effect.conditions_source) { + if (ce.condition_id != null) ce.condition = proj.getActorCondition(ce.condition_id); + if (ce.condition != null) ce.condition.addBacklink(this); + } + } this.state = State.linked; } @@ -343,6 +448,69 @@ public class NPC extends JSONElement { } } } + if (this.hit_received_effect != null) { + clone.hit_received_effect = new HitReceivedEffect(); + clone.hit_received_effect.ap_boost_max = this.hit_received_effect.ap_boost_max; + clone.hit_received_effect.ap_boost_min = this.hit_received_effect.ap_boost_min; + clone.hit_received_effect.hp_boost_max = this.hit_received_effect.hp_boost_max; + clone.hit_received_effect.hp_boost_min = this.hit_received_effect.hp_boost_min; + clone.hit_received_effect.ap_boost_max_target = this.hit_received_effect.ap_boost_max_target; + clone.hit_received_effect.ap_boost_min_target = this.hit_received_effect.ap_boost_min_target; + clone.hit_received_effect.hp_boost_max_target = this.hit_received_effect.hp_boost_max_target; + clone.hit_received_effect.hp_boost_min_target = this.hit_received_effect.hp_boost_min_target; + if (this.hit_received_effect.conditions_source != null) { + clone.hit_received_effect.conditions_source = new ArrayList(); + for (TimedConditionEffect c : this.hit_received_effect.conditions_source) { + TimedConditionEffect cclone = new TimedConditionEffect(); + cclone.magnitude = c.magnitude; + cclone.condition_id = c.condition_id; + cclone.condition = c.condition; + cclone.chance = c.chance; + cclone.duration = c.duration; + if (cclone.condition != null) { + cclone.condition.addBacklink(clone); + } + clone.hit_received_effect.conditions_source.add(cclone); + } + } + if (this.hit_received_effect.conditions_target != null) { + clone.hit_received_effect.conditions_target = new ArrayList(); + for (TimedConditionEffect c : this.hit_received_effect.conditions_target) { + TimedConditionEffect cclone = new TimedConditionEffect(); + cclone.magnitude = c.magnitude; + cclone.condition_id = c.condition_id; + cclone.condition = c.condition; + cclone.chance = c.chance; + cclone.duration = c.duration; + if (cclone.condition != null) { + cclone.condition.addBacklink(clone); + } + clone.hit_received_effect.conditions_target.add(cclone); + } + } + } + if (this.death_effect != null) { + clone.death_effect = new DeathEffect(); + clone.death_effect.ap_boost_max = this.death_effect.ap_boost_max; + clone.death_effect.ap_boost_min = this.death_effect.ap_boost_min; + clone.death_effect.hp_boost_max = this.death_effect.hp_boost_max; + clone.death_effect.hp_boost_min = this.death_effect.hp_boost_min; + if (this.death_effect.conditions_source != null) { + clone.death_effect.conditions_source = new ArrayList(); + for (TimedConditionEffect c : this.death_effect.conditions_source) { + TimedConditionEffect cclone = new TimedConditionEffect(); + cclone.magnitude = c.magnitude; + cclone.condition_id = c.condition_id; + cclone.condition = c.condition; + cclone.chance = c.chance; + cclone.duration = c.duration; + if (cclone.condition != null) { + cclone.condition.addBacklink(clone); + } + clone.death_effect.conditions_source.add(cclone); + } + } + } clone.max_ap = this.max_ap; clone.max_hp = this.max_hp; clone.monster_class = this.monster_class; @@ -478,6 +646,110 @@ public class NPC extends JSONElement { } } } + if (this.hit_received_effect != null) { + Map hitReceivedEffectJson = new LinkedHashMap(); + npcJson.put("hitReceivedEffect", hitReceivedEffectJson); + if (this.hit_received_effect.hp_boost_min != null || this.hit_received_effect.hp_boost_max != null) { + Map hpJson = new LinkedHashMap(); + hitReceivedEffectJson.put("increaseCurrentHP", hpJson); + if (this.hit_received_effect.hp_boost_min != null) hpJson.put("min", this.hit_received_effect.hp_boost_min); + else hpJson.put("min", 0); + if (this.hit_received_effect.hp_boost_max != null) hpJson.put("max", this.hit_received_effect.hp_boost_max); + else hpJson.put("max", 0); + } + if (this.hit_received_effect.ap_boost_min != null || this.hit_received_effect.ap_boost_max != null) { + Map apJson = new LinkedHashMap(); + hitReceivedEffectJson.put("increaseCurrentAP", apJson); + if (this.hit_received_effect.ap_boost_min != null) apJson.put("min", this.hit_received_effect.ap_boost_min); + else apJson.put("min", 0); + if (this.hit_received_effect.ap_boost_max != null) apJson.put("max", this.hit_received_effect.ap_boost_max); + else apJson.put("max", 0); + } + if (this.hit_received_effect.hp_boost_min_target != null || this.hit_received_effect.hp_boost_max_target != null) { + Map hpJson = new LinkedHashMap(); + hitReceivedEffectJson.put("increaseAttackerCurrentHP", hpJson); + if (this.hit_received_effect.hp_boost_min_target != null) hpJson.put("min", this.hit_received_effect.hp_boost_min_target); + else hpJson.put("min", 0); + if (this.hit_received_effect.hp_boost_max_target != null) hpJson.put("max", this.hit_received_effect.hp_boost_max_target); + else hpJson.put("max", 0); + } + if (this.hit_received_effect.ap_boost_min_target != null || this.hit_received_effect.ap_boost_max_target != null) { + Map apJson = new LinkedHashMap(); + hitReceivedEffectJson.put("increaseAttackerCurrentAP", apJson); + if (this.hit_received_effect.ap_boost_min_target != null) apJson.put("min", this.hit_received_effect.ap_boost_min_target); + else apJson.put("min", 0); + if (this.hit_received_effect.ap_boost_max_target != null) apJson.put("max", this.hit_received_effect.ap_boost_max_target); + else apJson.put("max", 0); + } + if (this.hit_received_effect.conditions_source != null) { + List conditionsSourceJson = new ArrayList(); + hitReceivedEffectJson.put("conditionsSource", conditionsSourceJson); + for (TimedConditionEffect condition : this.hit_received_effect.conditions_source) { + Map conditionJson = new LinkedHashMap(); + conditionsSourceJson.add(conditionJson); + if (condition.condition != null) { + conditionJson.put("condition", condition.condition.id); + } else if (condition.condition_id != null) { + conditionJson.put("condition", condition.condition_id); + } + if (condition.magnitude != null) conditionJson.put("magnitude", condition.magnitude); + if (condition.duration != null) conditionJson.put("duration", condition.duration); + if (condition.chance != null) conditionJson.put("chance", JSONElement.printJsonChance(condition.chance)); + } + } + if (this.hit_received_effect.conditions_target != null) { + List conditionsTargetJson = new ArrayList(); + hitReceivedEffectJson.put("conditionsTarget", conditionsTargetJson); + for (TimedConditionEffect condition : this.hit_received_effect.conditions_target) { + Map conditionJson = new LinkedHashMap(); + conditionsTargetJson.add(conditionJson); + if (condition.condition != null) { + conditionJson.put("condition", condition.condition.id); + } else if (condition.condition_id != null) { + conditionJson.put("condition", condition.condition_id); + } + if (condition.magnitude != null) conditionJson.put("magnitude", condition.magnitude); + if (condition.duration != null) conditionJson.put("duration", condition.duration); + if (condition.chance != null) conditionJson.put("chance", JSONElement.printJsonChance(condition.chance)); + } + } + } + if (this.death_effect != null) { + Map deathEffectJson = new LinkedHashMap(); + npcJson.put("deathEffect", deathEffectJson); + if (this.death_effect.hp_boost_min != null || this.death_effect.hp_boost_max != null) { + Map hpJson = new LinkedHashMap(); + deathEffectJson.put("increaseCurrentHP", hpJson); + if (this.death_effect.hp_boost_min != null) hpJson.put("min", this.death_effect.hp_boost_min); + else hpJson.put("min", 0); + if (this.death_effect.hp_boost_max != null) hpJson.put("max", this.death_effect.hp_boost_max); + else hpJson.put("max", 0); + } + if (this.death_effect.ap_boost_min != null || this.death_effect.ap_boost_max != null) { + Map apJson = new LinkedHashMap(); + deathEffectJson.put("increaseCurrentAP", apJson); + if (this.death_effect.ap_boost_min != null) apJson.put("min", this.death_effect.ap_boost_min); + else apJson.put("min", 0); + if (this.death_effect.ap_boost_max != null) apJson.put("max", this.death_effect.ap_boost_max); + else apJson.put("max", 0); + } + if (this.death_effect.conditions_source != null) { + List conditionsSourceJson = new ArrayList(); + deathEffectJson.put("conditionsSource", conditionsSourceJson); + for (TimedConditionEffect condition : this.death_effect.conditions_source) { + Map conditionJson = new LinkedHashMap(); + conditionsSourceJson.add(conditionJson); + if (condition.condition != null) { + conditionJson.put("condition", condition.condition.id); + } else if (condition.condition_id != null) { + conditionJson.put("condition", condition.condition_id); + } + if (condition.magnitude != null) conditionJson.put("magnitude", condition.magnitude); + if (condition.duration != null) conditionJson.put("duration", condition.duration); + if (condition.chance != null) conditionJson.put("chance", JSONElement.printJsonChance(condition.chance)); + } + } + } return npcJson; } diff --git a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/ItemEditor.java b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/ItemEditor.java index 9eaede4..8107052 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/ItemEditor.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/ItemEditor.java @@ -57,7 +57,9 @@ public class ItemEditor extends JSONElementEditor { private Item.TimedConditionEffect selectedHitEffectSourceCondition; private Item.TimedConditionEffect selectedHitEffectTargetCondition; private Item.TimedConditionEffect selectedKillEffectCondition; - + private Item.TimedConditionEffect selectedHitReceivedEffectSourceCondition; + private Item.TimedConditionEffect selectedHitReceivedEffectTargetCondition; + private JButton itemIcon; private JTextField idField; @@ -143,6 +145,40 @@ public class ItemEditor extends JSONElementEditor { private JRadioButton killSourceConditionForever; private JSpinner killSourceConditionDuration; + private CollapsiblePanel hitReceivedEffectPane; + private Item.HitReceivedEffect hitReceivedEffect; + private JSpinner hitReceivedHPMin; + private JSpinner hitReceivedHPMax; + private JSpinner hitReceivedAPMin; + private JSpinner hitReceivedAPMax; + private JSpinner hitReceivedHPMinTarget; + private JSpinner hitReceivedHPMaxTarget; + private JSpinner hitReceivedAPMinTarget; + private JSpinner hitReceivedAPMaxTarget; + private SourceTimedConditionsListModel hitReceivedSourceConditionsModel; + @SuppressWarnings("rawtypes") + private JList hitReceivedSourceConditionsList; + private MyComboBox hitReceivedSourceConditionBox; + private JSpinner hitReceivedSourceConditionChance; + private JRadioButton hitReceivedSourceConditionClear; + private JRadioButton hitReceivedSourceConditionApply; + private JRadioButton hitReceivedSourceConditionImmunity; + private JSpinner hitReceivedSourceConditionMagnitude; + private JRadioButton hitReceivedSourceConditionTimed; + private JRadioButton hitReceivedSourceConditionForever; + private JSpinner hitReceivedSourceConditionDuration; + private TargetTimedConditionsListModel hitReceivedTargetConditionsModel; + @SuppressWarnings("rawtypes") + private JList hitReceivedTargetConditionsList; + private MyComboBox hitReceivedTargetConditionBox; + private JSpinner hitReceivedTargetConditionChance; + private JRadioButton hitReceivedTargetConditionClear; + private JRadioButton hitReceivedTargetConditionApply; + private JRadioButton hitReceivedTargetConditionImmunity; + private JSpinner hitReceivedTargetConditionMagnitude; + private JRadioButton hitReceivedTargetConditionTimed; + private JRadioButton hitReceivedTargetConditionForever; + private JSpinner hitReceivedTargetConditionDuration; public ItemEditor(Item item) { super(item, item.getDesc(), item.getIcon()); @@ -459,6 +495,142 @@ public class ItemEditor extends JSONElementEditor { } pane.add(killEffectPane, JideBoxLayout.FIX); + + hitReceivedEffectPane = new CollapsiblePanel("Effect on every received hit: "); + hitReceivedEffectPane.setLayout(new JideBoxLayout(hitReceivedEffectPane, JideBoxLayout.PAGE_AXIS)); + if (item.hit_received_effect == null) { + hitReceivedEffect = new Item.HitReceivedEffect(); + } else { + hitReceivedEffect = item.hit_received_effect; + } + hitReceivedHPMin = addIntegerField(hitReceivedEffectPane, "Player HP bonus min: ", hitReceivedEffect.hp_boost_min, true, item.writable, listener); + hitReceivedHPMax = addIntegerField(hitReceivedEffectPane, "Player HP bonus max: ", hitReceivedEffect.hp_boost_max, true, item.writable, listener); + hitReceivedAPMin = addIntegerField(hitReceivedEffectPane, "Player AP bonus min: ", hitReceivedEffect.ap_boost_min, true, item.writable, listener); + hitReceivedAPMax = addIntegerField(hitReceivedEffectPane, "Player AP bonus max: ", hitReceivedEffect.ap_boost_max, true, item.writable, listener); + hitReceivedHPMinTarget = addIntegerField(hitReceivedEffectPane, "Attacker HP bonus min: ", hitReceivedEffect.hp_boost_min_target, true, item.writable, listener); + hitReceivedHPMaxTarget = addIntegerField(hitReceivedEffectPane, "Attacker HP bonus max: ", hitReceivedEffect.hp_boost_max_target, true, item.writable, listener); + hitReceivedAPMinTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus min: ", hitReceivedEffect.ap_boost_min_target, true, item.writable, listener); + hitReceivedAPMaxTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus max: ", hitReceivedEffect.ap_boost_max_target, true, item.writable, listener); + final CollapsiblePanel hitReceivedSourceConditionsPane = new CollapsiblePanel("Actor Conditions applied to the player: "); + hitReceivedSourceConditionsPane.setLayout(new JideBoxLayout(hitReceivedSourceConditionsPane, JideBoxLayout.PAGE_AXIS)); + hitReceivedSourceConditionsModel = new SourceTimedConditionsListModel(hitReceivedEffect); + hitReceivedSourceConditionsList = new JList(hitReceivedSourceConditionsModel); + hitReceivedSourceConditionsList.setCellRenderer(new TimedConditionsCellRenderer()); + hitReceivedSourceConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + hitReceivedSourceConditionsPane.add(new JScrollPane(hitReceivedSourceConditionsList), JideBoxLayout.FIX); + final JPanel hitReceivedSourceTimedConditionsEditorPane = new JPanel(); + final JButton createHitReceivedSourceCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon())); + final JButton deleteHitReceivedSourceCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); + hitReceivedSourceConditionsList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + selectedHitReceivedEffectSourceCondition = (Item.TimedConditionEffect) hitReceivedSourceConditionsList.getSelectedValue(); + updateHitReceivedSourceTimedConditionEditorPane(hitReceivedSourceTimedConditionsEditorPane, selectedHitReceivedEffectSourceCondition, listener); + if (selectedHitReceivedEffectSourceCondition == null) { + deleteHitReceivedSourceCondition.setEnabled(false); + } else { + deleteHitReceivedSourceCondition.setEnabled(true); + } + } + }); + if (item.writable) { + JPanel listButtonsPane = new JPanel(); + listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6)); + createHitReceivedSourceCondition.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Item.TimedConditionEffect condition = new Item.TimedConditionEffect(); + hitReceivedSourceConditionsModel.addItem(condition); + hitReceivedSourceConditionsList.setSelectedValue(condition, true); + listener.valueChanged(hitReceivedSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. + } + }); + deleteHitReceivedSourceCondition.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (selectedHitReceivedEffectSourceCondition != null) { + hitReceivedSourceConditionsModel.removeItem(selectedHitReceivedEffectSourceCondition); + selectedHitReceivedEffectSourceCondition = null; + hitReceivedSourceConditionsList.clearSelection(); + listener.valueChanged(hitReceivedSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. + } + } + }); + + listButtonsPane.add(createHitReceivedSourceCondition, JideBoxLayout.FIX); + listButtonsPane.add(deleteHitReceivedSourceCondition, JideBoxLayout.FIX); + listButtonsPane.add(new JPanel(), JideBoxLayout.VARY); + hitReceivedSourceConditionsPane.add(listButtonsPane, JideBoxLayout.FIX); + } + hitReceivedSourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitReceivedSourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS)); + hitReceivedSourceConditionsPane.add(hitReceivedSourceTimedConditionsEditorPane, JideBoxLayout.FIX); + if (item.hit_received_effect == null || item.hit_received_effect.conditions_source == null || item.hit_received_effect.conditions_source.isEmpty()) { + hitReceivedSourceConditionsPane.collapse(); + } + hitReceivedEffectPane.add(hitReceivedSourceConditionsPane, JideBoxLayout.FIX); + final CollapsiblePanel hitReceivedTargetConditionsPane = new CollapsiblePanel("Actor Conditions applied to the attacker: "); + hitReceivedTargetConditionsPane.setLayout(new JideBoxLayout(hitReceivedTargetConditionsPane, JideBoxLayout.PAGE_AXIS)); + hitReceivedTargetConditionsModel = new TargetTimedConditionsListModel(hitReceivedEffect); + hitReceivedTargetConditionsList = new JList(hitReceivedTargetConditionsModel); + hitReceivedTargetConditionsList.setCellRenderer(new TimedConditionsCellRenderer()); + hitReceivedTargetConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + hitReceivedTargetConditionsPane.add(new JScrollPane(hitReceivedTargetConditionsList), JideBoxLayout.FIX); + final JPanel hitReceivedTargetTimedConditionsEditorPane = new JPanel(); + final JButton createHitReceivedTargetCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon())); + final JButton deleteHitReceivedTargetCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); + hitReceivedTargetConditionsList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + selectedHitReceivedEffectTargetCondition = (Item.TimedConditionEffect) hitReceivedTargetConditionsList.getSelectedValue(); + updateHitReceivedTargetTimedConditionEditorPane(hitReceivedTargetTimedConditionsEditorPane, selectedHitReceivedEffectTargetCondition, listener); + if (selectedHitReceivedEffectTargetCondition == null) { + deleteHitReceivedTargetCondition.setEnabled(false); + } else { + deleteHitReceivedTargetCondition.setEnabled(true); + } + } + }); + if (item.writable) { + JPanel listButtonsPane = new JPanel(); + listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6)); + createHitReceivedTargetCondition.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Item.TimedConditionEffect condition = new Item.TimedConditionEffect(); + hitReceivedTargetConditionsModel.addItem(condition); + hitReceivedTargetConditionsList.setSelectedValue(condition, true); + listener.valueChanged(hitReceivedTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. + } + }); + deleteHitReceivedTargetCondition.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (selectedHitReceivedEffectTargetCondition != null) { + hitReceivedTargetConditionsModel.removeItem(selectedHitReceivedEffectTargetCondition); + selectedHitReceivedEffectTargetCondition = null; + hitReceivedTargetConditionsList.clearSelection(); + listener.valueChanged(hitReceivedTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. + } + } + }); + + listButtonsPane.add(createHitReceivedTargetCondition, JideBoxLayout.FIX); + listButtonsPane.add(deleteHitReceivedTargetCondition, JideBoxLayout.FIX); + listButtonsPane.add(new JPanel(), JideBoxLayout.VARY); + hitReceivedTargetConditionsPane.add(listButtonsPane, JideBoxLayout.FIX); + } + hitReceivedTargetTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitReceivedTargetTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS)); + hitReceivedTargetConditionsPane.add(hitReceivedTargetTimedConditionsEditorPane, JideBoxLayout.FIX); + if (item.hit_received_effect == null || item.hit_received_effect.conditions_target == null || item.hit_received_effect.conditions_target.isEmpty()) { + hitReceivedTargetConditionsPane.collapse(); + } + hitReceivedEffectPane.add(hitReceivedTargetConditionsPane, JideBoxLayout.FIX); + if (item.hit_received_effect == null) { + hitReceivedEffectPane.collapse(); + } + pane.add(hitReceivedEffectPane, JideBoxLayout.FIX); + + if (item.category == null || item.category.action_type == null || item.category.action_type == ItemCategory.ActionType.none) { equipEffectPane.setVisible(false); hitEffectPane.setVisible(false); @@ -817,6 +989,199 @@ public class ItemEditor extends JSONElementEditor { pane.repaint(); } + public void updateHitReceivedSourceTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) { + pane.removeAll(); + if (hitReceivedSourceConditionBox != null) { + removeElementListener(hitReceivedSourceConditionBox); + } + if (condition == null) { + pane.revalidate(); + pane.repaint(); + return; + } + + boolean writable = ((Item)target).writable; + Project proj = ((Item)target).getProject(); + + hitReceivedSourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); + hitReceivedSourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); + + hitReceivedSourceConditionClear = new JRadioButton("Clear active condition"); + pane.add(hitReceivedSourceConditionClear, JideBoxLayout.FIX); + hitReceivedSourceConditionApply = new JRadioButton("Apply condition with magnitude"); + pane.add(hitReceivedSourceConditionApply, JideBoxLayout.FIX); + hitReceivedSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); + hitReceivedSourceConditionImmunity = new JRadioButton("Give immunity to condition"); + pane.add(hitReceivedSourceConditionImmunity, JideBoxLayout.FIX); + + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(hitReceivedSourceConditionApply); + radioEffectGroup.add(hitReceivedSourceConditionClear); + radioEffectGroup.add(hitReceivedSourceConditionImmunity); + + hitReceivedSourceConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(hitReceivedSourceConditionTimed, JideBoxLayout.FIX); + hitReceivedSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, 1, false, writable, listener); + hitReceivedSourceConditionForever = new JRadioButton("Forever"); + pane.add(hitReceivedSourceConditionForever, JideBoxLayout.FIX); + + ButtonGroup radioDurationGroup = new ButtonGroup(); + radioDurationGroup.add(hitReceivedSourceConditionTimed); + radioDurationGroup.add(hitReceivedSourceConditionForever); + + updateHitReceivedSourceTimedConditionWidgets(condition); + + hitReceivedSourceConditionClear.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedSourceConditionClear, new Boolean(hitReceivedSourceConditionClear.isSelected())); + } + }); + hitReceivedSourceConditionApply.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedSourceConditionApply, new Boolean(hitReceivedSourceConditionApply.isSelected())); + } + }); + hitReceivedSourceConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedSourceConditionImmunity, new Boolean(hitReceivedSourceConditionImmunity.isSelected())); + } + }); + + hitReceivedSourceConditionTimed.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedSourceConditionTimed, new Boolean(hitReceivedSourceConditionTimed.isSelected())); + } + }); + hitReceivedSourceConditionForever.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedSourceConditionForever, new Boolean(hitReceivedSourceConditionForever.isSelected())); + } + }); + + pane.revalidate(); + pane.repaint(); + } + + public void updateHitReceivedSourceTimedConditionWidgets(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; + + hitReceivedSourceConditionClear.setSelected(clear); + hitReceivedSourceConditionApply.setSelected(!clear && !immunity); + hitReceivedSourceConditionMagnitude.setEnabled(!clear && !immunity); + hitReceivedSourceConditionImmunity.setSelected(immunity); + + hitReceivedSourceConditionTimed.setSelected(!forever); + hitReceivedSourceConditionTimed.setEnabled(!clear); + hitReceivedSourceConditionDuration.setEnabled(!clear && !forever); + hitReceivedSourceConditionForever.setSelected(forever); + hitReceivedSourceConditionForever.setEnabled(!clear); + } + + public void updateHitReceivedTargetTimedConditionEditorPane(JPanel pane, Item.TimedConditionEffect condition, final FieldUpdateListener listener) { + pane.removeAll(); + if (hitReceivedTargetConditionBox != null) { + removeElementListener(hitReceivedTargetConditionBox); + } + if (condition == null) { + pane.revalidate(); + pane.repaint(); + return; + } + + boolean writable = ((Item)target).writable; + Project proj = ((Item)target).getProject(); + + hitReceivedTargetConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); + hitReceivedTargetConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); + + hitReceivedTargetConditionClear = new JRadioButton("Clear active condition"); + pane.add(hitReceivedTargetConditionClear, JideBoxLayout.FIX); + hitReceivedTargetConditionApply = new JRadioButton("Apply condition with magnitude"); + pane.add(hitReceivedTargetConditionApply, JideBoxLayout.FIX); + hitReceivedTargetConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); + hitReceivedTargetConditionImmunity = new JRadioButton("Give immunity to condition"); + pane.add(hitReceivedTargetConditionImmunity, JideBoxLayout.FIX); + + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(hitReceivedTargetConditionApply); + radioEffectGroup.add(hitReceivedTargetConditionClear); + radioEffectGroup.add(hitReceivedTargetConditionImmunity); + + hitReceivedTargetConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(hitReceivedTargetConditionTimed, JideBoxLayout.FIX); + hitReceivedTargetConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, 1, false, writable, listener); + hitReceivedTargetConditionForever = new JRadioButton("Forever"); + pane.add(hitReceivedTargetConditionForever, JideBoxLayout.FIX); + + ButtonGroup radioDurationGroup = new ButtonGroup(); + radioDurationGroup.add(hitReceivedTargetConditionTimed); + radioDurationGroup.add(hitReceivedTargetConditionForever); + + updateHitReceivedTargetTimedConditionWidgets(condition); + + hitReceivedTargetConditionClear.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedTargetConditionClear, new Boolean(hitReceivedTargetConditionClear.isSelected())); + } + }); + hitReceivedTargetConditionApply.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedTargetConditionApply, new Boolean(hitReceivedTargetConditionApply.isSelected())); + } + }); + hitReceivedTargetConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedTargetConditionImmunity, new Boolean(hitReceivedTargetConditionImmunity.isSelected())); + } + }); + + hitReceivedTargetConditionTimed.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedTargetConditionTimed, new Boolean(hitReceivedTargetConditionTimed.isSelected())); + } + }); + hitReceivedTargetConditionForever.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedTargetConditionForever, new Boolean(hitReceivedTargetConditionForever.isSelected())); + } + }); + + pane.revalidate(); + pane.repaint(); + } + + public void updateHitReceivedTargetTimedConditionWidgets(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; + + hitReceivedTargetConditionClear.setSelected(clear); + hitReceivedTargetConditionApply.setSelected(!clear && !immunity); + hitReceivedTargetConditionMagnitude.setEnabled(!clear && !immunity); + hitReceivedTargetConditionImmunity.setSelected(immunity); + + hitReceivedTargetConditionTimed.setSelected(!forever); + hitReceivedTargetConditionTimed.setEnabled(!clear); + hitReceivedTargetConditionDuration.setEnabled(!clear && !forever); + hitReceivedTargetConditionForever.setSelected(forever); + hitReceivedTargetConditionForever.setEnabled(!clear); + } + + public static class SourceTimedConditionsListModel implements ListModel { Item.KillEffect source; @@ -1102,13 +1467,28 @@ public class ItemEditor extends JSONElementEditor { return true; } + public static boolean isNull(Item.HitReceivedEffect effect) { + if (effect.ap_boost_min != null) return false; + if (effect.ap_boost_max != null) return false; + if (effect.hp_boost_min != null) return false; + if (effect.hp_boost_max != null) return false; + if (effect.ap_boost_min_target != null) return false; + if (effect.ap_boost_max_target != null) return false; + if (effect.hp_boost_min_target != null) return false; + if (effect.hp_boost_max_target != null) return false; + if (effect.conditions_source != null) return false; + if (effect.conditions_target != null) return false; + return true; + } + + public class ItemFieldUpdater implements FieldUpdateListener { @Override public void valueChanged(JComponent source, Object value) { Item item = (Item)target; - boolean updatePrice, updateEquip, updateHit, updateKill; - updatePrice = updateEquip = updateHit = updateKill = false; + boolean updatePrice, updateEquip, updateHit, updateKill, updateHitReceived; + updatePrice = updateEquip = updateHit = updateKill = updateHitReceived = false; if (source == idField) { //Events caused by cancel an ID edition. Dismiss. if (skipNext) { @@ -1177,6 +1557,8 @@ public class ItemEditor extends JSONElementEditor { item.hit_effect = null; killEffectPane.setVisible(false); item.kill_effect = null; + hitReceivedEffectPane.setVisible(false); + item.hit_received_effect = null; ItemEditor.this.revalidate(); ItemEditor.this.repaint(); } else if (item.category.action_type == ItemCategory.ActionType.use) { @@ -1186,6 +1568,8 @@ public class ItemEditor extends JSONElementEditor { item.hit_effect = null; killEffectPane.setVisible(true); updateKill = true; + hitReceivedEffectPane.setVisible(false); + item.hit_received_effect = null; killEffectPane.setTitle(useLabel); ItemEditor.this.revalidate(); ItemEditor.this.repaint(); @@ -1196,6 +1580,8 @@ public class ItemEditor extends JSONElementEditor { updateEquip = true; killEffectPane.setVisible(true); updateKill = true; + hitReceivedEffectPane.setVisible(true); + updateEquip = true; killEffectPane.setTitle(killLabel); ItemEditor.this.revalidate(); ItemEditor.this.repaint(); @@ -1502,6 +1888,166 @@ public class ItemEditor extends JSONElementEditor { selectedKillEffectCondition.chance = (Double) value; killSourceConditionsModel.itemChanged(selectedKillEffectCondition); updateKill = true; + } else if (source == hitReceivedHPMin) { + hitReceivedEffect.hp_boost_min = (Integer) value; + updatePrice = true; + updateHitReceived = true; + } else if (source == hitReceivedHPMax) { + hitReceivedEffect.hp_boost_max = (Integer) value; + updatePrice = true; + updateHitReceived = true; + } else if (source == hitReceivedAPMin) { + hitReceivedEffect.ap_boost_min = (Integer) value; + updatePrice = true; + updateHitReceived = true; + } else if (source == hitReceivedAPMax) { + hitReceivedEffect.ap_boost_max = (Integer) value; + updatePrice = true; + updateHitReceived = true; + } else if (source == hitReceivedHPMinTarget) { + hitReceivedEffect.hp_boost_min_target = (Integer) value; + updatePrice = true; + updateHitReceived = true; + } else if (source == hitReceivedHPMaxTarget) { + hitReceivedEffect.hp_boost_max_target = (Integer) value; + updatePrice = true; + updateHitReceived = true; + } else if (source == hitReceivedAPMinTarget) { + hitReceivedEffect.ap_boost_min_target = (Integer) value; + updatePrice = true; + updateHitReceived = true; + } else if (source == hitReceivedAPMaxTarget) { + hitReceivedEffect.ap_boost_max_target = (Integer) value; + updatePrice = true; + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionsList) { + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionBox) { + if (selectedHitReceivedEffectSourceCondition.condition != null) { + selectedHitReceivedEffectSourceCondition.condition.removeBacklink(item); + } + selectedHitReceivedEffectSourceCondition.condition = (ActorCondition) value; + if (selectedHitReceivedEffectSourceCondition.condition != null) { + selectedHitReceivedEffectSourceCondition.condition_id = selectedHitReceivedEffectSourceCondition.condition.id; + selectedHitReceivedEffectSourceCondition.condition.addBacklink(item); + } else { + selectedHitReceivedEffectSourceCondition.condition_id = null; + } + hitReceivedSourceConditionsModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionClear && (Boolean) value) { + selectedHitReceivedEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitReceivedEffectSourceCondition.duration = null; + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectSourceCondition); + hitReceivedSourceConditionsModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionApply && (Boolean) value) { + selectedHitReceivedEffectSourceCondition.magnitude = (Integer) hitReceivedSourceConditionMagnitude.getValue(); + selectedHitReceivedEffectSourceCondition.duration = hitReceivedSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitReceivedSourceConditionDuration.getValue(); + if (selectedHitReceivedEffectSourceCondition.duration == null) { + selectedHitReceivedEffectSourceCondition.duration = 1; + } + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectSourceCondition); + hitReceivedSourceConditionsModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionImmunity && (Boolean) value) { + selectedHitReceivedEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitReceivedEffectSourceCondition.duration = hitReceivedSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitReceivedSourceConditionDuration.getValue(); + if (selectedHitReceivedEffectSourceCondition.duration == null || selectedHitReceivedEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectSourceCondition.duration = 1; + } + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectSourceCondition); + hitReceivedSourceConditionsModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionMagnitude) { + selectedHitReceivedEffectSourceCondition.magnitude = (Integer) value; + hitReceivedSourceConditionsModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionTimed && (Boolean) value) { + selectedHitReceivedEffectSourceCondition.duration = (Integer) hitReceivedSourceConditionDuration.getValue(); + if (selectedHitReceivedEffectSourceCondition.duration == null || selectedHitReceivedEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectSourceCondition.duration = 1; + } + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectSourceCondition); + hitReceivedSourceConditionsModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionForever && (Boolean) value) { + selectedHitReceivedEffectSourceCondition.duration = ActorCondition.DURATION_FOREVER; + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectSourceCondition); + hitReceivedSourceConditionsModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionDuration) { + selectedHitReceivedEffectSourceCondition.duration = (Integer) value; + hitReceivedSourceConditionsModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionChance) { + selectedHitReceivedEffectSourceCondition.chance = (Double) value; + hitReceivedSourceConditionsModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionsList) { + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionBox) { + if (selectedHitReceivedEffectTargetCondition.condition != null) { + selectedHitReceivedEffectTargetCondition.condition.removeBacklink(item); + } + selectedHitReceivedEffectTargetCondition.condition = (ActorCondition) value; + if (selectedHitReceivedEffectTargetCondition.condition != null) { + selectedHitReceivedEffectTargetCondition.condition_id = selectedHitReceivedEffectTargetCondition.condition.id; + selectedHitReceivedEffectTargetCondition.condition.addBacklink(item); + } else { + selectedHitReceivedEffectTargetCondition.condition_id = null; + } + hitReceivedTargetConditionsModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionClear && (Boolean) value) { + selectedHitReceivedEffectTargetCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitReceivedEffectTargetCondition.duration = null; + updateHitReceivedTargetTimedConditionWidgets(selectedHitReceivedEffectTargetCondition); + hitReceivedTargetConditionsModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionApply && (Boolean) value) { + selectedHitReceivedEffectTargetCondition.magnitude = (Integer) hitReceivedTargetConditionMagnitude.getValue(); + selectedHitReceivedEffectTargetCondition.duration = hitReceivedTargetConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitReceivedTargetConditionDuration.getValue(); + if (selectedHitReceivedEffectTargetCondition.duration == null || selectedHitReceivedEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectTargetCondition.duration = 1; + } + updateHitReceivedTargetTimedConditionWidgets(selectedHitReceivedEffectTargetCondition); + hitReceivedTargetConditionsModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionImmunity && (Boolean) value) { + selectedHitReceivedEffectTargetCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitReceivedEffectTargetCondition.duration = hitReceivedTargetConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitReceivedTargetConditionDuration.getValue(); + if (selectedHitReceivedEffectTargetCondition.duration == null || selectedHitReceivedEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectTargetCondition.duration = 1; + } + updateHitReceivedTargetTimedConditionWidgets(selectedHitReceivedEffectTargetCondition); + hitReceivedTargetConditionsModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionMagnitude) { + selectedHitReceivedEffectTargetCondition.magnitude = (Integer) value; + hitReceivedTargetConditionsModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionTimed && (Boolean) value) { + selectedHitReceivedEffectTargetCondition.duration = (Integer) hitReceivedTargetConditionDuration.getValue(); + if (selectedHitReceivedEffectTargetCondition.duration == null || selectedHitReceivedEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectTargetCondition.duration = 1; + } + updateHitReceivedTargetTimedConditionWidgets(selectedHitReceivedEffectTargetCondition); + hitReceivedTargetConditionsModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionForever && (Boolean) value) { + selectedHitReceivedEffectTargetCondition.duration = ActorCondition.DURATION_FOREVER; + updateHitReceivedTargetTimedConditionWidgets(selectedHitReceivedEffectTargetCondition); + hitReceivedTargetConditionsModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionDuration) { + selectedHitReceivedEffectTargetCondition.duration = (Integer) value; + hitReceivedTargetConditionsModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionChance) { + selectedHitReceivedEffectTargetCondition.chance = (Double) value; + hitReceivedTargetConditionsModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; } if (updateEquip) { @@ -1525,6 +2071,13 @@ public class ItemEditor extends JSONElementEditor { item.kill_effect = killEffect; } } + if (updateHitReceived) { + if (isNull(hitReceivedEffect)) { + item.hit_received_effect = null; + } else { + item.hit_received_effect = hitReceivedEffect; + } + } if (updatePrice && !manualPriceBox.isSelected()) { baseCostField.setValue(item.computePrice()); } diff --git a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/NPCEditor.java b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/NPCEditor.java index 0723111..888a9d0 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/NPCEditor.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/NPCEditor.java @@ -55,6 +55,9 @@ public class NPCEditor extends JSONElementEditor { private NPC.TimedConditionEffect selectedHitEffectSourceCondition; private NPC.TimedConditionEffect selectedHitEffectTargetCondition; + private NPC.TimedConditionEffect selectedHitReceivedEffectSourceCondition; + private NPC.TimedConditionEffect selectedHitReceivedEffectTargetCondition; + private NPC.TimedConditionEffect selectedDeathEffectSourceCondition; private JButton npcIcon; private JTextField idField; @@ -92,29 +95,86 @@ public class NPCEditor extends JSONElementEditor { private SourceTimedConditionsListModel hitSourceConditionsListModel; @SuppressWarnings("rawtypes") private JList hitSourceConditionsList; - private MyComboBox sourceConditionBox; - 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 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 TargetTimedConditionsListModel hitTargetConditionsListModel; @SuppressWarnings("rawtypes") private JList hitTargetConditionsList; - private MyComboBox targetConditionBox; - 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 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 NPC.HitReceivedEffect hitReceivedEffect; + private CollapsiblePanel hitReceivedEffectPane; + private JSpinner hitReceivedEffectHPMin; + private JSpinner hitReceivedEffectHPMax; + private JSpinner hitReceivedEffectAPMin; + private JSpinner hitReceivedEffectAPMax; + private JSpinner hitReceivedEffectHPMinTarget; + private JSpinner hitReceivedEffectHPMaxTarget; + private JSpinner hitReceivedEffectAPMinTarget; + private JSpinner hitReceivedEffectAPMaxTarget; + + private SourceTimedConditionsListModel hitReceivedSourceConditionsListModel; + @SuppressWarnings("rawtypes") + private JList hitReceivedSourceConditionsList; + private MyComboBox hitReceivedSourceConditionBox; + private JSpinner hitReceivedSourceConditionChance; + private JRadioButton hitReceivedSourceConditionClear; + private JRadioButton hitReceivedSourceConditionApply; + private JRadioButton hitReceivedSourceConditionImmunity; + private JSpinner hitReceivedSourceConditionMagnitude; + private JRadioButton hitReceivedSourceConditionTimed; + private JRadioButton hitReceivedSourceConditionForever; + private JSpinner hitReceivedSourceConditionDuration; + + private TargetTimedConditionsListModel hitReceivedTargetConditionsListModel; + @SuppressWarnings("rawtypes") + private JList hitReceivedTargetConditionsList; + private MyComboBox hitReceivedTargetConditionBox; + private JSpinner hitReceivedTargetConditionChance; + private JRadioButton hitReceivedTargetConditionClear; + private JRadioButton hitReceivedTargetConditionApply; + private JRadioButton hitReceivedTargetConditionImmunity; + private JSpinner hitReceivedTargetConditionMagnitude; + private JRadioButton hitReceivedTargetConditionTimed; + private JRadioButton hitReceivedTargetConditionForever; + private JSpinner hitReceivedTargetConditionDuration; + + private NPC.DeathEffect deathEffect; + private CollapsiblePanel deathEffectPane; + private JSpinner deathEffectHPMin; + private JSpinner deathEffectHPMax; + private JSpinner deathEffectAPMin; + private JSpinner deathEffectAPMax; + + private SourceTimedConditionsListModel deathSourceConditionsListModel; + @SuppressWarnings("rawtypes") + private JList deathSourceConditionsList; + private MyComboBox deathSourceConditionBox; + private JSpinner deathSourceConditionChance; + private JRadioButton deathSourceConditionClear; + private JRadioButton deathSourceConditionApply; + private JRadioButton deathSourceConditionImmunity; + private JSpinner deathSourceConditionMagnitude; + private JRadioButton deathSourceConditionTimed; + private JRadioButton deathSourceConditionForever; + private JSpinner deathSourceConditionDuration; + private JPanel dialogueGraphPane; private DialogueGraphView dialogueGraphView; @@ -224,14 +284,14 @@ public class NPCEditor extends JSONElementEditor { hitSourceConditionsList.setCellRenderer(new TimedConditionsCellRenderer()); hitSourceConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); hitSourceConditionsPane.add(new JScrollPane(hitSourceConditionsList), JideBoxLayout.FIX); - final JPanel sourceTimedConditionsEditorPane = new JPanel(); + final JPanel hitSourceTimedConditionsEditorPane = new JPanel(); final JButton createHitSourceCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon())); final JButton deleteHitSourceCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); hitSourceConditionsList.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { selectedHitEffectSourceCondition = (NPC.TimedConditionEffect) hitSourceConditionsList.getSelectedValue(); - updateSourceTimedConditionEditorPane(sourceTimedConditionsEditorPane, selectedHitEffectSourceCondition, listener); + updateHitSourceTimedConditionEditorPane(hitSourceTimedConditionsEditorPane, selectedHitEffectSourceCondition, listener); } }); if (npc.writable) { @@ -263,8 +323,8 @@ public class NPCEditor extends JSONElementEditor { listButtonsPane.add(new JPanel(), JideBoxLayout.VARY); hitSourceConditionsPane.add(listButtonsPane, JideBoxLayout.FIX); } - sourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(sourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS)); - hitSourceConditionsPane.add(sourceTimedConditionsEditorPane, JideBoxLayout.FIX); + hitSourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitSourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS)); + hitSourceConditionsPane.add(hitSourceTimedConditionsEditorPane, JideBoxLayout.FIX); if (npc.hit_effect == null || npc.hit_effect.conditions_source == null || npc.hit_effect.conditions_source.isEmpty()) { hitSourceConditionsPane.collapse(); } @@ -276,14 +336,14 @@ public class NPCEditor extends JSONElementEditor { hitTargetConditionsList.setCellRenderer(new TimedConditionsCellRenderer()); hitTargetConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); hitTargetConditionsPane.add(new JScrollPane(hitTargetConditionsList), JideBoxLayout.FIX); - final JPanel targetTimedConditionsEditorPane = new JPanel(); + final JPanel hitTargetTimedConditionsEditorPane = new JPanel(); final JButton createHitTargetCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon())); final JButton deleteHitTargetCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); hitTargetConditionsList.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { selectedHitEffectTargetCondition = (NPC.TimedConditionEffect) hitTargetConditionsList.getSelectedValue(); - updateTargetTimedConditionEditorPane(targetTimedConditionsEditorPane, selectedHitEffectTargetCondition, listener); + updateHitTargetTimedConditionEditorPane(hitTargetTimedConditionsEditorPane, selectedHitEffectTargetCondition, listener); } }); if (npc.writable) { @@ -315,197 +375,657 @@ public class NPCEditor extends JSONElementEditor { listButtonsPane.add(new JPanel(), JideBoxLayout.VARY); hitTargetConditionsPane.add(listButtonsPane, JideBoxLayout.FIX); } - targetTimedConditionsEditorPane.setLayout(new JideBoxLayout(targetTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS)); - hitTargetConditionsPane.add(targetTimedConditionsEditorPane, JideBoxLayout.FIX); + hitTargetTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitTargetTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS)); + hitTargetConditionsPane.add(hitTargetTimedConditionsEditorPane, JideBoxLayout.FIX); hitEffectPane.add(hitTargetConditionsPane, JideBoxLayout.FIX); if (npc.hit_effect == null || npc.hit_effect.conditions_target == null || npc.hit_effect.conditions_target.isEmpty()) { hitTargetConditionsPane.collapse(); } combatTraitPane.add(hitEffectPane, JideBoxLayout.FIX); + hitReceivedEffectPane = new CollapsiblePanel("Effect on every hit received: "); + hitReceivedEffectPane.setLayout(new JideBoxLayout(hitReceivedEffectPane, JideBoxLayout.PAGE_AXIS)); + if (npc.hit_received_effect == null) { + hitReceivedEffect = new NPC.HitReceivedEffect(); + } else { + hitReceivedEffect = npc.hit_received_effect; + } + hitReceivedEffectHPMin = addIntegerField(hitReceivedEffectPane, "NPC HP bonus min: ", hitReceivedEffect.hp_boost_min, true, npc.writable, listener); + hitReceivedEffectHPMax = addIntegerField(hitReceivedEffectPane, "NPC HP bonus max: ", hitReceivedEffect.hp_boost_max, true, npc.writable, listener); + hitReceivedEffectAPMin = addIntegerField(hitReceivedEffectPane, "NPC AP bonus min: ", hitReceivedEffect.ap_boost_min, true, npc.writable, listener); + hitReceivedEffectAPMax = addIntegerField(hitReceivedEffectPane, "NPC AP bonus max: ", hitReceivedEffect.ap_boost_max, true, npc.writable, listener); + hitReceivedEffectHPMinTarget = addIntegerField(hitReceivedEffectPane, "Attacker HP bonus min: ", hitReceivedEffect.hp_boost_min_target, true, npc.writable, listener); + hitReceivedEffectHPMaxTarget = addIntegerField(hitReceivedEffectPane, "Attacker HP bonus max: ", hitReceivedEffect.hp_boost_max_target, true, npc.writable, listener); + hitReceivedEffectAPMinTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus min: ", hitReceivedEffect.ap_boost_min_target, true, npc.writable, listener); + hitReceivedEffectAPMaxTarget = addIntegerField(hitReceivedEffectPane, "Attacker AP bonus max: ", hitReceivedEffect.ap_boost_max_target, true, npc.writable, listener); + + CollapsiblePanel hitReceivedSourceConditionsPane = new CollapsiblePanel("Actor Conditions applied to this NPC: "); + hitReceivedSourceConditionsPane.setLayout(new JideBoxLayout(hitReceivedSourceConditionsPane, JideBoxLayout.PAGE_AXIS)); + hitReceivedSourceConditionsListModel = new SourceTimedConditionsListModel(hitReceivedEffect); + hitReceivedSourceConditionsList = new JList(hitReceivedSourceConditionsListModel); + hitReceivedSourceConditionsList.setCellRenderer(new TimedConditionsCellRenderer()); + hitReceivedSourceConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + hitReceivedSourceConditionsPane.add(new JScrollPane(hitReceivedSourceConditionsList), JideBoxLayout.FIX); + final JPanel hitReceivedSourceTimedConditionsEditorPane = new JPanel(); + final JButton createHitReceivedSourceCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon())); + final JButton deleteHitReceivedSourceCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); + hitReceivedSourceConditionsList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + selectedHitReceivedEffectSourceCondition = (NPC.TimedConditionEffect) hitReceivedSourceConditionsList.getSelectedValue(); + updateHitReceivedSourceTimedConditionEditorPane(hitReceivedSourceTimedConditionsEditorPane, selectedHitReceivedEffectSourceCondition, listener); + } + }); + if (npc.writable) { + JPanel listButtonsPane = new JPanel(); + listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6)); + createHitReceivedSourceCondition.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + NPC.TimedConditionEffect condition = new NPC.TimedConditionEffect(); + hitReceivedSourceConditionsListModel.addItem(condition); + hitReceivedSourceConditionsList.setSelectedValue(condition, true); + listener.valueChanged(hitReceivedSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. + } + }); + deleteHitReceivedSourceCondition.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (selectedHitReceivedEffectSourceCondition != null) { + hitReceivedSourceConditionsListModel.removeItem(selectedHitReceivedEffectSourceCondition); + selectedHitReceivedEffectSourceCondition = null; + hitReceivedSourceConditionsList.clearSelection(); + listener.valueChanged(hitReceivedSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. + } + } + }); + + listButtonsPane.add(createHitReceivedSourceCondition, JideBoxLayout.FIX); + listButtonsPane.add(deleteHitReceivedSourceCondition, JideBoxLayout.FIX); + listButtonsPane.add(new JPanel(), JideBoxLayout.VARY); + hitReceivedSourceConditionsPane.add(listButtonsPane, JideBoxLayout.FIX); + } + hitReceivedSourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitReceivedSourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS)); + hitReceivedSourceConditionsPane.add(hitReceivedSourceTimedConditionsEditorPane, JideBoxLayout.FIX); + if (npc.hit_received_effect == null || npc.hit_received_effect.conditions_source == null || npc.hit_received_effect.conditions_source.isEmpty()) { + hitReceivedSourceConditionsPane.collapse(); + } + hitReceivedEffectPane.add(hitReceivedSourceConditionsPane, JideBoxLayout.FIX); + final CollapsiblePanel hitReceivedTargetConditionsPane = new CollapsiblePanel("Actor Conditions applied to the attacker: "); + hitReceivedTargetConditionsPane.setLayout(new JideBoxLayout(hitReceivedTargetConditionsPane, JideBoxLayout.PAGE_AXIS)); + hitReceivedTargetConditionsListModel = new TargetTimedConditionsListModel(hitReceivedEffect); + hitReceivedTargetConditionsList = new JList(hitReceivedTargetConditionsListModel); + hitReceivedTargetConditionsList.setCellRenderer(new TimedConditionsCellRenderer()); + hitReceivedTargetConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + hitReceivedTargetConditionsPane.add(new JScrollPane(hitReceivedTargetConditionsList), JideBoxLayout.FIX); + final JPanel hitReceivedTargetTimedConditionsEditorPane = new JPanel(); + final JButton createHitReceivedTargetCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon())); + final JButton deleteHitReceivedTargetCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); + hitReceivedTargetConditionsList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + selectedHitReceivedEffectTargetCondition = (NPC.TimedConditionEffect) hitReceivedTargetConditionsList.getSelectedValue(); + updateHitReceivedTargetTimedConditionEditorPane(hitReceivedTargetTimedConditionsEditorPane, selectedHitReceivedEffectTargetCondition, listener); + } + }); + if (npc.writable) { + JPanel listButtonsPane = new JPanel(); + listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6)); + createHitReceivedTargetCondition.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + NPC.TimedConditionEffect condition = new NPC.TimedConditionEffect(); + hitReceivedTargetConditionsListModel.addItem(condition); + hitReceivedTargetConditionsList.setSelectedValue(condition, true); + listener.valueChanged(hitReceivedTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. + } + }); + deleteHitReceivedTargetCondition.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (selectedHitReceivedEffectTargetCondition != null) { + hitReceivedTargetConditionsListModel.removeItem(selectedHitReceivedEffectTargetCondition); + selectedHitReceivedEffectTargetCondition = null; + hitReceivedTargetConditionsList.clearSelection(); + listener.valueChanged(hitReceivedTargetConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. + } + } + }); + + listButtonsPane.add(createHitReceivedTargetCondition, JideBoxLayout.FIX); + listButtonsPane.add(deleteHitReceivedTargetCondition, JideBoxLayout.FIX); + listButtonsPane.add(new JPanel(), JideBoxLayout.VARY); + hitReceivedTargetConditionsPane.add(listButtonsPane, JideBoxLayout.FIX); + } + hitReceivedTargetTimedConditionsEditorPane.setLayout(new JideBoxLayout(hitReceivedTargetTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS)); + hitReceivedTargetConditionsPane.add(hitReceivedTargetTimedConditionsEditorPane, JideBoxLayout.FIX); + hitReceivedEffectPane.add(hitReceivedTargetConditionsPane, JideBoxLayout.FIX); + if (npc.hit_received_effect == null || npc.hit_received_effect.conditions_target == null || npc.hit_received_effect.conditions_target.isEmpty()) { + hitReceivedTargetConditionsPane.collapse(); + } + combatTraitPane.add(hitReceivedEffectPane, JideBoxLayout.FIX); + + deathEffectPane = new CollapsiblePanel("Effect when killed: "); + deathEffectPane.setLayout(new JideBoxLayout(deathEffectPane, JideBoxLayout.PAGE_AXIS)); + if (npc.death_effect == null) { + deathEffect = new NPC.DeathEffect(); + } else { + deathEffect = npc.death_effect; + } + deathEffectHPMin = addIntegerField(deathEffectPane, "Killer HP bonus min: ", deathEffect.hp_boost_min, true, npc.writable, listener); + deathEffectHPMax = addIntegerField(deathEffectPane, "Killer HP bonus max: ", deathEffect.hp_boost_max, true, npc.writable, listener); + deathEffectAPMin = addIntegerField(deathEffectPane, "Killer AP bonus min: ", deathEffect.ap_boost_min, true, npc.writable, listener); + deathEffectAPMax = addIntegerField(deathEffectPane, "Killer AP bonus max: ", deathEffect.ap_boost_max, true, npc.writable, listener); + + CollapsiblePanel deathSourceConditionsPane = new CollapsiblePanel("Actor Conditions applied to the killer: "); + deathSourceConditionsPane.setLayout(new JideBoxLayout(deathSourceConditionsPane, JideBoxLayout.PAGE_AXIS)); + deathSourceConditionsListModel = new SourceTimedConditionsListModel(deathEffect); + deathSourceConditionsList = new JList(deathSourceConditionsListModel); + deathSourceConditionsList.setCellRenderer(new TimedConditionsCellRenderer()); + deathSourceConditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + deathSourceConditionsPane.add(new JScrollPane(deathSourceConditionsList), JideBoxLayout.FIX); + final JPanel deathSourceTimedConditionsEditorPane = new JPanel(); + final JButton createDeathSourceCondition = new JButton(new ImageIcon(DefaultIcons.getCreateIcon())); + final JButton deleteDeathSourceCondition = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); + deathSourceConditionsList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + selectedDeathEffectSourceCondition = (NPC.TimedConditionEffect) deathSourceConditionsList.getSelectedValue(); + updateDeathSourceTimedConditionEditorPane(deathSourceTimedConditionsEditorPane, selectedDeathEffectSourceCondition, listener); + } + }); + if (npc.writable) { + JPanel listButtonsPane = new JPanel(); + listButtonsPane.setLayout(new JideBoxLayout(listButtonsPane, JideBoxLayout.LINE_AXIS, 6)); + createDeathSourceCondition.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + NPC.TimedConditionEffect condition = new NPC.TimedConditionEffect(); + deathSourceConditionsListModel.addItem(condition); + deathSourceConditionsList.setSelectedValue(condition, true); + listener.valueChanged(deathSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. + } + }); + deleteDeathSourceCondition.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (selectedDeathEffectSourceCondition != null) { + deathSourceConditionsListModel.removeItem(selectedDeathEffectSourceCondition); + selectedDeathEffectSourceCondition = null; + deathSourceConditionsList.clearSelection(); + listener.valueChanged(deathSourceConditionsList, null); //Item changed, but we took care of it, just do the usual notification and JSON update stuff. + } + } + }); + + listButtonsPane.add(createDeathSourceCondition, JideBoxLayout.FIX); + listButtonsPane.add(deleteDeathSourceCondition, JideBoxLayout.FIX); + listButtonsPane.add(new JPanel(), JideBoxLayout.VARY); + deathSourceConditionsPane.add(listButtonsPane, JideBoxLayout.FIX); + } + deathSourceTimedConditionsEditorPane.setLayout(new JideBoxLayout(deathSourceTimedConditionsEditorPane, JideBoxLayout.PAGE_AXIS)); + deathSourceConditionsPane.add(deathSourceTimedConditionsEditorPane, JideBoxLayout.FIX); + if (npc.death_effect == null || npc.death_effect.conditions_source == null || npc.death_effect.conditions_source.isEmpty()) { + deathSourceConditionsPane.collapse(); + } + deathEffectPane.add(deathSourceConditionsPane, JideBoxLayout.FIX); + combatTraitPane.add(deathEffectPane, JideBoxLayout.FIX); + + pane.add(combatTraitPane, JideBoxLayout.FIX); } - public void updateSourceTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) { + public void updateHitSourceTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) { pane.removeAll(); - if (sourceConditionBox != null) { - removeElementListener(sourceConditionBox); + if (hitSourceConditionBox != null) { + removeElementListener(hitSourceConditionBox); } boolean writable = ((NPC)target).writable; Project proj = ((NPC)target).getProject(); - sourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); - sourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); + hitSourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); + hitSourceConditionChance = 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); + 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 radioEffectGroup = new ButtonGroup(); - radioEffectGroup.add(sourceConditionApply); - radioEffectGroup.add(sourceConditionClear); - radioEffectGroup.add(sourceConditionImmunity); + radioEffectGroup.add(hitSourceConditionApply); + radioEffectGroup.add(hitSourceConditionClear); + radioEffectGroup.add(hitSourceConditionImmunity); - sourceConditionTimed = new JRadioButton("For a number of rounds"); - pane.add(sourceConditionTimed, JideBoxLayout.FIX); - sourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, 1, false, writable, listener); - sourceConditionForever = new JRadioButton("Forever"); - pane.add(sourceConditionForever, JideBoxLayout.FIX); + hitSourceConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(hitSourceConditionTimed, JideBoxLayout.FIX); + hitSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, 1, false, writable, listener); + hitSourceConditionForever = new JRadioButton("Forever"); + pane.add(hitSourceConditionForever, JideBoxLayout.FIX); ButtonGroup radioDurationGroup = new ButtonGroup(); - radioDurationGroup.add(sourceConditionTimed); - radioDurationGroup.add(sourceConditionForever); + radioDurationGroup.add(hitSourceConditionTimed); + radioDurationGroup.add(hitSourceConditionForever); - updateSourceTimedConditionWidgets(condition); + updateHitSourceTimedConditionWidgets(condition); - sourceConditionClear.addActionListener(new ActionListener() { + hitSourceConditionClear.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - listener.valueChanged(sourceConditionClear, new Boolean(sourceConditionClear.isSelected())); + listener.valueChanged(hitSourceConditionClear, new Boolean(hitSourceConditionClear.isSelected())); } }); - sourceConditionApply.addActionListener(new ActionListener() { + hitSourceConditionApply.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - listener.valueChanged(sourceConditionApply, new Boolean(sourceConditionApply.isSelected())); + listener.valueChanged(hitSourceConditionApply, new Boolean(hitSourceConditionApply.isSelected())); } }); - sourceConditionImmunity.addActionListener(new ActionListener() { + hitSourceConditionImmunity.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - listener.valueChanged(sourceConditionImmunity, new Boolean(sourceConditionImmunity.isSelected())); + listener.valueChanged(hitSourceConditionImmunity, new Boolean(hitSourceConditionImmunity.isSelected())); } }); - sourceConditionTimed.addActionListener(new ActionListener() { + hitSourceConditionTimed.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - listener.valueChanged(sourceConditionTimed, new Boolean(sourceConditionTimed.isSelected())); + listener.valueChanged(hitSourceConditionTimed, new Boolean(hitSourceConditionTimed.isSelected())); } }); - sourceConditionForever.addActionListener(new ActionListener() { + hitSourceConditionForever.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - listener.valueChanged(sourceConditionForever, new Boolean(sourceConditionForever.isSelected())); + listener.valueChanged(hitSourceConditionForever, new Boolean(hitSourceConditionForever.isSelected())); } }); pane.revalidate(); pane.repaint(); } - public void updateSourceTimedConditionWidgets(NPC.TimedConditionEffect condition) { + public void updateHitSourceTimedConditionWidgets(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); + hitSourceConditionClear.setSelected(clear); + hitSourceConditionApply.setSelected(!clear && !immunity); + hitSourceConditionMagnitude.setEnabled(!clear && !immunity); + hitSourceConditionImmunity.setSelected(immunity); - sourceConditionTimed.setSelected(!forever); - sourceConditionTimed.setEnabled(!clear); - sourceConditionDuration.setEnabled(!clear && !forever); - sourceConditionForever.setSelected(forever); - sourceConditionForever.setEnabled(!clear); + hitSourceConditionTimed.setSelected(!forever); + hitSourceConditionTimed.setEnabled(!clear); + hitSourceConditionDuration.setEnabled(!clear && !forever); + hitSourceConditionForever.setSelected(forever); + hitSourceConditionForever.setEnabled(!clear); } - public void updateTargetTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) { + public void updateHitTargetTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) { pane.removeAll(); - if (targetConditionBox != null) { - removeElementListener(targetConditionBox); + if (hitTargetConditionBox != null) { + removeElementListener(hitTargetConditionBox); } boolean writable = ((NPC)target).writable; Project proj = ((NPC)target).getProject(); - targetConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, 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); + hitTargetConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); + hitTargetConditionChance = addDoubleField(pane, "Chance: ", condition.chance, 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 radioEffectGroup = new ButtonGroup(); - radioEffectGroup.add(targetConditionApply); - radioEffectGroup.add(targetConditionClear); - radioEffectGroup.add(targetConditionImmunity); + radioEffectGroup.add(hitTargetConditionApply); + radioEffectGroup.add(hitTargetConditionClear); + radioEffectGroup.add(hitTargetConditionImmunity); - targetConditionTimed = new JRadioButton("For a number of rounds"); - pane.add(targetConditionTimed, JideBoxLayout.FIX); - targetConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, 1, false, writable, listener); - targetConditionForever = new JRadioButton("Forever"); - pane.add(targetConditionForever, JideBoxLayout.FIX); + hitTargetConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(hitTargetConditionTimed, JideBoxLayout.FIX); + hitTargetConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, 1, false, writable, listener); + hitTargetConditionForever = new JRadioButton("Forever"); + pane.add(hitTargetConditionForever, JideBoxLayout.FIX); ButtonGroup radioDurationGroup = new ButtonGroup(); - radioDurationGroup.add(targetConditionTimed); - radioDurationGroup.add(targetConditionForever); + radioDurationGroup.add(hitTargetConditionTimed); + radioDurationGroup.add(hitTargetConditionForever); - updateTargetTimedConditionWidgets(condition); + updateHitTargetTimedConditionWidgets(condition); - targetConditionClear.addActionListener(new ActionListener() { + hitTargetConditionClear.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - listener.valueChanged(targetConditionClear, new Boolean(targetConditionClear.isSelected())); + listener.valueChanged(hitTargetConditionClear, new Boolean(hitTargetConditionClear.isSelected())); } }); - targetConditionApply.addActionListener(new ActionListener() { + hitTargetConditionApply.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - listener.valueChanged(targetConditionApply, new Boolean(targetConditionApply.isSelected())); + listener.valueChanged(hitTargetConditionApply, new Boolean(hitTargetConditionApply.isSelected())); } }); - targetConditionImmunity.addActionListener(new ActionListener() { + hitTargetConditionImmunity.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - listener.valueChanged(targetConditionImmunity, new Boolean(targetConditionImmunity.isSelected())); + listener.valueChanged(hitTargetConditionImmunity, new Boolean(hitTargetConditionImmunity.isSelected())); } }); - targetConditionTimed.addActionListener(new ActionListener() { + hitTargetConditionTimed.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - listener.valueChanged(targetConditionTimed, new Boolean(targetConditionTimed.isSelected())); + listener.valueChanged(hitTargetConditionTimed, new Boolean(hitTargetConditionTimed.isSelected())); } }); - targetConditionForever.addActionListener(new ActionListener() { + hitTargetConditionForever.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - listener.valueChanged(targetConditionForever, new Boolean(targetConditionForever.isSelected())); + listener.valueChanged(hitTargetConditionForever, new Boolean(hitTargetConditionForever.isSelected())); } }); pane.revalidate(); pane.repaint(); } - public void updateTargetTimedConditionWidgets(NPC.TimedConditionEffect condition) { + public void updateHitTargetTimedConditionWidgets(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); + hitTargetConditionClear.setSelected(clear); + hitTargetConditionApply.setSelected(!clear && !immunity); + hitTargetConditionMagnitude.setEnabled(!clear && !immunity); + hitTargetConditionImmunity.setSelected(immunity); - targetConditionTimed.setSelected(!forever); - targetConditionTimed.setEnabled(!clear); - targetConditionDuration.setEnabled(!clear && !forever); - targetConditionForever.setSelected(forever); - targetConditionForever.setEnabled(!clear); + hitTargetConditionTimed.setSelected(!forever); + hitTargetConditionTimed.setEnabled(!clear); + hitTargetConditionDuration.setEnabled(!clear && !forever); + hitTargetConditionForever.setSelected(forever); + hitTargetConditionForever.setEnabled(!clear); } + + public void updateHitReceivedSourceTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) { + pane.removeAll(); + if (hitReceivedSourceConditionBox != null) { + removeElementListener(hitReceivedSourceConditionBox); + } + + boolean writable = ((NPC)target).writable; + Project proj = ((NPC)target).getProject(); + + hitReceivedSourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); + hitReceivedSourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); + + hitReceivedSourceConditionClear = new JRadioButton("Clear active condition"); + pane.add(hitReceivedSourceConditionClear, JideBoxLayout.FIX); + hitReceivedSourceConditionApply = new JRadioButton("Apply condition with magnitude"); + pane.add(hitReceivedSourceConditionApply, JideBoxLayout.FIX); + hitReceivedSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); + hitReceivedSourceConditionImmunity = new JRadioButton("Give immunity to condition"); + pane.add(hitReceivedSourceConditionImmunity, JideBoxLayout.FIX); + + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(hitReceivedSourceConditionApply); + radioEffectGroup.add(hitReceivedSourceConditionClear); + radioEffectGroup.add(hitReceivedSourceConditionImmunity); + + hitReceivedSourceConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(hitReceivedSourceConditionTimed, JideBoxLayout.FIX); + hitReceivedSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, 1, false, writable, listener); + hitReceivedSourceConditionForever = new JRadioButton("Forever"); + pane.add(hitReceivedSourceConditionForever, JideBoxLayout.FIX); + + ButtonGroup radioDurationGroup = new ButtonGroup(); + radioDurationGroup.add(hitReceivedSourceConditionTimed); + radioDurationGroup.add(hitReceivedSourceConditionForever); + + updateHitReceivedSourceTimedConditionWidgets(condition); + + hitReceivedSourceConditionClear.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedSourceConditionClear, new Boolean(hitReceivedSourceConditionClear.isSelected())); + } + }); + hitReceivedSourceConditionApply.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedSourceConditionApply, new Boolean(hitReceivedSourceConditionApply.isSelected())); + } + }); + hitReceivedSourceConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedSourceConditionImmunity, new Boolean(hitReceivedSourceConditionImmunity.isSelected())); + } + }); + + hitReceivedSourceConditionTimed.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedSourceConditionTimed, new Boolean(hitReceivedSourceConditionTimed.isSelected())); + } + }); + hitReceivedSourceConditionForever.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedSourceConditionForever, new Boolean(hitReceivedSourceConditionForever.isSelected())); + } + }); + pane.revalidate(); + pane.repaint(); + } + + public void updateHitReceivedSourceTimedConditionWidgets(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; + + hitReceivedSourceConditionClear.setSelected(clear); + hitReceivedSourceConditionApply.setSelected(!clear && !immunity); + hitReceivedSourceConditionMagnitude.setEnabled(!clear && !immunity); + hitReceivedSourceConditionImmunity.setSelected(immunity); + + hitReceivedSourceConditionTimed.setSelected(!forever); + hitReceivedSourceConditionTimed.setEnabled(!clear); + hitReceivedSourceConditionDuration.setEnabled(!clear && !forever); + hitReceivedSourceConditionForever.setSelected(forever); + hitReceivedSourceConditionForever.setEnabled(!clear); + } + + + public void updateHitReceivedTargetTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) { + pane.removeAll(); + if (hitReceivedTargetConditionBox != null) { + removeElementListener(hitReceivedTargetConditionBox); + } + + boolean writable = ((NPC)target).writable; + Project proj = ((NPC)target).getProject(); + + hitReceivedTargetConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); + hitReceivedTargetConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); + hitReceivedTargetConditionClear = new JRadioButton("Clear active condition"); + pane.add(hitReceivedTargetConditionClear, JideBoxLayout.FIX); + hitReceivedTargetConditionApply = new JRadioButton("Apply condition with magnitude"); + pane.add(hitReceivedTargetConditionApply, JideBoxLayout.FIX); + hitReceivedTargetConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); + hitReceivedTargetConditionImmunity = new JRadioButton("Give immunity to condition"); + pane.add(hitReceivedTargetConditionImmunity, JideBoxLayout.FIX); + + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(hitReceivedTargetConditionApply); + radioEffectGroup.add(hitReceivedTargetConditionClear); + radioEffectGroup.add(hitReceivedTargetConditionImmunity); + + hitReceivedTargetConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(hitReceivedTargetConditionTimed, JideBoxLayout.FIX); + hitReceivedTargetConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, 1, false, writable, listener); + hitReceivedTargetConditionForever = new JRadioButton("Forever"); + pane.add(hitReceivedTargetConditionForever, JideBoxLayout.FIX); + + ButtonGroup radioDurationGroup = new ButtonGroup(); + radioDurationGroup.add(hitReceivedTargetConditionTimed); + radioDurationGroup.add(hitReceivedTargetConditionForever); + + updateHitReceivedTargetTimedConditionWidgets(condition); + + hitReceivedTargetConditionClear.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedTargetConditionClear, new Boolean(hitReceivedTargetConditionClear.isSelected())); + } + }); + hitReceivedTargetConditionApply.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedTargetConditionApply, new Boolean(hitReceivedTargetConditionApply.isSelected())); + } + }); + hitReceivedTargetConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedTargetConditionImmunity, new Boolean(hitReceivedTargetConditionImmunity.isSelected())); + } + }); + + hitReceivedTargetConditionTimed.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedTargetConditionTimed, new Boolean(hitReceivedTargetConditionTimed.isSelected())); + } + }); + hitReceivedTargetConditionForever.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(hitReceivedTargetConditionForever, new Boolean(hitReceivedTargetConditionForever.isSelected())); + } + }); + pane.revalidate(); + pane.repaint(); + } + + public void updateHitReceivedTargetTimedConditionWidgets(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; + + hitReceivedTargetConditionClear.setSelected(clear); + hitReceivedTargetConditionApply.setSelected(!clear && !immunity); + hitReceivedTargetConditionMagnitude.setEnabled(!clear && !immunity); + hitReceivedTargetConditionImmunity.setSelected(immunity); + + hitReceivedTargetConditionTimed.setSelected(!forever); + hitReceivedTargetConditionTimed.setEnabled(!clear); + hitReceivedTargetConditionDuration.setEnabled(!clear && !forever); + hitReceivedTargetConditionForever.setSelected(forever); + hitReceivedTargetConditionForever.setEnabled(!clear); + } + + public void updateDeathSourceTimedConditionEditorPane(JPanel pane, NPC.TimedConditionEffect condition, final FieldUpdateListener listener) { + pane.removeAll(); + if (deathSourceConditionBox != null) { + removeElementListener(deathSourceConditionBox); + } + + boolean writable = ((NPC)target).writable; + Project proj = ((NPC)target).getProject(); + + deathSourceConditionBox = addActorConditionBox(pane, proj, "Actor Condition: ", condition.condition, writable, listener); + deathSourceConditionChance = addDoubleField(pane, "Chance: ", condition.chance, writable, listener); + + deathSourceConditionClear = new JRadioButton("Clear active condition"); + pane.add(deathSourceConditionClear, JideBoxLayout.FIX); + deathSourceConditionApply = new JRadioButton("Apply condition with magnitude"); + pane.add(deathSourceConditionApply, JideBoxLayout.FIX); + deathSourceConditionMagnitude = addIntegerField(pane, "Magnitude: ", condition.magnitude == null ? null : condition.magnitude >= 0 ? condition.magnitude : 0, 1, false, writable, listener); + deathSourceConditionImmunity = new JRadioButton("Give immunity to condition"); + pane.add(deathSourceConditionImmunity, JideBoxLayout.FIX); + + ButtonGroup radioEffectGroup = new ButtonGroup(); + radioEffectGroup.add(deathSourceConditionApply); + radioEffectGroup.add(deathSourceConditionClear); + radioEffectGroup.add(deathSourceConditionImmunity); + + deathSourceConditionTimed = new JRadioButton("For a number of rounds"); + pane.add(deathSourceConditionTimed, JideBoxLayout.FIX); + deathSourceConditionDuration = addIntegerField(pane, "Duration: ", condition.duration, 1, false, writable, listener); + deathSourceConditionForever = new JRadioButton("Forever"); + pane.add(deathSourceConditionForever, JideBoxLayout.FIX); + + ButtonGroup radioDurationGroup = new ButtonGroup(); + radioDurationGroup.add(deathSourceConditionTimed); + radioDurationGroup.add(deathSourceConditionForever); + + updateDeathSourceTimedConditionWidgets(condition); + + deathSourceConditionClear.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(deathSourceConditionClear, new Boolean(deathSourceConditionClear.isSelected())); + } + }); + deathSourceConditionApply.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(deathSourceConditionApply, new Boolean(deathSourceConditionApply.isSelected())); + } + }); + deathSourceConditionImmunity.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(deathSourceConditionImmunity, new Boolean(deathSourceConditionImmunity.isSelected())); + } + }); + + deathSourceConditionTimed.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(deathSourceConditionTimed, new Boolean(deathSourceConditionTimed.isSelected())); + } + }); + deathSourceConditionForever.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + listener.valueChanged(deathSourceConditionForever, new Boolean(deathSourceConditionForever.isSelected())); + } + }); + pane.revalidate(); + pane.repaint(); + } + + public void updateDeathSourceTimedConditionWidgets(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; + + deathSourceConditionClear.setSelected(clear); + deathSourceConditionApply.setSelected(!clear && !immunity); + deathSourceConditionMagnitude.setEnabled(!clear && !immunity); + deathSourceConditionImmunity.setSelected(immunity); + + deathSourceConditionTimed.setSelected(!forever); + deathSourceConditionTimed.setEnabled(!clear); + deathSourceConditionDuration.setEnabled(!clear && !forever); + deathSourceConditionForever.setSelected(forever); + deathSourceConditionForever.setEnabled(!clear); + } + public static class TargetTimedConditionsListModel implements ListModel { NPC.HitEffect source; @@ -570,9 +1090,9 @@ public class NPCEditor extends JSONElementEditor { public static class SourceTimedConditionsListModel implements ListModel { - NPC.HitEffect source; + NPC.DeathEffect source; - public SourceTimedConditionsListModel(NPC.HitEffect effect) { + public SourceTimedConditionsListModel(NPC.DeathEffect effect) { this.source = effect; } @@ -674,12 +1194,36 @@ public class NPCEditor extends JSONElementEditor { return true; } + public static boolean isNull(NPC.HitReceivedEffect effect) { + if (effect.ap_boost_min != null) return false; + if (effect.ap_boost_max != null) return false; + if (effect.hp_boost_min != null) return false; + if (effect.hp_boost_max != null) return false; + if (effect.ap_boost_min_target != null) return false; + if (effect.ap_boost_max_target != null) return false; + if (effect.hp_boost_min_target != null) return false; + if (effect.hp_boost_max_target != null) return false; + if (effect.conditions_source != null) return false; + if (effect.conditions_target != null) return false; + return true; + } + + public static boolean isNull(NPC.DeathEffect effect) { + if (effect.ap_boost_min != null) return false; + if (effect.ap_boost_max != null) return false; + if (effect.hp_boost_min != null) return false; + if (effect.hp_boost_max != null) return false; + if (effect.conditions_source != null) return false; + return true; + } + public class NPCFieldUpdater implements FieldUpdateListener { @Override public void valueChanged(JComponent source, Object value) { NPC npc = (NPC)target; - boolean updateHit = false; + boolean updateHit, updateHitReceived, updateDeath; + updateHit = updateHitReceived = updateDeath = false; if (source == idField) { //Events caused by cancel an ID edition. Dismiss. if (skipNext) { @@ -777,7 +1321,7 @@ public class NPCEditor extends JSONElementEditor { updateHit = true; } else if (source == hitSourceConditionsList) { updateHit = true; - } else if (source == sourceConditionBox) { + } else if (source == hitSourceConditionBox) { if (selectedHitEffectSourceCondition.condition != null) { selectedHitEffectSourceCondition.condition.removeBacklink(npc); } @@ -789,57 +1333,57 @@ public class NPCEditor extends JSONElementEditor { selectedHitEffectSourceCondition.condition_id = null; } hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); - } else if (source == sourceConditionClear && (Boolean) value) { + } else if (source == hitSourceConditionClear && (Boolean) value) { selectedHitEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; selectedHitEffectSourceCondition.duration = null; - updateSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + updateHitSourceTimedConditionWidgets(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(); + } 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 == ActorCondition.DURATION_NONE) { selectedHitEffectSourceCondition.duration = 1; } - updateSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + updateHitSourceTimedConditionWidgets(selectedHitEffectSourceCondition); hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); updateHit = true; - } else if (source == sourceConditionImmunity && (Boolean) value) { + } else if (source == hitSourceConditionImmunity && (Boolean) value) { selectedHitEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; - selectedHitEffectSourceCondition.duration = sourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) sourceConditionDuration.getValue(); + selectedHitEffectSourceCondition.duration = hitSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitSourceConditionDuration.getValue(); if (selectedHitEffectSourceCondition.duration == null || selectedHitEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { selectedHitEffectSourceCondition.duration = 1; } - updateSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + updateHitSourceTimedConditionWidgets(selectedHitEffectSourceCondition); hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); updateHit = true; - } else if (source == sourceConditionMagnitude) { + } else if (source == hitSourceConditionMagnitude) { selectedHitEffectSourceCondition.magnitude = (Integer) value; hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); updateHit = true; - } else if (source == sourceConditionTimed && (Boolean) value) { - selectedHitEffectSourceCondition.duration = (Integer) sourceConditionDuration.getValue(); + } else if (source == hitSourceConditionTimed && (Boolean) value) { + selectedHitEffectSourceCondition.duration = (Integer) hitSourceConditionDuration.getValue(); if (selectedHitEffectSourceCondition.duration == null || selectedHitEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { selectedHitEffectSourceCondition.duration = 1; } - updateSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + updateHitSourceTimedConditionWidgets(selectedHitEffectSourceCondition); hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); updateHit = true; - } else if (source == sourceConditionForever && (Boolean) value) { + } else if (source == hitSourceConditionForever && (Boolean) value) { selectedHitEffectSourceCondition.duration = ActorCondition.DURATION_FOREVER; - updateSourceTimedConditionWidgets(selectedHitEffectSourceCondition); + updateHitSourceTimedConditionWidgets(selectedHitEffectSourceCondition); hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); updateHit = true; - } else if (source == sourceConditionDuration) { + } else if (source == hitSourceConditionDuration) { selectedHitEffectSourceCondition.duration = (Integer) value; hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); updateHit = true; - } else if (source == sourceConditionChance) { + } else if (source == hitSourceConditionChance) { selectedHitEffectSourceCondition.chance = (Double) value; hitSourceConditionsListModel.itemChanged(selectedHitEffectSourceCondition); } else if (source == hitTargetConditionsList) { updateHit = true; - } else if (source == targetConditionBox) { + } else if (source == hitTargetConditionBox) { if (selectedHitEffectTargetCondition.condition != null) { selectedHitEffectTargetCondition.condition.removeBacklink(npc); } @@ -851,54 +1395,276 @@ public class NPCEditor extends JSONElementEditor { selectedHitEffectTargetCondition.condition_id = null; } hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); - } else if (source == targetConditionClear && (Boolean) value) { + } else if (source == hitTargetConditionClear && (Boolean) value) { selectedHitEffectTargetCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; selectedHitEffectTargetCondition.duration = null; - updateSourceTimedConditionWidgets(selectedHitEffectTargetCondition); + updateHitSourceTimedConditionWidgets(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(); + } 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; } - updateSourceTimedConditionWidgets(selectedHitEffectTargetCondition); + updateHitSourceTimedConditionWidgets(selectedHitEffectTargetCondition); hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); updateHit = true; - } else if (source == targetConditionImmunity && (Boolean) value) { + } else if (source == hitTargetConditionImmunity && (Boolean) value) { selectedHitEffectTargetCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; - selectedHitEffectTargetCondition.duration = targetConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) targetConditionDuration.getValue(); + selectedHitEffectTargetCondition.duration = hitTargetConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitTargetConditionDuration.getValue(); if (selectedHitEffectTargetCondition.duration == null || selectedHitEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { selectedHitEffectTargetCondition.duration = 1; } - updateSourceTimedConditionWidgets(selectedHitEffectTargetCondition); + updateHitSourceTimedConditionWidgets(selectedHitEffectTargetCondition); hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); updateHit = true; - } else if (source == targetConditionMagnitude) { + } else if (source == hitTargetConditionMagnitude) { selectedHitEffectTargetCondition.magnitude = (Integer) value; hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); updateHit = true; - } else if (source == targetConditionTimed && (Boolean) value) { - selectedHitEffectTargetCondition.duration = (Integer) targetConditionDuration.getValue(); + } else if (source == hitTargetConditionTimed && (Boolean) value) { + selectedHitEffectTargetCondition.duration = (Integer) hitTargetConditionDuration.getValue(); if (selectedHitEffectTargetCondition.duration == null || selectedHitEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { selectedHitEffectTargetCondition.duration = 1; } - updateSourceTimedConditionWidgets(selectedHitEffectTargetCondition); + updateHitSourceTimedConditionWidgets(selectedHitEffectTargetCondition); hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); updateHit = true; - } else if (source == targetConditionForever && (Boolean) value) { + } else if (source == hitTargetConditionForever && (Boolean) value) { selectedHitEffectTargetCondition.duration = ActorCondition.DURATION_FOREVER; - updateSourceTimedConditionWidgets(selectedHitEffectTargetCondition); + updateHitSourceTimedConditionWidgets(selectedHitEffectTargetCondition); hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); updateHit = true; - } else if (source == targetConditionDuration) { + } else if (source == hitTargetConditionDuration) { selectedHitEffectTargetCondition.duration = (Integer) value; hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); updateHit = true; - } else if (source == targetConditionChance) { + } else if (source == hitTargetConditionChance) { selectedHitEffectTargetCondition.chance = (Double) value; hitTargetConditionsListModel.itemChanged(selectedHitEffectTargetCondition); + } else if (source == hitReceivedEffectHPMin) { + hitReceivedEffect.hp_boost_min = (Integer) value; + updateHitReceived = true; + } else if (source == hitReceivedEffectHPMax) { + hitReceivedEffect.hp_boost_max = (Integer) value; + updateHitReceived = true; + } else if (source == hitReceivedEffectAPMin) { + hitReceivedEffect.ap_boost_min = (Integer) value; + updateHitReceived = true; + } else if (source == hitReceivedEffectAPMax) { + hitReceivedEffect.ap_boost_max = (Integer) value; + updateHitReceived = true; + } else if (source == hitReceivedEffectHPMinTarget) { + hitReceivedEffect.hp_boost_min_target = (Integer) value; + updateHitReceived = true; + } else if (source == hitReceivedEffectHPMaxTarget) { + hitReceivedEffect.hp_boost_max_target = (Integer) value; + updateHitReceived = true; + } else if (source == hitReceivedEffectAPMinTarget) { + hitReceivedEffect.ap_boost_min_target = (Integer) value; + updateHitReceived = true; + } else if (source == hitReceivedEffectAPMaxTarget) { + hitReceivedEffect.ap_boost_max_target = (Integer) value; + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionsList) { + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionBox) { + if (selectedHitReceivedEffectSourceCondition.condition != null) { + selectedHitReceivedEffectSourceCondition.condition.removeBacklink(npc); + } + selectedHitReceivedEffectSourceCondition.condition = (ActorCondition) value; + if (selectedHitReceivedEffectSourceCondition.condition != null) { + selectedHitReceivedEffectSourceCondition.condition.addBacklink(npc); + selectedHitReceivedEffectSourceCondition.condition_id = selectedHitReceivedEffectSourceCondition.condition.id; + } else { + selectedHitReceivedEffectSourceCondition.condition_id = null; + } + hitReceivedSourceConditionsListModel.itemChanged(selectedHitReceivedEffectSourceCondition); + } else if (source == hitReceivedSourceConditionClear && (Boolean) value) { + selectedHitReceivedEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitReceivedEffectSourceCondition.duration = null; + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectSourceCondition); + hitReceivedSourceConditionsListModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionApply && (Boolean) value) { + selectedHitReceivedEffectSourceCondition.magnitude = (Integer) hitReceivedSourceConditionMagnitude.getValue(); + selectedHitReceivedEffectSourceCondition.duration = hitReceivedSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitReceivedSourceConditionDuration.getValue(); + if (selectedHitReceivedEffectSourceCondition.duration == null || selectedHitReceivedEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectSourceCondition.duration = 1; + } + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectSourceCondition); + hitReceivedSourceConditionsListModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionImmunity && (Boolean) value) { + selectedHitReceivedEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitReceivedEffectSourceCondition.duration = hitReceivedSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitReceivedSourceConditionDuration.getValue(); + if (selectedHitReceivedEffectSourceCondition.duration == null || selectedHitReceivedEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectSourceCondition.duration = 1; + } + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectSourceCondition); + hitReceivedSourceConditionsListModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionMagnitude) { + selectedHitReceivedEffectSourceCondition.magnitude = (Integer) value; + hitReceivedSourceConditionsListModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionTimed && (Boolean) value) { + selectedHitReceivedEffectSourceCondition.duration = (Integer) hitReceivedSourceConditionDuration.getValue(); + if (selectedHitReceivedEffectSourceCondition.duration == null || selectedHitReceivedEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectSourceCondition.duration = 1; + } + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectSourceCondition); + hitReceivedSourceConditionsListModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionForever && (Boolean) value) { + selectedHitReceivedEffectSourceCondition.duration = ActorCondition.DURATION_FOREVER; + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectSourceCondition); + hitReceivedSourceConditionsListModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionDuration) { + selectedHitReceivedEffectSourceCondition.duration = (Integer) value; + hitReceivedSourceConditionsListModel.itemChanged(selectedHitReceivedEffectSourceCondition); + updateHitReceived = true; + } else if (source == hitReceivedSourceConditionChance) { + selectedHitReceivedEffectSourceCondition.chance = (Double) value; + hitReceivedSourceConditionsListModel.itemChanged(selectedHitReceivedEffectSourceCondition); + } else if (source == hitReceivedTargetConditionsList) { + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionBox) { + if (selectedHitReceivedEffectTargetCondition.condition != null) { + selectedHitReceivedEffectTargetCondition.condition.removeBacklink(npc); + } + selectedHitReceivedEffectTargetCondition.condition = (ActorCondition) value; + if (selectedHitReceivedEffectTargetCondition.condition != null) { + selectedHitReceivedEffectTargetCondition.condition_id = selectedHitReceivedEffectTargetCondition.condition.id; + selectedHitReceivedEffectTargetCondition.condition.addBacklink(npc); + } else { + selectedHitReceivedEffectTargetCondition.condition_id = null; + } + hitReceivedTargetConditionsListModel.itemChanged(selectedHitReceivedEffectTargetCondition); + } else if (source == hitReceivedTargetConditionClear && (Boolean) value) { + selectedHitReceivedEffectTargetCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitReceivedEffectTargetCondition.duration = null; + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectTargetCondition); + hitReceivedTargetConditionsListModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionApply && (Boolean) value) { + selectedHitReceivedEffectTargetCondition.magnitude = (Integer) hitReceivedTargetConditionMagnitude.getValue(); + selectedHitReceivedEffectTargetCondition.duration = hitReceivedTargetConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitReceivedTargetConditionDuration.getValue(); + if (selectedHitReceivedEffectTargetCondition.duration == null || selectedHitReceivedEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectTargetCondition.duration = 1; + } + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectTargetCondition); + hitReceivedTargetConditionsListModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionImmunity && (Boolean) value) { + selectedHitReceivedEffectTargetCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedHitReceivedEffectTargetCondition.duration = hitReceivedTargetConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) hitReceivedTargetConditionDuration.getValue(); + if (selectedHitReceivedEffectTargetCondition.duration == null || selectedHitReceivedEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectTargetCondition.duration = 1; + } + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectTargetCondition); + hitReceivedTargetConditionsListModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionMagnitude) { + selectedHitReceivedEffectTargetCondition.magnitude = (Integer) value; + hitReceivedTargetConditionsListModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionTimed && (Boolean) value) { + selectedHitReceivedEffectTargetCondition.duration = (Integer) hitReceivedTargetConditionDuration.getValue(); + if (selectedHitReceivedEffectTargetCondition.duration == null || selectedHitReceivedEffectTargetCondition.duration == ActorCondition.DURATION_NONE) { + selectedHitReceivedEffectTargetCondition.duration = 1; + } + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectTargetCondition); + hitReceivedTargetConditionsListModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionForever && (Boolean) value) { + selectedHitReceivedEffectTargetCondition.duration = ActorCondition.DURATION_FOREVER; + updateHitReceivedSourceTimedConditionWidgets(selectedHitReceivedEffectTargetCondition); + hitReceivedTargetConditionsListModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionDuration) { + selectedHitReceivedEffectTargetCondition.duration = (Integer) value; + hitReceivedTargetConditionsListModel.itemChanged(selectedHitReceivedEffectTargetCondition); + updateHitReceived = true; + } else if (source == hitReceivedTargetConditionChance) { + selectedHitReceivedEffectTargetCondition.chance = (Double) value; + hitReceivedTargetConditionsListModel.itemChanged(selectedHitReceivedEffectTargetCondition); + } else if (source == deathEffectHPMin) { + deathEffect.hp_boost_min = (Integer) value; + updateDeath = true; + } else if (source == deathEffectHPMax) { + deathEffect.hp_boost_max = (Integer) value; + updateDeath = true; + } else if (source == deathEffectAPMin) { + deathEffect.ap_boost_min = (Integer) value; + updateDeath = true; + } else if (source == deathEffectAPMax) { + deathEffect.ap_boost_max = (Integer) value; + updateDeath = true; + } else if (source == deathSourceConditionsList) { + updateDeath = true; + } else if (source == deathSourceConditionBox) { + if (selectedDeathEffectSourceCondition.condition != null) { + selectedDeathEffectSourceCondition.condition.removeBacklink(npc); + } + selectedDeathEffectSourceCondition.condition = (ActorCondition) value; + if (selectedDeathEffectSourceCondition.condition != null) { + selectedDeathEffectSourceCondition.condition.addBacklink(npc); + selectedDeathEffectSourceCondition.condition_id = selectedDeathEffectSourceCondition.condition.id; + } else { + selectedDeathEffectSourceCondition.condition_id = null; + } + deathSourceConditionsListModel.itemChanged(selectedDeathEffectSourceCondition); + } else if (source == deathSourceConditionClear && (Boolean) value) { + selectedDeathEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedDeathEffectSourceCondition.duration = null; + updateDeathSourceTimedConditionWidgets(selectedDeathEffectSourceCondition); + deathSourceConditionsListModel.itemChanged(selectedDeathEffectSourceCondition); + updateDeath = true; + } else if (source == deathSourceConditionApply && (Boolean) value) { + selectedDeathEffectSourceCondition.magnitude = (Integer) deathSourceConditionMagnitude.getValue(); + selectedDeathEffectSourceCondition.duration = deathSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) deathSourceConditionDuration.getValue(); + if (selectedDeathEffectSourceCondition.duration == null || selectedDeathEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedDeathEffectSourceCondition.duration = 1; + } + updateDeathSourceTimedConditionWidgets(selectedDeathEffectSourceCondition); + deathSourceConditionsListModel.itemChanged(selectedDeathEffectSourceCondition); + updateDeath = true; + } else if (source == deathSourceConditionImmunity && (Boolean) value) { + selectedDeathEffectSourceCondition.magnitude = ActorCondition.MAGNITUDE_CLEAR; + selectedDeathEffectSourceCondition.duration = deathSourceConditionForever.isSelected() ? ActorCondition.DURATION_FOREVER : (Integer) deathSourceConditionDuration.getValue(); + if (selectedDeathEffectSourceCondition.duration == null || selectedDeathEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedDeathEffectSourceCondition.duration = 1; + } + updateDeathSourceTimedConditionWidgets(selectedDeathEffectSourceCondition); + deathSourceConditionsListModel.itemChanged(selectedDeathEffectSourceCondition); + updateDeath = true; + } else if (source == deathSourceConditionMagnitude) { + selectedDeathEffectSourceCondition.magnitude = (Integer) value; + deathSourceConditionsListModel.itemChanged(selectedDeathEffectSourceCondition); + updateDeath = true; + } else if (source == deathSourceConditionTimed && (Boolean) value) { + selectedDeathEffectSourceCondition.duration = (Integer) deathSourceConditionDuration.getValue(); + if (selectedDeathEffectSourceCondition.duration == null || selectedDeathEffectSourceCondition.duration == ActorCondition.DURATION_NONE) { + selectedDeathEffectSourceCondition.duration = 1; + } + updateDeathSourceTimedConditionWidgets(selectedDeathEffectSourceCondition); + deathSourceConditionsListModel.itemChanged(selectedDeathEffectSourceCondition); + updateDeath = true; + } else if (source == deathSourceConditionForever && (Boolean) value) { + selectedDeathEffectSourceCondition.duration = ActorCondition.DURATION_FOREVER; + updateDeathSourceTimedConditionWidgets(selectedDeathEffectSourceCondition); + deathSourceConditionsListModel.itemChanged(selectedDeathEffectSourceCondition); + updateDeath = true; + } else if (source == deathSourceConditionDuration) { + selectedDeathEffectSourceCondition.duration = (Integer) value; + deathSourceConditionsListModel.itemChanged(selectedDeathEffectSourceCondition); + updateDeath = true; + } else if (source == deathSourceConditionChance) { + selectedDeathEffectSourceCondition.chance = (Double) value; + deathSourceConditionsListModel.itemChanged(selectedDeathEffectSourceCondition); } if (updateHit) { @@ -908,6 +1674,20 @@ public class NPCEditor extends JSONElementEditor { npc.hit_effect = hitEffect; } } + if (updateHitReceived) { + if (isNull(hitReceivedEffect)) { + npc.hit_received_effect = null; + } else { + npc.hit_received_effect = hitReceivedEffect; + } + } + if (updateDeath) { + if (isNull(deathEffect)) { + npc.death_effect = null; + } else { + npc.death_effect = deathEffect; + } + } experienceField.setValue(npc.getMonsterExperience());