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.
*/
public static long getHour() {
if (Squad.active == null) {
/* all training */
return 0;
}
return Squad.active.hourselapsed % 24;
}

View File

@ -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)));
}
}

View File

@ -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<Combatant> foes) {
while (ChallengeRatingCalculator.calculateel(foes) < temple.el) {
Combatant foe = RPG.pick(foes);
MercenariesGuild.upgradeunit(foe, temple.realm);
Combatant.upgradeweakest(foes, temple.realm);
}
}

View File

@ -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<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();
}
hall.level();
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -45,6 +45,13 @@ public abstract class Damage extends Upgrade {
if (all.isEmpty()) {
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 Attack a : sequence) {
a.damage[0] += 1;

View File

@ -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 <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.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<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
public boolean interact() {
if (!super.interact()) {

View File

@ -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<Monster> candidates = new ArrayList<Monster>();
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<Monster> senseis = SquadScreen.getcandidates();
for (Monster sensei : new ArrayList<Monster>(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<Combatant> 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<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();
}
}
}