diff --git a/patches/empireReplacement.json b/patches/empireReplacement.json new file mode 100644 index 00000000..f018b083 --- /dev/null +++ b/patches/empireReplacement.json @@ -0,0 +1,15 @@ +name: "temporary boss replacement" + +unit.evoke.weapons: [ { +reload: 69420 +alwaysShooting: true +shoot: { + shots: 4 +} +bullet: { + lifetime: 1 + spawnUnit: eclipse + killShooter: true + } +} +] diff --git a/patches/empirenewlegs.json b/patches/empirenewlegs.json new file mode 100644 index 00000000..2b758526 --- /dev/null +++ b/patches/empirenewlegs.json @@ -0,0 +1,396 @@ +name: empire boss by alphy,evoke base + +unit.evoke: { +localizedName: Empire +region: "reign" + +parts: [ +{ +name: "reign" +xScl: 1.5 +yScl: 1.2 +layerOffset: -0.002 +} +{ +name: "scepter" +layerOffset: -0.001 +xScl: 1.1 +yScl: 1.1 +x: 10 +} +{ +name: "scepter" +layerOffset: -0.001 +xScl: 1.1 +yScl: 1.1 +x: -10 +} +{ +name: "scepter" +y: 8 +xScl: 1.5 +layerOffset: -0.003 +} +{ +name: "scepter" +xScl: 2.25 +y: -2 +layerOffset: -0.003 +} +] + +flying: false + +controller: groundAI + +type: mech +legLength: 35 +legRegion: "reign-leg" + +hittable: true +fogRadius: 300 +coreUnitDock: false +targetAir: true +targetGround: true +playerControllable: true +logicControllable: true +targetable: true +autoFindTarget: true +useUnitCap: true +createScorch: true +uiIcon: "unit-reign-ui" + + +speed: 0.3f +range: 350 +maxRange: 450 +rotateSpeed: 0.6 +aimDst: 120 +hitSize: 45f +health: 62000 +mechStepParticles: true +stepShake: 1.2f +drownTimeMultiplier: 4 +mechFrontSway: 1f +mechSideSway: 0.6f +aiController: GroundAI +controller: GroundAI + +stepSound: mechStepHeavy +stepSoundPitch: 0.8 +stepSoundVolume: 0.7 + +weapons: [ +{ +name: "reign-weapon" +layerOffset: -0.0005 +top: true +x: 26 +y: 5 +parts: [ +{ +name: "reign-weapon" +layerOffset: 0.0001 +xScl: 1.6 +yScl: 1.1 +} +{ +name: "reign-weapon" +layerOffset: 0.0002 +xScl: 0.8 +yScl: 0.8 +} +{ +name: "scepter-weapon" +layerOffset: 0.0001 +xScl: 0.8 +yScl: 0.8 +y: -16 +} +{ +name: "scepter-weapon" +layerOffset: 0.0001 +xScl: 0.8 +yScl: 0.8 +y: 16 +} +] +shootY: 16 +reload: 50 +recoil: 8f +recoils: 1 +recoilTime: 50 +shake: 3.5 +ejectEffect: casing4 +shootSound: shootMalign + +bullet: { +damage: 60 +splashDamage: 300 +splashDamageRadius: 30 +type: BasicBulletType +speed: 14 +width: 20 +height: 80 +lifetime: 25 +shootEffect: shootBig +hitEffect: blastExplosion +fragBullets: 1 +fragRandomSpread: 1 +fragLifeMin: 5 +fragLifeMax: 6 +despawnSound: shockBullet +lightning: 3 +lightningDamage: 30 +lightningLength: 14 +lightningColor: "fffd7a" +fragBullet: { +type: BasicBulletType +damage: 100 +width: 20 +height: 40 +lifetime: 4 +speed: 14 +pierce: true +pierceBuilding: true +hitSound: shockBullet +pierceCap: 99999 +lightning: 1 +lightningDamage: 20 +lightningLength: 14 +lightningColor: "fffd7a" +despawnSound: explosion +} +} +} + +{ +name: "reign-weapon" +layerOffset: -0.0005 +top: true +x: -26 +y: 5 +parts: [ +{ +name: "reign-weapon" +layerOffset: 0.0001 +xScl: -1.6 +yScl: 1.1 +} +{ +name: "reign-weapon" +layerOffset: 0.0002 +xScl: -0.8 +yScl: 0.8 +} +{ +name: "scepter-weapon" +layerOffset: 0.0001 +xScl: -0.8 +yScl: 0.8 +y: -16 +} +{ +name: "scepter-weapon" +layerOffset: 0.0001 +xScl: -0.8 +yScl: 0.8 +y: 16 +} +] +shootY: 16 +reload: 50 +shoot : { +firstShotDelay: 25 +} +recoil: 8f +recoils: 1 +recoilTime: 50 +shake: 3.5 +ejectEffect: casing4 +shootSound: shootMalign + +bullet: { +damage: 60 +splashDamage: 300 +splashDamageRadius: 30 +type: BasicBulletType +speed: 14 +width: 20 +height: 80 +lifetime: 25 +shootEffect: shootBig +hitEffect: blastExplosion +fragBullets: 1 +fragRandomSpread: 1 +fragLifeMin: 5 +fragLifeMax: 6 +despawnSound: shockBullet +lightning: 3 +lightningDamage: 30 +lightningLength: 14 +lightningColor: "fffd7a" +fragBullet: { +type: BasicBulletType +damage: 100 +width: 20 +height: 40 +lifetime: 4 +speed: 14 +pierce: true +pierceBuilding: true +hitSound: shockBullet +pierceCap: 99999 +lightning: 1 +lightningDamage: 20 +lightningLength: 14 +lightningColor: "fffd7a" +despawnSound: explosion +} +} +} + +{ +layerOffset: 0.05 +parts: [ +{ +name: "scepter-weapon" +layerOffset: 0.061 +} +{ +name: "sei-launcher" +layerOffset: 0.06 +xScl: 0.7 +} +] +x: 12 +y: -8 +shootY: 6 +rotate: true +autoTarget: true +alwaysShooting: true +controllable: false +reload: 900 +rotateSpeed: 99999 +targetInterval: 180 +shake: 4 +recoil: 6 +recoils: 1 +recoilTime: 60 +inaccuracy: 12f +velocityRnd: 0.4 +extraVelocity: 0.4 +shootSound: shootArtillery +shoot: { +firstShotDelay: 30 +shots: 10 +} +bullet: { +collidesAir: true +type: artilleryBulletType +range: 99999999 +width: 15 +height: 15 +speed: 4 +lifetime: 9999 +fragBullets: 1 +fragLifeMin: 2.5 +fragBullet: { +type: basicBulletType +speed: 0 +lifetime: 60 +collides: false +despawnEffect: unitCapKill +despawnSound: uiUnlock +width: 15 +height: 15 +fragBullets: 1 +fragBullet: { +type: basicBulletType +speed: 0 +lifetime: 60 +collides: false +despawnEffect: unitCapKill +despawnSound: uiUnlock +width: 15 +height: 15 +fragBullets: 1 +fragBullet: { +type: basicBulletType +speed: 0 +lifetime: 60 +collides: false +despawnEffect: unitCapKill +despawnSound: uiUnlock +width: 15 +height: 15 +fragBullets: 1 +fragBullet: { +type: basicBulletType +speed: 0 +lifetime: 60 +collides: false +despawnEffect: unitCapKill +despawnSound: uiUnlock +width: 15 +height: 15 +fragBullets: 1 +fragBullet: { +type: basicBulletType +width: 10 +height: 10 +speed: 0 +lifetime: 90 +collides: false +despawnEffect: none +fragBullets: 1 +fragBullet: { +type: explosionBulletType +collidesAir: true +despawnEffect: { +type: ExplosionEffect +lifetime: 50f +waveStroke: 5f +waveLife: 24f +waveColor: "ffff6b" +sparkColor: "ffff6b" +smokeColor: "ffffff" +waveRad: 64f +smokeSize: 4f +smokes: 21 +smokeSizeBase: 0f +sparks: 30 +sparkRad: 64f +sparkLen: 5f +sparkStroke: 2f +} +despawnHit: true +lightning: 3 +lightningLength: 24 +lightningDamage: 24 +lightningColor: "ffff6b" +hitSound: explosionMissile +killShooter: false +splashDamage: 2000 +scaledSplashDamage: true +splashDamageRadius: 45 +buildingDamageMultiplier: 999 +} +} +} +} +} +} +} +} +] +} + + + + + + + + + diff --git a/patches/rvsb.json b/patches/rvsb.json index 7609b138..6c85af1d 100644 --- a/patches/rvsb.json +++ b/patches/rvsb.json @@ -1,13 +1,92 @@ name: rvsb +//flare rework +unit.flare.omniMovement: true +unit.flare.rotateSpeed: 99999 +unit.flare.health: 120 +unit.flare.maxRange: 120 +unit.flare.rotateMoveFirst: false +unit.flare.weapons: [ + { + x: 2f + y: 0f + reload: 40f + ejectEffect: casing1 + shootSound: shoot + bullet: { + range: 120 + maxRange: 120 + speed: 2.2 + damage: 8 + type: basicBulletType + width: 7f + height: 9f + lifetime: 45f + shootEffect: shootSmall + smokeEffect: shootSmallSmoke + keepVelocity: false + } + } + { + x: -2f + y: 0f + reload: 40f + ejectEffect: casing1 + shootSound: shoot + shoot: { + firstShotDelay: 20 + } + bullet: { + range: 120 + maxRange: 120 + speed: 2.2 + damage: 8 + type: basicBulletType + width: 7f + height: 9f + lifetime: 45f + shootEffect: shootSmall + smokeEffect: shootSmallSmoke + keepVelocity: false + } + } +] + +// obviate shield +unit.obviate.hitSize: 19.9 +//unit.obviate.flyingLayer: 115 +//unit.obviate.abilities.+: [ { + //type: forceFieldAbility + //sides: 4 + //radius: 40 + //max: 600 + //regen: 0.5 + //cooldown: 600 +//} +//] +// flare shield +unit.flare.abilities.+: [ +{ + type: shieldRegenFieldAbility + max: 60 + amount: 10 + reload: 90 + range: 30 +} +] + + //disrupt ability by alphy unit.disrupt.speed: 2 //disrupt ability "wings" -unit.disrupt.weapons.+: [ { +//disrupt ability uses emanate as "base" because minShootVelocity is broken +unit.emanate.hitSize: 0 +unit.emanate.region: dagger +unit.emanate.weapons.+: [ { alwaysShooting: true -minShootVelocity: 3.6 +//minShootVelocity: 28.8 x: 0 y: 0 name: small-mount-weapon @@ -17,7 +96,7 @@ recoilTime: 0 reload: 10 shake: 3.5f inaccuracy: 360 -shootSound: flux +shootSound: loopFlux bullet: { type: lightningBulletType lightningLength: 1 @@ -34,7 +113,7 @@ x: 14 y: 4 xScl: 0.4 yScl: 2.5 -heatColor: fc4e03 +heatColor: "fc4e03" } { name: obviate @@ -46,7 +125,7 @@ x: 16 y: -4 xScl: 0.6 yScl: 3.4 -heatColor: fc4e03 +heatColor: "fc4e03" } { name: obviate @@ -58,7 +137,7 @@ x: 18 y: -12 xScl: 0.8 yScl: 4.5 -heatColor: fc4e03 +heatColor: "fc4e03" } //mirror parts @@ -72,7 +151,7 @@ x: -14 y: 4 xScl: 0.4 yScl: 2.5 -heatColor: fc4e03 +heatColor: "fc4e03" } { name: obviate @@ -84,7 +163,7 @@ x: -16 y: -4 xScl: 0.6 yScl: 3.4 -heatColor: fc4e03 +heatColor: "fc4e03" } { name: obviate @@ -96,7 +175,7 @@ x: -18 y: -12 xScl: 0.8 yScl: 4.5 -heatColor: fc4e03 +heatColor: "fc4e03" } ] @@ -105,28 +184,28 @@ heatColor: fc4e03 //disrupt ability additional sfx { alwaysShooting: true -minShootVelocity: 3.6 +//minShootVelocity: 28.8 reload: 20 -shootSound: spellLoop +shootSound: loopMalign bullet: { lifetime: 0 speed: 0 } } -// disrupt ability bombs +//disrupt ability bombs { shake: 7 alwaysShooting: true x: 0 y: 0 -minShootVelocity: 3.6 +//minShootVelocity: 28.8 reload: 540 shoot: { firstShotDelay: 60 } shootSound: none -chargeSound: lasercharge2 +chargeSound: chargeVela bullet: { splashDamagePierce: true despawnHit: true @@ -135,7 +214,7 @@ splashDamageRadius: 80f splashDamage: 900 weaveScale: 8 weaveMag: 1 -trailColor: 760ee6 +trailColor: "760ee6" trailWidth: 5f trailLength: 10 sprite: missile-large @@ -149,26 +228,26 @@ keepVelocity: false speed: 3 lightRadius: 180f lightOpacity: 0.7f -lightColor: 760ee6 -backColor: 760ee6 -frontColor: ffffff +lightColor: "760ee6" +backColor: "760ee6" +frontColor: "ffffff" lifetime: 25f fragBullets: 5 fragRandomSpread: 360f fragVelocityMin: 0.3f -hitSound: plasmaboom -despawnSound: plasmaboom +hitSound: explosionQuad +despawnSound: explosionQuad hitEffect: { lifetime: 90f type: explosionEffect waveStroke: 6 waveLife: 10f waveRadBase: 7f -waveColor: 760ee6 +waveColor: "760ee6" waveRad: 120f smokes: 18 -smokeColor: ffffff -sparkColor: 760ee6 +smokeColor: "ffffff" +sparkColor: "760ee6" sparks: 18 sparkRad: 120f sparkStroke: 1.5f @@ -186,8 +265,8 @@ height: 22 hitSize: 0 damage: 0 lifetime: 60 -backColor: 760ee6 -trailColor: 760ee6 +backColor: "760ee6" +trailColor: "760ee6" trailWidth: 3 trailLength: 12 despawnEffect: hitBulletColor @@ -197,7 +276,7 @@ fragBullets: 1 fragBullet: { speed: 0f keepVelocity: false -spawnUnit: emanate +spawnUnit: incite } } } @@ -205,41 +284,42 @@ spawnUnit: emanate ] +//disrupt drone(incite) +unit.incite.localizedName: "Disruption drone" +unit.incite.controller: flyingAI +unit.incite.hitSize: 9 +unit.incite.flyingLayer: 85 +unit.incite.region: "unit-assembly-drone-full" +unit.incite.fullIcon: "unit-assembly-drone-preview" +unit.incite.uiIcon: "unit-assembly-drone-ui" +unit.incite.playerControllable: false +unit.incite.logicControllable: false +unit.incite.allowedInPayloads: false +unit.incite.range: 320 +unit.incite.maxRange: 400 +unit.incite.faceTarget: false +unit.incite.fogRadius: 20 +unit.incite.useUnitCap: false +unit.incite.health: 60 +unit.incite.hittable: true +unit.incite.targetable: true +unit.incite.controller: FlyingAI +unit.incite.aiController: FlyingAI -//disrupt drone(emanate) -unit.emanate.localizedName: "Disruption drone" -unit.emanate.hitSize: 0 -unit.emanate.flyingLayer: 85 -unit.emanate.region: "unit-assembly-drone-full" -unit.emanate.fullIcon: "unit-assembly-drone-preview" -unit.emanate.uiIcon: "unit-assembly-drone-ui" -unit.emanate.playerControllable: false -unit.emanate.logicControllable: false -unit.emanate.allowedInPayloads: false -unit.emanate.range: 320 -unit.emanate.maxRange: 400 -unit.emanate.faceTarget: false -unit.emanate.fogRadius: 20 -unit.emanate.flyingLayer: -11000 -unit.emanate.useUnitCap: false -unit.emanate.health: 1500 -unit.emanate.hittable: true -unit.emanate.targetable: true //drone timed death -unit.emanate.abilities.+: [ +unit.incite.abilities.+: [ { type: RepairFieldAbility amount: -1 reload: 60 -range: 1 +range: 0.1 healEffect: hitFlameSmall activeEffect: hitFlameSmall } ] -unit.emanate.weapons: [ -//drone body because you cant edit engines for some reason so they go to -11000 +unit.incite.weapons: [ { x: 0 y: 0 @@ -248,8 +328,8 @@ recoil: 0 recoils: 0 recoilTime: 0 name: "assembly-drone" -layerOffset: 11085 -shootSound: spark +layerOffset: 0 +shootSound: shootArc controllable: false autoTarget: true bullet: { @@ -260,12 +340,25 @@ pierceArmor: true } } +//invulnerability +{ + alwaysShooting: true + reload: 99999999999999 + shootStatus: invincible + shootStatusDuration: 1800 + bullet: { + type: lightningBulletType + lightningLength: 1 + damage: 0 + } +} + // parallax with very low reload and range { name: small-mount-weapon x: 0 y: -5 -layerOffset: 11085.0001 +layerOffset: 0.0001 type: pointDefenseWeapon reload: 4 targetInterval: 4 @@ -273,7 +366,7 @@ targetSwitchInterval: 4 recoil: 0 recoils: 0 recoilTime: 0 -shootSound: lasershoot +shootSound: shootLaser bullet: { shootEffect: sparkShoot hitEffect: pointHit @@ -287,14 +380,14 @@ damage: 20 x: 0 y: 0 name: "vanquish-point-weapon" -layerOffset: 11085.0001 +layerOffset: 0.0001 controllable: false autoTarget: true recoils: 0 recoil: 5 recoilTime: 120 -reload: 600 -shootSound: malignShoot +reload: 1200 +shootSound: shootMalign rotate: true alwaysShooting: true shoot: { @@ -302,7 +395,7 @@ firstShotDelay: 105 } bullet: { type: laserBulletType -colors: [4d0505,940909,ff0000] +colors: ["4d0505","940909","ff0000"] lifetime: 55 maxRange: 320 range: 320 @@ -328,17 +421,17 @@ controllable: false autoTarget: true x: 0 y: 0 -shootSound: unlock +shootSound: uiUnlock rotate: true alwaysShooting: true -reload: 600 +reload: 1200 shoot: { firstShotDelay: 70 } bullet: { lifetime: 8 damage: 0 -colors: [666666,999999,aaaaaa] +colors: ["666666","999999","aaaaaa"] type: laserBulletType maxRange: 320 range: 320 @@ -350,17 +443,17 @@ controllable: false autoTarget: true x: 0 y: 0 -shootSound: unlock +shootSound: uiUnlock rotate: true alwaysShooting: true -reload: 600 +reload: 1200 shoot: { firstShotDelay: 30 } bullet: { lifetime: 8 damage: 0 -colors: [666666,999999,aaaaaa] +colors: ["666666","999999","aaaaaa"] type: laserBulletType maxRange: 320 range: 320 @@ -373,7 +466,7 @@ shoot: { shots: 3 shotDelay: 1 } -shootSound: spark +shootSound: shootArc inaccuracy: 360f rotate: false x: 0 @@ -400,7 +493,7 @@ shoot: { shots: 10 shotDelay: 6 } -shootSound: spark +shootSound: shootArc reload: 270 alwaysShooting: true inaccuracy: 360f @@ -415,156 +508,189 @@ damage: 10 -//quell and disrupt missile change for kill reward to work,yeah they pierce now,quell missile is same as disrupt except a bit more damage -unit.disrupt-missile.range: 23 -unit.disrupt-missile.maxRange: 23 +//quell and disrupt missiles unit.disrupt.targetAir: true unit.disrupt-missile.targetAir: true -unit.disrupt.weapons.0.bullet.collidesAir: true -unit.disrupt-missile.health: 99999 -unit.disrupt-missile.weapons: [ - { - shootSound: none - shootStatusDuration: 2 - shootStatus: freezing - shootCone: 360f - bullet: { - range: 13 - maxRange: 13 - lifetime: 1f - type: basicBulletType - damage: 0 - } - } - { - shootSound: none - shootStatusDuration: 2 - shootStatus: tarred - shootCone: 360f - bullet: { - range: 13 - maxRange: 13 - lifetime: 1f - type: basicBulletType - damage: 0 - } - } - { - shootCone: 360f - mirror: false - reload: 3f - shootSound: flame - shootStatusDuration: 2 - shootStatus: slow - shootOnDeath: true - bullet: { - range: 13 - maxRange: 13 - type: basicBulletType - lightning: 1 - sprite: "" - lifetime: 1f - collidesAir: true - suppressionRange: 140f - width: 49.6f - height: 49.6f - damage: 80f - pierce: true - shootEffect: { - type: ExplosionEffect - lifetime: 50f - waveStroke: 5f - waveLife: 8f - waveColor: ffffff - sparkColor: 665c9f - smokeColor: 665c9f - waveRad: 40f - smokeSize: 4f - smokes: 7 - smokeSizeBase: 0f - sparks: 10 - sparkRad: 40f - sparkLen: 6f - sparkStroke: 2f - } - } +unit.disrupt-missile.weapons.0: { +reload: 9999 +bullet: { +collidesAir: true +killShooter: false +fragBullets: 1 +fragBullet: { +type: basicBulletType +collides: false +speed: 0f +lifetime: 5f +drawSize: 0 +fragBullets: 1 +fragBullet: { +killShooter: true +instantDisappear: true } -] +} +} +} +unit.disrupt-missile.health: 99999 +// unit.disrupt-missile.weapons: [ +// { +// shootSound: none +// shootStatusDuration: 2 +// shootStatus: freezing +// shootCone: 360f +// bullet: { +// range: 13 +// maxRange: 13 +// lifetime: 1f +// type: basicBulletType +// damage: 0 +// } +// } +// { +// shootSound: none +// shootStatusDuration: 2 +// shootStatus: tarred +// shootCone: 360f +// bullet: { +// range: 13 +// maxRange: 13 +// lifetime: 1f +// type: basicBulletType +// damage: 0 +// } +// } +// { +// shootCone: 360f +// mirror: false +// reload: 3f +// shootSound: shootFlame +// shootStatusDuration: 2 +// shootStatus: slow +// shootOnDeath: true +// bullet: { +// range: 13 +// maxRange: 13 +// type: basicBulletType +// lightning: 1 +// sprite: "" +// lifetime: 1f +// collidesAir: true +// suppressionRange: 140f +// width: 49.6f +// height: 49.6f +// damage: 33f +// pierce: true +// shootEffect: { +// type: ExplosionEffect +// lifetime: 50f +// waveStroke: 5f +// waveLife: 8f +// waveColor: "ffffff" +// sparkColor: "665c9f" +// smokeColor: "665c9f" +// waveRad: 40f +// smokeSize: 4f +// smokes: 7 +// smokeSizeBase: 0f +// sparks: 10 +// sparkRad: 40f +// sparkLen: 6f +// sparkStroke: 2f +// } +// } +// } +// ] -unit.quell-missile.range: 40 -unit.quell-missile.maxRange: 40 unit.quell.targetAir: true unit.quell-missile.targetAir: true -unit.quell.weapons.0.bullet.collidesAir: true -unit.quell-missile.health: 99999 -unit.quell-missile.weapons: [ - { - shootSound: none - shootStatusDuration: 2 - shootStatus: freezing - shootCone: 360f - bullet: { - range: 13 - maxRange: 13 - lifetime: 1f - type: basicBulletType - damage: 0 - } - } - { - shootSound: none - shootStatusDuration: 2 - shootStatus: tarred - shootCone: 360f - bullet: { - range: 13 - maxRange: 13 - lifetime: 1f - type: basicBulletType - damage: 0 - } - } - { - shootCone: 360f - mirror: false - reload: 3f - shootSound: flame - shootStatusDuration: 2 - shootStatus: slow - shootOnDeath: true - bullet: { - range: 13 - maxRange: 13 - type: basicBulletType - lightning: 1 - sprite: "" - lifetime: 1f - collidesAir: true - suppressionRange: 140f - width: 49.6f - height: 49.6f - damage: 140f - pierce: true - shootEffect: { - type: ExplosionEffect - lifetime: 90f - waveStroke: 5f - waveLife: 8f - waveColor: ffffff - sparkColor: 665c9f - smokeColor: 665c9f - waveRad: 40f - smokeSize: 4f - smokes: 7 - smokeSizeBase: 0f - sparks: 10 - sparkRad: 40f - sparkLen: 6f - sparkStroke: 2f - } - } +unit.quell-missile.weapons.0: { +reload: 9999 +bullet: { +collidesAir: true +killShooter: false +fragBullets: 1 +fragBullet: { +type: basicBulletType +collides: false +speed: 0f +lifetime: 5f +drawSize: 0 +fragBullets: 1 +fragBullet: { +killShooter: true +instantDisappear: true } -] +} +} +} +// unit.quell-missile.weapons: [ +// { +// shootSound: none +// shootStatusDuration: 2 +// shootStatus: freezing +// shootCone: 360f +// bullet: { +// range: 13 +// maxRange: 13 +// lifetime: 1f +// type: basicBulletType +// damage: 0 +// } +// } +// { +// shootSound: none +// shootStatusDuration: 2 +// shootStatus: tarred +// shootCone: 360f +// bullet: { +// range: 13 +// maxRange: 13 +// lifetime: 1f +// type: basicBulletType +// damage: 0 +// } +// } +// { +// shootCone: 360f +// mirror: false +// reload: 3f +// shootSound: shootFlame +// shootStatusDuration: 2 +// shootStatus: slow +// shootOnDeath: true +// bullet: { +// range: 13 +// maxRange: 13 +// type: basicBulletType +// lightning: 1 +// sprite: "" +// lifetime: 1f +// collidesAir: true +// suppressionRange: 140f +// width: 49.6f +// height: 49.6f +// damage: 45f +// pierce: true +// shootEffect: { +// type: ExplosionEffect +// lifetime: 90f +// waveStroke: 5f +// waveLife: 8f +// waveColor: "ffffff" +// sparkColor: "665c9f" +// smokeColor: "665c9f" +// waveRad: 40f +// smokeSize: 4f +// smokes: 7 +// smokeSizeBase: 0f +// sparks: 10 +// sparkRad: 40f +// sparkLen: 6f +// sparkStroke: 2f +// } +// } +// } +// ] @@ -599,18 +725,18 @@ unit.anthicus.weapons: [ x: 0 y: 0 shootY: 11.75f - shootSound: torch + shootSound: shootSublimate bullet: { status: freezing range: 350 maxRange: 350 type: railBulletType pierceCap: 1 - damage: 1.6 + damage: 0 length: 340 pierceDamageFactor: 0.1 pointEffect: railTrail - hitColor: 89cffa + hitColor: "89cffa" pierceArmor: true hitEffect: hitSquaresColor } @@ -634,18 +760,18 @@ unit.anthicus.weapons: [ x: 0 y: 0 shootY: 11.75f - shootSound: spellLoop + shootSound: loopMalign bullet: { range: 350 maxRange: 350 type: continuousFlameBulletType - flareColor: 89cffa + flareColor: "89cffa" pierceCap: 1 - damage: 0 + damage: 1.6 length: 350 pierceDamageFactor: 0.1 width: 4f - colors: [89cffa,ffffff,30a7f0,ffffff] + colors: ["89cffa","ffffff","30a7f0","ffffff"] } } { @@ -662,7 +788,7 @@ unit.anthicus.weapons: [ recoil: 2f recoils: 1 recoilTime: 120f - shootSound: beam + shootSound: beamMeltdown bullet: { range: 350 maxRange: 350 @@ -686,7 +812,7 @@ name: "retusa-weapon" x: 0 y: -2f rotate: true -shootSound: lasershoot +shootSound: shootLaser reload: 125f cooldownTime: 40f useAttackRange: true @@ -707,16 +833,46 @@ maxRange: 144f speed: 10f lifetime: 14f type: laserBoltBulletType -backColor: 99ff99 -frontColor: ffffff +backColor: "99ff99" +frontColor: "ffffff" healPercent: 5f collidesTeam: true -damage: 20f +damage: 25f ammoMultiplier: 2 } } + +//crux vela wproc bullet +unit.vela.weapons.+: { +shoot: { +firstShotDelay: 9999999 +} +bullet: { +type: ShrapnelBulletType +length: 90f +damage: 110f +width: 25f +serrations : 5 +serrationLenScl: 7 +serrationSpaceOffset: 60f +serrationFadeOffset: 0f +serrationWidth: 4f +fromColor: ffcb82 +toColor: c2ffbf +shootEffect: sparkShoot +} +} + +//dont register crawlers that manually explode +unit.crawler.weapons.0.shootStatus: noRegisterKills +unit.crawler.weapons.0.shootStatusDuration: 1000 + //update unit and block stats + +// Hit size +unit.vanquish.hitSize: 16 + // Health unit.stell.health: 400 @@ -725,6 +881,7 @@ unit.locus.armor: -20 unit.retusa.health: 800 unit.pulsar.health: 500 unit.pulsar.armor: 6 +unit.merui.health: 400 // Health unit.elude.health: 300 @@ -738,12 +895,13 @@ unit.pulsar.itemCapacity: 40 unit.mace.weapons.0.bullet.damage: 17 unit.mace.weapons.1.bullet.damage: 17 unit.avert.weapons.0.bullet.damage: 35 -unit.mega.weapons.0.bullet.damage: 30 -unit.mega.weapons.1.bullet.damage: 30 -unit.mega.weapons.2.bullet.damage: 30 -unit.mega.weapons.3.bullet.damage: 30 +unit.mega.weapons.0.bullet.damage: 18 +unit.mega.weapons.1.bullet.damage: 18 +unit.mega.weapons.2.bullet.damage: 18 +unit.mega.weapons.3.bullet.damage: 18 //blocks +block.launch-pad.itemCapacity: 50000 block.combustion-generator.health: 320 block.mender.health: 120 @@ -751,3 +909,179 @@ block.tungsten-wall.targetable: false block.tungsten-wall.health: 99999 block.tungsten-wall-large.targetable: false block.tungsten-wall-large.health: 99999 + +//generators consumption +block.combustion-generator.itemDuration: 2400 +block.steam-generator.itemDuration: 2400 +block.thorium-reactor.itemDuration: 1800 +block.thorium-reactor.powerProduction: 45 +block.rtg-generator.itemDuration: 14400 + +//statuses +status.electrified.reloadMultiplier: 0.75 + +//building system,match prices with Buildings.java +item.dormant-cyst.localizedName: " Points" +item.dormant-cyst.uiIcon: "unit-dagger-ui" +item.dormant-cyst.fullIcon: "unit-dagger-preview" + +block.bridge-conduit.requirements: [dormant-cyst/3] +block.bridge-conduit.category: effect + +block.bridge-conveyor.requirements: [dormant-cyst/3] +block.bridge-conveyor.category: effect + +block.unloader.requirements: [dormant-cyst/9] +block.unloader.category: effect + +block.power-node-large.requirements: [dormant-cyst/9] +block.power-node-large.category: effect + +block.pneumatic-drill.requirements: [dormant-cyst/9] +block.pneumatic-drill.category: effect + +block.container.requirements: [dormant-cyst/3] +block.container.category: effect + +block.beryllium-wall.requirements: [dormant-cyst/2] +block.beryllium-wall.category: effect + +block.beryllium-wall-large.requirements: [dormant-cyst/6] +block.beryllium-wall-large.category: effect + +block.thorium-wall.requirements: [dormant-cyst/4] +block.thorium-wall.category: effect + +block.thorium-wall-large.requirements: [dormant-cyst/12] +block.thorium-wall-large.category: effect + +block.blast-door.requirements: [dormant-cyst/30] +block.blast-door.category: effect + +block.combustion-generator.requirements: [dormant-cyst/9] +block.combustion-generator.category: effect + +block.rtg-generator.requirements: [dormant-cyst/30] +block.rtg-generator.category: effect + +block.laser-drill.requirements: [dormant-cyst/25] +block.laser-drill.category: effect + +block.force-projector.requirements: [dormant-cyst/35] +block.force-projector.category: effect + +block.power-node.requirements: [dormant-cyst/3] +block.power-node.category: effect + +block.battery.requirements: [dormant-cyst/5] +block.battery.category: effect + +block.segment.requirements: [dormant-cyst/80] +block.segment.category: effect + +block.mechanical-pump.requirements: [dormant-cyst/4] +block.mechanical-pump.category: effect + +block.mender.requirements: [dormant-cyst/10] +block.mender.category: logic +block.mender.localizedName: "Repair point" + +block.phase-wall.requirements: [dormant-cyst/20] +block.phase-wall.category: logic +block.phase-wall.localizedName: "Suppressor tower" + +block.radar.requirements: [dormant-cyst/8] +block.radar.category: logic +block.radar.localizedName: "Workbench" + +block.carbide-wall.requirements: [dormant-cyst/7] +block.carbide-wall.category: logic +block.carbide-wall.localizedName: "Laboratory" + +block.beam-node.requirements: [dormant-cyst/18] +block.beam-node.category: logic +block.beam-node.localizedName: "Booster" + +block.slag-incinerator.requirements: [dormant-cyst/6] +block.slag-incinerator.category: logic +block.slag-incinerator.localizedName: "Recycler" + +block.pulverizer.requirements: [dormant-cyst/20] +block.pulverizer.category: logic +block.pulverizer.localizedName: "Miner" + + + +//building for everyone +unit.dagger.buildSpeed: 0.01 +unit.mace.buildSpeed: 0.01 +unit.fortress.buildSpeed: 0.01 +unit.scepter.buildSpeed: 0.01 +unit.reign.buildSpeed: 0.01 + +unit.flare.buildSpeed: 0.01 +unit.horizon.buildSpeed: 0.01 +unit.zenith.buildSpeed: 0.01 +unit.antumbra.buildSpeed: 0.01 +unit.eclipse.buildSpeed: 0.01 + +unit.nova.buildSpeed: 0.01 +unit.pulsar.buildSpeed: 0.01 +unit.quasar.buildSpeed: 0.01 +unit.vela.buildSpeed: 0.01 +unit.corvus.buildSpeed: 0.01 + +unit.crawler.buildSpeed: 0.01 +unit.atrax.buildSpeed: 0.01 +unit.spiroct.buildSpeed: 0.01 +unit.arkyid.buildSpeed: 0.01 +unit.toxopid.buildSpeed: 0.01 + +unit.mono.buildSpeed: 0.01 +unit.poly.buildSpeed: 0.01 +unit.mega.buildSpeed: 0.01 +unit.quad.buildSpeed: 0.01 +unit.oct.buildSpeed: 0.01 + +unit.risso.buildSpeed: 0.01 +unit.minke.buildSpeed: 0.01 +unit.bryde.buildSpeed: 0.01 +unit.sei.buildSpeed: 0.01 +unit.omura.buildSpeed: 0.01 + +unit.retusa.buildSpeed: 0.01 +unit.oxynoe.buildSpeed: 0.01 +unit.cyerce.buildSpeed: 0.01 +unit.aegires.buildSpeed: 0.01 +unit.navanax.buildSpeed: 0.01 + +unit.stell.buildSpeed: 0.01 +unit.locus.buildSpeed: 0.01 +unit.precept.buildSpeed: 0.01 +unit.vanquish.buildSpeed: 0.01 +unit.conquer.buildSpeed: 0.01 + +unit.merui.buildSpeed: 0.01 +unit.cleroi.buildSpeed: 0.01 +unit.anthicus.buildSpeed: 0.01 +unit.tecta.buildSpeed: 0.01 +unit.collaris.buildSpeed: 0.01 + +unit.elude.buildSpeed: 0.01 +unit.avert.buildSpeed: 0.01 +unit.obviate.buildSpeed: 0.01 +unit.quell.buildSpeed: 0.01 +unit.disrupt.buildSpeed: 0.01 + +//boat accesibility to match cheat clients/mods +unit.risso.omniMovement: true +unit.minke.omniMovement: true +unit.bryde.omniMovement: true +unit.sei.omniMovement: true +unit.omura.omniMovement: true + +unit.retusa.omniMovement: true +unit.oxynoe.omniMovement: true +unit.cyerce.omniMovement: true +unit.aegires.omniMovement: true +unit.navanax.omniMovement: true diff --git a/src/main/java/net/voiddustry/redvsblue/PlayerData.java b/src/main/java/net/voiddustry/redvsblue/PlayerData.java index e5c0d28b..cd4d20a1 100644 --- a/src/main/java/net/voiddustry/redvsblue/PlayerData.java +++ b/src/main/java/net/voiddustry/redvsblue/PlayerData.java @@ -20,6 +20,8 @@ public class PlayerData { private int level; private int exp; private int maxExp; + private double lastEvolutionTime; + private double lastRedeemTime; public PlayerData(String name, String uuid, String ip, Unit unit, Team team, Integer evolutionStage, Integer level, Integer exp, Integer maxExp) { this.name = name; @@ -36,6 +38,8 @@ public PlayerData(String name, String uuid, String ip, Unit unit, Team team, Int this.level = 1; this.exp = 0; this.maxExp = 20; + this.lastEvolutionTime = 0; + this.lastRedeemTime = 0; } public PlayerData(Player player) { @@ -62,6 +66,13 @@ public Team getTeam() { return team; } + public double getLastEvolutionTime() { + return lastEvolutionTime; + } + public double getLastRedeemTime() { + return lastRedeemTime; + } + public void addScore(int amount) { score += amount; } @@ -158,4 +169,11 @@ public int getMaxExp() { public void setMaxExp(int amount) { this.maxExp = amount; } + + public void setLastEvolutionTime(double time) { + this.lastEvolutionTime = time; + } + public void setLastRedeemTime(double time) { + this.lastRedeemTime = time; + } } diff --git a/src/main/java/net/voiddustry/redvsblue/RedVsBluePlugin.java b/src/main/java/net/voiddustry/redvsblue/RedVsBluePlugin.java index a5803d15..6e3ff448 100644 --- a/src/main/java/net/voiddustry/redvsblue/RedVsBluePlugin.java +++ b/src/main/java/net/voiddustry/redvsblue/RedVsBluePlugin.java @@ -1,6 +1,7 @@ package net.voiddustry.redvsblue; import arc.Events; +import arc.Core; import arc.graphics.Color; import arc.struct.Seq; @@ -13,6 +14,7 @@ import mindustry.content.Fx; import mindustry.content.StatusEffects; import mindustry.content.UnitTypes; +import mindustry.type.*; import mindustry.game.EventType; import mindustry.game.Team; import mindustry.gen.*; @@ -20,6 +22,7 @@ import mindustry.type.UnitType; import mindustry.ui.Menus; import mindustry.world.Tile; +import mindustry.net.*; import net.voiddustry.redvsblue.admin.Admin; import net.voiddustry.redvsblue.ai.AirAI; import net.voiddustry.redvsblue.ai.BluePlayerTarget; @@ -29,8 +32,8 @@ import net.voiddustry.redvsblue.evolution.Evolutions; import net.voiddustry.redvsblue.game.crux.*; import net.voiddustry.redvsblue.game.stations.StationsMenu; -import net.voiddustry.redvsblue.game.building.BuildBlock; -import net.voiddustry.redvsblue.game.building.BuildMenu; +import net.voiddustry.redvsblue.game.stations.Laboratory; +import net.voiddustry.redvsblue.game.building.UpdateConstructBlocks; import net.voiddustry.redvsblue.game.starting_menu.StartingMenu; import net.voiddustry.redvsblue.game.stations.*; import net.voiddustry.redvsblue.game.units.SpecialUnits; @@ -44,6 +47,7 @@ import java.util.Locale; import java.util.Objects; import java.lang.Math; +import java.time.Instant; import static net.voiddustry.redvsblue.util.MapVote.callMapVoting; import static net.voiddustry.redvsblue.util.Utils.*; @@ -69,17 +73,58 @@ public class RedVsBluePlugin extends Plugin { public static float stageTimer = 0; public static boolean playing = false; + public static boolean stage11 = false; + public int restartCounter = 0; + public int gamesUntilRestart = 2000000; static Timer.Task task = new Timer.Task() { @Override public void run() { - stage++; - stageTimer = 300; - spawnBoss(); - announceBundled("game.new-stage", 15, stage); - ClassChooseMenu.updateUnitsMap(); - if (stage >= 11) { + if (stage != 10) { + stage++; + stageTimer = 300; + spawnBoss(); + announceBundled("game.new-stage", 15, stage); + ClassChooseMenu.updateUnitsMap(); + } else { + //calculate blue unit value for stage 11 + int blueUnitValue = 0; + float typeModifier = 1; + for (Unit u : Groups.unit) { + if (u.team==Team.blue) { + typeModifier = 1; + if (u.type == UnitTypes.quad) { + typeModifier = 2; + } else if (u.type == UnitTypes.sei) { + typeModifier = 2; + } else if (u.type == UnitTypes.aegires) { + typeModifier = 3; + } else if (u.type == UnitTypes.omura) { + typeModifier = 2; + } else if (u.type == UnitTypes.navanax) { + typeModifier = 1.5f; + } + blueUnitValue = blueUnitValue + ((int)(u.type.health*typeModifier)); + } + } + Log.info("Blue unit value for stage 11: " + blueUnitValue); + if (blueUnitValue < 100000) { + gameOver(Team.blue); + } else { + stage11 = true; + announceBundled("game.stage11", 5); + Timer timer = new Timer(); + timer.schedule(() -> { + stage++; + stageTimer = 300; + spawnBoss(); + announceBundled("game.new-stage", 15, 11); + ClassChooseMenu.updateUnitsMap(); + }, 6); + } + } + if (stage >= 12) { gameOver(Team.blue); } } @@ -89,7 +134,8 @@ public void run() { public void init() { Log.info("&gRedVsBlue Plugin &rStarted!"); - + + Utils.initRules(); Utils.initTimers(); Utils.loadContent(); @@ -97,6 +143,8 @@ public void init() { SpawnEffect.initEffect(); Boss.forEachBoss(); Premium.init(); + CruxUnit.addEvent(); + for (UnitType unit : Vars.content.units()) { if (unit == UnitTypes.crawler) { @@ -127,6 +175,7 @@ public void init() { } else { players.put(player.uuid(), new PlayerData(player)); PlayerData data = players.get(player.uuid()); + Vars.world.tile(((int)blueSpawnX)/8,((int)blueSpawnY)/8).setNet(Blocks.air,Team.derelict,0); Unit unit = getStartingUnit().spawn(Team.blue, blueSpawnX, blueSpawnY); data.setUnit(unit); @@ -143,7 +192,6 @@ public void init() { }); Events.on(EventType.PlayerChatEvent.class, event -> { - Call.sound(Sounds.chatMessage, 2, 2, 1); if (Utils.voting) { if (Strings.canParseInt(event.message)) { MapVote.registerVote(event.player, Strings.parseInt(event.message)); @@ -155,6 +203,12 @@ public void init() { HashMap spawnedUnitOwnership = new HashMap<>(); HashMap killCredit = new HashMap<>(); + //situations where kills should not be registered + StatusEffect noRegisterKills = new StatusEffect("noRegisterKills") {{ + show = false; + }}; + + Events.on(EventType.UnitDamageEvent.class, event -> { if (event.unit != null && event.bullet.owner() instanceof Unit damager) { if ((damager.isPlayer() || (spawnedUnitOwnership.get(damager) != null && spawnedUnitOwnership.get(damager).isPlayer())) && damager.team == Team.blue) { @@ -171,30 +225,39 @@ public void init() { } }); + Events.on(EventType.PlayEvent.class, event -> { + Utils.initRules(); + }); + //blue kill registration Events.on(EventType.UnitDestroyEvent.class, event -> { - Player killerPlayer = killCredit.get(event.unit); - killCredit.remove(event.unit); - if (killerPlayer == null) { - float minDist = 69420; - for (Player p : Groups.player) { - if (((!(p.unit() == null)) && event.unit.dst(p)= 2) { - Boss.spawnBoss(killer.getPlayer()); + if (!(data == null)) { + data.addKill(); + Call.label(killer.getPlayer().con, "[scarlet]+1", 2, event.unit.x, event.unit.y); + if (data.getKills() >= 2) { + Boss.spawnBoss(killer.getPlayer()); + } } } @@ -228,9 +293,11 @@ public void init() { if (event.unit.team() == Team.blue) { event.unit.getPlayer().team(Team.crux); PlayerData data = players.get(event.unit.getPlayer().uuid()); - data.setTeam(Team.crux); - data.setScore(0); - data.setKills(0); + if (!(data == null)) { + data.setTeam(Team.crux); + data.setScore(0); + data.setKills(0); + } UnitTypes.renale.spawn(Team.malis, event.unit.x, event.unit.y).kill(); @@ -258,6 +325,9 @@ public void init() { + + + Events.on(EventType.WorldLoadEvent.class, event -> { Miner.clearMiners(); RepairPoint.clearPoints(); @@ -266,7 +336,6 @@ public void init() { ArmorWorkbench.clearWorkbenches(); Recycler.clearRecyclers(); SuppressorTower.clearTowers(); - BuildBlock.clear(); Boss.bosses.clear(); initRules(); @@ -276,11 +345,22 @@ public void init() { Groups.player.each(p -> { PlayerData data = players.get(p.uuid()); - data.setUnit(null); - data.setExp(0); - data.setLevel(1); - data.setScore(0); + if (!(data == null)) { + data.setUnit(null); + data.setExp(0); + data.setLevel(1); + data.setScore(0); + } }); + Log.info("Games until restart: "+(gamesUntilRestart-restartCounter)); + restartCounter = restartCounter+1; + if (restartCounter >= gamesUntilRestart) { + Log.info("[scarlet]The server is restarting"); + //net.dispose(); where do you find this mythical method + Groups.player.each(p -> p.kick("[scarlet]Server is restarting")); + System.exit(0); + } + }); Events.on(EventType.WorldLoadEvent.class, event -> Timer.schedule(() -> { @@ -290,6 +370,13 @@ public void init() { Vars.state.rules.canGameOver = false; Vars.state.rules.unitCap = 32; + Timer.schedule(() -> { + UpdateConstructBlocks updateConstructBlocks = new UpdateConstructBlocks(); + Timer.schedule(updateConstructBlocks, 10f, 0.2f); + Vars.state.rules.bannedBlocks.clear(); + initRules(); + }, 0.5f); + Building core = Vars.state.teams.cores(Team.blue).first(); redSpawns.clear(); @@ -297,6 +384,8 @@ public void init() { blueSpawnX = core.x(); blueSpawnY = core.y(); + stage11 = false; + Vars.state.teams.cores(Team.blue).each(Building::kill); for (int x = 0; x < Vars.state.map.width; x++) { @@ -312,6 +401,7 @@ public void init() { Timer timer = new Timer(); timer.scheduleTask(task, 300, 300); + Groups.player.each(player -> { if (player != null) { player.team(Team.blue); @@ -329,7 +419,7 @@ public void init() { gameover = false; hardcore = false; stage = 1; - stageTimer = 420; + stageTimer = 300; voting = false; StartingMenu.canOpenMenu = true; @@ -340,12 +430,19 @@ public void init() { launchGameStartTimer(); spawnedUnitOwnership.clear(); + killCredit.clear(); Call.setRules(Vars.state.rules); + }, 10)); + // StatusEffect superShielded = new StatusEffect("superShielded") {{ + // show = false; + // healthMultiplier = 9; + // }}; + Events.run(EventType.Trigger.update, () -> { tick++; if (playing) { @@ -367,6 +464,9 @@ public void init() { }); RedVsBluePlugin.redSpawns.remove(RedVsBluePlugin.redSpawns.firstOpt()); } + + + CruxUnit.checkUnitCount(); if(tick%3==0){ @@ -390,12 +490,6 @@ public void init() { } } } - - Groups.bullet.forEach(bullet -> { - if (bullet.lifetime == 59f){ - Call.effect(Fx.shootHeal, bullet.x, bullet.y, bullet.rotation(), Color.cyan); - } - }); } } }); @@ -413,7 +507,21 @@ public void registerClientCommands(CommandHandler handler) { String[][] buttons = new String[evolution.evolutions.length][1]; for (int i = 0; i < evolution.evolutions.length; i++) { - buttons[i][0] = Bundle.format("menu.evolution.evolve", locale, evolution.evolutions[i], Evolutions.evolutions.get(evolution.evolutions[i]).cost); + float multiplier = Laboratory.getMultiplier(evolution.evolutions[i], player); + int cost = (int)(Evolutions.evolutions.get(evolution.evolutions[i]).cost*multiplier); + + String textColor = ""; + + if (multiplier > 1 && multiplier <= 1.99) { + textColor = "[orange]"; + } else if (cost>Evolutions.evolutions.get(evolution.evolutions[i]).cost) { + textColor = "[red]"; + } else if (costregister("b", "Open Building menu", (args, player) -> { - if (playing && player.team() == Team.blue) { - BuildMenu.openMenu(player); - } - }); + // handler.register("b", "Open Building menu", (args, player) -> { + // if (playing && player.team() == Team.blue) { + // BuildMenu.openMenu(player); + //} + // }); handler.register("bc", "Boss select menu", (args, player) -> { if (playing) { @@ -459,6 +567,40 @@ public void registerClientCommands(CommandHandler handler) { } }); + + handler.register("list-pinned-maps", "[scarlet]Admin only", (args, player) -> { + if (player.admin) { + try { + String mapList = ""; + for (String mn : MapVote.pinnedMaps) { + mapList = mapList+"\n"+mn; + } + player.sendMessage(mapList); + } catch (Exception e) { + player.sendMessage("Failed to list pinned maps" + e); + } + } + }); + + handler.register("pin-map","", "[scarlet]Admin only", (args, player) -> { + if (player.admin) { + try { + MapVote.pinnedMaps.add(args[0].trim()); + } catch (Exception e) { + player.sendMessage("Failed to pin a map" + e); + } + } + }); + + handler.register("clear-pinned-maps", "[scarlet]Admin only", (args, player) -> { + if (player.admin) { + try { + MapVote.pinnedMaps.clear(); + } catch (Exception e) { + player.sendMessage("Failed to clear pinned maps" + e); + } + } + }); handler.register("gameover", "Only for admins", (args, player) -> { if (player.admin) { @@ -468,7 +610,7 @@ public void registerClientCommands(CommandHandler handler) { }); handler.register("blue", "Makes you blue, works only before stage 3", (args, player) -> { - if (stage <= 3 && playing && player.team() != Team.blue) { + if (stage <= 3 && playing && player.team() != Team.blue && players.get(player.uuid()).getLastRedeemTime()+45removeCommand("rtv"); - + handler.removeCommand("observer"); + handler.removeCommand("spectator"); // handler.register("reset-data", "Use that if you blue and dont have unit.", (args, player) -> { // if (player.team() == Team.blue) { // players.put(player.uuid(), new PlayerData(player)); @@ -505,8 +649,51 @@ public void registerServerCommands(CommandHandler handler) { // } // }); - handler.register("restart", "ae", (args) -> Groups.player.each(p -> p.kick("[scarlet]Server is going to restart"))); - } + handler.register("setpoints", "[number] [playername...]", "give people money, or take it(better), admin abuse, breaks capitalism, evil", (args) -> { + try { + Player player = null; + for (Player p : Groups.player) { + if (p.name.contains(args[1].trim())) { + player = p; + } + } + players.get(player.uuid()).setScore(Integer.parseInt(args[0])); + Log.info("Gave " + args[0] + " points to player " + player.name); + } catch (Exception e) { + Log.info("An error occured while executing the command"); + e.printStackTrace(); + } + }); + + handler.register("restart", "now actually works", (args) -> { + Groups.player.each(p -> p.kick("[scarlet]Server is restarting")); + Log.info("Server is restarting"); + System.exit(0); + }); + + handler.register("setstage","" ,"Sets rvsb stage", (args) -> { + try { + stage = Integer.parseInt(args[0]); + } catch (Exception e) { + Log.info("Failed to set stage"); + } + }); + + + handler.register("autorestart", " ", "self explanatory", (args) -> { + try { + if (args[0].trim().contains("yes")) { + Log.info("Games until restart: "+Integer.parseInt(args[1])); + gamesUntilRestart = Integer.parseInt(args[1]); + } else { + Log.info("Autorestart disabled"); + gamesUntilRestart = 2000000; + } + } catch (Exception e) { + Log.info("A mysterious error has appeared while executing the command"); + } + }); + } public static void gameOverCheck() { int blueUnitCount = 0; @@ -522,6 +709,18 @@ public static void gameOverCheck() { } public static void gameOver(Team winner) { + Events.fire("rvsb_game_over:" + winner.name); + + Groups.player.each(p -> { + PlayerData data = players.get(p.uuid()); + if (!(data == null)) { + data.setUnit(null); + data.setExp(0); + data.setLevel(1); + data.setScore(0); + } + }); + if (winner == Team.crux) { if (playing) { RedVsBluePlugin.playing = false; diff --git a/src/main/java/net/voiddustry/redvsblue/admin/Admin.java b/src/main/java/net/voiddustry/redvsblue/admin/Admin.java index 5674759f..27af7c39 100644 --- a/src/main/java/net/voiddustry/redvsblue/admin/Admin.java +++ b/src/main/java/net/voiddustry/redvsblue/admin/Admin.java @@ -10,6 +10,10 @@ public class Admin { public static void openAdminPanelMenu(Player player) { int menu = Menus.registerMenu((playerInMenu, option) -> { + if (option < 0) { + return; + } + switch (option) { case 0 -> Boss.spawnBoss(Utils.getRandomPlayer(Team.crux)); } diff --git a/src/main/java/net/voiddustry/redvsblue/evolution/Evolution.java b/src/main/java/net/voiddustry/redvsblue/evolution/Evolution.java index f5122174..9e81303c 100644 --- a/src/main/java/net/voiddustry/redvsblue/evolution/Evolution.java +++ b/src/main/java/net/voiddustry/redvsblue/evolution/Evolution.java @@ -7,69 +7,71 @@ public enum Evolution { - DAGGER(UnitTypes.dagger, 1, 2*multp, new String[] { "atrax", "mace", "elude", "flare", "nova", "mono" }), - NOVA(UnitTypes.nova, 1, 3*multp, new String[] { "pulsar", "elude", "flare", "dagger", "mono" }), - ELUDE(UnitTypes.elude, 1, 10*multp, new String[] { "atrax", "nova", "flare", "dagger", "mono" }), - FLARE(UnitTypes.flare, 1, 6*multp, new String[] { "risso", "nova", "elude", "dagger", "mono" }), - MONO(UnitTypes.mono, 1, 5*multp, new String[] { "poly", "nova", "elude", "dagger" }), - - PULSAR(UnitTypes.pulsar, 2, 25*multp, new String[] { "quasar" }), - ATRAX(UnitTypes.atrax, 2, 18*multp, new String[] { "cleroi" }), - RISSO(UnitTypes.risso, 2, 45*multp, new String[] { "zenith" }), - POLY(UnitTypes.poly, 2, 21*multp, new String[] { "retusa" }), - - MACE(UnitTypes.mace, 3, 20*multp, new String[] { "fortress"}), - QUASAR(UnitTypes.quasar, 3, 60*multp, new String[] { "vela" }), - CLEROI(UnitTypes.cleroi, 3, 65*multp, new String[] { "spiroct" }), - ZENITH(UnitTypes.zenith, 3, 70*multp, new String[] { "minke" }), - RETUSA(UnitTypes.retusa, 3, 15*multp, new String[] { "oxynoe" }), - - FORTRESS(UnitTypes.fortress, 4, 48*multp, new String[] { "locus" }), - VELA(UnitTypes.vela, 4, 170*multp, new String[] { "corvus" }), - SPIROCT(UnitTypes.spiroct, 4, 95*multp, new String[] { "toxopid" }), - MINKE(UnitTypes.minke, 4, 90*multp, new String[] { "avert" }), - OXYNOE(UnitTypes.oxynoe, 4, 35*multp, new String[] { "mega" }), - - LOCUS(UnitTypes.locus, 5, 55*multp, new String[] { "precept" }), - CORVUS(UnitTypes.corvus, 5, 300*multp, new String[] { "aegires" }), - MEGA(UnitTypes.mega, 5, 100*multp, new String[] { "cyerce" }), - - PRECEPT(UnitTypes.precept, 6, 60*multp, new String[] { "scepter" }), - AEGIRES(UnitTypes.aegires, 6, 450*multp, new String[] { "navanax" }), - AVERT(UnitTypes.avert, 6, 27*multp, new String[] { "bryde" }), - CYERCE(UnitTypes.cyerce, 6, 150*multp, new String[] { "quad" }), - - SCEPTER(UnitTypes.scepter, 7, 105*multp, new String[] { "vanquish" }), - NAVANAX(UnitTypes.navanax, 7, 450*multp, new String[] { "flare", "elude", "dagger" }), - TOXOPID(UnitTypes.toxopid, 7, 415*multp, new String[] { "collaris" }), - BRYDE(UnitTypes.bryde, 7, 180*multp, new String[] { "antumbra", "obviate" }), - QUAD(UnitTypes.quad, 7, 450*multp, new String[] { "oct" }), - - VANQUISH(UnitTypes.vanquish, 8, 250*multp, new String[] { "reign" }), - COLLARIS(UnitTypes.collaris, 8, 1170*multp, new String[] { "nova", "flare", "dagger", "mono" }), - ANTUMBRA(UnitTypes.antumbra, 8, 180*multp, new String[] { "eclipse" }), - OBVIATE(UnitTypes.obviate, 8, 90*multp, new String[] { "quell" }), - OCT(UnitTypes.oct, 8, 1500*multp, new String[] { "elude", "nova", "flare", "dagger" }), - - REIGN(UnitTypes.reign, 9, 450*multp, new String[] { "conquer" }), - ECLIPSE(UnitTypes.eclipse, 9, 270*multp, new String[] { "sei" }), - QUELL(UnitTypes.quell, 9, 180*multp, new String[] { "disrupt" }), - - CONQUER(UnitTypes.conquer, 10, 450*multp, new String[] { "elude", "nova", "flare", "mono" }), - SEI(UnitTypes.sei, 10, 270*multp, new String[] { "omura" }), - DISRUPT(UnitTypes.disrupt, 10, 800*multp, new String[] { "nova", "flare", "dagger"}), - - OMURA(UnitTypes.omura, 11, 1650*multp, new String[] { "elude", "nova", "dagger", "mono" }); + DAGGER(UnitTypes.dagger, 1, 2*multp, new String[] { "atrax", "mace", "merui", "flare", "nova", "mono" }, 1), + NOVA(UnitTypes.nova, 1, 3*multp, new String[] { "pulsar", "merui", "flare", "dagger", "mono" }, 1), + MERUI(UnitTypes.merui, 1, 8*multp, new String[] { "atrax", "nova", "flare", "dagger", "mono" }, 1), + FLARE(UnitTypes.flare, 1, 6*multp, new String[] { "risso", "nova", "merui", "dagger", "mono" }, 1), + MONO(UnitTypes.mono, 1, 5*multp, new String[] { "poly", "nova", "merui", "dagger" }, 1), + + PULSAR(UnitTypes.pulsar, 2, 25*multp, new String[] { "quasar" }, 2), + ATRAX(UnitTypes.atrax, 2, 18*multp, new String[] { "cleroi" }, 2), + RISSO(UnitTypes.risso, 2, 45*multp, new String[] { "zenith" }, 3), + POLY(UnitTypes.poly, 2, 21*multp, new String[] { "retusa" }, 2), + + MACE(UnitTypes.mace, 3, 20*multp, new String[] { "fortress"}, 2), + QUASAR(UnitTypes.quasar, 3, 60*multp, new String[] { "vela" }, 3), + CLEROI(UnitTypes.cleroi, 3, 65*multp, new String[] { "spiroct" }, 3), + ZENITH(UnitTypes.zenith, 3, 70*multp, new String[] { "minke" }, 3), + RETUSA(UnitTypes.retusa, 3, 15*multp, new String[] { "oxynoe" }, 3), + + FORTRESS(UnitTypes.fortress, 4, 48*multp, new String[] { "locus" }, 2), + VELA(UnitTypes.vela, 4, 170*multp, new String[] { "corvus" }, 6), + SPIROCT(UnitTypes.spiroct, 4, 95*multp, new String[] { "toxopid" }, 4), + MINKE(UnitTypes.minke, 4, 90*multp, new String[] { "avert" }, 3), + OXYNOE(UnitTypes.oxynoe, 4, 35*multp, new String[] { "mega" }, 3), + + LOCUS(UnitTypes.locus, 5, 55*multp, new String[] { "precept" }, 4), + CORVUS(UnitTypes.corvus, 5, 300*multp, new String[] { "aegires" }, 7), + MEGA(UnitTypes.mega, 5, 100*multp, new String[] { "cyerce" }, 4), + + PRECEPT(UnitTypes.precept, 6, 60*multp, new String[] { "scepter" }, 5), + AEGIRES(UnitTypes.aegires, 6, 450*multp, new String[] { "navanax" }, 8), + AVERT(UnitTypes.avert, 6, 27*multp, new String[] { "bryde" , "obviate" }, 4), + CYERCE(UnitTypes.cyerce, 6, 150*multp, new String[] { "quad" }, 5), + + SCEPTER(UnitTypes.scepter, 7, 105*multp, new String[] { "vanquish" }, 6), + NAVANAX(UnitTypes.navanax, 7, 450*multp, new String[] { "flare", "merui", "dagger" }, 9), + TOXOPID(UnitTypes.toxopid, 7, 415*multp, new String[] { "collaris" }, 7), + BRYDE(UnitTypes.bryde, 7, 180*multp, new String[] { "antumbra" }, 5), + OBVIATE(UnitTypes.obviate, 7, 90*multp, new String[] { "quell" }, 5), + QUAD(UnitTypes.quad, 7, 450*multp, new String[] { "oct" }, 7), + + VANQUISH(UnitTypes.vanquish, 8, 250*multp, new String[] { "reign" }, 6), + COLLARIS(UnitTypes.collaris, 8, 1170*multp, new String[] { "nova", "flare", "dagger", "mono" }, 7), + ANTUMBRA(UnitTypes.antumbra, 8, 180*multp, new String[] { "eclipse" }, 6), + OCT(UnitTypes.oct, 8, 1500*multp, new String[] { "merui", "nova", "flare", "dagger" }, 9), + QUELL(UnitTypes.quell, 8, 180*multp, new String[] { "disrupt" }, 6), + + REIGN(UnitTypes.reign, 9, 450*multp, new String[] { "conquer" }, 7), + ECLIPSE(UnitTypes.eclipse, 9, 270*multp, new String[] { "sei" }, 6), + DISRUPT(UnitTypes.disrupt, 9, 800*multp, new String[] { "nova", "flare", "dagger"}, 8), + + + CONQUER(UnitTypes.conquer, 10, 450*multp, new String[] { "merui", "nova", "flare", "mono" }, 7), + SEI(UnitTypes.sei, 10, 270*multp, new String[] { "omura" }, 8), + + OMURA(UnitTypes.omura, 11, 1650*multp, new String[] { "merui", "nova", "dagger", "mono" }, 9); public final UnitType unitType; - public final int tier, cost; + public final int tier, cost, stage; public final String[] evolutions; - Evolution(mindustry.type.UnitType unitType, int tier, int cost, String[] evolutions) { + Evolution(mindustry.type.UnitType unitType, int tier, int cost, String[] evolutions, int stage) { this.unitType = unitType; this.tier = tier; this.cost = cost; this.evolutions = evolutions; + this.stage = stage; } } diff --git a/src/main/java/net/voiddustry/redvsblue/evolution/Evolutions.java b/src/main/java/net/voiddustry/redvsblue/evolution/Evolutions.java index eb93fc18..1d645311 100644 --- a/src/main/java/net/voiddustry/redvsblue/evolution/Evolutions.java +++ b/src/main/java/net/voiddustry/redvsblue/evolution/Evolutions.java @@ -8,7 +8,7 @@ public class Evolutions { public final static ObjectMap evolutions = ObjectMap.of( "dagger", Evolution.DAGGER, "nova", Evolution.NOVA, - "elude", Evolution.ELUDE, + "merui", Evolution.MERUI, "flare", Evolution.FLARE, "mono", Evolution.MONO, @@ -32,7 +32,7 @@ public class Evolutions { "locus", Evolution.LOCUS, "corvus", Evolution.CORVUS, - "elude", Evolution.ELUDE, + "merui", Evolution.MERUI, "mega", Evolution.MEGA, "precept", Evolution.PRECEPT, diff --git a/src/main/java/net/voiddustry/redvsblue/game/building/BlocksType.java b/src/main/java/net/voiddustry/redvsblue/game/building/BlocksType.java deleted file mode 100644 index 6927c819..00000000 --- a/src/main/java/net/voiddustry/redvsblue/game/building/BlocksType.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.voiddustry.redvsblue.game.building; - -import mindustry.world.Block; - -public class BlocksType { - public String name; - public Block block; - public int cost; - public String color; - - public BlocksType(String name, Block block, int cost, String color) { - this.name = name; - this.block = block; - this.cost = cost; - this.color = color; - } -} diff --git a/src/main/java/net/voiddustry/redvsblue/game/building/BlocksTypes.java b/src/main/java/net/voiddustry/redvsblue/game/building/BlocksTypes.java deleted file mode 100644 index bb63629b..00000000 --- a/src/main/java/net/voiddustry/redvsblue/game/building/BlocksTypes.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.voiddustry.redvsblue.game.building; - -import mindustry.content.Blocks; - -public class BlocksTypes { - - public static BlocksType - berylliumWall, berylliumWallLarge, thoriumWall, thoriumWallLarge, doorLarge, drill, laserDrill, powerNode, battery, combustion, rtg, repair, pump; - - - public static void load() { - berylliumWall = new BlocksType("Beryllium Wall", Blocks.berylliumWall, 2, "[#3a8f64]"); - berylliumWallLarge = new BlocksType("Large Beryllium Wall", Blocks.berylliumWallLarge, 8, "[#3a8f64]"); - - thoriumWall = new BlocksType("Thoruim Wall", Blocks.thoriumWall, 3, "[#f9a3c7]"); - thoriumWallLarge = new BlocksType("Large Thorium Wall", Blocks.thoriumWallLarge, 12, "[#f9a3c7]"); - - doorLarge = new BlocksType("Large Door", Blocks.blastDoor, 16, "[#768a9a]"); - - drill = new BlocksType("Pneumatic Drill", Blocks.pneumaticDrill, 3, "[#989AA4]"); - laserDrill = new BlocksType("Laser Drill", Blocks.laserDrill, 25, "[#665C9F]"); - - powerNode = new BlocksType("Power Node", Blocks.powerNode, 2, "[#fbd267]"); - battery = new BlocksType("Battery", Blocks.battery, 5, "[#fbd267]"); - combustion = new BlocksType("Combustion Generator", Blocks.combustionGenerator, 8, "[#F1BE6B]"); - rtg = new BlocksType("RTG", Blocks.rtgGenerator, 20, "[#8A73C6]"); - - repair = new BlocksType("Mender", Blocks.mender, 8, "[#84F490]"); - pump = new BlocksType("Pump", Blocks.mechanicalPump, 6, "[#8F665B]"); - - } -} diff --git a/src/main/java/net/voiddustry/redvsblue/game/building/BuildBlock.java b/src/main/java/net/voiddustry/redvsblue/game/building/BuildBlock.java deleted file mode 100644 index 41c42eb1..00000000 --- a/src/main/java/net/voiddustry/redvsblue/game/building/BuildBlock.java +++ /dev/null @@ -1,172 +0,0 @@ -package net.voiddustry.redvsblue.game.building; - -import arc.util.Timer; -import mindustry.Vars; -import mindustry.content.Blocks; -import mindustry.game.Team; -import mindustry.gen.Call; -import mindustry.gen.Groups; -import mindustry.gen.Player; -import mindustry.world.Tile; -import net.voiddustry.redvsblue.Bundle; - -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; - -import static net.voiddustry.redvsblue.RedVsBluePlugin.*; - -public class BuildBlock { - public static Map buildQueue = new ConcurrentHashMap<>(); - - public static void init() { - Timer.schedule(() -> { - buildQueue.forEach(((buildTicket, remove) -> { - if (playing && buildTicket.player() != null) { - Player player = buildTicket.player(); - Tile position; - if (player.mouseX >= 0 && player.mouseX <= (Vars.state.map.width - 1) * 8 && player.mouseY >= 0 && player.mouseY <= (Vars.state.map.height - 1) * 8) { - position = Vars.world.tile(Math.round(player.mouseX / 8), Math.round(player.mouseY / 8)); - - boolean canBuild; - String text = "[gray][ ]"; - - if (position.block().isAir()) { - canBuild = true; - - switch (buildTicket.block().size) { - case 1 -> { - for (Player p : Groups.player) { - if (p.dst(position.x*8, position.y*8) <= 16) { - canBuild = false; - } - } - if (canBuild) { - drawCursor(player, position, 1, text); - } - } - - case 2 -> { - int centerX = position.x; - int centerY = position.y; - - for (Player p : Groups.player) { - if (p.dst(centerX*8, centerY*8) <= 16) { - canBuild = false; - } - } - - for (int x = 0; x <= 1; x++) { - for (int y = 0; y <= 1; y++) { - if (Vars.world.tile(centerX + x, centerY + y) != null && Vars.world.tile(centerX + x, centerY + y).block() != Blocks.air) { - canBuild = false; - } - } - } - if (canBuild) { - drawCursor(player, position, 2, text); - } - } - case 3 -> { - int centerX = position.x; - int centerY = position.y; - - for (Player p : Groups.player) { - if (p.dst(centerX*8, centerY*8) <= 24) { - canBuild = false; - } - } - - for (int x = -1; x <= 1; x++) { - for (int y = -1; y <= 1; y++) { - if (Vars.world.tile(centerX + x, centerY + y) != null && Vars.world.tile(centerX + x, centerY + y).block() != Blocks.air) { - canBuild = false; - } - } - } - drawCursor(player, position, 3, text); - } - } - - if (players.get(player.uuid()).getScore() < buildTicket.cost()) { - text = Bundle.get("build.not-enough-money", player.locale); - canBuild = false; - drawCursor(player, position, buildTicket.block().size, text); - } - - if (player.shooting && canBuild) { - build(buildTicket, position); - players.get(player.uuid()).subtractScore(buildTicket.cost()); - removeTicket(buildTicket); - if (!buildTicket.single()) { - add(buildTicket); - } - } - } - } - } - })); - }, 0, .09F); - } - - public static void add(BuildTicket buildEntry) { - buildQueue.put(buildEntry, false); - } - - public static void build(BuildTicket buildTicket, Tile position) { - Call.constructFinish(position, buildTicket.block(), null, (byte) 0, Team.blue, null); - } - - public static void removeTicket(BuildTicket buildTicket) { - buildQueue.remove(buildTicket); - } - - public static void clear() { - buildQueue.clear(); - } - - public static void findAndRemove(Player player) { - buildQueue.forEach(((buildTicket, remove) -> { - if (buildTicket.player() == player) { - removeTicket(buildTicket); - } - })); - } - - public static void drawCursor(Player player, Tile position, Integer size, String text) { - switch (size) { - case 1 -> Call.label(player.con, text, 0.01F, (float) ((Math.round(player.mouseX / 8)) * 8), (float) ((Math.round(player.mouseY / 8)) * 8)); - - case 2 -> { - float centerX = position.x * 8; - float centerY = position.y * 8; - - float centerTextX = (position.x + (float) 0.5); - float centerTextY = (position.y + (float) 0.5); - if (Objects.equals(text, Bundle.get("build.not-enough-money", player.locale))) { - Call.label(player.con, text, 0.01F, centerTextX * 8, centerTextY * 8); - } - for (int x = 0; x <= 1; x++) { - for (int y = 0; y <= 1; y++) { - Call.label(player.con, "[orange]#", 0.09F, centerX + x * 8, centerY + y * 8); - } - } - } - - case 3 -> { - int centerX = position.x * 8; - int centerY = position.y * 8; - - for (int x = -1; x <= 1; x++) { - for (int y = -1; y <= 1; y++) { - if (x == 0 && y == 0) { - Call.label(player.con, text, 0.01F, (float) ((Math.round(player.mouseX / 8)) * 8), (float) ((Math.round(player.mouseY / 8)) * 8)); - } else { - Call.label(player.con, "[orange]#", 0.01F, centerX + x * 8, centerY + y * 8); - } - } - } - } - } - } -} diff --git a/src/main/java/net/voiddustry/redvsblue/game/building/BuildMenu.java b/src/main/java/net/voiddustry/redvsblue/game/building/BuildMenu.java deleted file mode 100644 index d2bba847..00000000 --- a/src/main/java/net/voiddustry/redvsblue/game/building/BuildMenu.java +++ /dev/null @@ -1,129 +0,0 @@ -package net.voiddustry.redvsblue.game.building; - -import mindustry.gen.Call; -import mindustry.gen.Player; - -import mindustry.net.NetConnection; -import mindustry.ui.Menus; -import net.voiddustry.redvsblue.Bundle; - -import java.util.HashMap; -import java.util.Map; - -public class BuildMenu { - - private static final Map selectedBlock = new HashMap<>(); - private static final Map singleBlock = new HashMap<>(); - - public static void openMenu(Player player) { - if (player != null) { - if (!selectedBlock.containsKey(player)) { - selectedBlock.put(player, BlocksTypes.berylliumWall); - singleBlock.put(player, true); - } - - int menu = Menus.registerMenu(((player1, option) -> { - switch (option) { - case 1 -> { - if (singleBlock.get(player)) { - singleBlock.put(player, false); - } else { - singleBlock.put(player, true); - } - openMenu(player); - } - case 3 -> BuildBlock.add(new BuildTicket(player, selectedBlock.get(player).block, singleBlock.get(player), false, selectedBlock.get(player).cost)); - case 4 -> BuildBlock.findAndRemove(player); - - case 5 -> { - selectedBlock.put(player, BlocksTypes.berylliumWall); - openMenu(player); - } - case 6 -> { - selectedBlock.put(player, BlocksTypes.berylliumWallLarge); - openMenu(player); - } - case 7 -> { - selectedBlock.put(player, BlocksTypes.thoriumWall); - openMenu(player); - } - case 8 -> { - selectedBlock.put(player, BlocksTypes.thoriumWallLarge); - openMenu(player); - } - case 9 -> { - selectedBlock.put(player, BlocksTypes.doorLarge); - openMenu(player); - } - case 10 -> { - selectedBlock.put(player, BlocksTypes.drill); - openMenu(player); - } - case 11 -> { - selectedBlock.put(player, BlocksTypes.laserDrill); - openMenu(player); - } - case 12 -> { - selectedBlock.put(player, BlocksTypes.powerNode); - openMenu(player); - } - case 13 -> { - selectedBlock.put(player, BlocksTypes.battery); - openMenu(player); - } - case 14 -> { - selectedBlock.put(player, BlocksTypes.combustion); - openMenu(player); - } - case 15 -> { - selectedBlock.put(player, BlocksTypes.rtg); - openMenu(player); - } - case 16 -> { - selectedBlock.put(player, BlocksTypes.repair); - openMenu(player); - } - case 17 -> { - selectedBlock.put(player, BlocksTypes.pump); - openMenu(player); - } - } - })); - - BlocksType sBlock = selectedBlock.get(player); - - String text = Bundle.format("menu.build.text", Bundle.findLocale(player.locale), sBlock.color, sBlock.name, sBlock.block.health, sBlock.cost); - - String[][] buttons = { - { - "[gray][ [cyan]<- [gray]]", - (singleBlock.get(player))? "[lime]" + Bundle.get("menu.build.single", player.locale) : "[scarlet]" + Bundle.get("menu.build.single", player.locale), - "[gray][ [cyan]-> [gray]]", - - }, - { - Bundle.get("menu.build.build", player.locale), - Bundle.get("menu.build.cancel", player.locale), - }, - {BlocksTypes.berylliumWall.color + BlocksTypes.berylliumWall.name}, - {BlocksTypes.berylliumWallLarge.color + BlocksTypes.berylliumWallLarge.name}, - {BlocksTypes.thoriumWall.color + BlocksTypes.thoriumWallLarge.name}, - {BlocksTypes.thoriumWallLarge.color + BlocksTypes.thoriumWallLarge.name}, - {BlocksTypes.doorLarge.color + BlocksTypes.doorLarge.name}, - {BlocksTypes.drill.color + BlocksTypes.drill.name}, - {BlocksTypes.laserDrill.color + BlocksTypes.laserDrill.name}, - {BlocksTypes.powerNode.color + BlocksTypes.powerNode.name}, - {BlocksTypes.battery.color + BlocksTypes.battery.name}, - {BlocksTypes.combustion.color + BlocksTypes.combustion.name}, - {BlocksTypes.rtg.color + BlocksTypes.rtg.name}, - {BlocksTypes.repair.color + BlocksTypes.repair.name}, - {BlocksTypes.pump.color + BlocksTypes.pump.name} - }; - menu(player.con, menu, text, buttons); - } - } - - private static void menu(NetConnection connection, int menu, String text, String[][] buttons) { - Call.menu(connection, menu, Bundle.get("menu.build.title", connection.player.locale), text, buttons); - } -} diff --git a/src/main/java/net/voiddustry/redvsblue/game/building/BuildTicket.java b/src/main/java/net/voiddustry/redvsblue/game/building/BuildTicket.java deleted file mode 100644 index 04543881..00000000 --- a/src/main/java/net/voiddustry/redvsblue/game/building/BuildTicket.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.voiddustry.redvsblue.game.building; - -import mindustry.gen.Player; -import mindustry.world.Block; - -public record BuildTicket(Player player, Block block, Boolean single, Boolean station, int cost) {} diff --git a/src/main/java/net/voiddustry/redvsblue/game/building/BuildingsInspector.java b/src/main/java/net/voiddustry/redvsblue/game/building/BuildingsInspector.java deleted file mode 100644 index 482f9935..00000000 --- a/src/main/java/net/voiddustry/redvsblue/game/building/BuildingsInspector.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.voiddustry.redvsblue.game.building; - -public class BuildingsInspector { - -} diff --git a/src/main/java/net/voiddustry/redvsblue/game/building/UpdateConstructBlocks.java b/src/main/java/net/voiddustry/redvsblue/game/building/UpdateConstructBlocks.java new file mode 100644 index 00000000..c35f1849 --- /dev/null +++ b/src/main/java/net/voiddustry/redvsblue/game/building/UpdateConstructBlocks.java @@ -0,0 +1,101 @@ +package net.voiddustry.redvsblue.game.building; + +import java.lang.Math; +import java.lang.Runnable; +import arc.util.Timer; +import java.util.HashMap; +import java.util.WeakHashMap; +import arc.*; +import arc.util.*; +import arc.struct.Seq; +import arc.math.geom.QuadTree.*; +import mindustry.*; +import mindustry.world.Tile; +import mindustry.world.blocks.payloads.*; +import mindustry.world.blocks.*; +import mindustry.world.Block; +import mindustry.Vars; +import mindustry.game.Rules; +import mindustry.content.*; +import mindustry.type.Item; +import mindustry.type.ItemStack; +import mindustry.game.EventType.*; +import mindustry.gen.*; +import mindustry.gen.Call; +import mindustry.game.Team; +import mindustry.mod.*; +import mindustry.net.Administration.*; +import mindustry.content.Blocks; +import mindustry.entities.units.BuildPlan; +import mindustry.type.Category; + +import net.voiddustry.redvsblue.RedVsBluePlugin; +import net.voiddustry.redvsblue.game.stations.*; + + +// updates construct blocks instead of the game doing it, original in usurvplugin +public class UpdateConstructBlocks implements Runnable { + @Override + public void run() { + try { + + for (Unit u : Groups.unit) { + if (u.team == Team.blue && u.buildPlan() != null) { + if (u.buildPlan().worldContext) { + if (u.isBuilding()) { + BuildPlan bp = u.buildPlan(); + + int cost = 0; + Tile tile = Vars.world.tile(bp.x,bp.y); + + for(int i = 0; i < bp.block.requirements.length; i++){ + if (bp.block.requirements[i].item==Items.dormantCyst) { + cost = bp.block.requirements[i].amount; + break; + } + } + + if (u.getPlayer() != null && u.buildPlan().placeable(Team.blue) && u.dst(bp.x*8,bp.y*8)=cost && cost!=0) { + //Log.info("finishing construction"); + if (bp.block.category == Category.logic) { + if (bp.block == Blocks.pulverizer) { + Miner.buyMiner(player, tile); + } else if (bp.block == Blocks.mender) { + RepairPoint.buyRepairPoint(player, tile); + } else if (bp.block == Blocks.phaseWall) { + SuppressorTower.buyTower(player, tile); + } else if (bp.block == Blocks.radar) { + ArmorWorkbench.buyWorkbench(player, tile); + } else if (bp.block == Blocks.carbideWall) { + Laboratory.buyLab(player, tile); + } else if (bp.block == Blocks.beamNode) { + Booster.buyBooster(player, tile); + } else if (bp.block == Blocks.slagIncinerator) { + Recycler.buyRecycler(player, tile); + } + } else { + RedVsBluePlugin.players.get(player.uuid()).subtractScore(cost); + Call.constructFinish(tile,bp.block,null,(byte)bp.rotation,player.team(),bp.config); + tile.build.placed(); + } + } else { + if (tile.block() instanceof ConstructBlock cb) { + tile.setNet(Blocks.air,Team.derelict,0); + } + } + } + } + } + } + } + } + } catch (Exception e) { + Log.info("goofy ahh exception in the building system"); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/net/voiddustry/redvsblue/game/crux/BossChooseMenu.java b/src/main/java/net/voiddustry/redvsblue/game/crux/BossChooseMenu.java index 904b8d25..fe41229d 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/crux/BossChooseMenu.java +++ b/src/main/java/net/voiddustry/redvsblue/game/crux/BossChooseMenu.java @@ -18,6 +18,9 @@ public static void openMenu(Player player) { PlayerData data = RedVsBluePlugin.players.get(player.uuid()); int menu = Menus.registerMenu(((player1, option) -> { + if (option < 0) { + return; + } switch (option) { case 0 -> data.setSelectedBoss(UnitTypes.mace); diff --git a/src/main/java/net/voiddustry/redvsblue/game/crux/ClassChooseMenu.java b/src/main/java/net/voiddustry/redvsblue/game/crux/ClassChooseMenu.java index 0acda923..a8761d09 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/crux/ClassChooseMenu.java +++ b/src/main/java/net/voiddustry/redvsblue/game/crux/ClassChooseMenu.java @@ -31,8 +31,12 @@ public static void openMenu(Player player) { }); int menu = Menus.registerMenu((playerInMenu, option) -> { - selectedUnit.put(player.uuid(), unitsNumbers[option]); - CruxUnit.callSpawn(player); + if (option < 0 || option >= unitsNumbers.length) { + return; + } + + selectedUnit.put(playerInMenu.uuid(), unitsNumbers[option]); + CruxUnit.callSpawn(playerInMenu); }); Call.menu(player.con, menu, Bundle.get("units.crux.menu.title", player.locale), "", unitsBundleKeys); @@ -48,8 +52,8 @@ public static void updateUnitsMap() { case 6 -> units.putAll(StageUnits.sixthStage); case 7 -> units.putAll(StageUnits.sevenStage); case 8,9 -> units.putAll(StageUnits.eighthAndNinthStage); - case 10,11 -> units.putAll(StageUnits.tenthStage); + case 10 -> units.putAll(StageUnits.tenthStage); + case 11,12 -> units.putAll(StageUnits.eleventhStage); } } } - diff --git a/src/main/java/net/voiddustry/redvsblue/game/crux/CruxUnit.java b/src/main/java/net/voiddustry/redvsblue/game/crux/CruxUnit.java index 9db8827d..38538f33 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/crux/CruxUnit.java +++ b/src/main/java/net/voiddustry/redvsblue/game/crux/CruxUnit.java @@ -1,10 +1,13 @@ package net.voiddustry.redvsblue.game.crux; import arc.util.Timer; +import arc.Events; +import mindustry.Vars; import mindustry.content.Items; import mindustry.content.StatusEffects; import mindustry.content.UnitTypes; import mindustry.game.Team; +import mindustry.game.EventType; import mindustry.gen.Call; import mindustry.gen.Groups; import mindustry.gen.Player; @@ -14,7 +17,20 @@ import net.voiddustry.redvsblue.RedVsBluePlugin; import net.voiddustry.redvsblue.util.Utils; +import java.util.Random; +import java.util.HashMap; +import java.lang.Math; + public class CruxUnit { + + private static final HashMap spawnTimes = new HashMap<>(); + + public static void addEvent() { + Events.on(EventType.UnitDestroyEvent.class, event -> { + spawnTimes.remove(event.unit); + }); + } + public static void callSpawn(Player player) { UnitType type = ClassChooseMenu.selectedUnit.get(player.uuid()); @@ -31,6 +47,17 @@ public static void callSpawn(Player player) { unit.health = Integer.MAX_VALUE; unit.apply(StatusEffects.overclock, 180);; + //unit.apply(Vars.content.statusEffect("superShielded"), 120f); + unit.apply(Vars.content.statusEffect("shielded"), 300f); + + if (unit.type == UnitTypes.obviate) { + if (RedVsBluePlugin.stage == 11) { + unit.apply(StatusEffects.shielded, 600f); + unit.apply(StatusEffects.overdrive, 99999f); + unit.apply(StatusEffects.fast, 99999f); + } + } + Timer.schedule(() -> { if (unit.type == UnitTypes.crawler) { unit.health = 20; @@ -59,13 +86,54 @@ private static void spawnCrux() { if (!ClassChooseMenu.units.isEmpty()) { unitType = ClassChooseMenu.units.keys().toSeq().get(Utils.getRandomInt(0, ClassChooseMenu.units.size)); //Utils.getRandomInt(0, ClassChooseMenu.units.size) } + spawnCrux(unitType); + } + + private static void spawnCrux(UnitType unitType) { if (Utils.gameRun) { Tile cruxSpawn = RedVsBluePlugin.redSpawns.random(); if (cruxSpawn != null && cruxSpawn.block() != null) { Call.logicExplosion(Team.crux, cruxSpawn.x*8, cruxSpawn.y*8, 80, 999999, true, true, true, true); } + + if (RedVsBluePlugin.stage >= 11) { + + boolean s11BossDead = true; + + for (Unit u : Groups.unit) { + if (u.type==UnitTypes.evoke) { + s11BossDead = false; + } + } + + if (s11BossDead) { + Random rand = new Random(); + if (rand.nextInt(20) == 1) { + UnitTypes.latum.spawn(Team.crux, cruxSpawn); + } + if (rand.nextInt(13) == 1) { + UnitTypes.conquer.spawn(Team.crux, cruxSpawn); + } + if (rand.nextInt(7) == 1) { + UnitTypes.tecta.spawn(Team.crux, cruxSpawn); + } + } + } + Unit unit = unitType.spawn(Team.crux, cruxSpawn); + spawnTimes.put(unit, System.currentTimeMillis()); + + //unit.apply(Vars.content.statusEffect("superShielded"), 120f); + unit.apply(Vars.content.statusEffect("shielded"), 300f); + + if (unit.type == UnitTypes.obviate) { + if (RedVsBluePlugin.stage == 11) { + unit.apply(StatusEffects.shielded, 600f); + unit.apply(StatusEffects.overdrive, 99999f); + unit.apply(StatusEffects.fast, 99999f); + } + } Timer.schedule(() -> { if (unit.type == UnitTypes.crawler) { @@ -85,6 +153,7 @@ private static void spawnCrux() { } }; + public static void checkUnitCount() { if (Utils.gameRun) { int players = Groups.player.size(); @@ -92,25 +161,26 @@ public static void checkUnitCount() { int cruxUnitsCount = Math.round((players + stage) / (float) 3); - final int[] cruxUnits = {0}; - final int[] cruxPlayersWithUnits = {0}; - - Groups.player.each(p -> { - if (!(p.unit() == null)) { - if (p.unit().team == Team.crux) { - cruxPlayersWithUnits[0]++; + final HashMap cruxUnits = new HashMap<>(); + + if (!ClassChooseMenu.units.isEmpty()) { + ClassChooseMenu.units.keys().toSeq().each(type -> { + Groups.unit.each(u -> { + if (u.team == Team.crux && u.type == type) { + + if ((!(spawnTimes.get(u) == null)) && System.currentTimeMillis()-spawnTimes.get(u)<45000) { + if (cruxUnits.get(type) == null) { + cruxUnits.put(type, 0); + } else { + cruxUnits.put(type, cruxUnits.get(type)+1); + } + } + } + }); + if (cruxUnits.get(type) == null || cruxUnits.get(type) < cruxUnitsCount/ClassChooseMenu.units.keys().toSeq().size) { + spawnCrux(type); } - } - }); - - Groups.unit.each(u -> { - if (u.team == Team.crux) { - cruxUnits[0]++; - } - }); - - if (cruxUnitsCount > (cruxUnits[0]-cruxPlayersWithUnits[0])) { - spawnCrux(); + }); } } } diff --git a/src/main/java/net/voiddustry/redvsblue/game/crux/StageUnits.java b/src/main/java/net/voiddustry/redvsblue/game/crux/StageUnits.java index b8d3fae7..320b1668 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/crux/StageUnits.java +++ b/src/main/java/net/voiddustry/redvsblue/game/crux/StageUnits.java @@ -58,6 +58,11 @@ public class StageUnits { UnitTypes.precept, "units.crux.menu.precept" ); + public final static ObjectMap eleventhStage = ObjectMap.of( + UnitTypes.obviate, "units.crux.menu.obviate", + UnitTypes.vanquish, "units.crux.menu.vanquish" + ); + public final static ObjectMap bosses = ObjectMap.of( 2, UnitTypes.horizon, 3, UnitTypes.locus, @@ -68,6 +73,7 @@ public class StageUnits { 8, UnitTypes.tecta, 9, UnitTypes.vanquish, 10, UnitTypes.eclipse, - 11, UnitTypes.navanax + 11, UnitTypes.evoke, + 12, UnitTypes.navanax ); } diff --git a/src/main/java/net/voiddustry/redvsblue/game/starting_menu/StartingMenu.java b/src/main/java/net/voiddustry/redvsblue/game/starting_menu/StartingMenu.java index 5d490f3f..4aef391e 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/starting_menu/StartingMenu.java +++ b/src/main/java/net/voiddustry/redvsblue/game/starting_menu/StartingMenu.java @@ -25,6 +25,10 @@ public static void openMenu(Player player, int category) { NetConnection connection = player.con; if (canOpenMenu) { int menu = Menus.registerMenu((player1, option) -> { + if (option < 0) { + return; + } + if (option <= 3) { switch (option) { case 0 -> openMenu(player, 0); diff --git a/src/main/java/net/voiddustry/redvsblue/game/stations/ArmorWorkbench.java b/src/main/java/net/voiddustry/redvsblue/game/stations/ArmorWorkbench.java index 73809156..0b4342a1 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/stations/ArmorWorkbench.java +++ b/src/main/java/net/voiddustry/redvsblue/game/stations/ArmorWorkbench.java @@ -1,9 +1,9 @@ package net.voiddustry.redvsblue.game.stations; import arc.graphics.Color; -import arc.util.Timer; +import arc.util.*; import mindustry.Vars; -import mindustry.content.Blocks; +import mindustry.content.*; import mindustry.content.Fx; import mindustry.game.Team; import mindustry.gen.Call; @@ -54,7 +54,7 @@ public static void initTimer() { maxShield = p.unit().type.health/3; } else if (p.unit().type.health <= 290) { maxShield = p.unit().type.health*4; - } else if (p.unit().type.health >= 11000) { + } else if (p.unit().type == UnitTypes.aegires) { maxShield = p.unit().type.health/2; } @@ -62,6 +62,10 @@ public static void initTimer() { float finalMaxShield = maxShield; int menu = Menus.registerMenu((player, option) -> { + if (option < 0) { + return; + } + if (option == 0 && players.get(p.uuid()).getScore() >= 1 && p.unit().shield <= (int) finalMaxShield) { p.unit().shield = p.unit().shield + shieldPerPoint; players.get(p.uuid()).subtractScore(1); @@ -89,7 +93,7 @@ public static void initTimer() { Timer.schedule(ArmorWorkbench::renderWorkbenches, 0, 1); } - public static void buyWorkbench(Player player) { + public static void buyWorkbench(Player player, Tile tile) { if (players.get(player.uuid()).getScore() < 8) { player.sendMessage(Bundle.format("station.not-enough-money", Bundle.findLocale(player.locale), 8)); } else { @@ -97,12 +101,14 @@ public static void buyWorkbench(Player player) { if (!player.dead()) { Tile playerTileOn = player.tileOn(); Tile tileUnderPlayer = Vars.world.tile(playerTileOn.x, playerTileOn.y - 1); - - if (!player.dead() && player.team() == Team.blue && tileUnderPlayer.block().isAir()) { - StationData workbenchData = new StationData(player, tileUnderPlayer); + if (tile == null) { + tile = tileUnderPlayer; + } + if (!player.dead() && player.team() == Team.blue && tile.block().isAir()) { + StationData workbenchData = new StationData(player, tile); workbenches.put(player.uuid(), workbenchData); - Call.constructFinish(tileUnderPlayer, Blocks.radar, null, (byte) 0, Team.blue, null); - Call.effect(Fx.regenParticle, tileUnderPlayer.x * 8, tileUnderPlayer.y * 8, 0, Color.red); + Call.constructFinish(tile, Blocks.radar, null, (byte) 0, Team.blue, null); + Call.effect(Fx.regenParticle, tile.x * 8, tile.y * 8, 0, Color.red); players.get(player.uuid()).subtractScore(8); } } @@ -113,7 +119,7 @@ public static void buyWorkbench(Player player) { public static void renderWorkbenches() { workbenches.forEach((owner, workbench) -> { if (workbench != null) { - if (workbench.tileOn().block() == Blocks.air || workbench.owner().team() != Team.blue) { + if (workbench.tileOn().block() != Blocks.radar || workbench.owner().team() != Team.blue) { workbenches.remove(owner); if (workbench.tileOn().block() == Blocks.radar) { workbench.tileOn().build.kill(); diff --git a/src/main/java/net/voiddustry/redvsblue/game/stations/Booster.java b/src/main/java/net/voiddustry/redvsblue/game/stations/Booster.java index eda79af2..11aa7143 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/stations/Booster.java +++ b/src/main/java/net/voiddustry/redvsblue/game/stations/Booster.java @@ -46,7 +46,7 @@ public static void initTimer() { Timer.schedule(Booster::renderBoosters, 0, 1); } - public static void buyBooster(Player player) { + public static void buyBooster(Player player, Tile tile) { if (players.get(player.uuid()).getScore() < 18) { player.sendMessage(Bundle.format("station.not-enough-money", Bundle.findLocale(player.locale), 18)); } else { @@ -54,12 +54,15 @@ public static void buyBooster(Player player) { if (!player.dead()) { Tile playerTileOn = player.tileOn(); Tile tileUnderPlayer = Vars.world.tile(playerTileOn.x, playerTileOn.y - 1); + if (tile == null) { + tile = tileUnderPlayer; + } - if (!player.dead() && player.team() == Team.blue && tileUnderPlayer.block().isAir()) { - StationData boosterData = new StationData(player, tileUnderPlayer); + if (!player.dead() && player.team() == Team.blue && tile.block().isAir()) { + StationData boosterData = new StationData(player, tile); boostersMap.put(player.uuid(), boosterData); - Call.constructFinish(tileUnderPlayer, Blocks.beamNode, null, (byte) 0, Team.blue, null); - Call.effect(Fx.regenParticle, tileUnderPlayer.x*8, tileUnderPlayer.y*8, 0, Color.red); + Call.constructFinish(tile, Blocks.beamNode, null, (byte) 0, Team.blue, null); + Call.effect(Fx.regenParticle, tile.x*8, tile.y*8, 0, Color.red); players.get(player.uuid()).subtractScore(18); } } @@ -70,7 +73,7 @@ public static void buyBooster(Player player) { public static void renderBoosters() { boostersMap.forEach((owner, booster) -> { if (booster != null) { - if (booster.tileOn().block() == Blocks.air || booster.owner().team() != Team.blue) { + if (booster.tileOn().block() != Blocks.beamNode || booster.owner().team() != Team.blue) { boostersMap.remove(owner); if (booster.tileOn().block() == Blocks.beamNode) { booster.tileOn().build.kill(); diff --git a/src/main/java/net/voiddustry/redvsblue/game/stations/Laboratory.java b/src/main/java/net/voiddustry/redvsblue/game/stations/Laboratory.java index e4d87d4e..d000ad86 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/stations/Laboratory.java +++ b/src/main/java/net/voiddustry/redvsblue/game/stations/Laboratory.java @@ -1,8 +1,8 @@ package net.voiddustry.redvsblue.game.stations; - import arc.graphics.Color; import arc.util.Timer; +import arc.util.Log; import mindustry.Vars; import mindustry.content.Blocks; import mindustry.content.Fx; @@ -10,16 +10,23 @@ import mindustry.gen.*; import mindustry.ui.Menus; import mindustry.world.Tile; +import net.voiddustry.redvsblue.RedVsBluePlugin; import net.voiddustry.redvsblue.Bundle; import net.voiddustry.redvsblue.PlayerData; import net.voiddustry.redvsblue.evolution.Evolution; import net.voiddustry.redvsblue.evolution.Evolutions; import net.voiddustry.redvsblue.game.stations.stationData.StationData; import net.voiddustry.redvsblue.util.Utils; +import mindustry.graphics.Layer; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.lang.Math; +import java.time.Instant; +import java.math.BigDecimal; +import java.math.RoundingMode; + import static net.voiddustry.redvsblue.RedVsBluePlugin.players; @@ -29,13 +36,19 @@ public class Laboratory { public static final int evolutionMenu = Menus.registerMenu((player, option) -> { if (option == -1) return; + if (player.unit() == null || player.unit().type() == null) return; Evolution evolution = Evolutions.evolutions.get(player.unit().type().name); - Evolution evolutionOption = Evolutions.evolutions.get(evolution.evolutions[option]); + + if (evolution == null || option < 0 || option >= evolution.evolutions.length) return; + String selectedEvolution = evolution.evolutions[option]; + Evolution evolutionOption = Evolutions.evolutions.get(selectedEvolution); + if (evolutionOption == null) return; PlayerData playerData = players.get(player.uuid()); + if (playerData == null) return; - if (playerData.getScore() >= evolutionOption.cost) { - if (player.unit() != null && (player.tileOn().block() == Blocks.air || evolutionOption.unitType.flying==true || evolutionOption.unitType.canBoost == true)) { + if (playerData.getScore() >= ((int)(evolutionOption.cost*getMultiplier(evolutionOption, player)))) { + if (player.unit() != null && (player.tileOn().block() == Blocks.air || evolutionOption.unitType.flying==true || evolutionOption.unitType.canBoost == true || evolutionOption.unitType.groundLayer==Layer.legUnit)) { Unit unit = evolutionOption.unitType.spawn(Team.blue, player.x(), player.y()); unit.health = unit.type.health/2; @@ -46,10 +59,11 @@ public class Laboratory { player.unit(unit); oldUnit.kill(); - playerData.subtractScore(evolutionOption.cost); + playerData.subtractScore((int)(getMultiplier(evolutionOption, player)*evolutionOption.cost)); playerData.setEvolutionStage(evolutionOption.tier); + playerData.setLastEvolutionTime(Instant.now().getEpochSecond()); - Utils.sendBundled("game.evolved", player.name(), evolution.evolutions[option]); + Utils.sendBundled("game.evolved", player.name(), selectedEvolution); } } } @@ -77,13 +91,30 @@ public static void initTimer() { Evolution evolution = Evolutions.evolutions.get(p.unit().type().name); - String[][] buttons = new String[evolution.evolutions.length][1]; - - for (int i = 0; i < evolution.evolutions.length; i++) { - buttons[i][0] = Bundle.format("menu.evolution.evolve", locale, evolution.evolutions[i], Evolutions.evolutions.get(evolution.evolutions[i]).cost); + if (!(evolution == null)) { + + String[][] buttons = new String[evolution.evolutions.length][1]; + + for (int i = 0; i < evolution.evolutions.length; i++) { + float multiplier = getMultiplier(evolution.evolutions[i], p); + int cost = (int)(Evolutions.evolutions.get(evolution.evolutions[i]).cost*multiplier); + + String textColor = ""; + + if (multiplier > 1 && multiplier <= 1.99) { + textColor = "[orange]"; + } else if (cost>Evolutions.evolutions.get(evolution.evolutions[i]).cost) { + textColor = "[red]"; + } else if (cost stage) { + multiplier = multiplier+0.75f; + } else { + multiplier = multiplier+1+((float)Math.pow(2,stage-RedVsBluePlugin.stage)/4); + } + BigDecimal bd = new BigDecimal(String.valueOf(multiplier)); + bd = bd.setScale(3, RoundingMode.HALF_UP); + multiplier = bd.floatValue(); + return multiplier; + } + + public static float getMultiplier(String evolution, Player player) { + return getMultiplier(Evolutions.evolutions.get(evolution), player); + } + + public static void buyLab(Player player, Tile tile) { if (players.get(player.uuid()).getScore() < 7) { player.sendMessage(Bundle.format("station.not-enough-money", Bundle.findLocale(player.locale), 7)); } else { @@ -115,12 +171,15 @@ public static void buyLab(Player player) { if (!player.dead()) { Tile playerTileOn = player.tileOn(); Tile tileUnderPlayer = Vars.world.tile(playerTileOn.x, playerTileOn.y - 1); + if (tile == null) { + tile = tileUnderPlayer; + } - if (!player.dead() && player.team() == Team.blue && tileUnderPlayer.block().isAir()) { - StationData laboratoryData = new StationData(player, tileUnderPlayer); + if (!player.dead() && player.team() == Team.blue && tile.block().isAir()) { + StationData laboratoryData = new StationData(player, tile); labsMap.put(player.uuid(), laboratoryData); - Call.constructFinish(tileUnderPlayer, Blocks.carbideWall, null, (byte) 0, Team.blue, null); - Call.effect(Fx.regenParticle, tileUnderPlayer.x*8, tileUnderPlayer.y*8, 0, Color.red); + Call.constructFinish(tile, Blocks.carbideWall, null, (byte) 0, Team.blue, null); + Call.effect(Fx.regenParticle, tile.x*8, tile.y*8, 0, Color.red); players.get(player.uuid()).subtractScore(7); } } @@ -131,7 +190,7 @@ public static void buyLab(Player player) { public static void renderLabs() { labsMap.forEach((owner, lab) -> { if (lab != null) { - if (lab.tileOn().block() == Blocks.air || lab.owner().team() != Team.blue) { + if (lab.tileOn().block() != Blocks.carbideWall || lab.owner().team() != Team.blue) { labsMap.remove(owner); if (lab.tileOn().block() == Blocks.carbideWall) { lab.tileOn().build.kill(); diff --git a/src/main/java/net/voiddustry/redvsblue/game/stations/Miner.java b/src/main/java/net/voiddustry/redvsblue/game/stations/Miner.java index ab199822..34f1167e 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/stations/Miner.java +++ b/src/main/java/net/voiddustry/redvsblue/game/stations/Miner.java @@ -43,20 +43,23 @@ public static void initTimer() { Timer.schedule(Miner::renderMiners, 0, 1); } - public static void buyMiner(Player player) { - if (players.get(player.uuid()).getScore() < 20) { + public static void buyMiner(Player player, Tile tile) { + if ((!(players.get(player.uuid()) == null)) && players.get(player.uuid()).getScore() < 20) { player.sendMessage(Bundle.format("station.not-enough-money", 20)); } else { if (!minersMap.containsKey(player.uuid())) { if (!player.dead()) { Tile playerTileOn = player.tileOn(); Tile tileUnderPlayer = Vars.world.tile(playerTileOn.x, playerTileOn.y - 1); + if (tile == null) { + tile = tileUnderPlayer; + } - if (!player.dead() && player.team() == Team.blue && tileUnderPlayer.block().isAir()) { - MinerData minerData = new MinerData(player, tileUnderPlayer); + if (!player.dead() && player.team() == Team.blue && tile.block().isAir()) { + MinerData minerData = new MinerData(player, tile); minersMap.put(player.uuid(), minerData); - Call.constructFinish(tileUnderPlayer, Blocks.combustionGenerator, null, (byte) 0, Team.blue, null); - Call.effect(Fx.explosion, tileUnderPlayer.x*8, tileUnderPlayer.y*8, 5, Color.red); + Call.constructFinish(tile, Blocks.pulverizer, null, (byte) 0, Team.blue, null); + Call.effect(Fx.explosion, tile.x*8, tile.y*8, 5, Color.red); players.get(player.uuid()).subtractScore(20); } } @@ -67,9 +70,9 @@ public static void buyMiner(Player player) { public static void renderMiners() { minersMap.forEach((owner, miner) -> { if (miner != null) { - if (miner.getTileOn().block() == Blocks.air || miner.getOwner().team() != Team.blue) { + if (miner.getTileOn().block() != Blocks.pulverizer || miner.getOwner().team() != Team.blue) { minersMap.remove(owner, miner); - if (miner.getTileOn().block() == Blocks.combustionGenerator) { + if (miner.getTileOn().block() == Blocks.pulverizer) { miner.getTileOn().build.kill(); } } else { diff --git a/src/main/java/net/voiddustry/redvsblue/game/stations/Recycler.java b/src/main/java/net/voiddustry/redvsblue/game/stations/Recycler.java index 0b1452e4..aa51fc0b 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/stations/Recycler.java +++ b/src/main/java/net/voiddustry/redvsblue/game/stations/Recycler.java @@ -15,6 +15,9 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import mindustry.content.Items; +import mindustry.content.UnitTypes; + import static net.voiddustry.redvsblue.RedVsBluePlugin.players; public class Recycler { @@ -33,14 +36,16 @@ public static void initTimer() { StationUtils.drawStationName(pointData.tileOn(), text, 0.8F); Groups.player.each(p -> { - if (p.team() == Team.blue && p.unit() != null) { + if (p.team() == Team.blue && p.unit() != null && (!(players.get(p.uuid()) == null))) { if (p.dst(centerX, centerY) <= 32) { if (p.unit().stack.amount >= 20) { - int add = p.unit().stack.amount/20; - Utils.label(p.x, p.y, "[#023919]+" + add, 3, 0.8F); - p.unit().stack.amount -= add * 20; - - players.get(p.uuid()).addScore(add); + if (!((p.unit().stack.item == Items.plastanium && p.unit().type == UnitTypes.cyerce) || (p.unit().stack.item == Items.sporePod && p.unit().type == UnitTypes.spiroct) || (p.unit().stack.item == Items.blastCompound && p.unit().type == UnitTypes.reign) || (p.unit().stack.item == Items.sporePod && p.unit().type == UnitTypes.toxopid) || (p.unit().stack.item == Items.surgeAlloy && (p.unit().type == UnitTypes.quad || p.unit().type == UnitTypes.oct)) || (p.unit().stack.item == Items.carbide && p.unit().type == UnitTypes.disrupt))) { + int add = p.unit().stack.amount/20; + Utils.label(p.x, p.y, "[#023919]+" + add, 3, 0.8F); + p.unit().stack.amount -= add * 20; + + players.get(p.uuid()).addScore(add); + } } } } @@ -50,7 +55,7 @@ public static void initTimer() { Timer.schedule(Recycler::renderRecycler, 0, 1); } - public static void buyRecycler(Player player) { + public static void buyRecycler(Player player, Tile tile) { if (players.get(player.uuid()).getScore() < 6) { player.sendMessage(Bundle.format("station.not-enough-money", Bundle.findLocale(player.locale), 6)); } else { @@ -58,12 +63,15 @@ public static void buyRecycler(Player player) { if (!player.dead()) { Tile playerTileOn = player.tileOn(); Tile tileUnderPlayer = Vars.world.tile(playerTileOn.x, playerTileOn.y - 1); + if (tile == null) { + tile = tileUnderPlayer; + } - if (!player.dead() && player.team() == Team.blue && tileUnderPlayer.block().isAir()) { - StationData recyclerData = new StationData(player, tileUnderPlayer); + if (!player.dead() && player.team() == Team.blue && tile.block().isAir()) { + StationData recyclerData = new StationData(player, tile); recyclersmap.put(player.uuid(), recyclerData); - Call.constructFinish(tileUnderPlayer, Blocks.slagIncinerator, null, (byte) 0, Team.blue, null); - Call.effect(Fx.regenParticle, tileUnderPlayer.x*8, tileUnderPlayer.y*8, 0, Color.red); + Call.constructFinish(tile, Blocks.slagIncinerator, null, (byte) 0, Team.blue, null); + Call.effect(Fx.regenParticle, tile.x*8, tile.y*8, 0, Color.red); players.get(player.uuid()).subtractScore(6); } } @@ -74,7 +82,7 @@ public static void buyRecycler(Player player) { public static void renderRecycler() { recyclersmap.forEach((owner, recycler) -> { if (recycler != null) { - if (recycler.tileOn().block() == Blocks.air || recycler.owner().team() != Team.blue) { + if (recycler.tileOn().block() != Blocks.slagIncinerator || recycler.owner().team() != Team.blue) { recyclersmap.remove(owner); if (recycler.tileOn().block() == Blocks.slagIncinerator) { recycler.tileOn().build.kill(); diff --git a/src/main/java/net/voiddustry/redvsblue/game/stations/RepairPoint.java b/src/main/java/net/voiddustry/redvsblue/game/stations/RepairPoint.java index 9625f8b7..b21822dc 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/stations/RepairPoint.java +++ b/src/main/java/net/voiddustry/redvsblue/game/stations/RepairPoint.java @@ -56,7 +56,7 @@ public static void initTimer() { Timer.schedule(RepairPoint::renderRepairPoints, 0, 1); } - public static void buyRepairPoint(Player player) { + public static void buyRepairPoint(Player player, Tile tile) { if (players.get(player.uuid()).getScore() < 10) { player.sendMessage(Bundle.format("station.not-enough-money", Bundle.findLocale(player.locale), 10)); } else { @@ -64,12 +64,15 @@ public static void buyRepairPoint(Player player) { if (!player.dead()) { Tile playerTileOn = player.tileOn(); Tile tileUnderPlayer = Vars.world.tile(playerTileOn.x, playerTileOn.y - 1); + if (tile == null) { + tile = tileUnderPlayer; + } - if (!player.dead() && player.team() == Team.blue && tileUnderPlayer.block().isAir()) { - StationData repairPointsData = new StationData(player, tileUnderPlayer); + if (!player.dead() && player.team() == Team.blue && tile.block().isAir()) { + StationData repairPointsData = new StationData(player, tile); repairPointsMap.put(player.uuid(), repairPointsData); - Call.constructFinish(tileUnderPlayer, Blocks.mender, null, (byte) 0, Team.blue, null); - Call.effect(Fx.regenParticle, tileUnderPlayer.x*8, tileUnderPlayer.y*8, 0, Color.red); + Call.constructFinish(tile, Blocks.mender, null, (byte) 0, Team.blue, null); + Call.effect(Fx.regenParticle, tile.x*8, tile.y*8, 0, Color.red); players.get(player.uuid()).subtractScore(10); } } @@ -80,7 +83,7 @@ public static void buyRepairPoint(Player player) { public static void renderRepairPoints() { repairPointsMap.forEach((owner, repairPoint) -> { if (repairPoint != null) { - if (repairPoint.tileOn().block() == Blocks.air || repairPoint.owner().team() != Team.blue) { + if (repairPoint.tileOn().block() != Blocks.mender || repairPoint.owner().team() != Team.blue) { repairPointsMap.remove(owner); if (repairPoint.tileOn().block() == Blocks.mender) { repairPoint.tileOn().build.kill(); diff --git a/src/main/java/net/voiddustry/redvsblue/game/stations/StationsMenu.java b/src/main/java/net/voiddustry/redvsblue/game/stations/StationsMenu.java index c1371b54..78951bd9 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/stations/StationsMenu.java +++ b/src/main/java/net/voiddustry/redvsblue/game/stations/StationsMenu.java @@ -10,14 +10,18 @@ public class StationsMenu { public static void openMenu(Player player) { if (!player.dead() && player.team() == Team.blue) { int menu = Menus.registerMenu((player1, option) -> { + if (option < 0) { + return; + } + switch (option) { - case 0 -> SuppressorTower.buyTower(player); - case 1 -> Miner.buyMiner(player); - case 2 -> RepairPoint.buyRepairPoint(player); - case 3 -> ArmorWorkbench.buyWorkbench(player); - case 4 -> Laboratory.buyLab(player); - case 5 -> Recycler.buyRecycler(player); - case 6 -> Booster.buyBooster(player); + case 0 -> SuppressorTower.buyTower(player, null); + case 1 -> Miner.buyMiner(player, null); + case 2 -> RepairPoint.buyRepairPoint(player, null); + case 3 -> ArmorWorkbench.buyWorkbench(player, null); + case 4 -> Laboratory.buyLab(player, null); + case 5 -> Recycler.buyRecycler(player, null); + case 6 -> Booster.buyBooster(player, null); } }); diff --git a/src/main/java/net/voiddustry/redvsblue/game/stations/SuppressorTower.java b/src/main/java/net/voiddustry/redvsblue/game/stations/SuppressorTower.java index 7c5a4840..553d5211 100644 --- a/src/main/java/net/voiddustry/redvsblue/game/stations/SuppressorTower.java +++ b/src/main/java/net/voiddustry/redvsblue/game/stations/SuppressorTower.java @@ -1,6 +1,8 @@ package net.voiddustry.redvsblue.game.stations; import arc.graphics.Color; +import arc.util.Timer; +import arc.struct.Seq; import arc.util.Timer; import mindustry.Vars; @@ -23,6 +25,7 @@ public class SuppressorTower { private static final Map suppressorTowerMap = new ConcurrentHashMap<>(); + private static final Seq suppressorPlaced = new Seq<>(); public static void initTimer() { Timer.schedule(() -> suppressorTowerMap.forEach((owner, pointData) -> { @@ -55,21 +58,30 @@ public static void initTimer() { Timer.schedule(SuppressorTower::renderSuppressorTowers, 0, 0.5F); } - public static void buyTower(Player player) { + public static void buyTower(Player player, Tile tile) { if (players.get(player.uuid()).getScore() < 20) { player.sendMessage(Bundle.format("station.not-enough-money", Bundle.findLocale(player.locale), 20)); } else { - if (!suppressorTowerMap.containsKey(player.uuid())) { + if (!suppressorTowerMap.containsKey(player.uuid()) && !suppressorPlaced.contains(player.uuid())) { if (!player.dead()) { Tile playerTileOn = player.tileOn(); Tile tileUnderPlayer = Vars.world.tile(playerTileOn.x, playerTileOn.y - 1); + if (tile == null) { + tile = tileUnderPlayer; + } - if (!player.dead() && player.team() == Team.blue && tileUnderPlayer.block().isAir()) { - StationData towerData = new StationData(player, tileUnderPlayer); - suppressorTowerMap.put(player.uuid(), towerData); - Call.constructFinish(tileUnderPlayer, Blocks.phaseWall, null, (byte) 0, Team.blue, null); - Call.effect(Fx.regenParticle, tileUnderPlayer.x*8, tileUnderPlayer.y*8, 0, Color.red); + final Tile placeTile = tile; + if (!player.dead() && player.team() == Team.blue && tile.block().isAir()) { + Call.constructFinish(tile, Blocks.phaseWall, null, (byte) 0, Team.blue, null); players.get(player.uuid()).subtractScore(20); + StationUtils.drawStationName(tile, player.name + "[gold]'s\n[accent]Suppressor Tower" + " - deploying", 10.5F); + suppressorPlaced.add(player.uuid()); + Timer.schedule(() -> { + StationData towerData = new StationData(player, placeTile); + suppressorTowerMap.put(player.uuid(), towerData); + suppressorPlaced.remove(player.uuid()); + Call.effect(Fx.regenParticle, placeTile.x*8, placeTile.y*8, 0, Color.red); + }, 10); } } } @@ -79,7 +91,7 @@ public static void buyTower(Player player) { public static void renderSuppressorTowers() { suppressorTowerMap.forEach((owner, tower) -> { if (tower != null) { - if (tower.tileOn().block() == Blocks.air || tower.owner().team() != Team.blue) { + if (tower.tileOn().block() != Blocks.phaseWall || tower.owner().team() != Team.blue) { suppressorTowerMap.remove(owner); if (tower.tileOn().block() == Blocks.phaseWall) { tower.tileOn().build.kill(); @@ -91,5 +103,6 @@ public static void renderSuppressorTowers() { public static void clearTowers() { suppressorTowerMap.clear(); + suppressorPlaced.clear(); } } diff --git a/src/main/java/net/voiddustry/redvsblue/player/Hud.java b/src/main/java/net/voiddustry/redvsblue/player/Hud.java index e7398bc4..a316bab3 100644 --- a/src/main/java/net/voiddustry/redvsblue/player/Hud.java +++ b/src/main/java/net/voiddustry/redvsblue/player/Hud.java @@ -20,8 +20,6 @@ public class Hud { public static void update() { - CruxUnit.checkUnitCount(); - int minutes = (int) Math.floor(RedVsBluePlugin.stageTimer / 60); int seconds = (int) (RedVsBluePlugin.stageTimer - minutes * 60); diff --git a/src/main/java/net/voiddustry/redvsblue/util/MapVote.java b/src/main/java/net/voiddustry/redvsblue/util/MapVote.java index 4c65d99a..506cad9a 100644 --- a/src/main/java/net/voiddustry/redvsblue/util/MapVote.java +++ b/src/main/java/net/voiddustry/redvsblue/util/MapVote.java @@ -19,7 +19,8 @@ public class MapVote { private static final Map playersVotesMap = new HashMap<>(); - private static ArrayList avaibleMapnumbers = new ArrayList(); + private static Seq avaibleMapnumbers = new Seq(); + public static Seq pinnedMaps = new Seq(); public static void callMapVoting() { if (!Utils.voting) { @@ -43,9 +44,12 @@ public void run() { int[] mapVotes = getMapVotes(); for (int j = 0; j < getMaps().size; j++) { - if (avaibleMapnumbers.contains(j) || maps.get(j).file.name().startsWith("[blue]")) { + if (avaibleMapnumbers.contains(j)) { int mapNumber = j + 1; mapsList.append("\n[lightgray]").append(mapNumber).append(" [gray]| [gold]").append(mapVotes[j]).append(" [gray]| ").append(maps.get(j).file.name().replace(".msav", "")); + } else if (pinnedMaps.contains(maps.get(j).file.name())) { + int mapNumber = j + 1; + mapsList.append("\n[lightgray]").append(mapNumber).append(" [gray]| [gold]").append(mapVotes[j]).append(" [gray]| ").append("[blue]").append(maps.get(j).file.name().replace(".msav", "")); } } @@ -72,10 +76,15 @@ private static mindustry.maps.Map getMostVotedMap() { Seq maps = getMaps(); int[] votes = getMapVotes(); int largest = 0; + Random rand = new Random(); for (int i = 0; i < votes.length; i++) { largest = votes[i] > votes[largest] ? i : largest; } + + if (votes[largest] == 0) { + largest = rand.nextInt(getMaps().size-1); + } return maps.get(largest); @@ -89,7 +98,7 @@ private static int[] getMapVotes() { public static void registerVote(Player player, Integer voteNumber) { if (!playersVotesMap.containsKey(player.uuid())) { - if (avaibleMapnumbers.contains(voteNumber-1) || getMaps().get(voteNumber-1).file.name().startsWith("[blue]")) { + if (avaibleMapnumbers.contains(voteNumber-1) || pinnedMaps.contains(getMaps().get(voteNumber-1).file.name())) { playersVotesMap.put(player.uuid(), voteNumber-1); } } diff --git a/src/main/java/net/voiddustry/redvsblue/util/Utils.java b/src/main/java/net/voiddustry/redvsblue/util/Utils.java index 95e58d04..7efd9c13 100644 --- a/src/main/java/net/voiddustry/redvsblue/util/Utils.java +++ b/src/main/java/net/voiddustry/redvsblue/util/Utils.java @@ -2,26 +2,31 @@ import arc.graphics.Color; +import arc.*; import arc.struct.Seq; import arc.util.Time; import arc.util.Timer; +import arc.util.serialization.*; import mindustry.Vars; import mindustry.content.*; +import mindustry.entities.EntityGroup; import mindustry.entities.bullet.BasicBulletType; import mindustry.game.Team; import mindustry.gen.*; +import mindustry.io.JsonIO; import mindustry.type.UnitType; import java.util.Locale; +import java.util.HashMap; import mindustry.type.Weapon; +import mindustry.world.Tile; import mindustry.world.Block; import mindustry.world.blocks.environment.*; +import mindustry.world.meta.BuildVisibility; import net.voiddustry.redvsblue.Bundle; import net.voiddustry.redvsblue.PlayerData; -import net.voiddustry.redvsblue.game.building.BlocksTypes; -import net.voiddustry.redvsblue.game.building.BuildBlock; import net.voiddustry.redvsblue.game.crux.StageUnits; import net.voiddustry.redvsblue.game.starting_menu.StartingItems; import net.voiddustry.redvsblue.game.starting_menu.StartingMenu; @@ -39,15 +44,33 @@ public class Utils { public static int money_per_min = 3; public static void initRules() { - for ( Block block : Vars.content.blocks()) { + + state.rules.bannedBlocks.clear(); + state.rules.revealedBlocks.clear(); + + for (Block block : Vars.content.blocks()) { state.rules.bannedBlocks.add(block); + for(int i = 0; i < block.requirements.length; i++){ + if (block.requirements[i].item==Items.dormantCyst) { + state.rules.bannedBlocks.remove(block); + state.rules.revealedBlocks.add(block); + + break; + } + } } + + state.rules.buildSpeedMultiplier = 0; + + state.rules.env = Vars.defaultEnv; + state.rules.planet = Planets.sun; state.rules.waveSpacing = Integer.MAX_VALUE; state.rules.waves = true; state.rules.bannedUnits.add(UnitTypes.alpha); state.rules.hideBannedBlocks = true; + state.rules.blockWhitelist = false; state.rules.teams.get(Team.malis).blockHealthMultiplier = 2; @@ -73,7 +96,6 @@ public void run() { } public static void loadContent() { - BlocksTypes.load(); StartingItems.load(); } @@ -85,12 +107,11 @@ public static void initTimers() { ArmorWorkbench.initTimer(); Recycler.initTimer(); SuppressorTower.initTimer(); - BuildBlock.init(); Timer.schedule(() -> { if (playing) { Groups.player.each(p -> { - if (p.team() == Team.blue && (!(((Integer)players.get(p.uuid()).getScore()) == null))) { + if (p.team() == Team.blue && (!(players.get(p.uuid()) == null)) && (!(((Integer)players.get(p.uuid()).getScore()) == null))) { players.get(p.uuid()).setScore(players.get(p.uuid()).getScore() + money_per_min); p.sendMessage(Bundle.format("game.salary", Bundle.findLocale(p.locale), money_per_min)); @@ -101,35 +122,26 @@ public static void initTimers() { Timer.schedule(() -> stageTimer--, 0, 1); - Timer.schedule(() -> Groups.player.each(player -> { - if (player.tileOn() != null && player.team() == Team.blue && player.unit() != null) { - if (player.tileOn().block() != null && (player.tileOn().block() == Blocks.cliff || (player.tileOn().block() instanceof Prop && player.tileOn().block().breakable) || player.tileOn().block() instanceof TallBlock)) { - return; - } - if (player.tileOn().build != null && player.tileOn().build.team != Team.blue && player.tileOn().build.team != Team.derelict) { - if (player.unit().health <= 1) { - player.unit().kill(); - } - player.unit().health -= player.unit().type.health/100; - Call.effect(Fx.burning, player.x, player.y, 1, Color.red); - - } else if (!player.tileOn().block().isAir() || player.tileOn().isDarkened()) { - if (player.unit().health <= 1) { - player.unit().kill(); - } - if (!player.tileOn().block().canBeBuilt()) { - player.unit().health -= player.unit().type.health/100; - Call.effect(Fx.burning, player.x, player.y, 1, Color.red); - } - } - } else if (player.tileOn() == null && player.unit() != null) { - if (player.unit().health <= 1) { - player.unit().kill(); + Timer.schedule(() -> { + EntityGroup units = Groups.unit; + int size = units.size(); + for (int i = 0; i < size; i++) { + Unit unit = units.index(i); + if (unit.team != Team.blue) continue; + Tile tile = unit.tileOn(); + if (tile == null) continue; + Building build = tile.build; + if (build != null) { + Team team = build.team; + if (team == Team.blue || team == Team.derelict) continue; + } else if (!tile.legSolid()) { + continue; } - player.unit().health -= player.unit().type.health/100; - Call.effect(Fx.burning, player.x, player.y, 1, Color.red); + if (unit.health <= 1f) unit.kill(); + unit.health -= unit.type.health / 100f; + Call.effect(Fx.burning, unit.x, unit.y, 1, Color.red); } - }), 0, 0.1F); + }, 0, 0.1f); } public static void processLevel(Player player, PlayerData data) { @@ -225,7 +237,7 @@ public static UnitType getStartingUnit() { return UnitTypes.nova; } case 7, 8 -> { - return UnitTypes.elude; + return UnitTypes.merui; } case 9 -> { return UnitTypes.flare; diff --git a/src/main/resources/bundles/bundle_en.properties b/src/main/resources/bundles/bundle_en.properties index c4df9fb6..6498f033 100644 --- a/src/main/resources/bundles/bundle_en.properties +++ b/src/main/resources/bundles/bundle_en.properties @@ -15,6 +15,7 @@ game.level-up={0}[accent] has leveled up! game.new-stage=[scarlet]Stage {0} has began! game.redeemed={0} [cyan]has been redeemed! game.salary=[lime]You survived one minute and got 3 points! +game.stage11=[crimson]Team Blue has attracted unwanted attention... menu.build.build=[gold]Select menu.build.cancel=[lightgray]Cancel menu.build.single=Single @@ -47,6 +48,8 @@ units.crux.menu.mace=[scarlet]Mace units.crux.menu.merui=[lightgray]Merui units.crux.menu.nova=[lime]Nova units.crux.menu.obviate=[purple]Obviate +units.crux.menu.antumbra=[lightgray]Antumbra +units.crux.menu.vanquish=[crimson]Vanquish units.crux.menu.precept=[lightgray]Precept units.crux.menu.stell=[gray]Stell units.crux.menu.title=[scarlet]Class Choose menu @@ -69,4 +72,4 @@ boss.bosses.mace=[#023919]Rotting Corpse boss.spawn=[accent]{0}[] [scarlet]spawned as {1}[scarlet]. stations.buttons.recycler=[#023919]Recycler stations.workbench.buy-armor=[lime]Buy {0} Armor for 1 point -stations.workbench.unit-armor=[blue]Unit Shield: {0} \ No newline at end of file +stations.workbench.unit-armor=[blue]Unit Shield: {0} diff --git a/src/main/resources/bundles/bundle_ru.properties b/src/main/resources/bundles/bundle_ru.properties index 23bfded0..4d0caf12 100644 --- a/src/main/resources/bundles/bundle_ru.properties +++ b/src/main/resources/bundles/bundle_ru.properties @@ -13,6 +13,7 @@ game.level-up={0}[accent] повысил свой уровень! game.new-stage=[scarlet]Стадия {0} началась! game.redeemed={0} [cyan]has been redeemed! game.salary=[lime]Вы продержались одну минуту и получили 3 очка! +game.stage11=[crimson]Синяя команда привлекла к себе ненужное внимание... menu.build.build=[gold]Выбрать menu.build.cancel=[lightgray]Отменить menu.build.single=Single @@ -46,6 +47,8 @@ units.crux.menu.merui=[lightgray]Меруй units.crux.menu.nova=[lime]Нова units.crux.menu.obviate=[purple]Устранение units.crux.menu.precept=[lightgray]Заповедь +units.crux.menu.antumbra=[lightgray]Затемь +units.crux.menu.vanquish=[crimson]Покоритель units.crux.menu.stell=[gray]Основа units.crux.menu.title=[scarlet]Меню выбора класса welcome=[cyan]Добро пожаловать! @@ -66,4 +69,4 @@ boss.bosses.mace=[#023919]Гниющий Труп boss.spawn=[accent]{0}[] [scarlet]появился как {1}[scarlet]. stations.buttons.recycler=[#023919]Переработчик stations.workbench.buy-armor=[lime]Купить {0} Брони за 1 поинт -stations.workbench.unit-armor=[blue]Щит Юнита: {0} \ No newline at end of file +stations.workbench.unit-armor=[blue]Щит Юнита: {0} diff --git a/src/main/resources/bundles/bundle_uk_UA.properties b/src/main/resources/bundles/bundle_uk_UA.properties index a1224baa..525b55ca 100644 --- a/src/main/resources/bundles/bundle_uk_UA.properties +++ b/src/main/resources/bundles/bundle_uk_UA.properties @@ -13,6 +13,7 @@ game.level-up={0}[accent] повисив свій рівень! game.new-stage=[scarlet]Стадія {0} почалась! game.redeemed={0} [cyan]has been redeemed! game.salary=[lime]Ви протримались одну хвилину та отримали 3 бали! +game.stage11="Ти привернув до себе занадто багато уваги..." menu.build.build=[gold]Вибрати menu.build.cancel=[lightgray]Скасувати menu.build.single=Single @@ -44,8 +45,10 @@ units.crux.menu.locus=[gold]Локус units.crux.menu.mace=[scarlet]Булава units.crux.menu.merui=[lightgray]Меруй units.crux.menu.nova=[lime]Нова -units.crux.menu.obviate=[purple]Quell +units.crux.menu.obviate=[purple]Уникач units.crux.menu.precept=[lightgray]Повчальник +units.crux.menu.antumbra=[lightgray]Тіньовик +units.crux.menu.vanquish=[crimson]Переможець units.crux.menu.stell=[gray]Стел units.crux.menu.title=[scarlet]Меню вибору класа welcome=[cyan]Добро пожаловать! @@ -66,4 +69,4 @@ boss.bosses.mace=[#023919]Гниючий Труп boss.spawn=[accent]{0}[] [scarlet]з'явився як {1}[scarlet]. stations.buttons.recycler=[#023919]Переробник stations.workbench.buy-armor=[lime]Придбати {0} Бронi за 1 поiнт -stations.workbench.unit-armor=[blue]Щит Юнiта: {0} \ No newline at end of file +stations.workbench.unit-armor=[blue]Щит Юнiта: {0} diff --git a/src/main/resources/plugin.json b/src/main/resources/plugin.json index 7971c5e6..0a376970 100644 --- a/src/main/resources/plugin.json +++ b/src/main/resources/plugin.json @@ -7,5 +7,5 @@ "hidden": false, "java": true, "version": "3.08", - "minGameVersion": 153 + "minGameVersion": 154.2 }