per-team toggles for core no-build radius / placement range check (#11448)
* per-team toggles for core no-build radius / placement range check * oops * fair enough
This commit is contained in:
@@ -1474,6 +1474,10 @@ rules.cleanupdeadteams = Clean Up Defeated Team Buildings (PvP)
|
|||||||
rules.corecapture = Capture Core On Destruction
|
rules.corecapture = Capture Core On Destruction
|
||||||
rules.polygoncoreprotection = Polygonal Core Protection
|
rules.polygoncoreprotection = Polygonal Core Protection
|
||||||
rules.placerangecheck = Placement Range Check
|
rules.placerangecheck = Placement Range Check
|
||||||
|
rules.protectcores = Protect Cores
|
||||||
|
rules.protectcores.info = When disabled, the core no-build radius won't affect this team.\nPlayers won't be assigned to unprotected teams.
|
||||||
|
rules.checkplacement = Check Placement
|
||||||
|
rules.checkplacement.info = When disabled, buildings of this team are ignored in placement range checks.
|
||||||
rules.enemyCheat = Infinite Enemy Team Resources
|
rules.enemyCheat = Infinite Enemy Team Resources
|
||||||
rules.blockhealthmultiplier = Block Health Multiplier
|
rules.blockhealthmultiplier = Block Health Multiplier
|
||||||
rules.blockdamagemultiplier = Block Damage Multiplier
|
rules.blockdamagemultiplier = Block Damage Multiplier
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
if(state.rules.pvp){
|
if(state.rules.pvp){
|
||||||
//find team with minimum amount of players and auto-assign player to that.
|
//find team with minimum amount of players and auto-assign player to that.
|
||||||
TeamData re = state.teams.getActive().min(data -> {
|
TeamData re = state.teams.getActive().min(data -> {
|
||||||
if((state.rules.waveTeam == data.team && state.rules.waves) || !data.hasCore() || data.team == Team.derelict) return Integer.MAX_VALUE;
|
if((state.rules.waveTeam == data.team && state.rules.waves) || !data.hasCore() || data.team == Team.derelict || !data.team.rules().protectCores) return Integer.MAX_VALUE;
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for(Player other : players){
|
for(Player other : players){
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ public class Rules{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public float buildRadius(Team team){
|
public float buildRadius(Team team){
|
||||||
return enemyCoreBuildRadius + teams.get(team).extraCoreBuildRadius;
|
return !teams.get(team).protectCores ? 0f : enemyCoreBuildRadius + teams.get(team).extraCoreBuildRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float unitBuildSpeed(Team team){
|
public float unitBuildSpeed(Team team){
|
||||||
@@ -299,6 +299,10 @@ public class Rules{
|
|||||||
public static class TeamRule{
|
public static class TeamRule{
|
||||||
/** Whether, when AI is enabled, ships should be spawned from the core. TODO remove / unnecessary? */
|
/** Whether, when AI is enabled, ships should be spawned from the core. TODO remove / unnecessary? */
|
||||||
public boolean aiCoreSpawn = true;
|
public boolean aiCoreSpawn = true;
|
||||||
|
/** Whether the core no-build radius/polygonal protection applies to this team, unprotected teams are ignored by team assigner */
|
||||||
|
public boolean protectCores = true;
|
||||||
|
/** Whether the placeRangeCheck applies to this team */
|
||||||
|
public boolean checkPlacement = true;
|
||||||
/** If true, blocks don't require power or resources. */
|
/** If true, blocks don't require power or resources. */
|
||||||
public boolean cheat;
|
public boolean cheat;
|
||||||
/** If true, the core is always filled to capacity with all items. */
|
/** If true, the core is always filled to capacity with all items. */
|
||||||
@@ -345,8 +349,18 @@ public class Rules{
|
|||||||
/** Extra spacing added to the no-build zone around the core. */
|
/** Extra spacing added to the no-build zone around the core. */
|
||||||
public float extraCoreBuildRadius = 0f;
|
public float extraCoreBuildRadius = 0f;
|
||||||
|
|
||||||
|
|
||||||
//build cost disabled due to technical complexity
|
//build cost disabled due to technical complexity
|
||||||
|
|
||||||
|
//for reading from json
|
||||||
|
public TeamRule(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public TeamRule(Team team){
|
||||||
|
if(team == Team.derelict){
|
||||||
|
protectCores = false;
|
||||||
|
checkPlacement = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A simple map for storing TeamRules in an efficient way without hashing. */
|
/** A simple map for storing TeamRules in an efficient way without hashing. */
|
||||||
@@ -355,7 +369,7 @@ public class Rules{
|
|||||||
|
|
||||||
public TeamRule get(Team team){
|
public TeamRule get(Team team){
|
||||||
TeamRule out = values[team.id];
|
TeamRule out = values[team.id];
|
||||||
return out == null ? (values[team.id] = new TeamRule()) : out;
|
return out == null ? (values[team.id] = new TeamRule(team)) : out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class Teams{
|
|||||||
|
|
||||||
public boolean anyEnemyCoresWithinBuildRadius(Team team, float x, float y){
|
public boolean anyEnemyCoresWithinBuildRadius(Team team, float x, float y){
|
||||||
for(TeamData data : active){
|
for(TeamData data : active){
|
||||||
if(team != data.team){
|
if(team != data.team && data.team.rules().protectCores){
|
||||||
for(CoreBuild tile : data.cores){
|
for(CoreBuild tile : data.cores){
|
||||||
if(tile.within(x, y, state.rules.buildRadius(tile.team) + tilesize)){
|
if(tile.within(x, y, state.rules.buildRadius(tile.team) + tilesize)){
|
||||||
return true;
|
return true;
|
||||||
@@ -71,7 +71,7 @@ public class Teams{
|
|||||||
|
|
||||||
public boolean anyEnemyCoresWithin(Team team, float x, float y, float radius){
|
public boolean anyEnemyCoresWithin(Team team, float x, float y, float radius){
|
||||||
for(TeamData data : active){
|
for(TeamData data : active){
|
||||||
if(team != data.team){
|
if(team != data.team && data.team.rules().protectCores){
|
||||||
for(CoreBuild tile : data.cores){
|
for(CoreBuild tile : data.cores){
|
||||||
if(tile.within(x, y, radius)){
|
if(tile.within(x, y, radius)){
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -50,8 +50,12 @@ public class OverlayRenderer{
|
|||||||
|
|
||||||
Seq<Vec2> pos = new Seq<>();
|
Seq<Vec2> pos = new Seq<>();
|
||||||
Seq<CoreBuild> teams = new Seq<>();
|
Seq<CoreBuild> teams = new Seq<>();
|
||||||
for(TeamData team : state.teams.active){
|
for(TeamData data : state.teams.active){
|
||||||
for(CoreBuild b : team.cores){
|
if(!data.team.rules().protectCores){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(CoreBuild b : data.cores){
|
||||||
teams.add(b);
|
teams.add(b);
|
||||||
pos.add(new Vec2(b.x, b.y));
|
pos.add(new Vec2(b.x, b.y));
|
||||||
}
|
}
|
||||||
@@ -179,7 +183,7 @@ public class OverlayRenderer{
|
|||||||
state.teams.eachEnemyCore(player.team(), core -> {
|
state.teams.eachEnemyCore(player.team(), core -> {
|
||||||
//it must be clear that there is a core here.
|
//it must be clear that there is a core here.
|
||||||
float br = state.rules.buildRadius(core.team);
|
float br = state.rules.buildRadius(core.team);
|
||||||
if(/*core.wasVisible && */Core.camera.bounds(Tmp.r1).overlaps(Tmp.r2.setCentered(core.x, core.y, br * 2f))){
|
if(/*core.wasVisible && */br > 0f && Core.camera.bounds(Tmp.r1).overlaps(Tmp.r2.setCentered(core.x, core.y, br * 2f))){
|
||||||
Draw.color(Color.darkGray);
|
Draw.color(Color.darkGray);
|
||||||
Lines.circle(core.x, core.y - 2,br);
|
Lines.circle(core.x, core.y - 2,br);
|
||||||
Draw.color(Pal.accent, core.team.color, 0.5f + Mathf.absin(Time.time, 10f, 0.5f));
|
Draw.color(Pal.accent, core.team.color, 0.5f + Mathf.absin(Time.time, 10f, 0.5f));
|
||||||
|
|||||||
@@ -309,7 +309,9 @@ public class CustomRulesDialog extends BaseDialog{
|
|||||||
check("@rules.buildai", b -> teams.buildAi = b, () -> teams.buildAi, () -> team != rules.defaultTeam && rules.env != Planets.erekir.defaultEnv && !rules.pvp);
|
check("@rules.buildai", b -> teams.buildAi = b, () -> teams.buildAi, () -> team != rules.defaultTeam && rules.env != Planets.erekir.defaultEnv && !rules.pvp);
|
||||||
number("@rules.buildaitier", false, f -> teams.buildAiTier = f, () -> teams.buildAiTier, () -> teams.buildAi && rules.env != Planets.erekir.defaultEnv && !rules.pvp, 0, 1);
|
number("@rules.buildaitier", false, f -> teams.buildAiTier = f, () -> teams.buildAiTier, () -> teams.buildAi && rules.env != Planets.erekir.defaultEnv && !rules.pvp, 0, 1);
|
||||||
|
|
||||||
number("@rules.extracorebuildradius", f -> teams.extraCoreBuildRadius = f * tilesize, () -> Math.min(teams.extraCoreBuildRadius / tilesize, 200), () -> !rules.polygonCoreProtection);
|
check("@rules.protectcores", b -> teams.protectCores = b, () -> teams.protectCores);
|
||||||
|
number("@rules.extracorebuildradius", f -> teams.extraCoreBuildRadius = f * tilesize, () -> Math.min(teams.extraCoreBuildRadius / tilesize, 200), () -> !rules.polygonCoreProtection && teams.protectCores);
|
||||||
|
check("@rules.checkplacement", b -> teams.checkPlacement = b, () -> teams.checkPlacement);
|
||||||
|
|
||||||
check("@rules.infiniteresources", b -> teams.infiniteResources = b, () -> teams.infiniteResources);
|
check("@rules.infiniteresources", b -> teams.infiniteResources = b, () -> teams.infiniteResources);
|
||||||
check("@rules.fillitems", b -> teams.fillItems = b, () -> teams.fillItems);
|
check("@rules.fillitems", b -> teams.fillItems = b, () -> teams.fillItems);
|
||||||
|
|||||||
@@ -191,6 +191,10 @@ public class Build{
|
|||||||
float mindst = Float.MAX_VALUE;
|
float mindst = Float.MAX_VALUE;
|
||||||
CoreBuild closest = null;
|
CoreBuild closest = null;
|
||||||
for(TeamData data : state.teams.active){
|
for(TeamData data : state.teams.active){
|
||||||
|
if(!data.team.rules().protectCores){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for(CoreBuild tile : data.cores){
|
for(CoreBuild tile : data.cores){
|
||||||
float dst = tile.dst2(x * tilesize + type.offset, y * tilesize + type.offset);
|
float dst = tile.dst2(x * tilesize + type.offset, y * tilesize + type.offset);
|
||||||
if(dst < mindst){
|
if(dst < mindst){
|
||||||
@@ -265,7 +269,7 @@ public class Build{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @Nullable Building getEnemyOverlap(Block block, Team team, int x, int y){
|
public static @Nullable Building getEnemyOverlap(Block block, Team team, int x, int y){
|
||||||
return indexer.findEnemyTile(team, x * tilesize + block.size, y * tilesize + block.size, block.placeOverlapRange + 4f, p -> true);
|
return indexer.findEnemyTile(team, x * tilesize + block.size, y * tilesize + block.size, block.placeOverlapRange + 4f, b -> b.team.rules().checkPlacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean contactsGround(int x, int y, Block block){
|
public static boolean contactsGround(int x, int y, Block block){
|
||||||
|
|||||||
Reference in New Issue
Block a user