From 7afc6d3631d22213f4deb849d559b691dfc272ca Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 21 Aug 2021 15:32:25 -0400 Subject: [PATCH] CrawlComp progress --- .../main/resources/revisions/scuttler/0.json | 2 +- .../units/neoplasm/scuttler-segment0.png | Bin 0 -> 1430 bytes .../units/neoplasm/scuttler-segment1.png | Bin 0 -> 1567 bytes .../units/neoplasm/scuttler-segment2.png | Bin 0 -> 1600 bytes .../units/neoplasm/scuttler-segment3.png | Bin 0 -> 1610 bytes core/assets-raw/sprites/units/scuttler.png | Bin 866 -> 0 bytes core/src/mindustry/content/Fx.java | 7 +++ core/src/mindustry/content/UnitTypes.java | 10 +++- .../mindustry/entities/comp/CrawlComp.java | 51 ++++++++++++++++-- core/src/mindustry/type/UnitType.java | 46 ++++++++++++++-- tools/src/mindustry/tools/Generators.java | 31 ++++++++--- 11 files changed, 129 insertions(+), 18 deletions(-) create mode 100644 core/assets-raw/sprites/units/neoplasm/scuttler-segment0.png create mode 100644 core/assets-raw/sprites/units/neoplasm/scuttler-segment1.png create mode 100644 core/assets-raw/sprites/units/neoplasm/scuttler-segment2.png create mode 100644 core/assets-raw/sprites/units/neoplasm/scuttler-segment3.png delete mode 100644 core/assets-raw/sprites/units/scuttler.png diff --git a/annotations/src/main/resources/revisions/scuttler/0.json b/annotations/src/main/resources/revisions/scuttler/0.json index d6d95c813a..7f2885cdcf 100644 --- a/annotations/src/main/resources/revisions/scuttler/0.json +++ b/annotations/src/main/resources/revisions/scuttler/0.json @@ -1 +1 @@ -{fields:[{name:ammo,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:crawlTime,type:float},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue},{name:rotation,type:float},{name:segmentRot,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:updateBuilding,type:boolean},{name:vel,type:arc.math.geom.Vec2},{name:x,type:float},{name:y,type:float}]} \ No newline at end of file +{fields:[{name:ammo,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:updateBuilding,type:boolean},{name:vel,type:arc.math.geom.Vec2},{name:x,type:float},{name:y,type:float}]} \ No newline at end of file diff --git a/core/assets-raw/sprites/units/neoplasm/scuttler-segment0.png b/core/assets-raw/sprites/units/neoplasm/scuttler-segment0.png new file mode 100644 index 0000000000000000000000000000000000000000..e9c533963fc1f793181337b66aa4b08ac97b06bf GIT binary patch literal 1430 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKL9Bd2>3=R9u&M+`AFct^7J29*~C-ahlfi=L> z#WAE}&fB}bMZ$&x4S~*uGv+k@7EeEsn=p~9bFyT0ok`H@-+N8Dlehl*Y$3YiF2g9G za|kqu+Pm#%=y>q`^y&My_5aSlUcKA7QjhWJo8F^gi=0f^=51NWbu{jfQyAOqkVP)Z zy)!0sCZ=UwZ2s7@z`*$M>5{bmV^W5RW^B_mQ+h!xwzerBRvmpjw?kkqqw11X7bBF_ zTv9YR-EF3Ia$J<~I3&=Q+tQ-Jqomkz+)l}frES8(md7%Ri7JPW3mm#QZGu75!o|`T zUpV``IJ)3sYsD8;r7sC5c1$VgQB{dKSx_kXvBS}2N7uncmJd5TJu=QZT%1yIL``W+ z%8U#*n`a72TaqSN_*y(uQJIt4VBu=>OigJ{Vugi|O_6|LpOJ-(lHAS?4tEKuGU5I? zE-ia`cy@QV=P4bMYim7wWHFmyqIUBkwMT*79UEE|A8LMF;ptLwtl`6iiYsbLHc1u{ zs&aSolnz-nA5{AIz*sP`bKwK&j|rU}AEq`w=&Sh9(edHt`HT7t4VFJm4%W}JyKyL( z<2?`4p@WJ}O^h0THWtnv)BKYw*i ztm&OP`>?N%O^1War=ks>o$M1kJpA}f6+dP?u6)!sDcj3eRw^}`+wrO-EzG_CYx0Kgb=Llhl|NjaPVG!;jO+?Y zc`^9|=Z~Fn-uEJH)OT1~9AVK}bKFf=`}wCC9cRun`kk8;C7$YNxwtg&Tu1UBo|Y*} zy30J)vqlLCTSNEgAOw zf?CSQJtsGn%y~Xr=Xqpj{i&9Gaq~}3r+1{-{hymw^$ z#awD3=R9u&M+`AFct^7J29*~C-ahlf%T@R zi(^Q|oVT|fi!M6|I9%jBx;LVbk#81v%GAjR+m^^!Zqlt>GV@(szPl)^=B~T;TxHn| zqW}>C4mtXZ_cP2mIRF0se|bOuuFroTXFcV)t3zb;;*D-TD^5KM_FG?|!^wFyqQc8U zODg+F3zv@N%DJ+As)~xnr+vK^AKs{R$hL25=kl?mW202P{J3Bd|BgEv?}4W=%L7dn{$?L1n+_M3B7-9=N18iaRP2~}{A@aWT#}6U95~X<)XG(=N~=1Yd$EMoi&n@-~Y{x?T44cgZ#uC~)%r%iOi;;ZiKLA(xk8#b{ykGI|pY(J&5O}O_4kG^92n_D;APw}kl zbhW$J>YBBp^Nhhl|tg8K<)#vhnvt?zdt;M{A4hM%BL03U(*;rU$nWEHd zz5lsKS|T|(4s#wio98v7RXoorkgvPoOX9trqy?U5>q2BE?>jSFkjHeRWPg`)k&f|m zAGYWtFAhKIm~(oMWwWBV!KWD(D#bP0l+XkK%2>rf literal 0 HcmV?d00001 diff --git a/core/assets-raw/sprites/units/neoplasm/scuttler-segment2.png b/core/assets-raw/sprites/units/neoplasm/scuttler-segment2.png new file mode 100644 index 0000000000000000000000000000000000000000..834ca5aaefbfbce4b2fa089a53d199a259f0760f GIT binary patch literal 1600 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKL9Bd2>3=R9u&M+`AFct^7J29*~C-ahlf%TWC zi(^Q|oVT}57K%6uI9zNypzmkVu+ZWF=jjJmT1;kTevR9?r~KK1fV8XgFB$kU3^~B^ zJ@pGegW#V(AOF6eR{#I?clq@8Z!%0#x25{rot)CA%`fY7dn{_WP@3CcI=uDq#0eK# zU6;4+eq<;tXtm+Vl+tpOI6>i6n{G@IQI#_mT&U#jYk3hQxoYEuDMF?oA)(VgoEHy& z^zc}5KxlH*wgMX=A*0QEmQ1ykGZs|T?)LTy1*tdMv}H-KE=Wk4+gmCWr2fRAMU$MS zSDbNa;nC4tSjv4|Sy9pGw5P{ikYvY+Afdhr8+9d@WJOL_n`xaK6C>OX3G|n`v}ouk z9p*f4=X5ATY{J4Lk0k^XRZbr_cvQ$Im?+YH{B6r)DW^ksb!4^+_EmFmmT%0s<7D$r zRq4*bNrjpZCA>X$OnUmr=#gM^M}cVfQPm^LVuBC3rga5#y5~3@nyDkaT(DoprDb!3 zil3s~&JK?B4K6Zja+aMO?vV;*g1u2kT5NTAXLq{$Djfv;A^eth7ibgBEj1H+A@%Uj*{*zITz_mF41+fq@WF8K1` z{0$)S7PdWh5(l-H*fHz**+_W0WPMiGVJQ3fa)H5mex(mwD^GK?G{n{zX`Fi9?6Jow z>k|`Wg7|zcu1~)dl-5tE+T-w`HGcp9n!=X{v-#W&I z#^Trqp<>Hgk-ttxoBJ1?@43FO_aEZ}o=ClgKc9;TX?YaB_;G@Din`Q%!_!uq-yFLj z^s4S*$ljbYTc5>f8*fP26=!r;PrO)-`F^87)OGHo<*F$cJ{6>0d8_nNsxSP^{0<(? zM!)Ip-N`d!6@-|%)}3yBxar2RIDy88EMY$<6&TJrz0RQNAWP_1rvk~C)AtJ0ojF%L zQhmU*W4i1kzJJpC(~Djl|8T!yXLCaV=fe(1j~$bo<$S(1>&a}qsedj-qA|tp4qusG zS+B8#i-08mmgbn|yUF_Z8#l~69Nqoi^Tugc0f%YL+A_8`+^>CNN}T9?>-_DR>7AU( z931|f?3bUMkJb?uxF^UrPf%!{pnyyB)jyTp+gX+vK77EjUWjFh;K2u6{ne@(wL1cu zc6_?P$*z3k3=R9u&M+`AFct^7J29*~C-ahlfsMt} z#WAE}&fB{i%PuZ-O!17yac%?Dbc*4;oBegI?Np5EchprCq>`r$-r9)w2ZN5j8%>@&=Pan#96xiIcVVY~A=*JbV zE)j<(eV9~nMMY^(l4FF5+}2JGZyk33PWH8N5(B(rn!6!CS}8-Jmv4i0i|*gQ9y{pQIl+*~uO*H1Q6Px#7nI z7Ntqk52~rk^|-hceNwby@U;RsL+&J6VpJ=yS!!a?2uTEgGY}v&VN9!&glIECgal`WG)x@YD@|=;rHlK`> zw+RS@6>hwecx{cU!k#BiE03Rvbase%qO|h#o64h2EJe@Q=jidjyJ;);kxi(h*|n_9 zM(i-xitm>fIG<7e)@RA=o%UX_ydyGc|BmPG5q};ReD0EcIIqFLcXD^**Ed||OikR4 zXW#H#R#8~_qr69AuIyP?hpx{mp4z*c8yGIQIBmdK II;Vst0KgRUssI20 literal 0 HcmV?d00001 diff --git a/core/assets-raw/sprites/units/scuttler.png b/core/assets-raw/sprites/units/scuttler.png deleted file mode 100644 index f281d6d03d62a3aca324ec5a5cdf1a041a2df235..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 866 zcmeAS@N?(olHy`uVBq!ia0y~yVE6#S9Lx+144mDP3m6y}7>k44ofy`glX=O&z#tmn z6XMFiz%XOhk`22K{9l%OAv-v)pn-vbAyiI(5(5JRdr6RA@P9C1kn(1BV_;x<;pyTS zQZeW4UGJ(_1_CY*4HEx*?`u|x&pUK_#p+e5FX!;C_|JLF%tQYA*Gh9JFF!ba_914MgWGTIv1G4X!aF=wsi$_Q^a??+S+OR!0NhNS%Ybe z@J)tmm9j~e5hqJ098E9{_rKO88@Dln>s!UvB*hy?uTCmWSRSr1t#NPM+z8gP>eM8` z8}CCqO&_#`t4wP!j_ZwJ^s7`&VzhW3+VT3ql5hpR=FRtZ?cnmOKK)3^;{DpL><4`L zfiXU9TaDQJ6%{;pa{ubEznfM! zovGZq{#3*6ssE=lluOsMNASH9`^RhWKx)VBa_I!k9nt0b2O5qayu0l;V_4(v#Qx0< zy93W(Zr<&>KB#%O?fT12yG`ALns)0Rztp%})jhazx9suD4ZB6(vq%^u9B4@AGf3E% z$!It6M@Q>z=L5?HP0q?pU17QMKor=1*I&b8n8IdS;y7ZJSfGrkoC2dn)Zo)%NIl7r7%O z6Am;mo@UnJ`S9w&UA}D$d+aI#a%4F-m>g&jXMSI{=vvzY#*LK`JiuFBowlTgdxcJC{^Cx#|Ha$>(^gy6tuI~fZoLuV<%!MT^2d*)!=i8@! z&X3`Sbi#pm46|QDE-iDvDYr4yx}lo8M}o{LiOIb1OFJ(nRECH%np2GNN0Yt z{wlYHz=Mp2zl?osH}01`$X+g9pmg9Q13S~4HOw`+Uzqw>EF>PdG&C2=e%pTcufczopr0KUwYs{jB1 diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index f664dc42ac..ff1904b857 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -313,6 +313,13 @@ public class Fx{ Lines.poly(e.x, e.y, 4, 13f * e.fout()); }).layer(Layer.debris), + crawlDust = new Effect(30, e -> { + color(Tmp.c1.set(e.color).mul(1.1f)); + randLenVectors(e.id, 2, 10f * e.finpow(), (x, y) -> { + Fill.circle(e.x + x, e.y + y, e.fslope() * 3f + 0.3f); + }); + }).layer(Layer.debris), + landShock = new Effect(12, e -> { color(Pal.lancerLaser); stroke(e.fout() * 3f); diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index a04625ae13..c3a2da5080 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -2412,10 +2412,16 @@ public class UnitTypes implements ContentList{ //region neoplasm scuttler = new UnitType("scuttler"){{ - hitSize = 30f; + hitSize = 44f; omniMovement = false; - rotateSpeed = 1f; + rotateSpeed = 2f; drawCell = false; + segments = 4; + drawBody = false; + + segmentScl = 4f; + segmentPhase = 5f; + speed = 1f; }}; //endregion diff --git a/core/src/mindustry/entities/comp/CrawlComp.java b/core/src/mindustry/entities/comp/CrawlComp.java index f14c0c7519..780f40ea6a 100644 --- a/core/src/mindustry/entities/comp/CrawlComp.java +++ b/core/src/mindustry/entities/comp/CrawlComp.java @@ -1,6 +1,8 @@ package mindustry.entities.comp; +import arc.math.*; import arc.math.geom.*; +import mindustry.*; import mindustry.ai.*; import mindustry.annotations.Annotations.*; import mindustry.content.*; @@ -8,18 +10,21 @@ import mindustry.entities.*; import mindustry.entities.EntityCollisions.*; import mindustry.gen.*; import mindustry.type.*; +import mindustry.world.*; import mindustry.world.blocks.environment.*; +import static mindustry.Vars.*; + //TODO @Component abstract class CrawlComp implements Posc, Rotc, Hitboxc, Unitc{ - @Import float x, y, speedMultiplier; + @Import float x, y, speedMultiplier, rotation, hitSize; @Import UnitType type; @Import Vec2 vel; //TODO segments - float segmentRot; - float crawlTime; + transient float lastCrawlSlowdown = 1f; + transient float segmentRot, crawlTime; @Replace @Override @@ -38,11 +43,49 @@ abstract class CrawlComp implements Posc, Rotc, Hitboxc, Unitc{ public float floorSpeedMultiplier(){ Floor on = isFlying() ? Blocks.air.asFloor() : floorOn(); //TODO take into account extra blocks - return on.speedMultiplier * speedMultiplier; + return on.speedMultiplier * speedMultiplier * lastCrawlSlowdown; + } + + @Override + public void add(){ + //reset segment rotation on add + segmentRot = rotation; } @Override public void update(){ + if(moving()){ + segmentRot = Angles.moveToward(segmentRot, rotation, type.segmentRotSpeed); + + int radius = (int)Math.max(0, hitSize / tilesize); + int count = 0, solids = 0; + + //calculate tiles under this unit, and apply slowdown + particle effects + for(int cx = -radius; cx <= radius; cx++){ + for(int cy = -radius; cy <= radius; cy++){ + if(cx*cx + cy*cy <= radius){ + count ++; + Tile t = Vars.world.tileWorld(x + cx*tilesize, y + cy*tilesize); + if(t != null){ + + if(t.solid()){ + solids ++; + } + + if(Mathf.chanceDelta(0.04)){ + Fx.crawlDust.at(t.worldx(), t.worldy(), t.floor().mapColor); + } + }else{ + solids ++; + } + } + } + } + + lastCrawlSlowdown = Mathf.lerp(1f, type.crawlSlowdown, Mathf.clamp((float)solids / count / type.crawlSlowdownFrac)); + } + segmentRot = Angles.clampRange(segmentRot, rotation, type.segmentMaxRot); + crawlTime += vel.len(); } } diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index dc4312a2fa..f89cb44459 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -118,7 +118,7 @@ public class UnitType extends UnlockableContent{ public float itemOffsetY = 3f; public float lightRadius = -1f, lightOpacity = 0.6f; public Color lightColor = Pal.powerLight; - public boolean drawCell = true, drawItems = true, drawShields = true; + public boolean drawCell = true, drawItems = true, drawShields = true, drawBody = true; public int trailLength = 3; public float trailX = 4f, trailY = -3f, trailScl = 1f; /** Whether the unit can heal blocks. Initialized in init() */ @@ -127,6 +127,14 @@ public class UnitType extends UnlockableContent{ public boolean singleTarget = false; public boolean forceMultiTarget = false; + //for crawlers + public int segments = 0; + public float segmentSpacing = 2f; + public float segmentScl = 4f, segmentPhase = 5f; + public float segmentRotSpeed = 1f, segmentMaxRot = 30f; + public float crawlSlowdown = 0.45f; + public float crawlSlowdownFrac = 0.4f; + public ObjectSet immunities = new ObjectSet<>(); public Sound deathSound = Sounds.bang; @@ -134,6 +142,7 @@ public class UnitType extends UnlockableContent{ public TextureRegion baseRegion, legRegion, region, shadowRegion, cellRegion, softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion; public TextureRegion[] wreckRegions; + public TextureRegion[] segmentRegions, segmentOutlineRegions; protected float buildTime = -1f; protected @Nullable ItemStack[] cachedRequirements; @@ -442,6 +451,13 @@ public class UnitType extends UnlockableContent{ wreckRegions[i] = Core.atlas.find(name + "-wreck" + i); } + segmentRegions = new TextureRegion[segments]; + segmentOutlineRegions = new TextureRegion[segments]; + for(int i = 0; i < segments; i++){ + segmentRegions[i] = Core.atlas.find(name + "-segment" + i); + segmentOutlineRegions[i] = Core.atlas.find(name + "-segment-outline" + i); + } + clipSize = Math.max(region.width * 2f, clipSize); } @@ -603,10 +619,14 @@ public class UnitType extends UnlockableContent{ Draw.z(z); - drawOutline(unit); + if(unit instanceof Crawlc c){ + drawCrawl(c); + } + + if(drawBody) drawOutline(unit); drawWeaponOutlines(unit); if(engineSize > 0) drawEngine(unit); - drawBody(unit); + if(drawBody) drawBody(unit); if(drawCell) drawCell(unit); drawWeapons(unit); if(drawItems) drawItems(unit); @@ -873,6 +893,26 @@ public class UnitType extends UnlockableContent{ Draw.reset(); } + public void drawCrawl(Crawlc crawl){ + Unit unit = (Unit)crawl; + applyColor(unit); + + for(int p = 0; p < 2; p++){ + TextureRegion[] regions = p == 0 ? segmentOutlineRegions : segmentRegions; + + for(int i = 0; i < segments; i++){ + float trns = Mathf.sin(crawl.crawlTime() + i * segmentPhase, segmentScl, segmentSpacing); + + //at segment 0, rotation = segmentRot, but at the last segment it is rotation + float rot = Mathf.slerp(crawl.segmentRot(), unit.rotation, i / (float)(segments - 1)); + float tx = Angles.trnsx(rot, trns), ty = Angles.trnsy(rot, trns); + + //TODO merge outlines? + Draw.rect(regions[i], unit.x + tx, unit.y + ty, rot - 90); + } + } + } + public void drawMech(Mechc mech){ Unit unit = (Unit)mech; diff --git a/tools/src/mindustry/tools/Generators.java b/tools/src/mindustry/tools/Generators.java index 416656cd33..084a785fa3 100644 --- a/tools/src/mindustry/tools/Generators.java +++ b/tools/src/mindustry/tools/Generators.java @@ -409,6 +409,7 @@ public class Generators{ ObjectSet outlined = new ObjectSet<>(); try{ + Unit sample = type.constructor.get(); type.load(); type.loadIcon(); type.init(); @@ -430,14 +431,26 @@ public class Generators{ outliner.get(type.footRegion); outliner.get(type.legBaseRegion); outliner.get(type.baseJointRegion); - if(type.constructor.get() instanceof Legsc) outliner.get(type.legRegion); + if(sample instanceof Legsc) outliner.get(type.legRegion); - Pixmap image = outline.get(get(type.region)); + Pixmap image = type.segments > 0 ? get(type.segmentRegions[0]) : outline.get(get(type.region)); + + //draw each extra segment on top before it is saved as outline + if(sample instanceof Crawlc){ + for(int i = 0; i < type.segments; i++){ + save(outline.get(get(type.segmentRegions[i])), type.name + "-segment-outline" + i); + + if(i > 0){ + drawCenter(image, get(type.segmentRegions[i])); + } + } + save(image, type.name); + } save(image, type.name + "-outline"); //draw mech parts - if(type.constructor.get() instanceof Mechc){ + if(sample instanceof Mechc){ drawCenter(image, get(type.baseRegion)); drawCenter(image, get(type.legRegion)); drawCenter(image, get(type.legRegion).flipX()); @@ -456,14 +469,16 @@ public class Generators{ } //draw base region on top to mask weapons - image.draw(get(type.region), true); + if(type.drawBody) image.draw(get(type.region), true); int baseColor = Color.valueOf("ffa665").rgba(); - Pixmap baseCell = get(type.cellRegion); - Pixmap cell = new Pixmap(type.cellRegion.width, type.cellRegion.height); - cell.each((x, y) -> cell.set(x, y, Color.muli(baseCell.getRaw(x, y), baseColor))); + if(type.drawCell){ + Pixmap baseCell = get(type.cellRegion); + Pixmap cell = new Pixmap(type.cellRegion.width, type.cellRegion.height); + cell.each((x, y) -> cell.set(x, y, Color.muli(baseCell.getRaw(x, y), baseColor))); - image.draw(cell, image.width / 2 - cell.width / 2, image.height / 2 - cell.height / 2, true); + image.draw(cell, image.width / 2 - cell.width / 2, image.height / 2 - cell.height / 2, true); + } for(Weapon weapon : type.weapons){ weapon.load();