1.6 (training hall fix)

master
Alex Henry 2016-07-15 12:37:10 -03:00
parent 064d0557c1
commit 858ee7be2e
11 changed files with 154 additions and 108 deletions

View File

@ -206,6 +206,10 @@ public class Javelin {
* @return Hour of the day, from 0 to 23. * @return Hour of the day, from 0 to 23.
*/ */
public static long getHour() { public static long getHour() {
if (Squad.active == null) {
/* all training */
return 0;
}
return Squad.active.hourselapsed % 24; return Squad.active.hourselapsed % 24;
} }

View File

@ -1,7 +1,7 @@
package javelin.controller.challenge.factor.quality; package javelin.controller.challenge.factor.quality;
import javelin.controller.challenge.factor.CrFactor; import javelin.controller.challenge.factor.CrFactor;
import javelin.controller.upgrade.BreathWeaponUpgrade; import javelin.controller.upgrade.BreathUpgrade;
import javelin.controller.upgrade.UpgradeHandler; import javelin.controller.upgrade.UpgradeHandler;
import javelin.model.unit.Monster; import javelin.model.unit.Monster;
import javelin.model.unit.abilities.BreathWeapon; import javelin.model.unit.abilities.BreathWeapon;
@ -44,27 +44,28 @@ public class BreathFactor extends CrFactor {
@Override @Override
public void listupgrades(UpgradeHandler handler) { public void listupgrades(UpgradeHandler handler) {
handler.fire.add(new BreathWeaponUpgrade( /* Too weak, doesnt resolve to positive CR */
new BreathWeapon("cone of magma", BreathArea.CONE, 10, 1, 4, 0, // handler.fire.add(new BreathUpgrade(
SavingThrow.REFLEXES, 13, .5f, true))); // new BreathWeapon("cone of magma", BreathArea.CONE, 10, 1, 4, 0,
handler.water.add(new BreathWeaponUpgrade( // SavingThrow.REFLEXES, 13, .5f, true)));
handler.water.add(new BreathUpgrade(
new BreathWeapon("caustic liquid", BreathArea.CONE, 15, 1, 8, 0, new BreathWeapon("caustic liquid", BreathArea.CONE, 15, 1, 8, 0,
SavingThrow.REFLEXES, 12, .5f, true))); SavingThrow.REFLEXES, 12, .5f, true)));
handler.evil.add(new BreathWeaponUpgrade( handler.evil
new BreathWeapon("acid", BreathArea.LINE, 80, 12, 4, 0, .add(new BreathUpgrade(new BreathWeapon("acid", BreathArea.LINE,
SavingThrow.REFLEXES, 23, .5f, true))); 80, 12, 4, 0, SavingThrow.REFLEXES, 23, .5f, true)));
handler.wind.add(new BreathWeaponUpgrade( handler.wind.add(
new BreathWeapon("lightning", BreathArea.LINE, 100, 12, 8, 0, new BreathUpgrade(new BreathWeapon("lightning", BreathArea.LINE,
SavingThrow.REFLEXES, 25, .5f, true))); 100, 12, 8, 0, SavingThrow.REFLEXES, 25, .5f, true)));
handler.fire.add(new BreathWeaponUpgrade( handler.fire
new BreathWeapon("fire", BreathArea.CONE, 50, 12, 10, 0, .add(new BreathUpgrade(new BreathWeapon("fire", BreathArea.CONE,
SavingThrow.REFLEXES, 25, .5f, true))); 50, 12, 10, 0, SavingThrow.REFLEXES, 25, .5f, true)));
handler.earth.add(new BreathWeaponUpgrade( handler.earth.add(new BreathUpgrade(
new BreathWeapon("corrosive gas", BreathArea.CONE, 50, 12, 6, 0, new BreathWeapon("corrosive gas", BreathArea.CONE, 50, 12, 6, 0,
SavingThrow.REFLEXES, 25, .5f, true))); SavingThrow.REFLEXES, 25, .5f, true)));
handler.wind.add(new BreathWeaponUpgrade( handler.wind
new BreathWeapon("cold", BreathArea.CONE, 40, 6, 6, 0, .add(new BreathUpgrade(new BreathWeapon("cold", BreathArea.CONE,
SavingThrow.REFLEXES, 23, .5f, true))); 40, 6, 6, 0, SavingThrow.REFLEXES, 23, .5f, true)));
} }
} }

View File

@ -11,7 +11,6 @@ import javelin.model.state.BattleState;
import javelin.model.unit.Combatant; import javelin.model.unit.Combatant;
import javelin.model.world.location.dungeon.Dungeon; import javelin.model.world.location.dungeon.Dungeon;
import javelin.model.world.location.dungeon.temple.Temple; import javelin.model.world.location.dungeon.temple.Temple;
import javelin.model.world.location.unique.MercenariesGuild;
import javelin.view.screen.BattleScreen; import javelin.view.screen.BattleScreen;
import tyrant.mikera.engine.RPG; import tyrant.mikera.engine.RPG;
@ -37,8 +36,7 @@ public class TempleEncounter extends RandomDungeonEncounter {
@Override @Override
public void enhance(List<Combatant> foes) { public void enhance(List<Combatant> foes) {
while (ChallengeRatingCalculator.calculateel(foes) < temple.el) { while (ChallengeRatingCalculator.calculateel(foes) < temple.el) {
Combatant foe = RPG.pick(foes); Combatant.upgradeweakest(foes, temple.realm);
MercenariesGuild.upgradeunit(foe, temple.realm);
} }
} }

View File

@ -2,19 +2,14 @@ package javelin.controller.fight;
import java.util.ArrayList; import java.util.ArrayList;
import javelin.Javelin;
import javelin.controller.Weather; import javelin.controller.Weather;
import javelin.controller.terrain.map.Arena; import javelin.controller.terrain.map.Arena;
import javelin.controller.upgrade.UpgradeHandler;
import javelin.controller.upgrade.feat.FeatUpgrade;
import javelin.model.BattleMap; import javelin.model.BattleMap;
import javelin.model.state.BattleState; import javelin.model.state.BattleState;
import javelin.model.unit.Combatant; import javelin.model.unit.Combatant;
import javelin.model.unit.Squad;
import javelin.model.world.location.Location; import javelin.model.world.location.Location;
import javelin.model.world.location.unique.TrainingHall; import javelin.model.world.location.unique.TrainingHall;
import javelin.view.screen.BattleScreen; import javelin.view.screen.BattleScreen;
import tyrant.mikera.engine.RPG;
/** /**
* A {@link Fight} that happens inside the {@link TrainingHall}. * A {@link Fight} that happens inside the {@link TrainingHall}.
@ -44,33 +39,6 @@ public class TrainingSession extends Siege {
if (!BattleMap.victory) { if (!BattleMap.victory) {
return; return;
} }
hall.currentlevel += 1; hall.level();
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<FeatUpgrade> feats = UpgradeHandler.singleton.getfeats();
ArrayList<FeatUpgrade> options = new ArrayList<FeatUpgrade>();
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();
}
} }
} }

View File

@ -137,6 +137,10 @@ public class EncounterGenerator {
* enemies). * enemies).
*/ */
public static int getmaxenemynumber() { public static int getmaxenemynumber() {
if (Squad.active == null) {
/* all training */
return 4 + 5;
}
return Squad.active.members.size() + 5; return Squad.active.members.size() + 5;
} }

View File

@ -9,10 +9,14 @@ import javelin.model.unit.abilities.BreathWeapon;
* *
* @author alex * @author alex
*/ */
public class BreathWeaponUpgrade extends Upgrade { public class BreathUpgrade extends Upgrade {
final private BreathWeapon breath; final private BreathWeapon breath;
public BreathWeaponUpgrade(BreathWeapon breathp) { /**
* @param breathp
* Breath to apply.
*/
public BreathUpgrade(BreathWeapon breathp) {
super("Breath weapon: " + breathp.description); super("Breath weapon: " + breathp.description);
breath = breathp; breath = breathp;
} }
@ -24,6 +28,9 @@ public class BreathWeaponUpgrade extends Upgrade {
@Override @Override
public boolean apply(Combatant m) { public boolean apply(Combatant m) {
if (breath.damage[0] > m.source.hd.count()) {
return false;
}
for (BreathWeapon b : m.source.breaths) { for (BreathWeapon b : m.source.breaths) {
if (b.description.equals(breath.description)) { if (b.description.equals(breath.description)) {
return false; return false;

View File

@ -22,12 +22,13 @@ public class NaturalArmor extends Upgrade {
@Override @Override
public boolean apply(final Combatant c) { public boolean apply(final Combatant c) {
Monster m = c.source; 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; return false;
} }
int delta = target - m.armor;
m.armor = target; m.armor = target;
m.ac += delta; m.ac = newac;
return true; return true;
} }
} }

View File

@ -45,6 +45,13 @@ public abstract class Damage extends Upgrade {
if (all.isEmpty()) { if (all.isEmpty()) {
return false; return false;
} }
for (final List<Attack> sequence : all) {
for (final Attack a : sequence) {
if (a.damage[0] + 1 > m.source.hd.count()) {
return false;
}
}
}
for (final List<Attack> sequence : all) { for (final List<Attack> sequence : all) {
for (final Attack a : sequence) { for (final Attack a : sequence) {
a.damage[0] += 1; a.damage[0] += 1;

View File

@ -11,12 +11,17 @@ import javelin.controller.action.Action;
import javelin.controller.action.Defend; import javelin.controller.action.Defend;
import javelin.controller.action.ai.MeleeAttack; import javelin.controller.action.ai.MeleeAttack;
import javelin.controller.ai.BattleAi; import javelin.controller.ai.BattleAi;
import javelin.controller.challenge.ChallengeRatingCalculator;
import javelin.controller.exception.RepeatTurn; import javelin.controller.exception.RepeatTurn;
import javelin.controller.old.Game; import javelin.controller.old.Game;
import javelin.controller.old.Game.Delay; import javelin.controller.old.Game.Delay;
import javelin.controller.upgrade.BreathUpgrade;
import javelin.controller.upgrade.Spell; import javelin.controller.upgrade.Spell;
import javelin.controller.upgrade.Upgrade;
import javelin.controller.upgrade.UpgradeHandler;
import javelin.model.BattleMap; import javelin.model.BattleMap;
import javelin.model.Cloneable; import javelin.model.Cloneable;
import javelin.model.Realm;
import javelin.model.TeamContainer; import javelin.model.TeamContainer;
import javelin.model.condition.Charging; import javelin.model.condition.Charging;
import javelin.model.condition.Condition; import javelin.model.condition.Condition;
@ -650,4 +655,48 @@ public class Combatant implements Serializable, Cloneable {
source = source.clone(); source = source.clone();
return this; return this;
} }
/**
* Updates {@link Monster#challengeRating} internally.
*
* @param r
* Applies one {@link Upgrade} from this set to the given
* {@link Combatant}.
* @return
* @return <code>true</code> if an upgrade has been successfully applied.
* @see Upgrade#upgrade(Combatant)
*/
public boolean upgrade(Realm r) {
Upgrade upgrade = RPG.pick(new ArrayList<Upgrade>(
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<Combatant> 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);
}
} }

View File

@ -9,9 +9,6 @@ import javelin.Javelin;
import javelin.controller.challenge.ChallengeRatingCalculator; import javelin.controller.challenge.ChallengeRatingCalculator;
import javelin.controller.challenge.RewardCalculator; import javelin.controller.challenge.RewardCalculator;
import javelin.controller.old.Game; 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.Realm;
import javelin.model.unit.Combatant; import javelin.model.unit.Combatant;
import javelin.model.unit.Monster; import javelin.model.unit.Monster;
@ -68,7 +65,7 @@ public class MercenariesGuild extends UniqueLocation {
} }
int tries = 0; int tries = 0;
while (c.source.challengeRating < cr) { while (c.source.challengeRating < cr) {
upgradeunit(c, r); c.upgrade(r);
tries += 1; tries += 1;
if (tries >= 100) { if (tries >= 100) {
return; return;
@ -78,29 +75,6 @@ public class MercenariesGuild extends UniqueLocation {
all.add(c); 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<Upgrade>(
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 @Override
public boolean interact() { public boolean interact() {
if (!super.interact()) { if (!super.interact()) {

View File

@ -11,10 +11,14 @@ import javelin.controller.fight.Siege;
import javelin.controller.fight.TrainingSession; import javelin.controller.fight.TrainingSession;
import javelin.controller.old.Game; import javelin.controller.old.Game;
import javelin.controller.old.Game.Delay; 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.Combatant;
import javelin.model.unit.Monster; import javelin.model.unit.Monster;
import javelin.model.unit.Squad; import javelin.model.unit.Squad;
import javelin.model.world.location.fortification.Fortification; import javelin.model.world.location.fortification.Fortification;
import javelin.view.screen.SquadScreen;
import tyrant.mikera.engine.RPG; import tyrant.mikera.engine.RPG;
/** /**
@ -32,9 +36,10 @@ public class TrainingHall extends Fortification {
private static final String DESCRIPTION = "The Training Hall"; private static final String DESCRIPTION = "The Training Hall";
/** /**
* Actual encounter level for each {@link TrainingSession}, by using the * 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 * From 1 upwards, the current training session difficulty, supposed to
* represent different floors. * represent different floors.
@ -61,29 +66,26 @@ public class TrainingHall extends Fortification {
if (currentlevel == null) { if (currentlevel == null) {
currentlevel = 1; currentlevel = 1;
} }
garrison.clear(); // garrison.clear();
ArrayList<Monster> candidates = new ArrayList<Monster>(); ArrayList<Monster> senseis = SquadScreen.getcandidates();
for (float cr : Javelin.MONSTERSBYCR.descendingKeySet()) { for (Monster sensei : new ArrayList<Monster>(senseis)) {
if (1 <= cr && cr <= Math.max(currentlevel, 2)) { if (!sensei.think(0)) {
candidates.clear(); senseis.remove(sensei);
for (Monster m : Javelin.MONSTERSBYCR.get(cr)) {
if (m.think(0)) {
candidates.add(m);
}
}
if (!candidates.isEmpty()) {
break;
}
} }
} }
while (ChallengeRatingCalculator int nstudents = Squad.active.members.size();
.calculateel(garrison) < EL[currentlevel - 1]) { int nsenseis = RPG.r(Math.min(3, nstudents), RPG.max(nstudents, 5));
garrison.add( while (isweak() && garrison.size() < nsenseis) {
new Combatant(null, RPG.pick(candidates).clone(), true)); garrison.add(new Combatant(null, RPG.pick(senseis).clone(), true));
if (DEBUG) {
break;
}
} }
while (isweak()) {
Combatant.upgradeweakest(garrison, Realm.random());
}
}
boolean isweak() {
return ChallengeRatingCalculator
.calculateel(garrison) < EL[currentlevel - 1];
} }
@Override @Override
@ -116,4 +118,35 @@ public class TrainingHall extends Fortification {
public List<Combatant> getcombatants() { public List<Combatant> getcombatants() {
return garrison; 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<FeatUpgrade> feats = UpgradeHandler.singleton.getfeats();
ArrayList<FeatUpgrade> options = new ArrayList<FeatUpgrade>();
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();
}
}
} }