From 865a5d56edba72cf5ddd10e9b9b1c115070d0c53 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 1 May 2022 14:49:30 -0400 Subject: [PATCH] Two units complete --- .../sprites/effects/large-orb-back.png | Bin 0 -> 626 bytes core/assets-raw/sprites/effects/large-orb.png | Bin 0 -> 249 bytes .../sprites/units/obviate-blade-heat.png | Bin 0 -> 1594 bytes .../sprites/units/obviate-blade.png | Bin 0 -> 1396 bytes .../assets-raw/sprites/units/obviate-cell.png | Bin 875 -> 597 bytes .../sprites/units/obviate-preview.png | Bin 0 -> 2872 bytes .../assets-raw/sprites/units/obviate-side.png | Bin 0 -> 419 bytes core/assets-raw/sprites/units/obviate.png | Bin 2872 -> 1209 bytes core/src/mindustry/content/Fx.java | 5 + core/src/mindustry/content/UnitTypes.java | 145 +++++++++++++----- .../entities/abilities/MoveEffectAbility.java | 41 +++++ .../mindustry/entities/bullet/BulletType.java | 4 +- .../entities/pattern/ShootBarrel.java | 1 + .../entities/pattern/ShootHelix.java | 2 +- .../entities/pattern/ShootMulti.java | 6 +- core/src/mindustry/mod/Mods.java | 18 +-- core/src/mindustry/type/UnitType.java | 3 +- core/src/mindustry/type/Weapon.java | 15 +- tools/src/mindustry/tools/Generators.java | 12 +- 19 files changed, 182 insertions(+), 70 deletions(-) create mode 100644 core/assets-raw/sprites/effects/large-orb-back.png create mode 100644 core/assets-raw/sprites/effects/large-orb.png create mode 100644 core/assets-raw/sprites/units/obviate-blade-heat.png create mode 100644 core/assets-raw/sprites/units/obviate-blade.png create mode 100644 core/assets-raw/sprites/units/obviate-preview.png create mode 100644 core/assets-raw/sprites/units/obviate-side.png create mode 100644 core/src/mindustry/entities/abilities/MoveEffectAbility.java diff --git a/core/assets-raw/sprites/effects/large-orb-back.png b/core/assets-raw/sprites/effects/large-orb-back.png new file mode 100644 index 0000000000000000000000000000000000000000..261446c5177d11799fc3d5f1b8891aa11a9c557a GIT binary patch literal 626 zcmeAS@N?(olHy`uVBq!ia0y~yUk44ofy`glX=O&z@+2p z;uumf=k1)^MMo5PoIRKS|9|?W_schLa`cW&$|*0I*Q_hT(c*B-;Fv^mPv*&Kx(Pjo z-)isApK^PfZft#5!}7M+iHR$86i;ta4oSN-c|~t^d#;LZ#kRut8+w+otWCSulBi^o z5c>F@qZB9im7{w&Pq}zZ$b051pw`A*Vwx{xY8WDsd++Y4l&60qzGXUws4mh~h(5m9 zDe&SN%gDBMPnkl`&R+4g)_u}ig=+J^XBSJ|nWl9$_onB<@84RrKCk<<;IZrH0NxaT z?-?H#vTb6~Sgx?fs%9;ltE!vbllMowqR%;okFLEtp3;W?! z#v1i_W#g;oAxC4vH)=GWSk-aPGLfz9#XjLBVO88`VhTc^*qLnj?PWa4SYJVRL-6;x z3rvD{7qo_*xuzi5`rp{hpo5nuiMjd40R=GA$#laZmf33=lM-4vKWk~6ZD$M1uno2N z-1Lv<%pSq6I|j_wrO8XePHN04VsM-C`HI7fw48;VUUx5u-B>8S*!0lu4Zn83@!~ti zyX;MGVE)^Lr#`o(7vEbwsqpZ>qWgO<+`i4XZnyLWX&wG`t5w*1SL*JYtf#iBk44ofy`glX=O&z_8iV z#WAE}&fA-Ye1{bTSR5w*|35RtM5J@kQJKE9DDm>BZH6)83{cRXb(Q-})%(AfzhAo* zXf40_%=QOq%UL4#9a(?y?5buR*?Dc|A#D+66`>W*p&hEu;qB%jEkADAez>1wzj601 z^EY`5+1j?vyLR`jblJ85W@jcIP6L$#6BxjZC;lo+8Wp!2D)RE|4Dfv(#v>c^QvX3< mrr`Nm-8OF%WuZ=JNZ!k+vcg7f$C+enkdUXVpUXO@geCw4Pg*tr literal 0 HcmV?d00001 diff --git a/core/assets-raw/sprites/units/obviate-blade-heat.png b/core/assets-raw/sprites/units/obviate-blade-heat.png new file mode 100644 index 0000000000000000000000000000000000000000..b6d8f68a40017926ce4889177c770768a7e9135f GIT binary patch literal 1594 zcmeAS@N?(olHy`uVBq!ia0y~yVCZ3BU})lCV_;yIa!SFEfq{XsILO_JVcj{ImkbQ7 zUp!qLLn`LHy&Ih`?J9BXRnj6?k8h7p%nq~db``Xzv`xw~{n0;WX;Qi7#S)j@H^Q~EC=5M)A zT$z4=@q#WO%@CQ9 zW!8{<>SAh%-i=!qGz_ll1fGl4+g+HE3X*zs{K6;J|LMx-*K+kT1>fcQ_pi6@Sl4mQ zf*_muqUUc0C#V@qNgY01*m6CU??csDL9R1%#XmGGS!h^ebcZ>PG5SZ$GV`U`YvxX4 zQxjI-V`vhaAiBT%7DLzv&QEVb)~#dYI`hQMd2??WPe6xAFrxeknW{P!Ez!qUg_O7GwLqCwU*&^#p-8T z7Z$QEw^_ltXI9DkK&gfX_GR7dPo4Kj?rAq~m!A1PI4EJ2$ACBKCFr@yvEh7?_Ir|nGY{MV-=p0 zXS{jy9XCnVWs3w3{bF6%xo-E)w?EX@@8sL%JD;rqH}4v18VK)7 z%Mkl``<35EtJ`ODBjdj02DdEhZ&zDwd2)xyj9D!L*BZ9-^c$sDbliI+eAn^guNj{g z2a1WzkZKhO)3BeF6!Gi8{vR&o>^BadKkoh7=w?7dmYCCvfNK$KKP30nGuJcC{xLUb zK2Ns6g4?f_9bvjF{m1MV{{!;}l6I$f8ZO_-GFTwEOmlg~!gcI>j<`?r{d47m?YZ-% zn-(50QC|Cw@5AkPawm5M^)2SsF!1fu)^za7GcIu=>HsQ{N8dcWXzPJYKeq zwI=Bg!}^nV7SH(oB;sx8!*y&&`I@d*tX2IhccRipq5nhdgxwW89(7zc-@HalNfaDC zXL9-x%Ers+^c8Q41Rg63cR$4^QrqKp?xoY$bAspC;ds$?vu`hNJjt0 zm5~=0NxJt$Jd8bXed@Gs_x7SrhsKHjk8U(WTud3YtUS?AYBe z{^4ElHkTAhDb{6dY2Re+X3Fw9>D)USsAkrY9$w$M#l%3-__x@7w%bSVpFb~YxAh^z z{M}zZ+?%2ET7M#w@lN@V1#3j?k569qYl`&8|4N^Kc`rHOqtWug`Qow*N1toji>|+a zG=FhDW8E?Lh2kku^_?O!q*?^_nQyMF>CNDdPpRo*f2=7t%eUsp$xZ)+QY}C3T6^YA z_5uDXIwl-C)+_z^)DGY0=hgIS9$W#7-edH??IUfb98mm~M@xOFF@$I{*Sws=^yhFJ2ti)TK$UcDyP zZFoFmpVTkTGm%*l!A=HK&+1AwyW4?zad&2$ z#k(XDMRq8km2o!YaO><$JGZezpl8($v$HV*J)2&eZ)@Ied-JaK>|bY04~9JGe)g}q z{rN&4OR1)nNBW+9TAE!{wMjKUu6~O7di$;uC5shjbgjF8W7_HI>uNuK)^v9^V4j&} z!eYEY-v7VA#7tLb16dilH|qDlFQ32v)9g zQk=o0CS^TkTgIJ;o|P`n2CX&n{wtMzPs~`XD8ah#=i&g9eDnEgw$CCKD@v$ZPVNit zYfBKhd2x%ci=U}fQ{Xl$JFi(=^JYzb^Z)ycKfmk${k5*RZ|G{g`*h%!hu81d<<~MN zZ@%{K+u4^Vul>Bfk@vA-j9rW1vPl;X?v2nZp-9wbIdYXt{#2x;*s8GcYi;B9^bDi)f9M1taoqYZLwb2Zo_FA9BzRc zQupr#Xh_BDX#N646*+ySbi1-)2 zkm`MZC;qDSR zqQw_GTw4-Ccm;iPM2s$G9942Mc=aa3OaEQYwdn1gu8SqRISz_&&OKL9v0=W5_o<2Z zCuO`T^^f9M7N9Zf%F@kS7kxasDMqjB`3w#>NBN6Ku4&)AmuJU&ENP01vw>HZTXLRv z@3E)Wd6z+{BSd-Dl#A+W+s^F<h4r|x`<)tMT4Iaoz|%VMYopf ze$@)w86NsL)bLe+8q^>l6OGQy72W%Gv@8R^|Robn0KGv#VIkbdiE}v_qXW(ZT)*|CVh3X z6rSh1S!pC)JV%qbMhac^CH82+Hc2gD;Y??WDimeW!oWjORxM#<> WGPdR!)5ay9AbC$$KbLh*2~7a>?u!%v literal 0 HcmV?d00001 diff --git a/core/assets-raw/sprites/units/obviate-cell.png b/core/assets-raw/sprites/units/obviate-cell.png index 80c360692626c592e23915e2e7c4d23d9e2c4bfe..9c807c22dcf9e12ce6f19db9fcef980a63f03a86 100644 GIT binary patch delta 520 zcmaFOc9msn0wEk~x%f9})_iNMduWy*Da!iw78uy>I zJA7x>-mjqndIr_A>~c?uCeDnm_7_;U=B3usyza})|NefvR&)3HTeIK4*RG#@ZT;5z z#in1+1)UFAc44QQET`}5Hy5R5EoNLNG)u^J-Q8W)Qd`Rd?sA=#EZ@C#myu`ugUCe5 zwWjr%d(Yoq`#UoubFb=6=gCzs{+`?L<=Ums6??*}zd2guCK$D*zTRxFX`;zI*-$6? z`kyHmmhhaJ`OTy#Z(GD{^S(c8SDj*gc82X7?~Kd!U#sQn``Ju(7d3WfSiiV-Ot{ZQ9**zKlwkBn-51RoU1T5x)x!n zBY2cqxbWQqOYt7#_$7M}1;khxgzpiZyRP!aR@wtDn~& hev6xdfq~(J%YOz#V}5SN(}fKnzNf37%Q~loCICLG19JcX delta 806 zcmcc0@|taefg!W1r;B4q#hkZy6RQ>(h_pUDoRhk%v+O^A-l27^|7P~^I8R{ke0TBv z-`lIqr#CCLXiQ90t-pBZc;T-8$5(du1+6PpcYe>*7h(42@$1t`GV4mu-xQs5+j_D2 z{jKj*S0@$w{{Q<^(^INV@kzz9%vmZgf0sr7-5s2f!{s||p=YA!qE@w5)yTGEnmUsb z6PCDVOiT1!)RHDSO{MjiuFj;)ge8BDO?bra))kz*GJY?&#i^|iCzZdg-_|(MM*4lk z=Q*VxPyShJe~Ya%=63XLtGE}sMY#-MaA4KT{(Ge^;!FKw{X_Mo53KxLI`P+)x2?t1 z+zWq(Z?P-g8MW6m+wRcqJdxv?9}XYMr?@_gQ~ zU0m1sa>`?y*)RWZmpHWP)y|VU2BiW~^Th^XBCrKmT888K3g+&eGDI8+m+A9-F^R^Y`Zc?tO_x{X6@U zFG`iH6Q1|R&i{F@-cHvquYUJ`zi0k$O}*H5&8cBW*S($UZgwS9`sK}h|GcXP&qbtW zJDqP+-T5o})WpYv&o4xXNSf-Lv~E?aX}oxN(jM;&C-LV()1JsWCI8&I%jLB3>UZgd z-#2jkob-KRYnE^_+e)uKNn9c`e(~;g$M-+pDtlOICY#%@{SOa2E#Fjj^|6%LNehEZ zi$4l7WqtBlb^EJ%P-<;Tw)#lqM{hHy-?$&kx zfVO3iX-$GkzuUa0MsD3olf$Dzopr0Ow|rX#fBK diff --git a/core/assets-raw/sprites/units/obviate-preview.png b/core/assets-raw/sprites/units/obviate-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..aac82cee84761d32242942741833c5df6f1602d0 GIT binary patch literal 2872 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 delta 2853 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 uOQ)SvSZ>gkk711B0ilpUXO@geCwZiBDAk diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index ca6ebce0bd..6f918c4c95 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -1004,6 +1004,11 @@ public class Fx{ Fill.circle(e.x, e.y, e.rotation * e.fout()); }).layer(Layer.bullet - 0.001f), //below bullets + missileTrailShort = new Effect(22, e -> { + color(e.color); + Fill.circle(e.x, e.y, e.rotation * e.fout()); + }).layer(Layer.bullet - 0.001f), + absorb = new Effect(12, e -> { color(Pal.accent); stroke(2f * e.fout()); diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 04d4a21131..ad2be53ac9 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -3399,6 +3399,10 @@ public class UnitTypes{ itemCapacity = 0; useEngineElevation = false; + engineColor = Pal.sapBullet; + + abilities.add(new MoveEffectAbility(0f, -7f, Pal.sapBulletBack, Fx.missileTrailShort, 4f)); + for(float f : new float[]{-3f, 3f}){ parts.add(new HoverPart(){{ x = 3.9f; @@ -3413,18 +3417,25 @@ public class UnitTypes{ } weapons.add(new Weapon("osc-weapon"){{ - y = 3f; - x = 3f; + y = -2f; + x = 4f; + top = true; mirror = true; - layerOffset = -0.0001f; reload = 40f; + baseRotation = -35f; + shootCone = 360f; + + shoot = new ShootSpread(){{ + shots = 2; + spread = 11f; + }}; bullet = new BasicBulletType(5f, 20){{ - pierceCap = 2; - pierceBuilding = false; + homingPower = 0.2f; + homingDelay = 4f; width = 7f; height = 12f; - lifetime = 25f; + lifetime = 50f; shootEffect = Fx.sparkShoot; smokeEffect = Fx.shootBigSmoke; hitColor = backColor = trailColor = Pal.suppress; @@ -3486,8 +3497,8 @@ public class UnitTypes{ obviate = new ErekirUnitType("obviate"){{ flying = true; drag = 0.08f; - speed = 1.9f; - rotateSpeed = 4f; + speed = 1.8f; + rotateSpeed = 2.5f; accel = 0.09f; health = 2300f; armor = 3f; @@ -3499,46 +3510,106 @@ public class UnitTypes{ lowAltitude = true; setEnginesMirror( - new UnitEngine(59 / 4f, -25 / 4f, 3.1f, 315f) + new UnitEngine(38 / 4f, -46 / 4f, 3.1f, 315f) ); - parts.add(new RegionPart("-heat"){{ - blending = Blending.additive; - progress = PartProgress.heat; - outline = false; - colorTo = new Color(1f, 0.5f, 0.5f, 0.7f); - color = colorTo.cpy().a(0f); - layerOffset = 0.01f; + parts.add( + new RegionPart("-blade"){{ + moveRot = -10f; + moveX = -1f; + moves.add(new PartMove(PartProgress.reload, 2f, 1f, -5f)); + progress = PartProgress.warmup; + mirror = true; + + children.add(new RegionPart("-side"){{ + moveX = 2f; + moveY = -2f; + progress = PartProgress.warmup; + under = true; + mirror = true; + moves.add(new PartMove(PartProgress.reload, -2f, 2f, 0f)); + }}); }}); - //TODO this is really dumb. weapons.add(new Weapon(){{ - y = 2f; - shootY = 0f; x = 0f; + y = -2f; + shootY = 0f; reload = 140f; mirror = false; - continuous = true; - // minWarmup = 0.5f; + minWarmup = 0.95f; + shake = 3f; + cooldownTime = reload - 10f; - bullet = new ContinuousLaserBulletType(140){{ - shake = 0f; - lifetime = 120f; - colors = new Color[]{Color.valueOf("bf92f9").a(0.4f), Color.valueOf("bf92f9"), Color.white}; - //TODO merge - chargeEffect = new MultiEffect(Fx.lancerLaserCharge, Fx.lancerLaserChargeBegin); - width = 4f; - largeHit = false; + bullet = new BasicBulletType(){{ + shoot = new ShootHelix(){{ + mag = 1f; + scl = 5f; + }}; - buildingDamageMultiplier = 0.25f; - hitEffect = Fx.hitLancer; - hitSize = 4; - drawSize = 400f; - length = 173f; - ammoMultiplier = 1f; - pierceCap = 4; - hitColor = colors[1]; + shootEffect = new MultiEffect(Fx.shootTitan, new WaveEffect(){{ + colorTo = Pal.sapBulletBack; + sizeTo = 26f; + lifetime = 14f; + strokeFrom = 4f; + }}); + smokeEffect = Fx.shootSmokeTitan; + hitColor = Pal.sapBullet; + + sprite = "large-orb"; + trailEffect = Fx.missileTrail; + trailInterval = 3f; + trailParam = 4f; + speed = 3f; + damage = 80f; + lifetime = 70f; + width = height = 15f; + backColor = Pal.sapBulletBack; + frontColor = Pal.sapBullet; + shrinkX = shrinkY = 0f; + trailColor = Pal.sapBulletBack; + trailLength = 12; + trailWidth = 2.2f; + despawnEffect = hitEffect = new ExplosionEffect(){{ + waveColor = Pal.sapBullet; + smokeColor = Color.gray; + sparkColor = Pal.sap; + waveStroke = 4f; + waveRad = 20f; + }}; + + intervalBullet = new LightningBulletType(){{ + damage = 15; + collidesAir = false; + ammoMultiplier = 1f; + lightningColor = Pal.sapBullet; + lightningLength = 2; + lightningLengthRand = 6; + + //for visual stats only. + buildingDamageMultiplier = 0.25f; + + lightningType = new BulletType(0.0001f, 0f){{ + lifetime = Fx.lightning.lifetime; + hitEffect = Fx.hitLancer; + despawnEffect = Fx.none; + status = StatusEffects.shocked; + statusDuration = 10f; + hittable = false; + lightColor = Color.white; + buildingDamageMultiplier = 0.25f; + }}; + }}; + + bulletInterval = 4f; + + lightningColor = Pal.sapBullet; + lightningDamage = 19; + lightning = 8; + lightningLength = 2; + lightningLengthRand = 8; }}; + }}); }}; diff --git a/core/src/mindustry/entities/abilities/MoveEffectAbility.java b/core/src/mindustry/entities/abilities/MoveEffectAbility.java new file mode 100644 index 0000000000..bbb8d36a6c --- /dev/null +++ b/core/src/mindustry/entities/abilities/MoveEffectAbility.java @@ -0,0 +1,41 @@ +package mindustry.entities.abilities; + +import arc.graphics.*; +import arc.util.*; +import mindustry.content.*; +import mindustry.entities.*; +import mindustry.gen.*; + +public class MoveEffectAbility extends Ability{ + public float minVelocity = 0.08f; + public float interval = 3f; + public float x, y; + public boolean rotateEffect = false; + public float effectParam = 3f; + public boolean teamColor = false; + public Color color = Color.white; + public Effect effect = Fx.missileTrail; + + protected float counter; + + public MoveEffectAbility(float x, float y, Color color, Effect effect, float interval){ + this.x = x; + this.y = y; + this.color = color; + this.effect = effect; + this.interval = interval; + } + + public MoveEffectAbility(){ + } + + @Override + public void update(Unit unit){ + counter += Time.delta; + if(unit.vel.len2() >= minVelocity * minVelocity && (counter >= interval)){ + Tmp.v1.trns(unit.rotation - 90f, x, y); + counter %= interval; + effect.at(Tmp.v1.x + unit.x, Tmp.v1.y + unit.y, rotateEffect ? unit.rotation : effectParam, teamColor ? unit.team.color : color); + } + } +} diff --git a/core/src/mindustry/entities/bullet/BulletType.java b/core/src/mindustry/entities/bullet/BulletType.java index ee7d5e918c..9b99917b3a 100644 --- a/core/src/mindustry/entities/bullet/BulletType.java +++ b/core/src/mindustry/entities/bullet/BulletType.java @@ -151,7 +151,7 @@ public class BulletType extends Content implements Cloneable{ public float fragVelocityMin = 0.2f, fragVelocityMax = 1f, fragLifeMin = 1f, fragLifeMax = 1f; public @Nullable BulletType fragBullet = null; public float bulletInterval = 20f; - public int intervalBulletCount = 1; + public int intervalBullets = 1; public @Nullable BulletType intervalBullet; public Color hitColor = Color.white; public Color healColor = Pal.heal; @@ -431,7 +431,7 @@ public class BulletType extends Content implements Cloneable{ public void updateBulletInterval(Bullet b){ if(intervalBullet != null && b.timer.get(2, bulletInterval)){ - for(int i = 0; i < intervalBulletCount; i++){ + for(int i = 0; i < intervalBullets; i++){ intervalBullet.create(b, b.x, b.y, Mathf.random(360f)); } } diff --git a/core/src/mindustry/entities/pattern/ShootBarrel.java b/core/src/mindustry/entities/pattern/ShootBarrel.java index 5c564e5551..18e6610ab6 100644 --- a/core/src/mindustry/entities/pattern/ShootBarrel.java +++ b/core/src/mindustry/entities/pattern/ShootBarrel.java @@ -11,6 +11,7 @@ public class ShootBarrel extends ShootPattern{ barrels = barrels.clone(); for(int i = 0; i < barrels.length; i += 3){ barrels[i] *= -1; + barrels[i + 2] *= -1; } } diff --git a/core/src/mindustry/entities/pattern/ShootHelix.java b/core/src/mindustry/entities/pattern/ShootHelix.java index 126c90532b..88ca6d20c0 100644 --- a/core/src/mindustry/entities/pattern/ShootHelix.java +++ b/core/src/mindustry/entities/pattern/ShootHelix.java @@ -10,7 +10,7 @@ public class ShootHelix extends ShootPattern{ for(int i = 0; i < shots; i++){ for(int sign : Mathf.signs){ handler.shoot(0, 0, 0, firstShotDelay + shotDelay * i, - b -> b.moveRelative(0f, Mathf.sin(b.time + offset, 2f, mag * sign))); + b -> b.moveRelative(0f, Mathf.sin(b.time + offset, scl, mag * sign))); } } } diff --git a/core/src/mindustry/entities/pattern/ShootMulti.java b/core/src/mindustry/entities/pattern/ShootMulti.java index 0d1c3ebefa..34497957cd 100644 --- a/core/src/mindustry/entities/pattern/ShootMulti.java +++ b/core/src/mindustry/entities/pattern/ShootMulti.java @@ -29,9 +29,9 @@ public class ShootMulti extends ShootPattern{ source.shoot(totalShots, (x, y, rotation, delay, move) -> { for(var pattern : dest){ pattern.shoot(totalShots, (x2, y2, rot2, delay2, mover) -> { - handler.shoot(x + x2, y + y2, rotation + rot2, delay + delay2, b -> { - move.move(b); - mover.move(b); + handler.shoot(x + x2, y + y2, rotation + rot2, delay + delay2, move == null && mover == null ? null : b -> { + if(move != null) move.move(b); + if(mover != null) mover.move(b); }); }); } diff --git a/core/src/mindustry/mod/Mods.java b/core/src/mindustry/mod/Mods.java index 3af4656afa..fc4208c003 100644 --- a/core/src/mindustry/mod/Mods.java +++ b/core/src/mindustry/mod/Mods.java @@ -353,23 +353,13 @@ public class Mods implements Loadable{ Log.debug("Total time to generate & flush textures synchronously: @", Time.elapsed()); } - private PageType getPage(AtlasRegion region){ - return - region.texture == Core.atlas.find("white").texture ? PageType.main : - region.texture == Core.atlas.find("stone1").texture ? PageType.environment : - region.texture == Core.atlas.find("clear-editor").texture ? PageType.editor : - region.texture == Core.atlas.find("whiteui").texture ? PageType.ui : - region.texture == Core.atlas.find("rubble-1-0").texture ? PageType.rubble : - PageType.main; - } - private PageType getPage(Fi file){ String path = file.path(); return - path.contains("sprites/blocks/environment") ? PageType.environment : - path.contains("sprites/editor") ? PageType.editor : - path.contains("sprites/rubble") ? PageType.editor : - path.contains("sprites/ui") ? PageType.ui : + path.contains("sprites/blocks/environment") || path.contains("sprites-override/blocks/environment") ? PageType.environment : + path.contains("sprites/editor") || path.contains("sprites-override/editor") ? PageType.editor : + path.contains("sprites/rubble") || path.contains("sprites-override/rubble") ? PageType.rubble : + path.contains("sprites/ui") || path.contains("sprites-override/ui") ? PageType.ui : PageType.main; } diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index fe5cc51fbd..49be96dae7 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -212,7 +212,7 @@ public class UnitType extends UnlockableContent{ public Sound deathSound = Sounds.bang; public Seq weapons = new Seq<>(); - public TextureRegion baseRegion, legRegion, region, shadowRegion, cellRegion, + public TextureRegion baseRegion, legRegion, region, previewRegion, shadowRegion, cellRegion, softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion, treadRegion; public TextureRegion[] wreckRegions, segmentRegions, segmentOutlineRegions; public TextureRegion[][] treadRegions; @@ -590,6 +590,7 @@ public class UnitType extends UnlockableContent{ } weapons.each(Weapon::load); region = Core.atlas.find(name); + previewRegion = Core.atlas.find(name + "-preview", name); legRegion = Core.atlas.find(name + "-leg"); jointRegion = Core.atlas.find(name + "-joint"); baseJointRegion = Core.atlas.find(name + "-joint-base"); diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index 047d348a19..9ee9cfdfed 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -41,6 +41,8 @@ public class Weapon implements Cloneable{ public boolean alternate = true; /** whether to rotate toward the target independently of unit */ public boolean rotate = false; + /** rotation at which this weapon is locked to if rotate = false. TODO buggy!*/ + public float baseRotation = 0f; /** whether to draw the outline on top. */ public boolean top = true; /** whether to hold the bullet in place while firing */ @@ -180,7 +182,7 @@ public class Weapon implements Cloneable{ float rotation = unit.rotation - 90, - weaponRotation = rotation + (rotate ? mount.rotation : 0), + weaponRotation = rotation + (rotate ? mount.rotation : baseRotation), wx = unit.x + Angles.trnsx(rotation, x, y) + Angles.trnsx(weaponRotation, 0, -mount.recoil), wy = unit.y + Angles.trnsy(rotation, x, y) + Angles.trnsy(weaponRotation, 0, -mount.recoil); @@ -263,12 +265,12 @@ public class Weapon implements Cloneable{ } } }else if(!rotate){ - mount.rotation = 0; + mount.rotation = baseRotation; mount.targetRotation = unit.angleTo(mount.aimX, mount.aimY); } float - weaponRotation = unit.rotation - 90 + (rotate ? mount.rotation : 0), + weaponRotation = unit.rotation - 90 + (rotate ? mount.rotation : baseRotation), mountX = unit.x + Angles.trnsx(unit.rotation - 90, x, y), mountY = unit.y + Angles.trnsy(unit.rotation - 90, x, y), bulletX = mountX + Angles.trnsx(weaponRotation, this.shootX, this.shootY), @@ -346,7 +348,7 @@ public class Weapon implements Cloneable{ mount.warmup >= minWarmup && //must be warmed up unit.vel.len() >= minShootVelocity && //check velocity requirements mount.reload <= 0.0001f && //reload has to be 0 - Angles.within(rotate ? mount.rotation : unit.rotation, mount.targetRotation, shootCone) //has to be within the cone + Angles.within(rotate ? mount.rotation : unit.rotation + baseRotation, mount.targetRotation, shootCone) //has to be within the cone ){ shoot(unit, mount, bulletX, bulletY, shootAngle); @@ -368,7 +370,7 @@ public class Weapon implements Cloneable{ } protected float bulletRotation(Unit unit, WeaponMount mount, float bulletX, float bulletY){ - return rotate ? unit.rotation + mount.rotation : Angles.angle(bulletX, bulletY, mount.aimX, mount.aimY) + (unit.rotation - unit.angleTo(mount.aimX, mount.aimY)); + return rotate ? unit.rotation + mount.rotation : Angles.angle(bulletX, bulletY, mount.aimX, mount.aimY) + (unit.rotation - unit.angleTo(mount.aimX, mount.aimY)) + baseRotation; } protected void shoot(Unit unit, WeaponMount mount, float shootX, float shootY, float rotation){ @@ -393,7 +395,7 @@ public class Weapon implements Cloneable{ if(!unit.isAdded()) return; float - weaponRotation = unit.rotation - 90 + (rotate ? mount.rotation : 0), + weaponRotation = unit.rotation - 90 + (rotate ? mount.rotation : baseRotation), mountX = unit.x + Angles.trnsx(unit.rotation - 90, x, y), mountY = unit.y + Angles.trnsy(unit.rotation - 90, x, y), bulletX = mountX + Angles.trnsx(weaponRotation, this.shootX + xOffset, this.shootY + yOffset), @@ -421,6 +423,7 @@ public class Weapon implements Cloneable{ public void flip(){ x *= -1; shootX *= -1; + baseRotation *= -1f; flipSprite = !flipSprite; shoot = shoot.copy(); shoot.flip(); diff --git a/tools/src/mindustry/tools/Generators.java b/tools/src/mindustry/tools/Generators.java index 0e4032aabd..d55f4227fe 100644 --- a/tools/src/mindustry/tools/Generators.java +++ b/tools/src/mindustry/tools/Generators.java @@ -557,7 +557,7 @@ public class Generators{ if(sample instanceof Legsc) outliner.get(type.legRegion); if(sample instanceof Tankc) outliner.get(type.treadRegion); - Pixmap image = type.segments > 0 ? get(type.segmentRegions[0]) : outline.get(get(type.region)); + Pixmap image = type.segments > 0 ? get(type.segmentRegions[0]) : outline.get(get(type.previewRegion)); Func weaponRegion = weapon -> Core.atlas.has(weapon.name + "-preview") ? get(weapon.name + "-preview") : get(weapon.region); Cons2 drawWeapon = (weapon, pixmap) -> @@ -585,7 +585,7 @@ public class Generators{ if(type.needsBodyOutline()){ save(image, type.name + "-outline"); }else{ - replace(type.name, image); + replace(type.name, type.segments > 0 ? get(type.segmentRegions[0]) : outline.get(get(type.region))); } //draw weapons that are under the base @@ -596,13 +596,13 @@ public class Generators{ //draw over the weapons under the image if(anyUnder){ - image.draw(outline.get(get(type.region)), true); + image.draw(outline.get(get(type.previewRegion)), true); } //draw treads if(sample instanceof Tankc){ image.draw(outline.get(get(type.treadRegion)), true); - image.draw(get(type.region), true); + image.draw(get(type.previewRegion), true); } //draw mech parts @@ -610,7 +610,7 @@ public class Generators{ drawCenter(image, get(type.baseRegion)); drawCenter(image, get(type.legRegion)); drawCenter(image, get(type.legRegion).flipX()); - image.draw(get(type.region), true); + image.draw(get(type.previewRegion), true); } //draw weapon outlines on base @@ -622,7 +622,7 @@ public class Generators{ } //draw base region on top to mask weapons - if(type.drawCell) image.draw(get(type.region), true); + if(type.drawCell) image.draw(get(type.previewRegion), true); if(type.drawCell){ Pixmap baseCell = get(type.cellRegion);