From 680e6e341093d1c6ad59b40a4ce5a8ff524301dc Mon Sep 17 00:00:00 2001 From: Slotterleet Date: Fri, 5 Jan 2024 21:12:42 +0300 Subject: [PATCH] A lot of Legion-related stuff --- core/res/bundles/bundle.properties | 3 ++ core/res/bundles/bundle_ru.properties | 3 ++ .../{legionnaire.png => legion-sapper.png} | Bin core/res/sprites/units/bosses/legion.png | Bin 3500 -> 3493 bytes .../units/core/legionnaire-replica-cell.png | Bin 0 -> 192 bytes .../units/core/legionnaire-replica.png | Bin 0 -> 908 bytes core/src/fos/ai/ProtectorAI.java | 13 ++++- core/src/fos/content/FOSUnitTypes.java | 47 ++++++++++++++++-- core/src/fos/content/FOSWeaponModules.java | 29 ++++++++++- .../type/abilities/UnitResistanceAbility.java | 4 +- core/src/fos/type/content/WeaponSet.java | 18 ++++++- .../type/units/comp/LumoniPlayerUnitComp.java | 7 +++ 12 files changed, 114 insertions(+), 10 deletions(-) rename core/res/sprites/units/bosses/{legionnaire.png => legion-sapper.png} (100%) create mode 100644 core/res/sprites/units/core/legionnaire-replica-cell.png create mode 100644 core/res/sprites/units/core/legionnaire-replica.png diff --git a/core/res/bundles/bundle.properties b/core/res/bundles/bundle.properties index 9566c06e..dd1df6fb 100644 --- a/core/res/bundles/bundle.properties +++ b/core/res/bundles/bundle.properties @@ -291,8 +291,11 @@ status.fos-standard4.name = Rifle Mk. IV status.fos-standard5.name = Rifle Mk. V status.fos-shotgun1.name = Sawed-off Shotgun Mount status.fos-shotgun1.description = A shotgun with poor range but decent damage. +status.fos-legion-fabricator.name = Legion's Mini-Fabricator Replica +status.fos-legion-fabricator.description = Periodically fabricates Legionnaire replicas that follow the player; each one gives +5% damage resistance to the bearer. unit.fos-legionnaire.name = Legionnaire +unit.fos-legionnaire-replica.name = Legionnaire Replica unit.fos-legion.name = Legion unit.fos-legion.description = Does not fight by itself, but summons a bunch of weaker drones on its side. [red]EXPERIMENTAL BOSS ENEMY[] unit.fos-legion.details = Produces [accent]Legionnaires[] on its side to attack targets while being supported by the Legion. Each Legionnaire currently functioning gives the Legion resistance to all damage. It's advised to deal with the Legionnaires first before attacking the Legion itself. diff --git a/core/res/bundles/bundle_ru.properties b/core/res/bundles/bundle_ru.properties index 192fa47b..755e00ce 100644 --- a/core/res/bundles/bundle_ru.properties +++ b/core/res/bundles/bundle_ru.properties @@ -294,8 +294,11 @@ status.fos-standard4.name = Винтовка Mk. IV status.fos-standard5.name = Винтовка Mk. V status.fos-shotgun1.name = Обрез status.fos-shotgun1.description = Дробовик с малой дальностью, но неплохим уроном. +status.fos-legion-fabricator.name = Мини-фабрика Легиона (реплика) +status.fos-legion-fabricator.description = Периодически производит реплики Легионеров, которые следуют за игроком; каждый из них дает +5% устойчивости к урону носителю. unit.fos-legionnaire.name = Легионер +unit.fos-legionnaire-replica.name = Легионер (реплика) unit.fos-legion.name = Легион unit.fos-legion.description = Не сражается напрямую, но конструирует множество более слабых дронов на своей стороне. [red]ЭКСПЕРИМЕНТАЛЬНЫЙ БОСС[] unit.fos-legion.details = Производит [accent]Легионеров[] на своей стороне, которые атакуют цели, будучи под поддержкой Легиона. Каждый функционирующий Легионер дает Легиону устойчивость ко всему урону. Рекомендуется сначала уничтожить Легионеров перед сражением с Легионом. diff --git a/core/res/sprites/units/bosses/legionnaire.png b/core/res/sprites/units/bosses/legion-sapper.png similarity index 100% rename from core/res/sprites/units/bosses/legionnaire.png rename to core/res/sprites/units/bosses/legion-sapper.png diff --git a/core/res/sprites/units/bosses/legion.png b/core/res/sprites/units/bosses/legion.png index d78f92c6a4748dffe9b7e6fd24fffdee9c94808e..fec2aaed21455b1f6dda808fabe7af8f51212777 100644 GIT binary patch delta 3491 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 RA<+N;002ovPDHLkV1m94HopJ> literal 3500 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 NZZ00q%+ptH{SWSuA~pa3 diff --git a/core/res/sprites/units/core/legionnaire-replica-cell.png b/core/res/sprites/units/core/legionnaire-replica-cell.png new file mode 100644 index 0000000000000000000000000000000000000000..33509cf64d1a3305dd7b9ef70a04dad4f7787a18 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=?Vc`>$7#@I8LU zY7c$R>2(KQDc;<@ z>9=p6#!ShzR-4R?y}#PuPf44y@3ENu{V#`So%y5ne)^f5sgJ$V_DwDKPRmPtc3|fA l_F0w%&vHSAg1`g&y$rYSd~H^_vf&tr@9FC2vd$@?2>@V^PE-H@ literal 0 HcmV?d00001 diff --git a/core/res/sprites/units/core/legionnaire-replica.png b/core/res/sprites/units/core/legionnaire-replica.png new file mode 100644 index 0000000000000000000000000000000000000000..fd117c0e8f8682d6dbf62165417ed1e299f57b58 GIT binary patch literal 908 zcmV;719SX|P)?a;JCroL z#kGBhk|vYSU%tNJ^DVae+<$kq%w~wKFtXJb&)k1^Y1Rn76h$h38{IA=6Zf3GUPytYjDYM+08d%@?y$}dCu z(dVnkpD)b>hHuqo_|_3>&usXc9KmI+VD$*rWv$`s5v&hp!zcRQMJ^G|^$Z$XtY4X3 z(f?I)cn?i#)UZ8PW{xn&MRMpCnoYxhKK*#Xu#$D7Su2=lNe)X!W?KJWGt|}*taHxj zd!^?mFxRvkRF}1uw!X0q)jNXkJ;KZ{i+-*?z}B+5v>Hs_ynX+Ip*(`mlk9hH`qD@1 z2vKXUY1L)t)7+m}^=NYAvn?G~2__v*DAGhZg3VmVuffqO#Ht1pjW&$M!Y!!!KK0Sq}hfPW|M z31z?j>JjXjRx~@bhMzrvK@Hz~=N$KhYP~-52=*+=ftt2H)C+$JD+dVlYyCy)g%7L^ z?G-**IY6*$_>@Z$>q236bTp0nyj8PufWW$4G`qx)p?x*jN{xF`_W6ES%`DNl0ev@H zdI)jgzUL(SGbq-I0S i)}1eQ)I*Xu8=5{I?;)?&E;0000 u.isPlayer() || u.type == FOSUnitTypes.legion); } } @@ -24,7 +24,16 @@ public void updateMovement() { if (protectTarget == null) return; // Just circle around the unit. That's the entire move set of this AI. - circle(protectTarget, protectTarget.hitSize * 2); + circle(protectTarget, protectTarget.hitSize * 2 + unit.hitSize); + + // Ok, I lied. A player has to somehow control their shooting. + if (protectTarget.isPlayer()) { + for (var wm : unit.mounts()) { + wm.aimX = protectTarget.aimX; + wm.aimY = protectTarget.aimY; + wm.shoot = protectTarget.isShooting(); + } + } faceTarget(); } diff --git a/core/src/fos/content/FOSUnitTypes.java b/core/src/fos/content/FOSUnitTypes.java index 6f6b8cef..bacf2e04 100644 --- a/core/src/fos/content/FOSUnitTypes.java +++ b/core/src/fos/content/FOSUnitTypes.java @@ -17,7 +17,7 @@ import mindustry.entities.abilities.*; import mindustry.entities.bullet.*; import mindustry.entities.part.*; -import mindustry.entities.pattern.ShootSpread; +import mindustry.entities.pattern.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.type.*; @@ -33,7 +33,7 @@ public class FOSUnitTypes { public static @Annotations.EntityDef({Unitc.class}) UnitType sergeant, lieutenant, captain, general, marshal, smoke, cloud, - legionnaire; + legionnaire, legionnaireReplica; public static @Annotations.EntityDef({ElevationMovec.class, Unitc.class}) UnitType assault; @@ -56,12 +56,14 @@ public static void load(){ legionnaire = new UnitType("legionnaire"){{ health = 200; hitSize = 8; + rotateSpeed = 6f; speed = 2.5f; accel = 0.08f; drag = 0.04f; isEnemy = false; flying = true; targetPriority = -2f; + playerControllable = false; outlineColor = Color.valueOf("2b2f36"); weapons.add( new Weapon(){{ @@ -83,7 +85,40 @@ public static void load(){ }}; }} ); - aiController = ProtectorAI::new; + controller = u -> new ProtectorAI(); + }}; + legionnaireReplica = new UnitType("legionnaire-replica"){{ + health = 150; + hitSize = 12; + rotateSpeed = 6f; + speed = 2f; + accel = 0.08f; + drag = 0.04f; + isEnemy = false; + flying = true; + targetPriority = -2f; + playerControllable = false; + outlineColor = Color.valueOf("2b2f36"); + weapons.add( + new Weapon(){{ + x = 0f; y = 3f; + mirror = false; + top = false; + rotate = false; + reload = 30f; + bullet = new BasicBulletType(2.5f, 55){{ + width = 7f; + height = 9f; + lifetime = 45f; + shootEffect = Fx.shootSmall; + smokeEffect = Fx.shootSmallSmoke; + ammoMultiplier = 2; + trailWidth = 3; + trailLength = 8; + }}; + }} + ); + controller = u -> new ProtectorAI(); }}; //TODO: campaign boss legion = new UnitType("legion"){{ @@ -105,7 +140,7 @@ public static void load(){ }}; }}, new Weapon("legion-sapper"){{ - x = 8f; y = 9f; + x = 0f; y = 6f; mirror = true; alternate = true; reload = 40f; @@ -113,6 +148,10 @@ public static void load(){ rotate = false; shootCone = 25f; shootSound = Sounds.sap; + shoot = new ShootAlternate(){{ + barrels = 2; + spread = 4f; + }}; bullet = new SapBulletType(){{ length = 80f; damage = 60; diff --git a/core/src/fos/content/FOSWeaponModules.java b/core/src/fos/content/FOSWeaponModules.java index 3bc9db54..cd9a5714 100644 --- a/core/src/fos/content/FOSWeaponModules.java +++ b/core/src/fos/content/FOSWeaponModules.java @@ -1,12 +1,18 @@ package fos.content; +import arc.Events; +import arc.struct.Seq; +import fos.type.abilities.UnitResistanceAbility; import fos.type.bullets.SmartBulletType; import fos.type.content.WeaponSet; import mindustry.content.Fx; +import mindustry.entities.abilities.UnitSpawnAbility; import mindustry.entities.bullet.*; +import mindustry.game.EventType; import mindustry.gen.Sounds; import mindustry.graphics.Pal; import mindustry.type.Weapon; +import mindustry.type.weapons.RepairBeamWeapon; import static fos.content.FOSItems.*; import static mindustry.content.Items.*; @@ -17,9 +23,11 @@ public class FOSWeaponModules { public static WeaponSet standard1, standard2, standard3, standard4, standard5, - shotgun1, shotgun2, shotgun3, shotgun4, shotgun5; + shotgun1, shotgun2, shotgun3, shotgun4, shotgun5, + legionFabricator; public static void load() { + // BASIC / ASSAULT RIFLES standard1 = new WeaponSet("standard1", new Weapon("fos-standard-weapon1"){{ x = 0; y = 0; alternate = mirror = false; @@ -113,6 +121,7 @@ public static void load() { }}; }}).reqs(with(tin, 500, silver, 500, vanadium, 300, nickel, 250, luminium, 200)); + // SHOTGUNS shotgun1 = new WeaponSet("shotgun1", new Weapon("fos-shotgun-mount1"){{ x = y = 0; alternate = mirror = false; @@ -139,5 +148,23 @@ public static void load() { shotgun3 = new WeaponSet("shotgun3", new Weapon()).reqs(with(lead, 1)); shotgun4 = new WeaponSet("shotgun4", new Weapon()).reqs(with(lead, 1)); shotgun5 = new WeaponSet("shotgun5", new Weapon()).reqs(with(lead, 1)); + + // BOSS WEAPONS + legionFabricator = new WeaponSet("legion-fabricator", + new RepairBeamWeapon("legion-beam-replica"){{ + x = 0; y = 0; + mirror = false; + bullet = new BulletType(){{ + maxRange = 40f; + }}; + }} + ){{ + Events.on(EventType.ContentInitEvent.class, e -> { + abilities = Seq.with( + new UnitResistanceAbility(FOSUnitTypes.legionnaireReplica, 0.05f), + new UnitSpawnAbility(FOSUnitTypes.legionnaireReplica, 600, -16, 0) + ); + }); + }}.reqs(with(tin, 200, silver, 125, silicon, 150)); } } diff --git a/core/src/fos/type/abilities/UnitResistanceAbility.java b/core/src/fos/type/abilities/UnitResistanceAbility.java index f3176e12..a714e6d0 100644 --- a/core/src/fos/type/abilities/UnitResistanceAbility.java +++ b/core/src/fos/type/abilities/UnitResistanceAbility.java @@ -32,8 +32,10 @@ public void draw(Unit unit) { int units = countUnits(unit); + if (units == 0) return; + Draw.color(unit.team.color); - Draw.alpha(Math.max(resistance * units, 0.5f)); + Draw.alpha(Math.min(resistance * units, 0.5f)); Fill.circle(unit.x, unit.y, unit.hitSize); Lines.stroke(2f); diff --git a/core/src/fos/type/content/WeaponSet.java b/core/src/fos/type/content/WeaponSet.java index b8e84466..5ae3efbc 100644 --- a/core/src/fos/type/content/WeaponSet.java +++ b/core/src/fos/type/content/WeaponSet.java @@ -2,6 +2,7 @@ import arc.struct.Seq; import fos.gen.LumoniPlayerUnitc; +import mindustry.entities.abilities.Ability; import mindustry.entities.units.WeaponMount; import mindustry.gen.Unit; import mindustry.type.*; @@ -9,7 +10,7 @@ //YES, this looks very cursed lmao /** * FOR MODDERS: applying this "status effect" will have no effect whatsoever - **/ + */ public class WeaponSet extends StatusEffect { public static Seq sets = new Seq<>(); @@ -17,6 +18,8 @@ public class WeaponSet extends StatusEffect { public Seq weapons; public ItemStack[] reqs; + public Seq abilities = new Seq<>(); + public WeaponSet(String name, Weapon... weapons) { super(name); id = sets.size; @@ -25,6 +28,15 @@ public WeaponSet(String name, Weapon... weapons) { this.weapons = new Seq<>(weapons); } + public WeaponSet(String name, Seq abilities, Weapon... weapons) { + this(name, weapons); + this.abilities = abilities; + } + + public WeaponSet(String name, Seq abilities) { + this(name, abilities, new Weapon()); + } + @Override public void init() { super.init(); @@ -52,11 +64,13 @@ public void applyToUnit(LumoniPlayerUnitc lpc) { lpc.isEditedWeapons(true); lpc.weaponSet(this); lpc.mounts(getMounts()); + if (!abilities.isEmpty()) + lpc.abilities(abilities.toArray()); } /** * Applies weapons to unit. - **/ + */ public WeaponMount[] getMounts() { WeaponMount[] mounts = new WeaponMount[weapons.size]; diff --git a/core/src/fos/type/units/comp/LumoniPlayerUnitComp.java b/core/src/fos/type/units/comp/LumoniPlayerUnitComp.java index c92380d9..6e2b3d4b 100644 --- a/core/src/fos/type/units/comp/LumoniPlayerUnitComp.java +++ b/core/src/fos/type/units/comp/LumoniPlayerUnitComp.java @@ -4,8 +4,10 @@ import fos.FOSTypeIO; import fos.type.content.WeaponSet; import mindustry.annotations.Annotations; +import mindustry.entities.abilities.Ability; import mindustry.entities.units.WeaponMount; import mindustry.gen.*; +import mindustry.io.TypeIO; // FIXME mounts @Annotations.Component @@ -13,12 +15,15 @@ public abstract class LumoniPlayerUnitComp implements Weaponsc, Entityc, Syncc, transient boolean isEditedWeapons = false; transient WeaponSet weaponSet = null; @Annotations.Import WeaponMount[] mounts; + @Annotations.Import Ability[] abilities; @Override public void write(Writes write) { write.bool(isEditedWeapons); write.i(weaponSet == null ? -1 : weaponSet.id); FOSTypeIO.writeMounts2(write, this); + // FIXME + TypeIO.writeAbilities(write, abilities); } @Override @@ -27,5 +32,7 @@ public void read(Reads read) { int weaponSetId = read.i(); weaponSet = weaponSetId == -1 ? null : WeaponSet.sets.get(weaponSetId); mounts = FOSTypeIO.readMounts2(read, type()); + // FIXME + TypeIO.readAbilities(read, abilities); } }