Fog fixes / Weapon attack fixes / Avert weapon
This commit is contained in:
@@ -173,6 +173,6 @@ public class BuilderAI extends AIController{
|
||||
|
||||
@Override
|
||||
public boolean shouldShoot(){
|
||||
return !unit.isBuilding();
|
||||
return !unit.isBuilding() && unit.type.canAttack;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"){{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -58,6 +58,7 @@ public class RepairBeamWeapon extends Weapon{
|
||||
useAmmo = false;
|
||||
mountType = HealBeamMount::new;
|
||||
recoil = 0f;
|
||||
noAttack = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user