v0.7.4: implemented directing functionality for the ghost hero
This commit is contained in:
parent
2024261813
commit
e047d1aee1
|
@ -44,9 +44,9 @@ import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution;
|
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast;
|
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
|
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Languages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Languages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.GhostSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.GhostSprite;
|
||||||
|
@ -102,9 +102,12 @@ public class DriedRose extends Artifact {
|
||||||
actions.remove(AC_EQUIP);
|
actions.remove(AC_EQUIP);
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
if (isEquipped( hero ) && charge == chargeCap && !cursed) {
|
if (isEquipped( hero ) && charge == chargeCap && !cursed && ghostID != 0) {
|
||||||
actions.add(AC_SUMMON);
|
actions.add(AC_SUMMON);
|
||||||
}
|
}
|
||||||
|
if (ghostID != 0){
|
||||||
|
actions.add(AC_DIRECT);
|
||||||
|
}
|
||||||
if (isIdentified() && !cursed){
|
if (isIdentified() && !cursed){
|
||||||
actions.add(AC_OUTFIT);
|
actions.add(AC_OUTFIT);
|
||||||
}
|
}
|
||||||
|
@ -160,6 +163,17 @@ public class DriedRose extends Artifact {
|
||||||
GLog.i( Messages.get(this, "no_space") );
|
GLog.i( Messages.get(this, "no_space") );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (action.equals(AC_DIRECT)){
|
||||||
|
if (ghost == null && ghostID != 0){
|
||||||
|
Actor a = Actor.findById(ghostID);
|
||||||
|
if (a != null){
|
||||||
|
ghost = (GhostHero)a;
|
||||||
|
} else {
|
||||||
|
ghostID = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ghost != null) GameScene.selectCell(ghostDirector);
|
||||||
|
|
||||||
} else if (action.equals(AC_OUTFIT)){
|
} else if (action.equals(AC_OUTFIT)){
|
||||||
GameScene.show( new WndGhostHero(this) );
|
GameScene.show( new WndGhostHero(this) );
|
||||||
}
|
}
|
||||||
|
@ -258,6 +272,8 @@ public class DriedRose extends Artifact {
|
||||||
ghostID = bundle.getInt( GHOSTID );
|
ghostID = bundle.getInt( GHOSTID );
|
||||||
droppedPetals = bundle.getInt( PETALS );
|
droppedPetals = bundle.getInt( PETALS );
|
||||||
|
|
||||||
|
if (ghostID != 0) defaultAction = AC_DIRECT;
|
||||||
|
|
||||||
if (bundle.contains(WEAPON)) weapon = (MeleeWeapon)bundle.get( WEAPON );
|
if (bundle.contains(WEAPON)) weapon = (MeleeWeapon)bundle.get( WEAPON );
|
||||||
if (bundle.contains(ARMOR)) armor = (Armor)bundle.get( ARMOR );
|
if (bundle.contains(ARMOR)) armor = (Armor)bundle.get( ARMOR );
|
||||||
}
|
}
|
||||||
|
@ -280,7 +296,10 @@ public class DriedRose extends Artifact {
|
||||||
|
|
||||||
//rose does not charge while ghost hero is alive
|
//rose does not charge while ghost hero is alive
|
||||||
if (ghost != null){
|
if (ghost != null){
|
||||||
|
defaultAction = AC_DIRECT;
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
defaultAction = AC_SUMMON;
|
||||||
}
|
}
|
||||||
|
|
||||||
LockedFloor lock = target.buff(LockedFloor.class);
|
LockedFloor lock = target.buff(LockedFloor.class);
|
||||||
|
@ -318,6 +337,47 @@ public class DriedRose extends Artifact {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME need to translate phrases here
|
||||||
|
public CellSelector.Listener ghostDirector = new CellSelector.Listener(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelect(Integer cell) {
|
||||||
|
if (cell == null) return;
|
||||||
|
|
||||||
|
if (!Dungeon.level.heroFOV[cell] || Actor.findChar(cell) == null){
|
||||||
|
GLog.i("Okay, I'll hold that position");
|
||||||
|
ghost.aggro(null);
|
||||||
|
ghost.state = ghost.WANDERING;
|
||||||
|
ghost.defendingPos = cell;
|
||||||
|
ghost.movingToDefendPos = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ghost.fieldOfView == null || ghost.fieldOfView.length != Dungeon.level.length()){
|
||||||
|
ghost.fieldOfView = new boolean[Dungeon.level.length()];
|
||||||
|
}
|
||||||
|
Dungeon.level.updateFieldOfView( ghost, ghost.fieldOfView );
|
||||||
|
|
||||||
|
if (Actor.findChar(cell) == Dungeon.hero){
|
||||||
|
GLog.i("Okay, I'll follow you.");
|
||||||
|
ghost.aggro(null);
|
||||||
|
ghost.state = ghost.WANDERING;
|
||||||
|
ghost.defendingPos = -1;
|
||||||
|
|
||||||
|
} else if (Actor.findChar(cell).alignment == Char.Alignment.ENEMY){
|
||||||
|
GLog.i("Okay, I'll attack that enemy.");
|
||||||
|
ghost.aggro(Actor.findChar(cell));
|
||||||
|
ghost.setTarget(cell);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String prompt() {
|
||||||
|
return "\"What should I do?\"";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static class Petal extends Item {
|
public static class Petal extends Item {
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -372,6 +432,9 @@ public class DriedRose extends Artifact {
|
||||||
properties.add(Property.UNDEAD);
|
properties.add(Property.UNDEAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int defendingPos = -1;
|
||||||
|
private boolean movingToDefendPos = false;
|
||||||
|
|
||||||
private DriedRose rose = null;
|
private DriedRose rose = null;
|
||||||
|
|
||||||
public GhostHero(){
|
public GhostHero(){
|
||||||
|
@ -451,13 +514,16 @@ public class DriedRose extends Artifact {
|
||||||
protected Char chooseEnemy() {
|
protected Char chooseEnemy() {
|
||||||
Char enemy = super.chooseEnemy();
|
Char enemy = super.chooseEnemy();
|
||||||
|
|
||||||
//will never attack something far from the player
|
int targetPos = defendingPos != -1 ? defendingPos : Dungeon.hero.pos;
|
||||||
if (enemy != null && Dungeon.level.mobs.contains(enemy)
|
|
||||||
&& Dungeon.level.distance(enemy.pos, Dungeon.hero.pos) <= 8){
|
//will never attack something far from their target
|
||||||
|
if (enemy != null
|
||||||
|
&& Dungeon.level.mobs.contains(enemy)
|
||||||
|
&& (Dungeon.level.distance(enemy.pos, targetPos) <= 8)){
|
||||||
return enemy;
|
return enemy;
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -573,6 +639,10 @@ public class DriedRose extends Artifact {
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setTarget(int cell) {
|
||||||
|
target = cell;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean interact() {
|
public boolean interact() {
|
||||||
updateRose();
|
updateRose();
|
||||||
|
@ -609,10 +679,28 @@ public class DriedRose extends Artifact {
|
||||||
if (rose != null) {
|
if (rose != null) {
|
||||||
rose.ghost = null;
|
rose.ghost = null;
|
||||||
rose.ghostID = -1;
|
rose.ghostID = -1;
|
||||||
|
rose.defaultAction = AC_SUMMON;
|
||||||
}
|
}
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String DEFEND_POS = "defend_pos";
|
||||||
|
private static final String MOVING_TO_DEFEND = "moving_to_defend";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeInBundle(Bundle bundle) {
|
||||||
|
super.storeInBundle(bundle);
|
||||||
|
bundle.put(DEFEND_POS, defendingPos);
|
||||||
|
bundle.put(MOVING_TO_DEFEND, movingToDefendPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreFromBundle(Bundle bundle) {
|
||||||
|
super.restoreFromBundle(bundle);
|
||||||
|
if (bundle.contains(DEFEND_POS)) defendingPos = bundle.getInt(DEFEND_POS);
|
||||||
|
movingToDefendPos = bundle.getBoolean(MOVING_TO_DEFEND);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
immunities.add( ToxicGas.class );
|
immunities.add( ToxicGas.class );
|
||||||
immunities.add( CorrosiveGas.class );
|
immunities.add( CorrosiveGas.class );
|
||||||
|
@ -626,7 +714,7 @@ public class DriedRose extends Artifact {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean act( boolean enemyInFOV, boolean justAlerted ) {
|
public boolean act( boolean enemyInFOV, boolean justAlerted ) {
|
||||||
if ( enemyInFOV ) {
|
if ( enemyInFOV && !movingToDefendPos ) {
|
||||||
|
|
||||||
enemySeen = true;
|
enemySeen = true;
|
||||||
|
|
||||||
|
@ -640,13 +728,15 @@ public class DriedRose extends Artifact {
|
||||||
enemySeen = false;
|
enemySeen = false;
|
||||||
|
|
||||||
int oldPos = pos;
|
int oldPos = pos;
|
||||||
|
target = defendingPos != -1 ? defendingPos : Dungeon.hero.pos;
|
||||||
//always move towards the hero when wandering
|
//always move towards the hero when wandering
|
||||||
if (getCloser( target = Dungeon.hero.pos )) {
|
if (getCloser( target )) {
|
||||||
//moves 2 tiles at a time when returning to the hero from a distance
|
//moves 2 tiles at a time when returning to the hero
|
||||||
if (!Dungeon.level.adjacent(Dungeon.hero.pos, pos)){
|
if (defendingPos == -1 && !Dungeon.level.adjacent(target, pos)){
|
||||||
getCloser( target = Dungeon.hero.pos );
|
getCloser( target );
|
||||||
}
|
}
|
||||||
spend( 1 / speed() );
|
spend( 1 / speed() );
|
||||||
|
if (pos == defendingPos) movingToDefendPos = false;
|
||||||
return moveSprite( oldPos, pos );
|
return moveSprite( oldPos, pos );
|
||||||
} else {
|
} else {
|
||||||
spend( TICK );
|
spend( TICK );
|
||||||
|
@ -661,6 +751,7 @@ public class DriedRose extends Artifact {
|
||||||
//************************************************************************************
|
//************************************************************************************
|
||||||
//This is a bunch strings & string arrays, used in all of the sad ghost's voice lines.
|
//This is a bunch strings & string arrays, used in all of the sad ghost's voice lines.
|
||||||
//************************************************************************************
|
//************************************************************************************
|
||||||
|
//FIXME, need to go over these for final polish (inc. translations!)
|
||||||
|
|
||||||
private static final String VOICE_INTRODUCE = "My spirit is bound to this rose, it was very precious to me, a "+
|
private static final String VOICE_INTRODUCE = "My spirit is bound to this rose, it was very precious to me, a "+
|
||||||
"gift from my love whom I left on the surface.\n\nI cannot return to him, but thanks to you I have a " +
|
"gift from my love whom I left on the surface.\n\nI cannot return to him, but thanks to you I have a " +
|
||||||
|
|
|
@ -187,6 +187,7 @@ items.artifacts.cloakofshadows$cloakstealth.desc=Your cloak of shadows is granti
|
||||||
|
|
||||||
items.artifacts.driedrose.name=dried rose
|
items.artifacts.driedrose.name=dried rose
|
||||||
items.artifacts.driedrose.ac_summon=SUMMON
|
items.artifacts.driedrose.ac_summon=SUMMON
|
||||||
|
items.artifacts.driedrose.ac_direct=DIRECT
|
||||||
items.artifacts.driedrose.ac_outfit=OUTFIT
|
items.artifacts.driedrose.ac_outfit=OUTFIT
|
||||||
items.artifacts.driedrose.spawned=You have already summoned the ghost.
|
items.artifacts.driedrose.spawned=You have already summoned the ghost.
|
||||||
items.artifacts.driedrose.no_charge=Your rose isn't fully charged yet.
|
items.artifacts.driedrose.no_charge=Your rose isn't fully charged yet.
|
||||||
|
@ -206,8 +207,8 @@ items.artifacts.driedrose$petal.desc=A frail dried up petal, which has somehow s
|
||||||
items.artifacts.driedrose$ghosthero.name=sad ghost
|
items.artifacts.driedrose$ghosthero.name=sad ghost
|
||||||
items.artifacts.driedrose$ghosthero.def_verb=evaded
|
items.artifacts.driedrose$ghosthero.def_verb=evaded
|
||||||
items.artifacts.driedrose$ghosthero.hello=Hello again %s.
|
items.artifacts.driedrose$ghosthero.hello=Hello again %s.
|
||||||
items.artifacts.driedrose$ghosthero.introduce=My spirit is bound to this rose, it was very precious to me, a gift from my love whom I left on the surface.\n\nI cannot return to him, but thanks to you I have a second chance to complete my journey. When I am able I will respond to your call and fight with you.\n\nHopefully you may succeed where I failed...
|
items.artifacts.driedrose$ghosthero.introduce=My spirit is bound to this rose, it was very precious to me, a gift from my love whom I left on the surface.\n\nI cannot return to him, but thanks to you I have a second chance to complete my journey. When I am able I will respond to your call and fight with you.\n\nAs long as you have the rose I can hear your voice, so you can use it to direct me from afar.\n\nHopefully you may succeed where I failed...
|
||||||
items.artifacts.driedrose$ghosthero.desc=A frail looking ethereal figure with a humanoid shape. Its power seems tied to the rose you have.\n\nThis ghost may not be much, but it seems to be your only true friend down here.
|
items.artifacts.driedrose$ghosthero.desc=A frail looking ethereal figure with a humanoid shape. Their power seems tied to the rose you have.\n\nThis ghost may not be much, they seem to be your only true friend down here.
|
||||||
items.artifacts.driedrose$wndghosthero.title=Ghost's Equipment
|
items.artifacts.driedrose$wndghosthero.title=Ghost's Equipment
|
||||||
items.artifacts.driedrose$wndghosthero.desc=The ghost is weak on their own, but their form is solid enough to be equipped with a weapon and armor. They will be able to use these items just like you do.\n\nThe ghost can currently equip items requiring up to _%d strength._
|
items.artifacts.driedrose$wndghosthero.desc=The ghost is weak on their own, but their form is solid enough to be equipped with a weapon and armor. They will be able to use these items just like you do.\n\nThe ghost can currently equip items requiring up to _%d strength._
|
||||||
items.artifacts.driedrose$wndghosthero.weapon_prompt=Select a weapon
|
items.artifacts.driedrose$wndghosthero.weapon_prompt=Select a weapon
|
||||||
|
|
Loading…
Reference in New Issue
Block a user