From 858ee7be2e08f7d9945fbbf30adfe566d21a14bb Mon Sep 17 00:00:00 2001 From: Alex Henry Date: Fri, 15 Jul 2016 12:37:10 -0300 Subject: [PATCH] 1.6 (training hall fix) --- javelin/Javelin.java | 4 + .../factor/quality/BreathFactor.java | 37 ++++----- javelin/controller/fight/TempleEncounter.java | 4 +- javelin/controller/fight/TrainingSession.java | 34 +------- .../encounter/EncounterGenerator.java | 4 + ...hWeaponUpgrade.java => BreathUpgrade.java} | 11 ++- javelin/controller/upgrade/NaturalArmor.java | 7 +- javelin/controller/upgrade/damage/Damage.java | 7 ++ javelin/model/unit/Combatant.java | 49 ++++++++++++ .../location/unique/MercenariesGuild.java | 28 +------ .../world/location/unique/TrainingHall.java | 77 +++++++++++++------ 11 files changed, 154 insertions(+), 108 deletions(-) rename javelin/controller/upgrade/{BreathWeaponUpgrade.java => BreathUpgrade.java} (78%) diff --git a/javelin/Javelin.java b/javelin/Javelin.java index c370112..aeedf2a 100644 --- a/javelin/Javelin.java +++ b/javelin/Javelin.java @@ -206,6 +206,10 @@ public class Javelin { * @return Hour of the day, from 0 to 23. */ public static long getHour() { + if (Squad.active == null) { + /* all training */ + return 0; + } return Squad.active.hourselapsed % 24; } diff --git a/javelin/controller/challenge/factor/quality/BreathFactor.java b/javelin/controller/challenge/factor/quality/BreathFactor.java index 4c251a5..679d9f9 100644 --- a/javelin/controller/challenge/factor/quality/BreathFactor.java +++ b/javelin/controller/challenge/factor/quality/BreathFactor.java @@ -1,7 +1,7 @@ package javelin.controller.challenge.factor.quality; import javelin.controller.challenge.factor.CrFactor; -import javelin.controller.upgrade.BreathWeaponUpgrade; +import javelin.controller.upgrade.BreathUpgrade; import javelin.controller.upgrade.UpgradeHandler; import javelin.model.unit.Monster; import javelin.model.unit.abilities.BreathWeapon; @@ -44,27 +44,28 @@ public class BreathFactor extends CrFactor { @Override public void listupgrades(UpgradeHandler handler) { - handler.fire.add(new BreathWeaponUpgrade( - new BreathWeapon("cone of magma", BreathArea.CONE, 10, 1, 4, 0, - SavingThrow.REFLEXES, 13, .5f, true))); - handler.water.add(new BreathWeaponUpgrade( + /* Too weak, doesnt resolve to positive CR */ + // handler.fire.add(new BreathUpgrade( + // new BreathWeapon("cone of magma", BreathArea.CONE, 10, 1, 4, 0, + // SavingThrow.REFLEXES, 13, .5f, true))); + handler.water.add(new BreathUpgrade( new BreathWeapon("caustic liquid", BreathArea.CONE, 15, 1, 8, 0, SavingThrow.REFLEXES, 12, .5f, true))); - handler.evil.add(new BreathWeaponUpgrade( - new BreathWeapon("acid", BreathArea.LINE, 80, 12, 4, 0, - SavingThrow.REFLEXES, 23, .5f, true))); - handler.wind.add(new BreathWeaponUpgrade( - new BreathWeapon("lightning", BreathArea.LINE, 100, 12, 8, 0, - SavingThrow.REFLEXES, 25, .5f, true))); - handler.fire.add(new BreathWeaponUpgrade( - new BreathWeapon("fire", BreathArea.CONE, 50, 12, 10, 0, - SavingThrow.REFLEXES, 25, .5f, true))); - handler.earth.add(new BreathWeaponUpgrade( + handler.evil + .add(new BreathUpgrade(new BreathWeapon("acid", BreathArea.LINE, + 80, 12, 4, 0, SavingThrow.REFLEXES, 23, .5f, true))); + handler.wind.add( + new BreathUpgrade(new BreathWeapon("lightning", BreathArea.LINE, + 100, 12, 8, 0, SavingThrow.REFLEXES, 25, .5f, true))); + handler.fire + .add(new BreathUpgrade(new BreathWeapon("fire", BreathArea.CONE, + 50, 12, 10, 0, SavingThrow.REFLEXES, 25, .5f, true))); + handler.earth.add(new BreathUpgrade( new BreathWeapon("corrosive gas", BreathArea.CONE, 50, 12, 6, 0, SavingThrow.REFLEXES, 25, .5f, true))); - handler.wind.add(new BreathWeaponUpgrade( - new BreathWeapon("cold", BreathArea.CONE, 40, 6, 6, 0, - SavingThrow.REFLEXES, 23, .5f, true))); + handler.wind + .add(new BreathUpgrade(new BreathWeapon("cold", BreathArea.CONE, + 40, 6, 6, 0, SavingThrow.REFLEXES, 23, .5f, true))); } } diff --git a/javelin/controller/fight/TempleEncounter.java b/javelin/controller/fight/TempleEncounter.java index c61d446..b3317ed 100644 --- a/javelin/controller/fight/TempleEncounter.java +++ b/javelin/controller/fight/TempleEncounter.java @@ -11,7 +11,6 @@ import javelin.model.state.BattleState; import javelin.model.unit.Combatant; import javelin.model.world.location.dungeon.Dungeon; import javelin.model.world.location.dungeon.temple.Temple; -import javelin.model.world.location.unique.MercenariesGuild; import javelin.view.screen.BattleScreen; import tyrant.mikera.engine.RPG; @@ -37,8 +36,7 @@ public class TempleEncounter extends RandomDungeonEncounter { @Override public void enhance(List foes) { while (ChallengeRatingCalculator.calculateel(foes) < temple.el) { - Combatant foe = RPG.pick(foes); - MercenariesGuild.upgradeunit(foe, temple.realm); + Combatant.upgradeweakest(foes, temple.realm); } } diff --git a/javelin/controller/fight/TrainingSession.java b/javelin/controller/fight/TrainingSession.java index c36000a..a9cf777 100644 --- a/javelin/controller/fight/TrainingSession.java +++ b/javelin/controller/fight/TrainingSession.java @@ -2,19 +2,14 @@ package javelin.controller.fight; import java.util.ArrayList; -import javelin.Javelin; import javelin.controller.Weather; import javelin.controller.terrain.map.Arena; -import javelin.controller.upgrade.UpgradeHandler; -import javelin.controller.upgrade.feat.FeatUpgrade; import javelin.model.BattleMap; import javelin.model.state.BattleState; import javelin.model.unit.Combatant; -import javelin.model.unit.Squad; import javelin.model.world.location.Location; import javelin.model.world.location.unique.TrainingHall; import javelin.view.screen.BattleScreen; -import tyrant.mikera.engine.RPG; /** * A {@link Fight} that happens inside the {@link TrainingHall}. @@ -44,33 +39,6 @@ public class TrainingSession extends Siege { if (!BattleMap.victory) { return; } - hall.currentlevel += 1; - boolean done = hall.currentlevel - 1 >= TrainingHall.EL.length; - String prefix; - if (done) { - prefix = "This has been the final lesson.\n\n"; - } else { - prefix = "Congratulations, you've graduated this level!\n\n"; - } - Combatant student = Squad.active.members - .get(Javelin.choose(prefix + "Which student will learn a feat?", - Squad.active.members, true, true)); - ArrayList feats = UpgradeHandler.singleton.getfeats(); - ArrayList options = new ArrayList(); - while (options.size() < 3 && !feats.isEmpty()) { - FeatUpgrade f = RPG.pick(feats); - feats.remove(f); - if (!options.contains(f) - && f.upgrade(student.clone().clonesource())) { - options.add(f); - } - } - options.get(Javelin.choose("Learn which feat?", options, true, true)) - .upgrade(student); - if (done) { - hall.remove(); - } else { - hall.generategarrison(); - } + hall.level(); } } diff --git a/javelin/controller/generator/encounter/EncounterGenerator.java b/javelin/controller/generator/encounter/EncounterGenerator.java index 91ab305..acf7eb9 100644 --- a/javelin/controller/generator/encounter/EncounterGenerator.java +++ b/javelin/controller/generator/encounter/EncounterGenerator.java @@ -137,6 +137,10 @@ public class EncounterGenerator { * enemies). */ public static int getmaxenemynumber() { + if (Squad.active == null) { + /* all training */ + return 4 + 5; + } return Squad.active.members.size() + 5; } diff --git a/javelin/controller/upgrade/BreathWeaponUpgrade.java b/javelin/controller/upgrade/BreathUpgrade.java similarity index 78% rename from javelin/controller/upgrade/BreathWeaponUpgrade.java rename to javelin/controller/upgrade/BreathUpgrade.java index 74f8a07..f1e3b7b 100644 --- a/javelin/controller/upgrade/BreathWeaponUpgrade.java +++ b/javelin/controller/upgrade/BreathUpgrade.java @@ -9,10 +9,14 @@ import javelin.model.unit.abilities.BreathWeapon; * * @author alex */ -public class BreathWeaponUpgrade extends Upgrade { +public class BreathUpgrade extends Upgrade { final private BreathWeapon breath; - public BreathWeaponUpgrade(BreathWeapon breathp) { + /** + * @param breathp + * Breath to apply. + */ + public BreathUpgrade(BreathWeapon breathp) { super("Breath weapon: " + breathp.description); breath = breathp; } @@ -24,6 +28,9 @@ public class BreathWeaponUpgrade extends Upgrade { @Override public boolean apply(Combatant m) { + if (breath.damage[0] > m.source.hd.count()) { + return false; + } for (BreathWeapon b : m.source.breaths) { if (b.description.equals(breath.description)) { return false; diff --git a/javelin/controller/upgrade/NaturalArmor.java b/javelin/controller/upgrade/NaturalArmor.java index b090a02..7fd8df4 100644 --- a/javelin/controller/upgrade/NaturalArmor.java +++ b/javelin/controller/upgrade/NaturalArmor.java @@ -22,12 +22,13 @@ public class NaturalArmor extends Upgrade { @Override public boolean apply(final Combatant c) { Monster m = c.source; - if (m.armor >= target || m.ac + 10 < target) { + int newac = m.ac + target - m.armor; + if (target < m.armor || newac > m.ac + 10 + || newac > m.dexterity + m.constitution) { return false; } - int delta = target - m.armor; m.armor = target; - m.ac += delta; + m.ac = newac; return true; } } \ No newline at end of file diff --git a/javelin/controller/upgrade/damage/Damage.java b/javelin/controller/upgrade/damage/Damage.java index 94823c3..6141efc 100644 --- a/javelin/controller/upgrade/damage/Damage.java +++ b/javelin/controller/upgrade/damage/Damage.java @@ -45,6 +45,13 @@ public abstract class Damage extends Upgrade { if (all.isEmpty()) { return false; } + for (final List sequence : all) { + for (final Attack a : sequence) { + if (a.damage[0] + 1 > m.source.hd.count()) { + return false; + } + } + } for (final List sequence : all) { for (final Attack a : sequence) { a.damage[0] += 1; diff --git a/javelin/model/unit/Combatant.java b/javelin/model/unit/Combatant.java index 497764f..ea4f9bc 100644 --- a/javelin/model/unit/Combatant.java +++ b/javelin/model/unit/Combatant.java @@ -11,12 +11,17 @@ import javelin.controller.action.Action; import javelin.controller.action.Defend; import javelin.controller.action.ai.MeleeAttack; import javelin.controller.ai.BattleAi; +import javelin.controller.challenge.ChallengeRatingCalculator; import javelin.controller.exception.RepeatTurn; import javelin.controller.old.Game; import javelin.controller.old.Game.Delay; +import javelin.controller.upgrade.BreathUpgrade; import javelin.controller.upgrade.Spell; +import javelin.controller.upgrade.Upgrade; +import javelin.controller.upgrade.UpgradeHandler; import javelin.model.BattleMap; import javelin.model.Cloneable; +import javelin.model.Realm; import javelin.model.TeamContainer; import javelin.model.condition.Charging; import javelin.model.condition.Condition; @@ -650,4 +655,48 @@ public class Combatant implements Serializable, Cloneable { source = source.clone(); return this; } + + /** + * Updates {@link Monster#challengeRating} internally. + * + * @param r + * Applies one {@link Upgrade} from this set to the given + * {@link Combatant}. + * @return + * @return true if an upgrade has been successfully applied. + * @see Upgrade#upgrade(Combatant) + */ + public boolean upgrade(Realm r) { + Upgrade upgrade = RPG.pick(new ArrayList( + UpgradeHandler.singleton.getfullupgrades(r))); + if (upgrade instanceof BreathUpgrade) { + /* TODO Breaths are pretty CPU intensive right now so avoid them */ + return false; + } + if (!upgrade.upgrade(this)) { + return false; + } + if (upgrade.purchaseskills) { + source.purchaseskills(upgrade).upgradeautomatically(); + } + ChallengeRatingCalculator.calculateCr(source); + return true; + } + + /** + * @param garrison + * Upgrades the weakest member of this group. + * @see #upgrade(Realm) + */ + public static void upgradeweakest(List garrison, Realm r) { + Combatant weakest = null; + for (Combatant sensei : garrison) { + ChallengeRatingCalculator.calculateCr(sensei.source); + if (weakest == null + || sensei.source.challengeRating < weakest.source.challengeRating) { + weakest = sensei; + } + } + weakest.upgrade(r); + } } diff --git a/javelin/model/world/location/unique/MercenariesGuild.java b/javelin/model/world/location/unique/MercenariesGuild.java index bd13980..b370dd0 100644 --- a/javelin/model/world/location/unique/MercenariesGuild.java +++ b/javelin/model/world/location/unique/MercenariesGuild.java @@ -9,9 +9,6 @@ import javelin.Javelin; import javelin.controller.challenge.ChallengeRatingCalculator; import javelin.controller.challenge.RewardCalculator; import javelin.controller.old.Game; -import javelin.controller.upgrade.BreathWeaponUpgrade; -import javelin.controller.upgrade.Upgrade; -import javelin.controller.upgrade.UpgradeHandler; import javelin.model.Realm; import javelin.model.unit.Combatant; import javelin.model.unit.Monster; @@ -68,7 +65,7 @@ public class MercenariesGuild extends UniqueLocation { } int tries = 0; while (c.source.challengeRating < cr) { - upgradeunit(c, r); + c.upgrade(r); tries += 1; if (tries >= 100) { return; @@ -78,29 +75,6 @@ public class MercenariesGuild extends UniqueLocation { all.add(c); } - /** - * Updates {@link Monster#challengeRating} internally. - * - * @param r - * Applies one {@link Upgrade} from this set to the given - * {@link Combatant}. - */ - static public void upgradeunit(Combatant c, Realm r) { - Upgrade upgrade = RPG.pick(new ArrayList( - UpgradeHandler.singleton.getfullupgrades(r))); - if (upgrade instanceof BreathWeaponUpgrade) { - /* TODO Breaths are pretty CPU intensive right now so avoid them */ - return; - } - if (!upgrade.upgrade(c)) { - return; - } - if (upgrade.purchaseskills) { - c.source.purchaseskills(upgrade).upgradeautomatically(); - } - ChallengeRatingCalculator.calculateCr(c.source); - } - @Override public boolean interact() { if (!super.interact()) { diff --git a/javelin/model/world/location/unique/TrainingHall.java b/javelin/model/world/location/unique/TrainingHall.java index 0783449..e028751 100644 --- a/javelin/model/world/location/unique/TrainingHall.java +++ b/javelin/model/world/location/unique/TrainingHall.java @@ -11,10 +11,14 @@ import javelin.controller.fight.Siege; import javelin.controller.fight.TrainingSession; import javelin.controller.old.Game; import javelin.controller.old.Game.Delay; +import javelin.controller.upgrade.UpgradeHandler; +import javelin.controller.upgrade.feat.FeatUpgrade; +import javelin.model.Realm; import javelin.model.unit.Combatant; import javelin.model.unit.Monster; import javelin.model.unit.Squad; import javelin.model.world.location.fortification.Fortification; +import javelin.view.screen.SquadScreen; import tyrant.mikera.engine.RPG; /** @@ -32,9 +36,10 @@ public class TrainingHall extends Fortification { private static final String DESCRIPTION = "The Training Hall"; /** * Actual encounter level for each {@link TrainingSession}, by using the - * shifted-to-zero index. + * shifted-to-zero index. Supposed to be difficult (EL-1) encounter party of + * levels 1 to 4. */ - public static int[] EL = new int[] { 2, 7, 10, 17 }; + public static int[] EL = new int[] { 4, 8, 10, 12 }; /** * From 1 upwards, the current training session difficulty, supposed to * represent different floors. @@ -61,29 +66,26 @@ public class TrainingHall extends Fortification { if (currentlevel == null) { currentlevel = 1; } - garrison.clear(); - ArrayList candidates = new ArrayList(); - for (float cr : Javelin.MONSTERSBYCR.descendingKeySet()) { - if (1 <= cr && cr <= Math.max(currentlevel, 2)) { - candidates.clear(); - for (Monster m : Javelin.MONSTERSBYCR.get(cr)) { - if (m.think(0)) { - candidates.add(m); - } - } - if (!candidates.isEmpty()) { - break; - } + // garrison.clear(); + ArrayList senseis = SquadScreen.getcandidates(); + for (Monster sensei : new ArrayList(senseis)) { + if (!sensei.think(0)) { + senseis.remove(sensei); } } - while (ChallengeRatingCalculator - .calculateel(garrison) < EL[currentlevel - 1]) { - garrison.add( - new Combatant(null, RPG.pick(candidates).clone(), true)); - if (DEBUG) { - break; - } + int nstudents = Squad.active.members.size(); + int nsenseis = RPG.r(Math.min(3, nstudents), RPG.max(nstudents, 5)); + while (isweak() && garrison.size() < nsenseis) { + garrison.add(new Combatant(null, RPG.pick(senseis).clone(), true)); } + while (isweak()) { + Combatant.upgradeweakest(garrison, Realm.random()); + } + } + + boolean isweak() { + return ChallengeRatingCalculator + .calculateel(garrison) < EL[currentlevel - 1]; } @Override @@ -116,4 +118,35 @@ public class TrainingHall extends Fortification { public List getcombatants() { return garrison; } + + public void level() { + currentlevel += 1; + boolean done = currentlevel - 1 >= EL.length; + String prefix; + if (done) { + prefix = "This has been the final lesson.\n\n"; + } else { + prefix = "Congratulations, you've graduated this level!\n\n"; + } + Combatant student = Squad.active.members + .get(Javelin.choose(prefix + "Which student will learn a feat?", + Squad.active.members, true, true)); + ArrayList feats = UpgradeHandler.singleton.getfeats(); + ArrayList options = new ArrayList(); + while (options.size() < 3 && !feats.isEmpty()) { + FeatUpgrade f = RPG.pick(feats); + feats.remove(f); + if (!options.contains(f) + && f.upgrade(student.clone().clonesource())) { + options.add(f); + } + } + options.get(Javelin.choose("Learn which feat?", options, true, true)) + .upgrade(student); + if (done) { + remove(); + } else { + generategarrison(); + } + } }