From d829e63f19838c763e83c8582d639cdf7526c982 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Fri, 30 Oct 2015 16:11:06 -0400 Subject: [PATCH] v0.3.2: added prison guards --- assets/guard.png | Bin 0 -> 1129 bytes .../shatteredpixeldungeon/Assets.java | 1 + .../shatteredpixeldungeon/Dungeon.java | 7 +- .../actors/mobs/Bestiary.java | 14 +- .../actors/mobs/Guard.java | 165 ++++++++++++++++++ .../sprites/GuardSprite.java | 59 +++++++ 6 files changed, 237 insertions(+), 9 deletions(-) create mode 100644 assets/guard.png create mode 100644 src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Guard.java create mode 100644 src/com/shatteredpixel/shatteredpixeldungeon/sprites/GuardSprite.java diff --git a/assets/guard.png b/assets/guard.png new file mode 100644 index 0000000000000000000000000000000000000000..5d07862d530b949cbbd934c02dbc8702536fa18d GIT binary patch literal 1129 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K51UQ(18JY9Pf~;1OBOz`!jG!i)^F=12eq z*-JcqUD@w*$%;$!O_*`uB2Z{ufKP}kkQNmcm6n#4m6cUsWz^HtGcYi)x3_n3adCBZ z_4M@g^78WY^9u?JN=%GNOiawn%PT7@D^GN*tE+2hC~0hLY^t>C?(Uv3W5(RM-HR75 z-nen&uHBiZPoKVVYZ=gRh{-@>4Gj&^jE#zlf*Xiz4#A~pZkrD@>hZgE|NsAg zf4TZT&`|l3AirQBjSoECX{QU6XH4>Tcd@+AFx7#9fmzJc#W5tJ_3hNe>RAQ?$2HGv zy_S3ETF~__)h%4CT}qC>{@UMsH%UP}O>61-&EdPnf9-zk@$SF)qSVd~CGVr(HD=Z9 z&DgwdopCRtZPd*vGp^0_@iXQPu1(0}pHyC!>v|F3A-AkXq{hv1af%W<*ERu3BF*5-KmyuR^DT=0$FqKu6*zPaAMG~*** z%S?{Mh9lP+lJ_1jxv|-HOO8+5o24@yU78Ig<{Kvb-*Mlbi&@~CJ9FPxxyy{_zg^g5 z$hrB|&Q&e^{|R zKHm@?5htU!@Z4=1PcI&};^&3;jBJkiu4}n8Px*5aw^4B>TY+A_uC$))1qrJem2J^U zAJ%H0S#h!F{yqWO1uu3#%__B@f7Z5s3FGUw)9m(FW}539_egMu zkIT~(*s_mB_ig_)^~LL{?-S3sNhhp*SWxMDxSGe`u6h!)5|goM1=s#LC2dPNlQZvp zvsYbn)ac!ejk%KhPq#^S9GvyB@A2>NUSBSKKfsm$MLS__e8PH-=CL!d(ww{a;3oD7e>bIm;=OX3KjFtVm4E&H$K}Jf$Q*TJi{u1lCr?*Dmvv4F FO#p{l>sJ5( literal 0 HcmV?d00001 diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/Assets.java b/src/com/shatteredpixel/shatteredpixeldungeon/Assets.java index bd5299fd2..cf1f23791 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/Assets.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/Assets.java @@ -92,6 +92,7 @@ public class Assets { public static final String MIMIC = "mimic.png"; public static final String ROT_LASH = "rot_lasher.png"; public static final String ROT_HEART= "rot_heart.png"; + public static final String GUARD = "guard.png"; public static final String ITEMS = "items.png"; public static final String PLANTS = "plants.png"; diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/src/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index aee9c2e5b..a707e5abc 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -78,13 +78,14 @@ public class Dungeon { //enum of items which have limited spawns, records how many have spawned //could all be their own separate numbers, but this allows iterating, much nicer for bundling/initializing. + //TODO: this is fairly brittle when it comes to bundling, should look into a more flexible solution. public static enum limitedDrops{ //limited world drops strengthPotions, upgradeScrolls, arcaneStyli, - //all unlimited health potion sources + //all unlimited health potion sources (except guards, which are at the bottom. swarmHP, batHP, warlockHP, @@ -101,7 +102,9 @@ public class Dungeon { seedBag, scrollBag, potionBag, - wandBag; + wandBag, + + guardHP; public int count = 0; diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java b/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java index beec5620c..a88924fb8 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java @@ -90,20 +90,20 @@ public class Bestiary { break; case 6: - chances = new float[]{ 4, 2, 1, 0.2f }; + chances = new float[]{ 4, 2, 1, 0.2f }; classes = new Class[]{ Skeleton.class, Thief.class, Swarm.class, Shaman.class }; break; case 7: - chances = new float[]{ 3, 1, 1, 0 }; - classes = new Class[]{ Skeleton.class, Shaman.class, Thief.class, Swarm.class }; + chances = new float[]{ 3, 1, 1, 1 }; + classes = new Class[]{ Skeleton.class, Shaman.class, Thief.class, Guard.class }; break; case 8: - chances = new float[]{ 3, 2, 1, 1, 0, 0.02f }; - classes = new Class[]{ Skeleton.class, Shaman.class, Gnoll.class, Thief.class, Swarm.class, Bat.class }; + chances = new float[]{ 3, 2, 2, 1, 0.02f }; + classes = new Class[]{ Skeleton.class, Shaman.class, Guard.class, Thief.class, Bat.class }; break; case 9: - chances = new float[]{ 3, 3, 1, 0, 0.02f, 0.01f }; - classes = new Class[]{ Skeleton.class, Shaman.class, Thief.class, Swarm.class, Bat.class, Brute.class }; + chances = new float[]{ 3, 3, 2, 1, 0.02f, 0.01f }; + classes = new Class[]{ Skeleton.class, Guard.class, Shaman.class, Thief.class, Bat.class, Brute.class }; break; case 10: diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Guard.java b/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Guard.java new file mode 100644 index 000000000..e3d85a0b0 --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Guard.java @@ -0,0 +1,165 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2015 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 + */ +package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; + +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple; +import com.shatteredpixel.shatteredpixeldungeon.effects.Chains; +import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing; +import com.shatteredpixel.shatteredpixeldungeon.items.Generator; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; +import com.shatteredpixel.shatteredpixeldungeon.sprites.GuardSprite; +import com.watabou.utils.Bundle; +import com.watabou.utils.Callback; +import com.watabou.utils.Random; + +public class Guard extends Mob { + + //they can only use their chains once + private boolean chainsUsed = false; + + { + name = "prison guard"; + spriteClass = GuardSprite.class; + + HP = HT = 30; + defenseSkill = 10; + + EXP = 6; + maxLvl = 14; + + loot = null; //see createloot. + lootChance = 1; + } + + @Override + public int damageRoll() { + return Random.NormalIntRange(4, 10); + } + + @Override + protected boolean act() { + if (state == HUNTING && + Level.fieldOfView[target] && + Level.distance( pos, target ) < 4 && !Level.adjacent( pos, target ) && + chain(target)) { + + return false; + + } else { + return super.act(); + } + } + + private boolean chain(int target){ + if (chainsUsed) + return false; + + Ballistica chain = new Ballistica(pos, target, Ballistica.PROJECTILE); + + if (chain.collisionPos != Dungeon.hero.pos) + return false; + else { + int newPos = -1; + for (int i : chain.subPath(1, chain.dist)){ + if (!Level.solid[i] && Actor.findChar(i) == null){ + newPos = i; + break; + } + } + + if (newPos == -1){ + return false; + } else { + final int newHeroPos = newPos; + yell("get over here!"); + sprite.parent.add(new Chains(pos, Dungeon.hero.pos, new Callback() { + public void call() { + Actor.addDelayed(new Pushing(Dungeon.hero, Dungeon.hero.pos, newHeroPos), -1); + Dungeon.hero.pos = newHeroPos; + Dungeon.observe(); + Dungeon.level.press(newHeroPos, Dungeon.hero); + Cripple.prolong(Dungeon.hero, Cripple.class, 4f); + next(); + } + })); + } + } + chainsUsed = true; + return true; + } + + @Override + public int attackSkill( Char target ) { + return 14; + } + + @Override + public int dr() { + return 7; + } + + @Override + public String defenseVerb() { + return "blocked"; + } + + @Override + protected Item createLoot() { + //first see if we drop armor, chance is 1/8 (0.125f) + if (Random.Int(8) == 0){ + return Generator.randomArmor(); + //otherwise, we may drop a health potion. Chance is 1/(7+potions dropped) + //including the chance for armor before it, effective droprate is ~1/(8 + (1.15*potions dropped)) + } else { + if (Random.Int(7 + Dungeon.limitedDrops.guardHP.count) == 0){ + Dungeon.limitedDrops.guardHP.drop(); + return new PotionOfHealing(); + } + } + + return null; + } + + @Override + public String description() { + return ""; //TODO + } + + private final String CHAINSUSED = "chainsused"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(CHAINSUSED, chainsUsed); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + chainsUsed = bundle.getBoolean(CHAINSUSED); + } +} diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/sprites/GuardSprite.java b/src/com/shatteredpixel/shatteredpixeldungeon/sprites/GuardSprite.java new file mode 100644 index 000000000..34f23604c --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/sprites/GuardSprite.java @@ -0,0 +1,59 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2015 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 + */ +package com.shatteredpixel.shatteredpixeldungeon.sprites; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; +import com.watabou.noosa.MovieClip; +import com.watabou.noosa.TextureFilm; + +public class GuardSprite extends MobSprite { + + public GuardSprite() { + super(); + + texture( Assets.GUARD ); + + TextureFilm frames = new TextureFilm( texture, 12, 16 ); + + idle = new Animation( 2, true ); + idle.frames( frames, 0, 0, 0, 1, 0, 0, 1, 1 ); + + run = new MovieClip.Animation( 15, true ); + run.frames( frames, 2, 3, 4, 5, 6, 7 ); + + attack = new MovieClip.Animation( 12, false ); + attack.frames( frames, 8, 9, 10 ); + + die = new MovieClip.Animation( 8, false ); + die.frames( frames, 11, 12, 13, 14 ); + + play( idle ); + } + + @Override + public void play( Animation anim ) { + if (anim == die) { + emitter().burst( ShadowParticle.UP, 4 ); + } + super.play( anim ); + } +} \ No newline at end of file