v0.8.0: substantially improved logic for damage immunity:
- now referred to as invulnerability, with standardized logic for all chars - chars now ignore enemies who are invulnerable - combo no longer builds on invulnerable targets - allies can now target Yog's eye when it is vulnerable
This commit is contained in:
parent
97236333d8
commit
b5989ee4f6
|
@ -416,6 +416,11 @@ public abstract class Char extends Actor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isInvulnerable(src.getClass())){
|
||||||
|
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "invulnerable"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(src instanceof LifeLink) && buff(LifeLink.class) != null){
|
if (!(src instanceof LifeLink) && buff(LifeLink.class) != null){
|
||||||
HashSet<LifeLink> links = buffs(LifeLink.class);
|
HashSet<LifeLink> links = buffs(LifeLink.class);
|
||||||
for (LifeLink link : links.toArray(new LifeLink[0])){
|
for (LifeLink link : links.toArray(new LifeLink[0])){
|
||||||
|
@ -697,6 +702,12 @@ public abstract class Char extends Actor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//similar to isImmune, but only factors in damage.
|
||||||
|
//Is used in AI decision-making
|
||||||
|
public boolean isInvulnerable( Class effect ){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected HashSet<Property> properties = new HashSet<>();
|
protected HashSet<Property> properties = new HashSet<>();
|
||||||
|
|
||||||
public HashSet<Property> properties() {
|
public HashSet<Property> properties() {
|
||||||
|
|
|
@ -74,7 +74,8 @@ public class Combo extends Buff implements ActionIndicator.Action {
|
||||||
|
|
||||||
public void hit( Char enemy ) {
|
public void hit( Char enemy ) {
|
||||||
|
|
||||||
count++;
|
//doesn't increment combo count if enemy invulnerable
|
||||||
|
if (!enemy.isInvulnerable(target.getClass())) count++;
|
||||||
comboTime = 4f;
|
comboTime = 4f;
|
||||||
misses = 0;
|
misses = 0;
|
||||||
BuffIndicator.refreshHero();
|
BuffIndicator.refreshHero();
|
||||||
|
|
|
@ -354,10 +354,15 @@ public class DwarfKing extends Mob {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInvulnerable(Class effect) {
|
||||||
|
return phase == 2 && effect != KingDamager.class;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void damage(int dmg, Object src) {
|
public void damage(int dmg, Object src) {
|
||||||
if (phase == 2 && !(src instanceof KingDamager)){
|
if (isInvulnerable(src.getClass())){
|
||||||
sprite.showStatus( CharSprite.POSITIVE, Messages.get(this, "immune") );
|
super.damage(dmg, src);
|
||||||
return;
|
return;
|
||||||
} else if (phase == 3 && !(src instanceof Viscosity.DeferedDamage)){
|
} else if (phase == 3 && !(src instanceof Viscosity.DeferedDamage)){
|
||||||
Viscosity.DeferedDamage deferred = Buff.affect( this, Viscosity.DeferedDamage.class );
|
Viscosity.DeferedDamage deferred = Buff.affect( this, Viscosity.DeferedDamage.class );
|
||||||
|
@ -378,7 +383,7 @@ public class DwarfKing extends Mob {
|
||||||
summonCooldown -= dmgTaken/8f;
|
summonCooldown -= dmgTaken/8f;
|
||||||
if (HP <= 50) {
|
if (HP <= 50) {
|
||||||
HP = 50;
|
HP = 50;
|
||||||
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "immune"));
|
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "invulnerable"));
|
||||||
ScrollOfTeleportation.appear(this, NewCityBossLevel.throne);
|
ScrollOfTeleportation.appear(this, NewCityBossLevel.throne);
|
||||||
properties.add(Property.IMMOVABLE);
|
properties.add(Property.IMMOVABLE);
|
||||||
phase = 2;
|
phase = 2;
|
||||||
|
|
|
@ -215,17 +215,21 @@ public abstract class Mob extends Char {
|
||||||
//find a new enemy if..
|
//find a new enemy if..
|
||||||
boolean newEnemy = false;
|
boolean newEnemy = false;
|
||||||
//we have no enemy, or the current one is dead/missing
|
//we have no enemy, or the current one is dead/missing
|
||||||
if ( enemy == null || !enemy.isAlive() || !Actor.chars().contains(enemy) || state == WANDERING)
|
if ( enemy == null || !enemy.isAlive() || !Actor.chars().contains(enemy) || state == WANDERING) {
|
||||||
newEnemy = true;
|
newEnemy = true;
|
||||||
//We are an ally, and current enemy is another ally.
|
//We are an ally, and current enemy is another ally.
|
||||||
else if (alignment == Alignment.ALLY && enemy.alignment == Alignment.ALLY)
|
} else if (alignment == Alignment.ALLY && enemy.alignment == Alignment.ALLY) {
|
||||||
newEnemy = true;
|
newEnemy = true;
|
||||||
//We are amoked and current enemy is the hero
|
//We are amoked and current enemy is the hero
|
||||||
else if (buff( Amok.class ) != null && enemy == Dungeon.hero)
|
} else if (buff( Amok.class ) != null && enemy == Dungeon.hero) {
|
||||||
newEnemy = true;
|
newEnemy = true;
|
||||||
//We are charmed and current enemy is what charmed us
|
//We are charmed and current enemy is what charmed us
|
||||||
else if (buff(Charm.class) != null && buff(Charm.class).object == enemy.id())
|
} else if (buff(Charm.class) != null && buff(Charm.class).object == enemy.id()) {
|
||||||
newEnemy = true;
|
newEnemy = true;
|
||||||
|
//we aren't amoked and current enemy is invulnerable to us
|
||||||
|
} else if (buff( Amok.class ) == null && enemy.isInvulnerable(getClass())) {
|
||||||
|
newEnemy = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ( newEnemy ) {
|
if ( newEnemy ) {
|
||||||
|
|
||||||
|
@ -285,6 +289,15 @@ public abstract class Mob extends Char {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if we are not amoked, remove any enemies which are invulnerable to us.
|
||||||
|
if (buff(Amok.class) == null) {
|
||||||
|
for (Char enemy : enemies.toArray(new Char[0])) {
|
||||||
|
if (enemy.isInvulnerable(getClass())){
|
||||||
|
enemies.remove(enemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//neutral characters in particular do not choose enemies.
|
//neutral characters in particular do not choose enemies.
|
||||||
if (enemies.isEmpty()){
|
if (enemies.isEmpty()){
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -407,13 +407,11 @@ public class NewDM300 extends Mob {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void damage(int dmg, Object src) {
|
public void damage(int dmg, Object src) {
|
||||||
if (supercharged){
|
super.damage(dmg, src);
|
||||||
sprite.showStatus( CharSprite.POSITIVE, Messages.get(this, "immune") );
|
if (isInvulnerable(src.getClass())){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.damage(dmg, src);
|
|
||||||
|
|
||||||
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
||||||
if (lock != null && !isImmune(src.getClass())) lock.addTime(dmg);
|
if (lock != null && !isImmune(src.getClass())) lock.addTime(dmg);
|
||||||
|
|
||||||
|
@ -426,6 +424,11 @@ public class NewDM300 extends Mob {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInvulnerable(Class effect) {
|
||||||
|
return supercharged;
|
||||||
|
}
|
||||||
|
|
||||||
public void supercharge(){
|
public void supercharge(){
|
||||||
supercharged = true;
|
supercharged = true;
|
||||||
((NewCavesBossLevel)Dungeon.level).activatePylon();
|
((NewCavesBossLevel)Dungeon.level).activatePylon();
|
||||||
|
@ -433,7 +436,7 @@ public class NewDM300 extends Mob {
|
||||||
|
|
||||||
spend(3f);
|
spend(3f);
|
||||||
yell(Messages.get(this, "charging"));
|
yell(Messages.get(this, "charging"));
|
||||||
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "immune"));
|
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "invulnerable"));
|
||||||
sprite.resetColor();
|
sprite.resetColor();
|
||||||
chargeAnnounced = false;
|
chargeAnnounced = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,8 @@ public class YogDzewa extends Mob {
|
||||||
|
|
||||||
EXP = 50;
|
EXP = 50;
|
||||||
|
|
||||||
state = PASSIVE;
|
//so that allies can attack it. States are never actually used.
|
||||||
|
state = HUNTING;
|
||||||
|
|
||||||
properties.add(Property.BOSS);
|
properties.add(Property.BOSS);
|
||||||
properties.add(Property.IMMOVABLE);
|
properties.add(Property.IMMOVABLE);
|
||||||
|
@ -113,8 +114,10 @@ public class YogDzewa extends Mob {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean act() {
|
protected boolean act() {
|
||||||
if (phase == 0 && Dungeon.hero.viewDistance >= Dungeon.level.distance(pos, Dungeon.hero.pos)){
|
if (phase == 0){
|
||||||
Dungeon.observe();
|
if (Dungeon.hero.viewDistance >= Dungeon.level.distance(pos, Dungeon.hero.pos)) {
|
||||||
|
Dungeon.observe();
|
||||||
|
}
|
||||||
if (Dungeon.level.heroFOV[pos]) {
|
if (Dungeon.level.heroFOV[pos]) {
|
||||||
notice();
|
notice();
|
||||||
}
|
}
|
||||||
|
@ -269,12 +272,12 @@ public class YogDzewa extends Mob {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void damage( int dmg, Object src ) {
|
public boolean isInvulnerable(Class effect) {
|
||||||
|
return phase == 0 || findFist() != null;
|
||||||
|
}
|
||||||
|
|
||||||
if (phase == 0 || findFist() != null){
|
@Override
|
||||||
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "immune"));
|
public void damage( int dmg, Object src ) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int preHP = HP;
|
int preHP = HP;
|
||||||
super.damage( dmg, src );
|
super.damage( dmg, src );
|
||||||
|
@ -292,7 +295,7 @@ public class YogDzewa extends Mob {
|
||||||
}
|
}
|
||||||
Dungeon.observe();
|
Dungeon.observe();
|
||||||
GLog.n(Messages.get(this, "darkness"));
|
GLog.n(Messages.get(this, "darkness"));
|
||||||
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "immune"));
|
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "invulnerable"));
|
||||||
|
|
||||||
YogFist fist = (YogFist) Reflection.newInstance(fistSummons.remove(0));
|
YogFist fist = (YogFist) Reflection.newInstance(fistSummons.remove(0));
|
||||||
fist.pos = Dungeon.level.exit;
|
fist.pos = Dungeon.level.exit;
|
||||||
|
@ -319,7 +322,7 @@ public class YogDzewa extends Mob {
|
||||||
}
|
}
|
||||||
|
|
||||||
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
LockedFloor lock = Dungeon.hero.buff(LockedFloor.class);
|
||||||
if (lock != null) lock.addTime(dmg);
|
if (lock != null) lock.addTime(dmgTaken);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,22 +91,25 @@ public abstract class YogFist extends Mob {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean immuneWarned = false;
|
boolean invulnWarned = false;
|
||||||
|
|
||||||
protected boolean isNearYog(){
|
protected boolean isNearYog(){
|
||||||
int yogPos = Dungeon.level.exit + 3*Dungeon.level.width();
|
int yogPos = Dungeon.level.exit + 3*Dungeon.level.width();
|
||||||
return Dungeon.level.distance(pos, yogPos) <= 4;
|
return Dungeon.level.distance(pos, yogPos) <= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInvulnerable(Class effect) {
|
||||||
|
return isNearYog();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void damage(int dmg, Object src) {
|
public void damage(int dmg, Object src) {
|
||||||
if (isNearYog()){
|
if (isInvulnerable(src.getClass())){
|
||||||
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "immune"));
|
if (!invulnWarned){
|
||||||
if (!immuneWarned){
|
invulnWarned = true;
|
||||||
immuneWarned = true;
|
GLog.w(Messages.get(this, "invuln_warn"));
|
||||||
GLog.w(Messages.get(this, "immune_hint"));
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
super.damage(dmg, src);
|
super.damage(dmg, src);
|
||||||
}
|
}
|
||||||
|
@ -344,15 +347,7 @@ public abstract class YogFist extends Mob {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void damage(int dmg, Object src) {
|
public void damage(int dmg, Object src) {
|
||||||
if (isNearYog()){
|
if (!isInvulnerable(src.getClass()) && !(src instanceof Bleeding)){
|
||||||
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "immune"));
|
|
||||||
if (!immuneWarned){
|
|
||||||
immuneWarned = true;
|
|
||||||
GLog.w(Messages.get(this, "immune_hint"));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(src instanceof Bleeding)){
|
|
||||||
Bleeding b = buff(Bleeding.class);
|
Bleeding b = buff(Bleeding.class);
|
||||||
if (b == null){
|
if (b == null){
|
||||||
b = new Bleeding();
|
b = new Bleeding();
|
||||||
|
@ -406,15 +401,7 @@ public abstract class YogFist extends Mob {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void damage(int dmg, Object src) {
|
public void damage(int dmg, Object src) {
|
||||||
if (isNearYog()){
|
if (!isInvulnerable(src.getClass()) && !(src instanceof Viscosity.DeferedDamage)){
|
||||||
sprite.showStatus(CharSprite.POSITIVE, Messages.get(this, "immune"));
|
|
||||||
if (!immuneWarned){
|
|
||||||
immuneWarned = true;
|
|
||||||
GLog.w(Messages.get(this, "immune_hint"));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(src instanceof Viscosity.DeferedDamage)){
|
|
||||||
Buff.affect(this, Viscosity.DeferedDamage.class).prolong(dmg);
|
Buff.affect(this, Viscosity.DeferedDamage.class).prolong(dmg);
|
||||||
sprite.showStatus( CharSprite.WARNING, Messages.get(Viscosity.class, "deferred", dmg) );
|
sprite.showStatus( CharSprite.WARNING, Messages.get(Viscosity.class, "deferred", dmg) );
|
||||||
} else{
|
} else{
|
||||||
|
|
|
@ -511,7 +511,6 @@ actors.mobs.newdm300.supercharged=SUPERCHARGE COMPLETE, OPERATING AT 200% POWER!
|
||||||
actors.mobs.newdm300.charge_lost=POWER GRID DAMAGED, REVERTING TO LOCAL POWER!
|
actors.mobs.newdm300.charge_lost=POWER GRID DAMAGED, REVERTING TO LOCAL POWER!
|
||||||
actors.mobs.newdm300.pylons_destroyed=ALERT, INSTABILITY DETECTED IN POWER GRID!
|
actors.mobs.newdm300.pylons_destroyed=ALERT, INSTABILITY DETECTED IN POWER GRID!
|
||||||
actors.mobs.newdm300.rankings_desc=Crushed by the DM-300
|
actors.mobs.newdm300.rankings_desc=Crushed by the DM-300
|
||||||
actors.mobs.newdm300.immune=IMMUNE
|
|
||||||
actors.mobs.newdm300.def_verb=blocked
|
actors.mobs.newdm300.def_verb=blocked
|
||||||
actors.mobs.newdm300.defeated=CRITICAL DAMAGE! ATTEMPTING SHUTDO-
|
actors.mobs.newdm300.defeated=CRITICAL DAMAGE! ATTEMPTING SHUTDO-
|
||||||
actors.mobs.newdm300.desc=The DM-300 is the largest and most powerful 'defense machine' that the dwarves ever built. Such an awesome machine is difficult to manufacture, so the dwarves only ever made a few to guard the entrances to their underground metropolis.\n\nIt is equipped with vents to jet its toxic exhaust fumes and a high power drill that it can use both to attack and disrupt the earth. DM-300 can also connect to an energy grid, further enhancing its power.
|
actors.mobs.newdm300.desc=The DM-300 is the largest and most powerful 'defense machine' that the dwarves ever built. Such an awesome machine is difficult to manufacture, so the dwarves only ever made a few to guard the entrances to their underground metropolis.\n\nIt is equipped with vents to jet its toxic exhaust fumes and a high power drill that it can use both to attack and disrupt the earth. DM-300 can also connect to an energy grid, further enhancing its power.
|
||||||
|
@ -524,7 +523,6 @@ actors.mobs.dwarfking.lifelink_1=I need of your essence, slave!
|
||||||
actors.mobs.dwarfking.lifelink_2=Bleed for me, slave!
|
actors.mobs.dwarfking.lifelink_2=Bleed for me, slave!
|
||||||
actors.mobs.dwarfking.teleport_1=Deal with them, slave!
|
actors.mobs.dwarfking.teleport_1=Deal with them, slave!
|
||||||
actors.mobs.dwarfking.teleport_2=Keep them busy, slave!
|
actors.mobs.dwarfking.teleport_2=Keep them busy, slave!
|
||||||
actors.mobs.dwarfking.immune=IMMUNE
|
|
||||||
actors.mobs.dwarfking.wave_1=Enough! Arise my slaves!
|
actors.mobs.dwarfking.wave_1=Enough! Arise my slaves!
|
||||||
actors.mobs.dwarfking.wave_2=More! Bleed for your king!
|
actors.mobs.dwarfking.wave_2=More! Bleed for your king!
|
||||||
actors.mobs.dwarfking.wave_3=Useless! KILL THEM NOW!
|
actors.mobs.dwarfking.wave_3=Useless! KILL THEM NOW!
|
||||||
|
@ -747,7 +745,6 @@ actors.mobs.yog$larva.desc=Yog-Dzewa is an Old God, a powerful entity from the r
|
||||||
|
|
||||||
actors.mobs.yogdzewa.name=Yog-Dzewa
|
actors.mobs.yogdzewa.name=Yog-Dzewa
|
||||||
actors.mobs.yogdzewa.notice=I. SEE. YOU.
|
actors.mobs.yogdzewa.notice=I. SEE. YOU.
|
||||||
actors.mobs.yogdzewa.immune=IMMUNE
|
|
||||||
actors.mobs.yogdzewa.darkness=The darkness pulls in closer...
|
actors.mobs.yogdzewa.darkness=The darkness pulls in closer...
|
||||||
actors.mobs.yogdzewa.hope=YOUR. HOPE. IS. AN. ILLUSION!
|
actors.mobs.yogdzewa.hope=YOUR. HOPE. IS. AN. ILLUSION!
|
||||||
actors.mobs.yogdzewa.defeated=...
|
actors.mobs.yogdzewa.defeated=...
|
||||||
|
@ -759,8 +756,7 @@ actors.mobs.yogdzewa$larva.rankings_desc=Devoured by Yog-Dzewa
|
||||||
actors.mobs.yogdzewa$larva.desc=These tiny spawn of Yog-Dzewa are simple minions that are easy to produce. While individually weak, they are summoned quickly and can become overwhelming in large numbers.
|
actors.mobs.yogdzewa$larva.desc=These tiny spawn of Yog-Dzewa are simple minions that are easy to produce. While individually weak, they are summoned quickly and can become overwhelming in large numbers.
|
||||||
actors.mobs.yogdzewa$yogripper.rankings_desc=Devoured by Yog-Dzewa
|
actors.mobs.yogdzewa$yogripper.rankings_desc=Devoured by Yog-Dzewa
|
||||||
|
|
||||||
actors.mobs.yogfist.immune=IMMUNE
|
actors.mobs.yogfist.invuln_warn=The fist is invulnerable while near to the eye!
|
||||||
actors.mobs.yogfist.immune_hint=The fist is immune while near to the eye!
|
|
||||||
actors.mobs.yogfist.rankings_desc=Devoured by Yog-Dzewa
|
actors.mobs.yogfist.rankings_desc=Devoured by Yog-Dzewa
|
||||||
actors.mobs.yogfist.desc=This fist is an aspect of Yog-Dzewa's power. Fists are linked to the power of Yog-Dzewa, and will be protected from all damage when they are close to the eye.
|
actors.mobs.yogfist.desc=This fist is an aspect of Yog-Dzewa's power. Fists are linked to the power of Yog-Dzewa, and will be protected from all damage when they are close to the eye.
|
||||||
actors.mobs.yogfist$burning.name=burning fist
|
actors.mobs.yogfist$burning.name=burning fist
|
||||||
|
@ -782,3 +778,4 @@ actors.mobs.yogfist$dark.desc=This fist is formed out of pure dark energy. It is
|
||||||
actors.char.kill=%s killed you...
|
actors.char.kill=%s killed you...
|
||||||
actors.char.defeat=You defeated %s.
|
actors.char.defeat=You defeated %s.
|
||||||
actors.char.def_verb=dodged
|
actors.char.def_verb=dodged
|
||||||
|
actors.char.invulnerable=invulnerable
|
||||||
|
|
Loading…
Reference in New Issue
Block a user