Fog fixes / Weapon attack fixes / Avert weapon

This commit is contained in:
Anuke
2022-03-05 11:06:28 -05:00
parent c3ce23731d
commit 6983959aeb
8 changed files with 80 additions and 26 deletions

View File

@@ -173,6 +173,6 @@ public class BuilderAI extends AIController{
@Override
public boolean shouldShoot(){
return !unit.isBuilding();
return !unit.isBuilding() && unit.type.canAttack;
}
}

View File

@@ -3119,18 +3119,44 @@ public class UnitTypes{
lowAltitude = false;
flying = true;
drag = 0.08f;
speed = 2.5f;
rotateSpeed = 5f;
speed = 2f;
rotateSpeed = 4f;
accel = 0.09f;
health = 600f;
health = 800f;
armor = 2f;
hitSize = 12f;
engineSize = 0;
fogRadius = 25;
setEnginesMirror(
new UnitEngine(34 / 4f, 31 / 4f, 3f, 45f),
new UnitEngine(35 / 4f, -38 / 4f, 3f, 315f)
);
weapons.add(new Weapon("avert-weapon"){{
reload = 35f;
x = 4f;
y = 6.25f;
shootY = 5.75f;
recoil = 1.5f;
top = false;
layerOffset = -0.01f;
rotate = false;
//TODO cooler + balancing
bullet = new BasicBulletType(5f, 15){{
width = 7f;
height = 12f;
lifetime = 25f;
shootEffect = Fx.sparkShoot;
smokeEffect = Fx.shootBigSmoke;
hitColor = backColor = trailColor = Pal.suppress;
frontColor = Color.white;
trailWidth = 1.5f;
trailLength = 5;
hitEffect = despawnEffect = Fx.hitBulletColor;
}};
}});
}};
quell = new ErekirUnitType("quell"){{

View File

@@ -145,7 +145,7 @@ public class AIController implements UnitController{
float wrange = weapon.range();
//let uncontrollable weapons do their own thing
if(!weapon.controllable) continue;
if(!weapon.controllable || weapon.noAttack) continue;
float mountX = unit.x + Angles.trnsx(rotation, weapon.x, weapon.y),
mountY = unit.y + Angles.trnsy(rotation, weapon.x, weapon.y);

View File

@@ -35,6 +35,7 @@ public final class FogControl implements CustomChunk{
private @Nullable Thread dynamicFogThread;
private boolean justLoaded = false;
private boolean loadedStatic = false;
public FogControl(){
Events.on(ResetEvent.class, e -> {
@@ -44,19 +45,18 @@ public final class FogControl implements CustomChunk{
Events.on(WorldLoadEvent.class, e -> {
stop();
loadedStatic = false;
justLoaded = true;
ww = world.width();
wh = world.height();
//all old buildings have static light scheduled around them
if(state.rules.fog && state.rules.staticFog){
synchronized(staticEvents){
for(var build : Groups.build){
if(build.block.flags.contains(BlockFlag.hasFogRadius)){
staticEvents.add(FogEvent.get(build.tile.x, build.tile.y, Mathf.round(build.fogRadius()), build.team.id));
}
}
}
pushStaticBlocks();
//force draw all static stuff immediately
updateStatic();
loadedStatic = true;
}
});
@@ -133,6 +133,16 @@ public final class FogControl implements CustomChunk{
}
}
void pushStaticBlocks(){
synchronized(staticEvents){
for(var build : Groups.build){
if(build.block.flags.contains(BlockFlag.hasFogRadius)){
pushEvent(FogEvent.get(build.tile.x, build.tile.y, Mathf.round(build.fogRadius()), build.team.id));
}
}
}
}
void pushEvent(long event){
if(!state.rules.staticFog) return;
@@ -159,6 +169,13 @@ public final class FogControl implements CustomChunk{
fog = new FogData[256];
}
//force update static
if(state.rules.staticFog && !loadedStatic){
pushStaticBlocks();
updateStatic();
loadedStatic = true;
}
//not run clientside, the CPU side isn't needed here.
if(staticFogThread == null && !net.client()){
staticFogThread = new StaticFogThread();
@@ -271,25 +288,29 @@ public final class FogControl implements CustomChunk{
}
}
//I really don't like synchronizing here, but there should be *some* performance benefit at least
synchronized(staticEvents){
int size = staticEvents.size;
for(int i = 0; i < size; i++){
long event = staticEvents.items[i];
int x = FogEvent.x(event), y = FogEvent.y(event), rad = FogEvent.radius(event), team = FogEvent.team(event);
var data = fog[team];
if(data != null){
circle(data.staticData, x, y, rad);
}
}
staticEvents.clear();
}
updateStatic();
//ignore, don't want to crash this thread
}catch(Exception e){}
}
}
}
void updateStatic(){
//I really don't like synchronizing here, but there should be *some* performance benefit at least
synchronized(staticEvents){
int size = staticEvents.size;
for(int i = 0; i < size; i++){
long event = staticEvents.items[i];
int x = FogEvent.x(event), y = FogEvent.y(event), rad = FogEvent.radius(event), team = FogEvent.team(event);
var data = fog[team];
if(data != null){
circle(data.staticData, x, y, rad);
}
}
staticEvents.clear();
}
}
class DynamicFogThread extends Thread{
final Bits cleared = new Bits();

View File

@@ -181,6 +181,8 @@ public class UnitType extends UnlockableContent{
/** If true, all weapons will attack the same target. */
public boolean singleTarget = false;
public boolean forceMultiTarget = false;
/** If false, this unit has no weapons that can attack. */
public boolean canAttack = true;
public boolean hidden = false;
public boolean internal = false;
/** Function used for calculating cost of moving with ControlPathfinder. Does not affect "normal" flow field pathfinding. */
@@ -464,7 +466,7 @@ public class UnitType extends UnlockableContent{
}
if(fogRadius < 0){
fogRadius = Math.max(lightRadius * 3.1f, 1f) / 8f;
fogRadius = Math.max(11f * 2.3f * 3f, hitSize * 2f) / 8f;
}
if(weapons.isEmpty()){
@@ -529,6 +531,8 @@ public class UnitType extends UnlockableContent{
weapons.each(Weapon::init);
canAttack = weapons.contains(w -> !w.noAttack);
//dynamically create ammo capacity based on firing rate
if(ammoCapacity < 0){
float shotsPerSecond = weapons.sumf(w -> w.useAmmo ? 60f / w.reload : 0f);

View File

@@ -89,6 +89,8 @@ public class Weapon implements Cloneable{
public float soundPitchMin = 0.8f, soundPitchMax = 1f;
/** whether shooter rotation is ignored when shooting. */
public boolean ignoreRotation = false;
/** If true, this weapon cannot be used to attack targets. */
public boolean noAttack = false;
/** min velocity required for this weapon to shoot */
public float minShootVelocity = -1f;
/** should the shoot effects follow the unit (effects need followParent set to true for this to work) */

View File

@@ -58,6 +58,7 @@ public class RepairBeamWeapon extends Weapon{
useAmmo = false;
mountType = HealBeamMount::new;
recoil = 0f;
noAttack = true;
}
@Override