Logic team-specific rules

This commit is contained in:
Anuken 2022-02-24 09:30:24 -05:00
parent 4ff1b5ac08
commit f9dfe8cbcc
10 changed files with 74 additions and 30 deletions

View file

@ -150,14 +150,17 @@ public class PhysicsProcess implements AsyncProcess{
trees[i].clear();
}
for(int i = 0; i < bodies.size; i++){
PhysicsBody body = bodies.items[i];
var bodyItems = bodies.items;
int bodySize = bodies.size;
for(int i = 0; i < bodySize; i++){
PhysicsBody body = bodyItems[i];
body.collided = false;
trees[body.layer].insert(body);
}
for(int i = 0; i < bodies.size; i++){
PhysicsBody body = bodies.items[i];
for(int i = 0; i < bodySize; i++){
PhysicsBody body = bodyItems[i];
//for clients, the only body that collides is the local one; all other physics simulations are handled by the server.
if(!body.local) continue;
@ -166,9 +169,11 @@ public class PhysicsProcess implements AsyncProcess{
seq.size = 0;
trees[body.layer].intersect(rect, seq);
int size = seq.size;
var items = seq.items;
for(int j = 0; j < seq.size; j++){
PhysicsBody other = seq.items[j];
for(int j = 0; j < size; j++){
PhysicsBody other = items[j];
if(other == body || other.collided) continue;

View file

@ -6,7 +6,7 @@ import arc.math.geom.*;
//TODO
public class ShotPattern{
public void shoot(Cons<Vec2> positionSetter, Cons<Vec2> positionHandler){
public void shoot(float x, float y, Cons<Vec2> positionHandler){
}
}

View file

@ -1299,6 +1299,18 @@ public class LExecutor{
}
}
case ambientLight -> state.rules.ambientLight.fromDouble(exec.num(value));
case unitBuildSpeed, unitDamage, blockHealth, blockDamage, buildSpeed -> {
if(exec.obj(p1) instanceof Team team){
float num = exec.numf(value);
switch(rule){
case buildSpeed -> team.rules().buildSpeedMultiplier = Mathf.clamp(num, 0.001f, 50f);
case unitBuildSpeed -> team.rules().unitBuildSpeedMultiplier = Mathf.clamp(num, 0f, 50f);
case unitDamage -> team.rules().unitDamageMultiplier = Math.max(num, 0f);
case blockHealth -> team.rules().blockHealthMultiplier = Math.max(num, 0.001f);
case blockDamage -> team.rules().blockDamageMultiplier = Math.max(num, 0f);
}
}
}
}
}
}

View file

@ -1237,13 +1237,20 @@ public class LStatements{
@RegisterStatement("setrule")
public static class SetRuleStatement extends LStatement{
public LogicRule rule = LogicRule.waveSpacing;
public String value = "100", p1 = "0", p2 = "0", p3 = "100", p4 = "100";
public String value = "10", p1 = "0", p2 = "0", p3 = "100", p4 = "100";
@Override
public void build(Table table){
rebuild(table);
}
/*
unitBuildSpeed,
unitDamage,
blockHealth,
blockDamage
*/
void rebuild(Table table){
table.clearChildren();
@ -1253,19 +1260,31 @@ public class LStatements{
rule = o;
rebuild(table);
}, 2, c -> c.width(150f)));
}, Styles.logict, () -> {}).size(160f, 40f).pad(4f).color(table.color);
table.add(" = ");
}, Styles.logict, () -> {}).size(160f, 40f).margin(5f).pad(4f).color(table.color);
switch(rule){
case mapArea -> {
table.add(" = ");
fields(table, "x", p1, s -> p1 = s);
fields(table, "y", p2, s -> p2 = s);
row(table);
fields(table, "w", p3, s -> p3 = s);
fields(table, "h", p4, s -> p4 = s);
}
case buildSpeed, unitBuildSpeed, unitDamage, blockHealth, blockDamage -> {
if(p1.equals("0")){
p1 = "@sharded";
}
fields(table, "of", p1, s -> p1 = s);
table.add(" = ");
row(table);
field(table, value, s -> value = s);
}
default -> {
table.add(" = ");
field(table, value, s -> value = s);
}
}

View file

@ -11,7 +11,14 @@ public enum LogicRule{
unitCap,
mapArea,
lighting,
ambientLight;
ambientLight,
//team specific
buildSpeed,
unitBuildSpeed,
unitDamage,
blockHealth,
blockDamage;
public static final LogicRule[] all = values();
}

View file

@ -175,7 +175,7 @@ public class CustomRulesDialog extends BaseDialog{
check("@rules.unitcapvariable", b -> rules.unitCapVariable = b, () -> rules.unitCapVariable);
numberi("@rules.unitcap", f -> rules.unitCap = f, () -> rules.unitCap, -999, 999);
number("@rules.unitdamagemultiplier", f -> rules.unitDamageMultiplier = f, () -> rules.unitDamageMultiplier);
number("@rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier, 0.001f, 50f);
number("@rules.unitbuildspeedmultiplier", f -> rules.unitBuildSpeedMultiplier = f, () -> rules.unitBuildSpeedMultiplier, 0f, 50f);
main.button("@bannedunits", () -> showBanned("@bannedunits", ContentType.unit, rules.bannedUnits, u -> !u.isHidden())).left().width(300f);
main.row();

View file

@ -115,8 +115,8 @@ public class ContinuousTurret extends Turret{
}
@Override
protected void bullet(BulletType type, float angle){
bullet = type.create(this, team, x + bulletOffset.x, y + bulletOffset.y, angle);
protected void handleBullet(@Nullable Bullet bullet){
this.bullet = bullet;
}
@Override

View file

@ -108,8 +108,8 @@ public class LaserTurret extends PowerTurret{
}
@Override
protected void bullet(BulletType type, float angle){
bullet = type.create(this, team, x + bulletOffset.x, y + bulletOffset.y, angle);
protected void handleBullet(@Nullable Bullet bullet){
this.bullet = bullet;
bulletLife = shootDuration;
}

View file

@ -178,7 +178,7 @@ public class Turret extends ReloadTurret{
}
public class TurretBuild extends ReloadTurretBuild implements ControlBlock{
//TODO storing these as instance variables is bad design, but it's probably too late to change everything
//TODO storing these as instance variables is horrible design
/** Turret sprite offset, based on recoil. Updated every frame. */
public Vec2 recoilOffset = new Vec2();
/** Turret bullet position offset. Updated every frame. */
@ -559,21 +559,18 @@ public class Turret extends ReloadTurret{
}
protected void bullet(BulletType type, float angle){
float lifeScl = type.scaleVelocity ? Mathf.clamp(Mathf.dst(x + bulletOffset.x, y + bulletOffset.y, targetPos.x, targetPos.y) / type.range, minRange / type.range, range() / type.range) : 1f;
float bulletX = x + bulletOffset.x, bulletY = y + bulletOffset.y;
float lifeScl = type.scaleVelocity ? Mathf.clamp(Mathf.dst(bulletX, bulletY, targetPos.x, targetPos.y) / type.range, minRange / type.range, range() / type.range) : 1f;
type.create(this, team, x + bulletOffset.x, y + bulletOffset.y, angle, 1f + Mathf.range(velocityInaccuracy), lifeScl);
effects();
}
handleBullet(type.create(this, team, bulletX, bulletY, angle, 1f + Mathf.range(velocityInaccuracy), lifeScl));
protected void effects(){
var bullet = peekAmmo();
//TODO "shoot" and "smoke" should just be MultiEffects there's no reason to have them separate
Effect fshootEffect = shootEffect == Fx.none ? bullet.shootEffect : shootEffect;
Effect fsmokeEffect = smokeEffect == Fx.none ? bullet.smokeEffect : smokeEffect;
Effect fshootEffect = shootEffect == Fx.none ? type.shootEffect : shootEffect;
Effect fsmokeEffect = smokeEffect == Fx.none ? type.smokeEffect : smokeEffect;
fshootEffect.at(x + bulletOffset.x, y + bulletOffset.y, rotation, bullet.hitColor);
fsmokeEffect.at(x + bulletOffset.x, y + bulletOffset.y, rotation, bullet.hitColor);
shootSound.at(x + bulletOffset.x, y + bulletOffset.y, Mathf.random(0.9f, 1.1f));
fshootEffect.at(bulletX, bulletY, rotation, type.hitColor);
fsmokeEffect.at(bulletX, bulletY, rotation, type.hitColor);
shootSound.at(bulletX, bulletY, Mathf.random(0.9f, 1.1f));
if(shootShake > 0){
Effect.shake(shootShake, shootShake, this);
@ -582,6 +579,10 @@ public class Turret extends ReloadTurret{
recoil = recoilAmount;
}
protected void handleBullet(@Nullable Bullet bullet){
}
protected void ejectEffects(){
if(dead) return;

View file

@ -24,4 +24,4 @@ android.useAndroidX=true
#used for slow jitpack builds; TODO see if this actually works
org.gradle.internal.http.socketTimeout=100000
org.gradle.internal.http.connectionTimeout=100000
archash=801bc93181
archash=62774bbfce