From 88efff430ba6aceceae3b5be74c8db59b51a91fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Mon, 12 May 2014 01:29:25 +0200 Subject: [PATCH] Heart pieces, more balanced entities & gen. --- res/img/gui.xcf | Bin 187969 -> 187969 bytes res/img/items.png | Bin 2136 -> 2328 bytes res/img/items.xcf | Bin 4939 -> 5057 bytes src/mightypork/rogue/Res.java | 1 + .../rogue/screens/game/InvLayer.java | 1 - .../rogue/screens/game/ScreenGame.java | 1 - .../screens/game/WorldConsoleRenderer.java | 25 ++++- src/mightypork/rogue/t/TryItemDmg.java | 16 ++++ src/mightypork/rogue/world/World.java | 19 +++- src/mightypork/rogue/world/WorldConsole.java | 7 ++ src/mightypork/rogue/world/WorldCreator.java | 12 +-- src/mightypork/rogue/world/entity/Entity.java | 6 ++ .../world/entity/entities/BrownRatAi.java | 6 +- .../world/entity/entities/EntityBossRat.java | 4 +- .../world/entity/entities/EntityBrownRat.java | 8 +- .../world/entity/entities/EntityGrayRat.java | 12 +-- .../world/entity/entities/GrayRatAi.java | 2 +- .../world/entity/entities/PlayerEntity.java | 5 +- .../entity/modules/EntityModuleHealth.java | 4 +- .../rogue/world/gen/LevelGenerator.java | 47 ++++++---- .../rogue/world/gen/ScratchMap.java | 22 +++-- .../world/gen/rooms/AbstractRectRoom.java | 8 +- .../rogue/world/gen/rooms/EntranceRoom.java | 2 +- .../rogue/world/gen/rooms/ExitRoom.java | 2 +- .../rogue/world/gen/rooms/HeartPieceRoom.java | 44 +++++++++ .../rogue/world/gen/rooms/Rooms.java | 5 +- .../rogue/world/gen/rooms/SecretRoom.java | 30 +----- .../rogue/world/gen/rooms/TreasureRoom.java | 38 ++++++++ src/mightypork/rogue/world/item/Item.java | 9 ++ src/mightypork/rogue/world/item/ItemType.java | 2 +- src/mightypork/rogue/world/item/Items.java | 8 +- .../item/items/active/ItemHeartPiece.java | 86 ++++++++++++++++++ .../world/item/items/weapons/ItemClub.java | 2 +- .../world/item/items/weapons/ItemHammer.java | 2 +- .../world/item/items/weapons/ItemStone.java | 2 +- .../world/item/items/weapons/ItemSword.java | 2 +- src/mightypork/rogue/world/level/Level.java | 6 +- 37 files changed, 339 insertions(+), 107 deletions(-) create mode 100644 src/mightypork/rogue/t/TryItemDmg.java create mode 100644 src/mightypork/rogue/world/gen/rooms/HeartPieceRoom.java create mode 100644 src/mightypork/rogue/world/gen/rooms/TreasureRoom.java create mode 100644 src/mightypork/rogue/world/item/items/active/ItemHeartPiece.java diff --git a/res/img/gui.xcf b/res/img/gui.xcf index 4185224afc787261a89a567b67da0e11ab6751af..04bd2b5b22738a9b56949ad7f5625179179b2a38 100644 GIT binary patch delta 375 zcmX@Ohx_0j?hWf1IhQdogbFY)RH{$j!I(0gX$w=q^m+T3q$kg3;#J+r009a>3aEyG zg@J+TEJTO_D#mno^F<~eRz}9@j^~-YCu?%3)I$}3D2_A;hY?7DFvtXsCI*I(A3$4y zY!HCSahwCn-2>uxK>Uw^fs+r2<$zcZi0y#bkAXq_Hv@wNHxNq$u{HyP>Kq0J;~oYE zcd(`PKsVM4O!f}5p6;-p$ziiQ=R}{3r>M4oTo4AdvXUQ&fu?`}%mrb-K)F~T&IRIH zAns*ghzeq0h)ri;i1P;GXakd~n1LY`=;E9W3=Bn+4|2F|mg@21+I%6Q bR$}^wKBf$CKsMi~Y`;;-xcx>YQ)UVPaBfEH delta 364 zcmX@Ohx_0j?hWf1Ip;AjgmN%2RLW1@!I&~Rw6bOL3ML-ajSLW=0Hg$fn1z9X=_o{q z0V>9Hb@NRo9@gm&=b3yaPhgUm?8(7X&j?imq&VUrY>*IG7-$AZ6$3-a2O$1~D#vjQ zD0dBrp8@eV1_n+xAQl5+H6S(vVmAf`@y`ql63jp>48+O|460KY7>rvO7~IQ2X4L~- zSuZf%az9he<^awKKACq>Z2_7}O0R&(!3v*>)2nz+`R3I(|;#LNRC@%(v z*mwqpIA`XwVdmIu5z9~p7lU*_?(?+j{!C3-eo2^; zmtjsvri}t15Pie=kGmmL)G2Q-n{THFX|-9|<+5g`8aK;4{SpVJmFybQZhbsiT3lkR zE@$bI|H@#p{7kjF$MEHh-BOA7sWH6d%Svj;zQ`4yDm^WB@%ERkY?nB}2d5H)l(uEH zZsb=atuiO;#Fy3*BJC6iaoD?9cL1j3Z_C;*oS8jj1H_hl1~u+DlhFDDWVI%!lB1Ef z16|B)Qll~#4A14R7*|FCPo-ey6gn#@9WtMq!&Sxyq-hL9eAbO-RV+BP{7C9|IxqQ@ z5~#BT4PUyBgoDU3NYB@~{!7$wFTndCrY=hDXB&(|aGh2axJI#tP2>9~R71HWAP~Qx zK49>(b34Oyp$*Y{(iuTziit~qU|~@5u4^Y2j;czg4?2Si%oGqs=_@NMvB-dkh=LG3 zGX%w|+CIkew-JClBPh(7m3h)f;qaiyS}3~U#JHDchH8B2bR1%G=FzFwdAr8K-$ocy zw)=(ck5weWe%sc*u8V3a?EL)v)(9X?dv7*FJ8~CV6dCogjdYhWk%&g849;uFqz_)j zn*BBh>FewBr6V){!aTZ^XD`TN5lV~_U7_YpgTyo|eUMjFbH3I$ld1>p+;0?J8^ZB~ zHBX$B14u+BLH9K!#}XARtfCwPwDJ3PxG_d;PC$a9UB-17Mq`?rKfd1p;sUh0r2j(t z;Ey&`pFM2EZ%o<{CXd6s?cxlio-bG(Pd+!f-|cQEO94LXW=Kb|YzKLJZwIvb#wXW1 zJyVh%M}{RY#$6!fjJ6E=@X4h9S?3xlm+3fOV@Fq>xuy6BotQW_FL*>sN~+}TTd&bc z;3o=Z0B4-84Pz|ih_1Q;I>Zjw7gg3mK34n8rJ3z?7Zk5k*&I-l?I5AxcrH7n-9BJG z^@{%-vGd_t22#3tScBPHi4f)G9-yEmw!nwK>g>;OUneMF%_KmONb?tTd)}Mzah@#jG+FIuZ86P}Du_@Wx-397B#wu8J?e!rF;`O~+ z$H6x;t@=@Lq%9WvbF3X0r^7Y#qm%oWjG6?0H@rNU9$s8Oa!d{WRWJ9E`J!s^_thPo zHgq|jhlHzhr&`Q}2CTm4p&z+qV)zu2JFMl*1$E!A@Uw4-2O_5vuH+Xo^EOG4PrIa} zEsPEL!)bGX@x*xE_|H3cvrmYp4OB7L3AmP?jkPs-s7QkkSqF_qZ?ZVsdwb4JB)_Xr zz3op%0YPF#M7JNbs|scXj=gB%dz;k(-t3CeFi)j-g3hg`bHDSv@2{m|$9=e*uvH(Z z!Qe*ugF2w`B}-qt0TnMr&5C0}BkX}sX*sWr|uJe>F!A`qm=@_yCt2;Tp z#4a4>SDzd%>ej?aQ_m_eF=ohtQMyLaxO{#aucN}qSyQ*GP**~})}-njo%vP`HPP%h z&y&|g&0C+itK8obu%xJ@BzscG!qU>xoiV9zupWjy$MDc4EL;^+0pPnvWy6!n;ptakVvH6L%Td2HYx4nPY`)1}=FK`GM4`j8TM zbFVX)A;s%R?qj@MwVxFp2bUz70R_-gM7Q6q%W`1}c# zdeX#pSp2Qa(ri9)da0yA$tp*PTp7t_RAo0ugY-rQkk=P(N8=$O!t|9X$Q|#P;lw9T zp0EMCcVIp6c|Q4=*9GI@-6>pd(fCgeTedksST|<-O5ORX33t6bo02R?i>hoXKDsO> z7&AM|H)K@;O3@HcO+61f&%LOKdE{IMjs?dqb2nJ=p+bYB!Ri|7F$F~en5!5Wb-;?t z7M@(8Ct4(j^~ogZFDFe6)@EDVQ#E0|-G^xOK9d>wN6`)F& z!+^4Q#YfrDBlOmu&aGrep%nfRPr<{FDzWKA-+hUL=hnPfL5FL_CTHaS?ug|AiiKbX)EPDr3334<gC$Rx%|2Ok)6U zNmKS?tZ^J3ezEbR&y?jeJTK={9Kx%y5`Jg>{*%^6kXYj;KUjnMRz*wOqdXZ! zoot`}Aos6@GBoe)YXcZJ+;MO06kE@u1jp{l7YfC|xII-zOl?A>wvc8~7N9CO7&(P7 zk84MJ(xA*e$f;IYm zSIYb{g{MhRFy*4@6kg(=qp)GK6Zl?MLRoMse&47{v15HHVa z8!a~&+0&1nhs=cS=Qm}8k$*l=-{EO@Z{D3dgt8}{lrjxloNq5S?=|T%*bk5wB!QFM zPNBr;DsP6mx+`fDcsr*x83Ky-uQ1oIJsd#=_a|@W0?kC=vVi`&1ouv9(T%NG@>17x z&~z2Mt_wH3P)G1$Xm@F0b<2BKw~`#j`fh>cjOkac<7B{KtAzr0bxqCtO-=FSRcOW& zHJwAEoeY=ESKR)snr0yJ!LVhC$2sP3H*|SiM3cF#V-LCK+$d^2zW?bx8k=7i@btoU zk;0qrQ^V(M(WS`sVIoN(zkl$@jo{b0z+$>W*`|WH+a?ao9y1gL9WP51fX@C=_-w~@ z;+=AhQAz~t1piIi0pmc1ic4>voZ3rqrhqe-)8BrY&16Ohc>qg+abt#gzQ_Mr$ndU~ zL&i~zQz+ruI@1N<92iawd3GgpXXUCZoB6DSBbmo_qsh$%p0CQK*&&$ zMuBNi5^Vke6v{WsGtF40Vm!aOOrGZGFoU-`PZ>e4X*&Zz2R<>Zs`6hZeu?HhdoU1(HbVyc=E zD*^ucuHKY~bxH;a>r?Nukjpa=N%-@X516zr@t^_v)A>`U`-=#_n6R6iXkLst1Ee=p zYcKJ4Y8-uz?R17Gn0yOHI}j#kL(J4#f=nIt;%7R_qby-Miq$PbfWmBr5h=UZR>Zlh zYiW&{h;Vr}HtCK6oU~;uHxqnmDetP1YNc!19=8J>TucXQ@_f@ZwAHV{5fSIpWtUE? z;amB?Ta)5{f>0P)+S;e(C!v!Yno!53fDYO@VLI6`)ec1Gwd5D_c5m z$nE_|RP4i@6aX!9J&hP^82g&uKb}m{C>#iCPYA)N?v=U4Q#%*T8q*~61%MglFm|!C7Pe~(DQ0OnZIy# ztE9bv81n}*(!v2UzVk7PJ@&Z{Q8$D&{5C;7GUy!)u#NOZBUP3Zj7#4S#Y{8pwX`18 z!Lfk%W5k7TcBAEC+r9F$h+d1hI$O$x za6mArTitPR_=EsfqU9KK=Iq(vH<=lyq|1Cc=MV8GLZ4o<*pvO|y@gotF`q&fP^=7( zx+Qjtq<@xtpVCtw!CNCo9&h71?ZnU=s0*R;(%7qa`4+@rVa$`U#7)Hm|C;E3CH^14 bhz3Z6-CsKO?qZuXXg4qqANOXr@SJ}D*XsHB diff --git a/res/img/items.xcf b/res/img/items.xcf index 73eb70f11141dc2eae21e42f46d8bdbcd11d4a51..31a7fdf50ad8ef09beccef6431b616751423c038 100644 GIT binary patch delta 736 zcma)4L2DC16#m|3)5hqj@hW(+jZ{H2t))~&a}Ib_&)tf86WfD_)q{d3rNx6Ho-8eb zhY}Qut=JU<;z}x&io)(M5Xp9vw(RcA^G)JK@!-O@^Ue3(y!XvxJ`S!8JvdFPOJ}YS z&CWfijRSYl`)e`YF7jt$5zOq zbk-wL-oM5%M6wTAx7uHmC~7Vv2jUFO7=-4K!i@EHi&{y0XLI4Y6t-DCVH}dIBnU&b zYhvl<@}gs6E~|ScXmN}n+wQbFJI#4GutZTW7(=qQ5$Gh2Hx}VI(kI)0^=xj*<^HozB$P_(yNh`Q8t2)36MX5tl_T-RsO2j(GBF0 z`ETACFOArwG~B|?`b_^cxl;5$Owd0}^!?r6#cgCYad--vOy3&%KvaRMT{TT>(i9hw zlTp~bPcAhKyMBMqLAr!UW@v^#A`uPFaRtTS&|BQkT8npGHLQw?VR^$w4a*reW*8YZ vj;zX6=_lMRys9r1_ZLP>XM0c5yvHtVpmag-@=v{VL$o`Bhl2UJbm06i()cZ~ delta 592 zcmY*X%W4!s6g{`laeSdp1UHJ{!dXc|9+NN)<_ik^iXO4uh)acW??xzSh>LuHyQJ3& zQ$lUhA&8&g!d)R$24NmOp4+psyDoK3oqKK_=$`b?o_=~R)yd&2k%#V!{Csp5>*oVE zmN^D)oC5d$06kQn&4rAoXpV3I@iXV0^B7>}V+1fY@c#@CSz4Us)A|JhG|D2OOhDkNt88l)@iAVw?uF5hc^6*d~c0ek5Uj97pBt`RvoU|5}8doSZHh@E9N%dCd8ML{HX zACgHiC$-qarS2*L!hzGm^35_X<~CLeZEh?{V~dWWJ@6naOd)pJdj7TsP9bY_2s`Ps zw+%#g!J8-ztMd9l%&lit|K|Pfpm( entries = WorldProvider.get().getWorld().getConsole().getEntries(); + final WorldConsole console = WorldProvider.get().getWorld().getConsole(); + final Collection entries = console.getEntries(); int cnt = 0; @@ -54,7 +62,7 @@ public class WorldConsoleRenderer extends BaseComponent { final Rect rrr = lowRow.moveY(-rh * cnt); - fr.draw(entry.getMessage(), rrr.move(rh / 12, rh / 12), AlignX.LEFT, RGB.BLACK_60); + fr.draw(entry.getMessage(), rrr.move(rh / 8D, rh / 8D), AlignX.LEFT, RGB.BLACK_60); fr.draw(entry.getMessage(), rrr, AlignX.LEFT, RGB.WHITE); cnt++; @@ -64,7 +72,20 @@ public class WorldConsoleRenderer extends BaseComponent { Log.e(e); // this should not happen anymore } + + if (console.lastPickupItem != null) { + + double alpha = 1; + if (console.timeSinceLastPickup > 2) { + alpha = 1 - Easing.CIRC_OUT.get(Calc.clamp((console.timeSinceLastPickup - 2) / 1, 0, 1)); + } + + alph.setTo(alpha); + console.lastPickupItem.render(itemViewRect); + } + Color.popAlpha(); + } } diff --git a/src/mightypork/rogue/t/TryItemDmg.java b/src/mightypork/rogue/t/TryItemDmg.java new file mode 100644 index 0000000..3fcfc3c --- /dev/null +++ b/src/mightypork/rogue/t/TryItemDmg.java @@ -0,0 +1,16 @@ +package mightypork.rogue.t; + + +import mightypork.rogue.world.item.Item; +import mightypork.rogue.world.item.Items; + + +public class TryItemDmg { + + public static void main(String[] args) + { + final Item itm = Items.CLUB.createItemDamaged(80); + System.out.println(itm.getMaxUses() + " - remaining: " + itm.getRemainingUses()); + } + +} diff --git a/src/mightypork/rogue/world/World.java b/src/mightypork/rogue/world/World.java index d7fa328..cd21fce 100644 --- a/src/mightypork/rogue/world/World.java +++ b/src/mightypork/rogue/world/World.java @@ -10,7 +10,6 @@ import mightypork.gamecore.eventbus.clients.DelegatingClient; import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.util.ion.IonBundle; import mightypork.gamecore.util.ion.IonObjBundled; -import mightypork.gamecore.util.math.Calc; import mightypork.gamecore.util.math.algo.Coord; import mightypork.gamecore.util.math.algo.Step; import mightypork.gamecore.util.math.constraints.vect.Vect; @@ -159,7 +158,7 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea public int getHealthMax() { - return playerEntity.health.getMaxHealth(); + return playerEntity.health.getHealthMax(); } @@ -349,6 +348,18 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea return true; } + + + public void setHealth(int health) + { + playerEntity.health.setHealth(health); + } + + + public void setHealthMax(int health) + { + playerEntity.health.setHealthMax(health); + } } // not saved stuffs @@ -540,6 +551,8 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea public void msgPick(Item item) { console.addMessage("You've picked a " + item.getVisualName() + "."); + console.lastPickupItem = item; + console.timeSinceLastPickup = 0; } @@ -599,6 +612,6 @@ public class World implements DelegatingClient, BusAccess, IonObjBundled, Pausea public void msgEnterFloor(int floor) { - console.addMessage("~ " + Calc.ordinal(floor + 1) + " floor ~"); + console.addMessage("~ Floor " + floor + " ~"); } } diff --git a/src/mightypork/rogue/world/WorldConsole.java b/src/mightypork/rogue/world/WorldConsole.java index 72c2937..04e3cef 100644 --- a/src/mightypork/rogue/world/WorldConsole.java +++ b/src/mightypork/rogue/world/WorldConsole.java @@ -9,10 +9,15 @@ import java.util.concurrent.LinkedBlockingDeque; import mightypork.gamecore.eventbus.events.Updateable; import mightypork.gamecore.util.math.Easing; import mightypork.gamecore.util.math.constraints.num.mutable.NumAnimated; +import mightypork.rogue.world.item.Item; public class WorldConsole implements Updateable { + /** Used only for display */ + public Item lastPickupItem; + public double timeSinceLastPickup = Integer.MAX_VALUE; + private static final double DURATION = 5; public class Entry implements Updateable { @@ -87,6 +92,8 @@ public class WorldConsole implements Updateable { iter.remove(); } } + + timeSinceLastPickup += delta; } diff --git a/src/mightypork/rogue/world/WorldCreator.java b/src/mightypork/rogue/world/WorldCreator.java index 8a3a9a3..9c867a4 100644 --- a/src/mightypork/rogue/world/WorldCreator.java +++ b/src/mightypork/rogue/world/WorldCreator.java @@ -19,15 +19,11 @@ public class WorldCreator { final World w = new World(); w.setSeed(seed); -// final int count = 7; -// -// for (int i = 1; i <= count; i++) { -// final Level l = LevelGenerator.build(w, rand.nextLong(), i, LevelGenerator.DUNGEON_THEME, i == count); -// w.addLevel(l); -// } + final int count = 7; - w.addLevel(LevelGenerator.build(w, rand.nextLong(), 6, LevelGenerator.DUNGEON_THEME, false)); - w.addLevel(LevelGenerator.build(w, rand.nextLong(), 7, LevelGenerator.DUNGEON_THEME, true)); + for (int lvl = 1; lvl <= count; lvl++) { + w.addLevel(LevelGenerator.build(w, rand.nextLong(), lvl, LevelGenerator.DUNGEON_THEME, lvl == count)); + } w.createPlayer(); diff --git a/src/mightypork/rogue/world/entity/Entity.java b/src/mightypork/rogue/world/entity/Entity.java index afe7c09..7c46e1c 100644 --- a/src/mightypork/rogue/world/entity/Entity.java +++ b/src/mightypork/rogue/world/entity/Entity.java @@ -44,6 +44,7 @@ public abstract class Entity implements IonObjBundled, Updateable { public final EntityModuleHealth health = new EntityModuleHealth(this); private double despawnDelay = 1; protected Entity lastAttacker; + private boolean freed; public Entity(EntityModel model, int eid) @@ -171,6 +172,11 @@ public abstract class Entity implements IonObjBundled, Updateable { @Override public void update(double delta) { + if (!freed && isDead() && health.getTimeSinceLastDamage() >= 0.2) { + getLevel().freeTile(getCoord()); + freed = true; + } + for (final Entry entry : modules.entrySet()) { entry.getValue().update(delta); } diff --git a/src/mightypork/rogue/world/entity/entities/BrownRatAi.java b/src/mightypork/rogue/world/entity/entities/BrownRatAi.java index f64ed65..238389e 100644 --- a/src/mightypork/rogue/world/entity/entities/BrownRatAi.java +++ b/src/mightypork/rogue/world/entity/entities/BrownRatAi.java @@ -10,8 +10,8 @@ public class BrownRatAi extends GrayRatAi { { super(entity); - setAttackTime(0.8); - setScanTime(1); + setAttackTime(1.2); + setScanTime(1.3); } @@ -25,7 +25,7 @@ public class BrownRatAi extends GrayRatAi { @Override protected int getAttackStrength() { - return 3 + rand.nextInt(2); + return 2 + rand.nextInt(3); } diff --git a/src/mightypork/rogue/world/entity/entities/EntityBossRat.java b/src/mightypork/rogue/world/entity/entities/EntityBossRat.java index 8746d2a..24b19e5 100644 --- a/src/mightypork/rogue/world/entity/entities/EntityBossRat.java +++ b/src/mightypork/rogue/world/entity/entities/EntityBossRat.java @@ -31,7 +31,7 @@ public class EntityBossRat extends Entity { pos.setStepTime(0.4); setDespawnDelay(1); - health.setMaxHealth(80); + health.setHealthMax(80); health.setHealth(80); health.setHitCooldownTime(0.35); } @@ -63,7 +63,7 @@ public class EntityBossRat extends Entity { @Override - public void onCorpseRemoved() + public void onKilled() { // TODO drop rare stuff & fire event. diff --git a/src/mightypork/rogue/world/entity/entities/EntityBrownRat.java b/src/mightypork/rogue/world/entity/entities/EntityBrownRat.java index 3bfe752..cf242d2 100644 --- a/src/mightypork/rogue/world/entity/entities/EntityBrownRat.java +++ b/src/mightypork/rogue/world/entity/entities/EntityBrownRat.java @@ -28,10 +28,10 @@ public class EntityBrownRat extends Entity { addModule("ai", ai); pos.addMoveListener(ai); - pos.setStepTime(0.37); // faster than gray rat + pos.setStepTime(0.39); // faster than gray rat setDespawnDelay(1); - health.setMaxHealth(14); + health.setHealthMax(14); health.setHealth(Calc.randInt(rand, 8, 14)); // tougher to kill health.setHitCooldownTime(0.35); // a bit longer than gray rat } @@ -63,11 +63,11 @@ public class EntityBrownRat extends Entity { @Override - public void onCorpseRemoved() + public void onKilled() { // drop rat stuff - if (rand.nextInt(8) == 0) { + if (rand.nextInt(7) == 0) { getLevel().dropNear(getCoord(), Items.BONE.createItemDamaged(10)); return; } diff --git a/src/mightypork/rogue/world/entity/entities/EntityGrayRat.java b/src/mightypork/rogue/world/entity/entities/EntityGrayRat.java index 556fc76..02f26aa 100644 --- a/src/mightypork/rogue/world/entity/entities/EntityGrayRat.java +++ b/src/mightypork/rogue/world/entity/entities/EntityGrayRat.java @@ -31,8 +31,8 @@ public class EntityGrayRat extends Entity { pos.setStepTime(0.5); setDespawnDelay(1); - health.setMaxHealth(5); - health.setHealth(Calc.randInt(rand, 3, 5)); + health.setHealthMax(6); + health.setHealth(Calc.randInt(rand, 4, 6)); health.setHitCooldownTime(0.3); } @@ -63,16 +63,16 @@ public class EntityGrayRat extends Entity { @Override - public void onCorpseRemoved() + public void onKilled() { // drop rat stuff - if (rand.nextInt(6) == 0) { - getLevel().dropNear(getCoord(), Items.BONE.createItemDamaged(10)); + if (rand.nextInt(4) == 0) { + getLevel().dropNear(getCoord(), Items.BONE.createItemDamaged(40)); return; } - if (rand.nextInt(7) == 0) { + if (rand.nextInt(6) == 0) { getLevel().dropNear(getCoord(), Items.MEAT.createItem()); return; } diff --git a/src/mightypork/rogue/world/entity/entities/GrayRatAi.java b/src/mightypork/rogue/world/entity/entities/GrayRatAi.java index 8db37a9..ec78a9f 100644 --- a/src/mightypork/rogue/world/entity/entities/GrayRatAi.java +++ b/src/mightypork/rogue/world/entity/entities/GrayRatAi.java @@ -26,7 +26,7 @@ public class GrayRatAi extends MonsterAi { @Override protected double getAttackDistance() { - return 1.43; + return 1.1; } diff --git a/src/mightypork/rogue/world/entity/entities/PlayerEntity.java b/src/mightypork/rogue/world/entity/entities/PlayerEntity.java index 86e5fce..3abf010 100644 --- a/src/mightypork/rogue/world/entity/entities/PlayerEntity.java +++ b/src/mightypork/rogue/world/entity/entities/PlayerEntity.java @@ -21,7 +21,7 @@ public class PlayerEntity extends Entity { super(entity); setDespawnDelay(2); - health.setMaxHealth(12); + health.setHealthMax(6); // 3 hearts health.fill(); // fill health bar to max health.setHitCooldownTime(0.5); } @@ -38,7 +38,8 @@ public class PlayerEntity extends Entity { final Tile t = getLevel().getTile(getCoord()); if (t.hasItem()) { final Item item = t.pickItem(); - if (getWorld().getPlayer().addItem(item)) { + + if (item.pickUp(getWorld().getPlayer())) { // player picked item } else { t.dropItem(item); // put back. diff --git a/src/mightypork/rogue/world/entity/modules/EntityModuleHealth.java b/src/mightypork/rogue/world/entity/modules/EntityModuleHealth.java index 007cf90..3b15d2a 100644 --- a/src/mightypork/rogue/world/entity/modules/EntityModuleHealth.java +++ b/src/mightypork/rogue/world/entity/modules/EntityModuleHealth.java @@ -68,13 +68,13 @@ public class EntityModuleHealth extends EntityModule { } - public int getMaxHealth() + public int getHealthMax() { return maxHealth; } - public void setMaxHealth(int maxHealth) + public void setHealthMax(int maxHealth) { if (maxHealth <= 0) throw new IllegalValueException("Max health out of allowed range: " + maxHealth); this.maxHealth = maxHealth; diff --git a/src/mightypork/rogue/world/gen/LevelGenerator.java b/src/mightypork/rogue/world/gen/LevelGenerator.java index c749eb0..d1deff2 100644 --- a/src/mightypork/rogue/world/gen/LevelGenerator.java +++ b/src/mightypork/rogue/world/gen/LevelGenerator.java @@ -4,6 +4,7 @@ package mightypork.rogue.world.gen; import java.util.Random; import mightypork.gamecore.logging.Log; +import mightypork.gamecore.util.math.Calc; import mightypork.gamecore.util.math.algo.Coord; import mightypork.rogue.world.World; import mightypork.rogue.world.entity.Entities; @@ -20,9 +21,9 @@ public class LevelGenerator { @SuppressWarnings("fallthrough") - public static Level build(World world, long seed, int complexity, MapTheme theme, boolean lastLevel) throws WorldGenError + public static Level build(World world, long seed, int level, MapTheme theme, boolean lastLevel) throws WorldGenError { - Log.f3("Generating level of complexity: " + complexity); + Log.f3("Generating level of complexity: " + level); final Random rand = new Random(seed + 13); @@ -35,10 +36,15 @@ public class LevelGenerator { throw new WorldGenError("Could not place entrance room."); } - for (int i = 0; i < 1 + complexity / 2 + rand.nextInt((int) (1 + complexity * 0.2)); i++) { + for (int i = 0; i < Calc.randInt(rand, 1 + level, (int) (1 + level * 1.5)); i++) { map.addRoom(Rooms.BASIC, false); - if (rand.nextInt(7) > 0) map.addRoom(Rooms.SECRET, false); - if (rand.nextInt(7) > 0) map.addRoom(Rooms.DEAD_END, false); + + // spice it up with dead ends + if (rand.nextInt(6) > 0) map.addRoom(Rooms.DEAD_END, false); + } + + for (int i = 0; i < Calc.randInt(rand, 1, level / 3); i++) { + map.addRoom(Rooms.TREASURE, false); } if (!lastLevel) { @@ -48,39 +54,48 @@ public class LevelGenerator { } if (lastLevel) { - if (!map.addRoom(Rooms.BOSS_ROOM, true)) { + if (!map.addRoom(Rooms.BOSS, true)) { throw new WorldGenError("Could not place boss room."); } } + map.addRoom(Rooms.HEART_ROOM, true); + map.buildCorridors(); - switch (complexity) { + switch (level) { default: case 3: case 2: - if (rand.nextInt(2) == 0) map.dropInMap(Items.CLUB.createItemDamaged(60), 50); + if (rand.nextInt(2) == 0) map.putItemInMap(Items.CLUB.createItemDamaged(30), 50); case 1: - case 0: - if (rand.nextInt(2) == 0) map.dropInMap(Items.ROCK.createItemDamaged(10), 50); + if (rand.nextInt(2) == 0) map.putItemInMap(Items.ROCK.createItemDamaged(10), 50); + } + + if (level == 1) { + map.putItemInMap(Items.BONE.createItemDamaged(20), 60); + } + + if (level == 2) { + map.putItemInMap(Items.CLUB.createItemDamaged(50), 60); } - if (complexity == 6) { - map.dropInMap(Items.SWORD.createItemDamaged(40), 200); + if (level == 6) { + map.putItemInMap(Items.SWORD.createItemDamaged(60), 200); } - if (complexity == 5) { - map.dropInMap(Items.HAMMER.createItemDamaged(40), 100); + if (level == 4) { + map.putItemInMap(Items.HAMMER.createItemDamaged(60), 100); } // entities - random rats - for (int i = 0; i < 3 + complexity + rand.nextInt(1 + complexity); i++) { + for (int i = 0; i < Calc.randInt(rand, (int) (3 + level * 1.5), (int) (3 + level * 2.5)); i++) { Entity e; - if (rand.nextInt((int) (complexity / 1.5) + 1) != 0) { + if (level > 2 && rand.nextInt(level - 2 + 1) != 0) { e = Entities.RAT_BROWN.createEntity(); } else { e = Entities.RAT_GRAY.createEntity(); diff --git a/src/mightypork/rogue/world/gen/ScratchMap.java b/src/mightypork/rogue/world/gen/ScratchMap.java index 34d5feb..e424e4d 100644 --- a/src/mightypork/rogue/world/gen/ScratchMap.java +++ b/src/mightypork/rogue/world/gen/ScratchMap.java @@ -578,26 +578,34 @@ public class ScratchMap { } - public boolean dropInArea(Item item, Coord min, Coord max, int tries) + public boolean putItem(Item item, Coord pos) + { + if (!isIn(pos)) return false; + + final Tile t = getTile(pos); + if (t.dropItem(item)) return true; + + return false; + } + + + public boolean putItemInArea(Item item, Coord min, Coord max, int tries) { final Coord pos = Coord.zero(); for (int i = 0; i < tries; i++) { pos.x = min.x + rand.nextInt(max.x - min.x); pos.y = min.y + rand.nextInt(max.y - min.y); - if (!isIn(pos)) continue; - - final Tile t = getTile(pos); - if (t.dropItem(item)) return true; + if (putItem(item, pos)) return true; } return false; } - public boolean dropInMap(Item item, int tries) + public boolean putItemInMap(Item item, int tries) { - return dropInArea(item, genMin, genMax, tries); + return putItemInArea(item, genMin, genMax, tries); } diff --git a/src/mightypork/rogue/world/gen/rooms/AbstractRectRoom.java b/src/mightypork/rogue/world/gen/rooms/AbstractRectRoom.java index 0bdb265..acebd14 100644 --- a/src/mightypork/rogue/world/gen/rooms/AbstractRectRoom.java +++ b/src/mightypork/rogue/world/gen/rooms/AbstractRectRoom.java @@ -21,12 +21,12 @@ public abstract class AbstractRectRoom implements RoomBuilder { { // half width, half height actually final Coord innerSize = getInnerSize(rand); - final int width = 2 + innerSize.x; - final int height = 2 + innerSize.y; + final int width = 2 + innerSize.x - 1; + final int height = 2 + innerSize.y - 1; - final int wLow = width / 2; + final int wLow = (int) Math.round(width / 2D); final int wHigh = width - wLow; - final int hLow = height / 2; + final int hLow = (int) Math.round(height / 2D); final int hHigh = height - hLow; final Coord min = new Coord(center.x - wLow, center.y - hLow); diff --git a/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java b/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java index dd80eeb..d263631 100644 --- a/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java +++ b/src/mightypork/rogue/world/gen/rooms/EntranceRoom.java @@ -15,7 +15,7 @@ public class EntranceRoom extends AbstractRectRoom { @Override protected Coord getInnerSize(Random rand) { - return Coord.make(3 + rand.nextInt(2) * 2, 3 + rand.nextInt(2) * 3); + return Coord.make(3 + rand.nextInt(3), 3 + rand.nextInt(3)); } diff --git a/src/mightypork/rogue/world/gen/rooms/ExitRoom.java b/src/mightypork/rogue/world/gen/rooms/ExitRoom.java index 4d9e97b..ec908e2 100644 --- a/src/mightypork/rogue/world/gen/rooms/ExitRoom.java +++ b/src/mightypork/rogue/world/gen/rooms/ExitRoom.java @@ -15,7 +15,7 @@ public class ExitRoom extends AbstractRectRoom { @Override protected Coord getInnerSize(Random rand) { - return Coord.make(3, 3); + return Coord.make(3 + rand.nextInt(2), 3 + rand.nextInt(2)); } diff --git a/src/mightypork/rogue/world/gen/rooms/HeartPieceRoom.java b/src/mightypork/rogue/world/gen/rooms/HeartPieceRoom.java new file mode 100644 index 0000000..35bd9e2 --- /dev/null +++ b/src/mightypork/rogue/world/gen/rooms/HeartPieceRoom.java @@ -0,0 +1,44 @@ +package mightypork.rogue.world.gen.rooms; + + +import java.util.Random; + +import mightypork.gamecore.util.math.algo.Coord; +import mightypork.rogue.world.gen.MapTheme; +import mightypork.rogue.world.gen.ScratchMap; +import mightypork.rogue.world.gen.WorldGenError; +import mightypork.rogue.world.item.Item; +import mightypork.rogue.world.item.Items; + + +public class HeartPieceRoom extends SecretRoom { + + @Override + protected int getDoorCount(Random rand) + { + return 1; + } + + + @Override + protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max) + { + final Item heart = Items.HEART_PIECE.createItem(); + + if (!map.putItem(heart, min.add(2, 2))) { + if (!map.putItemInArea(heart, min, max, 100)) { + if (!map.putItemInMap(heart, 100)) { + throw new WorldGenError("Could not place heart piece."); + } + + } + } + } + + + @Override + protected Coord getInnerSize(Random rand) + { + return Coord.make(3, 3); + } +} diff --git a/src/mightypork/rogue/world/gen/rooms/Rooms.java b/src/mightypork/rogue/world/gen/rooms/Rooms.java index 08f0e2e..b718b19 100644 --- a/src/mightypork/rogue/world/gen/rooms/Rooms.java +++ b/src/mightypork/rogue/world/gen/rooms/Rooms.java @@ -7,9 +7,10 @@ import mightypork.rogue.world.gen.RoomBuilder; public class Rooms { public static final RoomBuilder BASIC = new BasicRoom(); - public static final RoomBuilder SECRET = new SecretRoom(); + public static final RoomBuilder TREASURE = new TreasureRoom(); public static final RoomBuilder DEAD_END = new DeadEndRoom(); public static final RoomBuilder ENTRANCE = new EntranceRoom(); public static final RoomBuilder EXIT = new ExitRoom(); - public static final RoomBuilder BOSS_ROOM = new BossRoom(); + public static final RoomBuilder BOSS = new BossRoom(); + public static final RoomBuilder HEART_ROOM = new HeartPieceRoom(); } diff --git a/src/mightypork/rogue/world/gen/rooms/SecretRoom.java b/src/mightypork/rogue/world/gen/rooms/SecretRoom.java index 27c70d0..dbb32c8 100644 --- a/src/mightypork/rogue/world/gen/rooms/SecretRoom.java +++ b/src/mightypork/rogue/world/gen/rooms/SecretRoom.java @@ -3,16 +3,13 @@ package mightypork.rogue.world.gen.rooms; import java.util.Random; -import mightypork.gamecore.util.math.Calc; import mightypork.gamecore.util.math.algo.Coord; import mightypork.rogue.world.gen.MapTheme; -import mightypork.rogue.world.gen.ScratchMap; import mightypork.rogue.world.gen.TileProtectLevel; -import mightypork.rogue.world.item.Items; import mightypork.rogue.world.tile.TileModel; -public class SecretRoom extends AbstractRectRoom { +public abstract class SecretRoom extends AbstractRectRoom { @Override protected TileModel getDoorType(MapTheme theme, Random rand) @@ -35,31 +32,6 @@ public class SecretRoom extends AbstractRectRoom { } - @Override - protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max) - { - for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) { - map.dropInArea(Items.SANDWICH.createItem(), min, max, 50); - } - - for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { - map.dropInArea(Items.BONE.createItemDamaged(20), min, max, 50); - } - - for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) { - map.dropInArea(Items.ROCK.createItemDamaged(30), min, max, 50); - } - - for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { - map.dropInArea(Items.MEAT.createItem(), min, max, 50); - } - - for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { - map.dropInArea(Items.CHEESE.createItem(), min, max, 50); - } - } - - @Override protected Coord getInnerSize(Random rand) { diff --git a/src/mightypork/rogue/world/gen/rooms/TreasureRoom.java b/src/mightypork/rogue/world/gen/rooms/TreasureRoom.java new file mode 100644 index 0000000..49fb4fc --- /dev/null +++ b/src/mightypork/rogue/world/gen/rooms/TreasureRoom.java @@ -0,0 +1,38 @@ +package mightypork.rogue.world.gen.rooms; + + +import java.util.Random; + +import mightypork.gamecore.util.math.Calc; +import mightypork.gamecore.util.math.algo.Coord; +import mightypork.rogue.world.gen.MapTheme; +import mightypork.rogue.world.gen.ScratchMap; +import mightypork.rogue.world.item.Items; + + +public class TreasureRoom extends SecretRoom { + + @Override + protected void buildExtras(ScratchMap map, MapTheme theme, Random rand, Coord min, Coord max) + { + for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) { + map.putItemInArea(Items.SANDWICH.createItem(), min, max, 50); + } + + for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { + map.putItemInArea(Items.BONE.createItemDamaged(20), min, max, 50); + } + + for (int i = 0; i < Calc.randInt(rand, 0, 1); i++) { + map.putItemInArea(Items.ROCK.createItemDamaged(30), min, max, 50); + } + + for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { + map.putItemInArea(Items.MEAT.createItem(), min, max, 50); + } + + for (int i = 0; i < Calc.randInt(rand, 0, 2); i++) { + map.putItemInArea(Items.CHEESE.createItem(), min, max, 50); + } + } +} diff --git a/src/mightypork/rogue/world/item/Item.java b/src/mightypork/rogue/world/item/Item.java index c64f497..42e13d8 100644 --- a/src/mightypork/rogue/world/item/Item.java +++ b/src/mightypork/rogue/world/item/Item.java @@ -11,6 +11,7 @@ import mightypork.gamecore.util.ion.IonObjBlob; import mightypork.gamecore.util.ion.IonOutput; import mightypork.gamecore.util.math.Calc; import mightypork.gamecore.util.math.constraints.rect.Rect; +import mightypork.rogue.world.World.PlayerFacade; public abstract class Item implements IonObjBlob { @@ -139,6 +140,7 @@ public abstract class Item implements IonObjBlob { final int realRemoved = Math.min(removed, amount); final Item newItm = model.createItem(); + newItm.uses = uses; newItm.amount = realRemoved; this.amount -= realRemoved; @@ -188,4 +190,11 @@ public abstract class Item implements IonObjBlob { public abstract String getVisualName(); + + + @DefaultImpl + public boolean pickUp(PlayerFacade pl) + { + return pl.addItem(this); + } } diff --git a/src/mightypork/rogue/world/item/ItemType.java b/src/mightypork/rogue/world/item/ItemType.java index bc36cd9..5bd4b99 100644 --- a/src/mightypork/rogue/world/item/ItemType.java +++ b/src/mightypork/rogue/world/item/ItemType.java @@ -3,5 +3,5 @@ package mightypork.rogue.world.item; public enum ItemType { - FOOD, WEAPON; + FOOD, WEAPON, ACTIVE; } diff --git a/src/mightypork/rogue/world/item/Items.java b/src/mightypork/rogue/world/item/Items.java index a7ebd0b..1ac74c6 100644 --- a/src/mightypork/rogue/world/item/Items.java +++ b/src/mightypork/rogue/world/item/Items.java @@ -6,6 +6,7 @@ import java.util.Collection; import mightypork.gamecore.util.ion.IonInput; import mightypork.gamecore.util.ion.IonOutput; +import mightypork.rogue.world.item.items.active.ItemHeartPiece; import mightypork.rogue.world.item.items.food.ItemCheese; import mightypork.rogue.world.item.items.food.ItemMeat; import mightypork.rogue.world.item.items.food.ItemSandwich; @@ -33,6 +34,7 @@ public final class Items { public static final ItemModel HAMMER = new ItemModel(6, ItemHammer.class); public static final ItemModel SWORD = new ItemModel(7, ItemSword.class); public static final ItemModel ROCK = new ItemModel(8, ItemStone.class); + public static final ItemModel HEART_PIECE = new ItemModel(9, ItemHeartPiece.class); public static void register(int id, ItemModel model) @@ -79,12 +81,6 @@ public final class Items { } - public static Item create(int tileId) - { - return get(tileId).createItem(); - } - - public static void loadItems(IonInput in, Collection items) throws IOException { items.clear(); diff --git a/src/mightypork/rogue/world/item/items/active/ItemHeartPiece.java b/src/mightypork/rogue/world/item/items/active/ItemHeartPiece.java new file mode 100644 index 0000000..fcf5222 --- /dev/null +++ b/src/mightypork/rogue/world/item/items/active/ItemHeartPiece.java @@ -0,0 +1,86 @@ +package mightypork.rogue.world.item.items.active; + + +import mightypork.rogue.Res; +import mightypork.rogue.world.World.PlayerFacade; +import mightypork.rogue.world.item.Item; +import mightypork.rogue.world.item.ItemModel; +import mightypork.rogue.world.item.ItemRenderer; +import mightypork.rogue.world.item.ItemType; +import mightypork.rogue.world.item.render.QuadItemRenderer; + + +public class ItemHeartPiece extends Item { + + public ItemHeartPiece(ItemModel model) + { + super(model); + } + + + @Override + protected ItemRenderer makeRenderer() + { + return new QuadItemRenderer(this, Res.txq("item.heart_piece")); + } + + + @Override + protected boolean isStackable() + { + return false; + } + + + @Override + public int getAttackPoints() + { + return 0; + } + + + @Override + public int getFoodPoints() + { + return 0; + } + + + @Override + public ItemType getType() + { + return ItemType.ACTIVE; + } + + + @Override + public int getMaxUses() + { + return 1; + } + + + @Override + public boolean isDamageable() + { + return false; + } + + + @Override + public String getVisualName() + { + return "Heart Piece"; + } + + + @Override + public boolean pickUp(PlayerFacade pl) + { + pl.setHealthMax(pl.getHealthMax() + 2); // two points / heart + pl.setHealth(pl.getHealthMax()); + + return true; + } + +} diff --git a/src/mightypork/rogue/world/item/items/weapons/ItemClub.java b/src/mightypork/rogue/world/item/items/weapons/ItemClub.java index 15fe48d..7c3cb25 100644 --- a/src/mightypork/rogue/world/item/items/weapons/ItemClub.java +++ b/src/mightypork/rogue/world/item/items/weapons/ItemClub.java @@ -33,7 +33,7 @@ public class ItemClub extends ItemBaseWeapon { @Override public int getMaxUses() { - return 25; + return 40; } diff --git a/src/mightypork/rogue/world/item/items/weapons/ItemHammer.java b/src/mightypork/rogue/world/item/items/weapons/ItemHammer.java index 5ef5712..907aff5 100644 --- a/src/mightypork/rogue/world/item/items/weapons/ItemHammer.java +++ b/src/mightypork/rogue/world/item/items/weapons/ItemHammer.java @@ -33,7 +33,7 @@ public class ItemHammer extends ItemBaseWeapon { @Override public int getMaxUses() { - return 50; + return 60; } diff --git a/src/mightypork/rogue/world/item/items/weapons/ItemStone.java b/src/mightypork/rogue/world/item/items/weapons/ItemStone.java index e50e1a4..fb4b275 100644 --- a/src/mightypork/rogue/world/item/items/weapons/ItemStone.java +++ b/src/mightypork/rogue/world/item/items/weapons/ItemStone.java @@ -33,7 +33,7 @@ public class ItemStone extends ItemBaseWeapon { @Override public int getMaxUses() { - return 20; + return 30; } diff --git a/src/mightypork/rogue/world/item/items/weapons/ItemSword.java b/src/mightypork/rogue/world/item/items/weapons/ItemSword.java index 9459194..33f1e6c 100644 --- a/src/mightypork/rogue/world/item/items/weapons/ItemSword.java +++ b/src/mightypork/rogue/world/item/items/weapons/ItemSword.java @@ -33,7 +33,7 @@ public class ItemSword extends ItemBaseWeapon { @Override public int getMaxUses() { - return 100; + return 150; } diff --git a/src/mightypork/rogue/world/level/Level.java b/src/mightypork/rogue/world/level/Level.java index 0add773..1c16aa8 100644 --- a/src/mightypork/rogue/world/level/Level.java +++ b/src/mightypork/rogue/world/level/Level.java @@ -393,7 +393,11 @@ public class Level implements BusAccess, Updateable, DelegatingClient, Toggleabl if (removed == null) throw new NullPointerException("No such entity in level: " + eid); if (removed instanceof PlayerEntity) playerCount--; entityList.remove(removed); - freeTile(removed.getCoord()); + + // upon kill, entities free tile themselves. + if (!removed.isDead()) { + freeTile(removed.getCoord()); + } }