v2.4.0: finished impl of mimic tooth
This commit is contained in:
@@ -1198,6 +1198,12 @@ actors.mobs.dwarfking$dkmonk.rankings_desc=Fell Before the King of Dwarves
|
||||
actors.mobs.dwarfking$dkwarlock.rankings_desc=Fell Before the King of Dwarves
|
||||
actors.mobs.dwarfking$dkgolem.rankings_desc=Fell Before the King of Dwarves
|
||||
|
||||
actors.mobs.ebonymimic.name=ebony mimic
|
||||
actors.mobs.ebonymimic.reveal=There was a mimic there!
|
||||
actors.mobs.ebonymimic.hidden_name=suspicious outline
|
||||
actors.mobs.ebonymimic.hidden_desc=There seems to be something here, but it's almost totally transparent.
|
||||
actors.mobs.ebonymimic.desc=Mimics are magical creatures which can take any shape they wish. In dungeons they almost always choose a shape of a treasure chest, in order to lure in unsuspecting adventurers.\n\nEbony mimics are extremely tough mimics with the ability to make themselves almost invisible. They lurk on things that adventurers are likely to interact with, but do contain loot of their own as well.
|
||||
|
||||
actors.mobs.elemental$fireelemental.name=fire elemental
|
||||
actors.mobs.elemental$fireelemental.desc=Elementals are chaotic creatures that are often created when powerful occult magic isn't properly controlled. Elementals have minimal intelligence, and are usually associated with a particular type of magic.\n\nFire elementals are a common type of elemental which deals damage with fiery magic. They will set their target ablaze with melee attacks, and can occasionally shoot bolts of fire as well.
|
||||
actors.mobs.elemental$newbornfireelemental.name=newborn fire elemental
|
||||
|
||||
@@ -1304,7 +1304,7 @@ items.trinkets.exoticcrystals.name=exotic crystals
|
||||
items.trinkets.exoticcrystals.desc=These small pink crystals have the same shape as crystals of alchemical energy. While they can't be used for energy directly, they seem to be somehow influencing the potions and scrolls you find.\n\nAt its current level this trinket will replace _%d%%_ of potion or scroll drops with their exotic equivalents. This does not affect potions of strength, scrolls of upgrade, or items that are generated to help solve hazard rooms.
|
||||
|
||||
items.trinkets.mimictooth.name=mimic tooth
|
||||
items.trinkets.mimictooth.desc=TODO\n\nAt its current level this trinket will make all kinds of mimics _%sx_ more common, and will make mimics more difficult to detect.
|
||||
items.trinkets.mimictooth.desc=This large sharp tooth must have been pulled from a very unhappy mimic. It seems to be influencing the mimics of the dungeon, making them more frequent and dangerous.\n\nAt its current level this trinket will make all kinds of mimic _%1$sx_ more common, will make mimics much more difficult to detect, and will give each floor a _%2$s%%_ chance to contain an ebony mimic.
|
||||
|
||||
items.trinkets.mossyclump.name=mossy clump
|
||||
items.trinkets.mossyclump.desc=This clump of wet moss seems to hold onto its moisture no matter how hard you squeeze it. It seems to be magically tied to the dungeon itself, making grass and water more likely to appear.\n\nAt its current level this trinket will make _%d%%_ of regular floors become filled with either water or grass instead.\n\nThis trinket costs a relatively large amount of energy to upgrade.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2024 Evan Debenham
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.EquipableItem;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.Artifact;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Door;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.MimicSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class EbonyMimic extends Mimic {
|
||||
|
||||
{
|
||||
spriteClass = MimicSprite.Ebony.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
if (alignment == Alignment.NEUTRAL){
|
||||
return Messages.get(this, "hidden_name");
|
||||
} else {
|
||||
return super.name();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
if (alignment == Alignment.NEUTRAL){
|
||||
return Messages.get(this, "hidden_desc");
|
||||
} else {
|
||||
return super.description();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopHiding(){
|
||||
state = HUNTING;
|
||||
if (sprite != null) sprite.idle();
|
||||
if (Actor.chars().contains(this) && Dungeon.level.heroFOV[pos]) {
|
||||
enemy = Dungeon.hero;
|
||||
target = Dungeon.hero.pos;
|
||||
GLog.w(Messages.get(this, "reveal") );
|
||||
CellEmitter.get(pos).burst(Speck.factory(Speck.STAR), 10);
|
||||
Sample.INSTANCE.play(Assets.Sounds.MIMIC, 1, 0.85f);
|
||||
}
|
||||
if (Dungeon.level.map[pos] == Terrain.DOOR){
|
||||
Door.enter( pos );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageRoll() {
|
||||
if (alignment == Alignment.NEUTRAL){
|
||||
return Math.round(super.damageRoll()*1.5f); //BIG damage on surprise
|
||||
} else {
|
||||
return super.damageRoll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLevel(int level) {
|
||||
super.setLevel(Math.round(level*1.5f));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generatePrize( boolean useDecks ) {
|
||||
super.generatePrize( useDecks );
|
||||
//all existing prize items are guaranteed uncursed, and have a 50% chance to be +1 if they were +0
|
||||
for (Item i : items){
|
||||
if (i instanceof EquipableItem || i instanceof Wand){
|
||||
i.cursed = false;
|
||||
i.cursedKnown = true;
|
||||
if (i instanceof Weapon && ((Weapon) i).hasCurseEnchant()){
|
||||
((Weapon) i).enchant(null);
|
||||
}
|
||||
if (i instanceof Armor && ((Armor) i).hasCurseGlyph()){
|
||||
((Armor) i).inscribe(null);
|
||||
}
|
||||
if (!(i instanceof MissileWeapon || i instanceof Artifact) && i.level() == 0 && Random.Int(2) == 0){
|
||||
i.upgrade();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -296,6 +296,8 @@ public class Mimic extends Mob {
|
||||
m = new GoldenMimic();
|
||||
} else if (mimicType == CrystalMimic.class) {
|
||||
m = new CrystalMimic();
|
||||
} else if (mimicType == EbonyMimic.class) {
|
||||
m = new EbonyMimic();
|
||||
} else {
|
||||
m = new Mimic();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,9 @@ public class MimicTooth extends Trinket {
|
||||
|
||||
@Override
|
||||
public String desc() {
|
||||
return Messages.get(this, "desc", Float.toString(mimicChanceMultiplier(buffedLvl())));
|
||||
return Messages.get(this, "desc",
|
||||
Messages.decimalFormat("#.##", mimicChanceMultiplier(buffedLvl())),
|
||||
Messages.decimalFormat("#.##", 100*ebonyMimicChance(buffedLvl())));
|
||||
}
|
||||
|
||||
public static float mimicChanceMultiplier(){
|
||||
@@ -57,4 +59,16 @@ public class MimicTooth extends Trinket {
|
||||
return trinketLevel(MimicTooth.class) >= 0;
|
||||
}
|
||||
|
||||
public static float ebonyMimicChance(){
|
||||
return ebonyMimicChance(trinketLevel(MimicTooth.class));
|
||||
}
|
||||
|
||||
public static float ebonyMimicChance( int level ){
|
||||
if (level >= 0){
|
||||
return 0.125f + 0.125f * level;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.SacrificialFire;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.EbonyMimic;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.GoldenMimic;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
@@ -630,6 +631,35 @@ public abstract class RegularLevel extends Level {
|
||||
}
|
||||
Random.popGenerator();
|
||||
|
||||
//ebony mimics >:)
|
||||
Random.pushGenerator(Random.Long());
|
||||
if (Random.Float() < MimicTooth.ebonyMimicChance()){
|
||||
ArrayList<Integer> candidateCells = new ArrayList<>();
|
||||
if (Random.Int(2) == 0){
|
||||
for (Heap h : heaps.valueList()){
|
||||
if (h.type == Heap.Type.HEAP
|
||||
&& !(room(h.pos) instanceof SpecialRoom)
|
||||
&& findMob(h.pos) == null){
|
||||
candidateCells.add(h.pos);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Random.Int(5) == 0 && findMob(exit()) == null){
|
||||
candidateCells.add(exit());
|
||||
} else {
|
||||
for (int i = 0; i < length(); i++) {
|
||||
if (map[i] == Terrain.DOOR && findMob(i) == null) {
|
||||
candidateCells.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int pos = Random.element(candidateCells);
|
||||
mobs.add(Mimic.spawnAt(pos, EbonyMimic.class, false));
|
||||
}
|
||||
Random.popGenerator();
|
||||
|
||||
}
|
||||
|
||||
private static HashMap<Document, Dungeon.LimitedDrops> limitedDocs = new HashMap<>();
|
||||
|
||||
@@ -490,7 +490,7 @@ public class ItemSpriteSheet {
|
||||
assignItemRect(SUNDIAL, 16, 12);
|
||||
assignItemRect(CLOVER, 11, 15);
|
||||
assignItemRect(TRAP_MECHANISM, 13, 15);
|
||||
assignItemRect(MIMIC_TOOTH, 7, 13);
|
||||
assignItemRect(MIMIC_TOOTH, 8, 15);
|
||||
}
|
||||
|
||||
private static final int SCROLLS = xy(1, 19); //16 slots
|
||||
|
||||
@@ -28,9 +28,9 @@ import com.watabou.noosa.TextureFilm;
|
||||
|
||||
public class MimicSprite extends MobSprite {
|
||||
|
||||
private Animation advancedHiding;
|
||||
protected Animation advancedHiding;
|
||||
|
||||
private Animation hiding;
|
||||
protected Animation hiding;
|
||||
|
||||
{
|
||||
//adjust shadow slightly to account for 1 empty bottom pixel (used for border while hiding)
|
||||
@@ -68,7 +68,7 @@ public class MimicSprite extends MobSprite {
|
||||
attack.frames( frames, 3+c, 7+c, 8+c, 9+c );
|
||||
|
||||
die = new Animation( 5, false );
|
||||
die.frames( frames, 10+c, 111+c, 12+c );
|
||||
die.frames( frames, 10+c, 11+c, 12+c );
|
||||
|
||||
play( idle );
|
||||
}
|
||||
@@ -112,4 +112,25 @@ public class MimicSprite extends MobSprite {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Ebony extends MimicSprite{
|
||||
@Override
|
||||
protected int texOffset() {
|
||||
return 48;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideMimic() {
|
||||
super.hideMimic();
|
||||
alpha(0.2f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play(Animation anim) {
|
||||
if (curAnim == advancedHiding && anim != advancedHiding){
|
||||
alpha(1f);
|
||||
}
|
||||
super.play(anim);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user