Added dynamic status for custom speed/health/etc
This commit is contained in:
@@ -20,10 +20,12 @@ abstract class StatusComp implements Posc, Flyingc{
|
||||
private transient Bits applied = new Bits(content.getBy(ContentType.status).size);
|
||||
|
||||
//these are considered read-only
|
||||
transient float speedMultiplier = 1, damageMultiplier = 1, healthMultiplier = 1, reloadMultiplier = 1, buildSpeedMultiplier = 1, dragMultiplier = 1;
|
||||
//note: armor is a special case; it is an override when >= 0, otherwise ignored
|
||||
transient float speedMultiplier = 1, damageMultiplier = 1, healthMultiplier = 1, reloadMultiplier = 1, buildSpeedMultiplier = 1, dragMultiplier = 1, armorOverride = -1f;
|
||||
transient boolean disarmed = false;
|
||||
|
||||
@Import UnitType type;
|
||||
@Import float maxHealth;
|
||||
|
||||
/** Apply a status effect for 1 tick (for permanent effects) **/
|
||||
void apply(StatusEffect effect){
|
||||
@@ -108,6 +110,62 @@ abstract class StatusComp implements Posc, Flyingc{
|
||||
return Tmp.c1.set(r / count, g / count, b / count, 1f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a dynamic status effect, with stat multipliers that can be customized.
|
||||
* @return the entry to write multipliers to. If the dynamic status was already applied, returns the previous entry.
|
||||
* */
|
||||
public StatusEntry applyDynamicStatus(){
|
||||
if(hasEffect(StatusEffects.dynamic)){
|
||||
StatusEntry entry = statuses.find(s -> s.effect.dynamic);
|
||||
if(entry != null) return entry;
|
||||
}
|
||||
|
||||
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
|
||||
entry.set(StatusEffects.dynamic, Float.POSITIVE_INFINITY);
|
||||
statuses.add(entry);
|
||||
entry.effect.applied(self(), entry.time, false);
|
||||
return entry;
|
||||
}
|
||||
|
||||
/** Uses a dynamic status effect to override speed. */
|
||||
public void statusSpeed(float speed){
|
||||
//type.speed should never be 0
|
||||
applyDynamicStatus().speedMultiplier = speed / type.speed;
|
||||
}
|
||||
|
||||
/** Uses a dynamic status effect to change damage. */
|
||||
public void statusDamageMultiplier(float damageMultiplier){
|
||||
applyDynamicStatus().damageMultiplier = damageMultiplier;
|
||||
}
|
||||
|
||||
/** Uses a dynamic status effect to change reload. */
|
||||
public void statusReloadMultiplier(float reloadMultiplier){
|
||||
applyDynamicStatus().reloadMultiplier = reloadMultiplier;
|
||||
}
|
||||
|
||||
/** Uses a dynamic status effect to override max health. */
|
||||
public void statusMaxHealth(float health){
|
||||
//maxHealth should never be zero
|
||||
applyDynamicStatus().healthMultiplier = health / maxHealth;
|
||||
}
|
||||
|
||||
/** Uses a dynamic status effect to override build speed. */
|
||||
public void statusBuildSpeed(float buildSpeed){
|
||||
//build speed should never be zero
|
||||
applyDynamicStatus().buildSpeedMultiplier = buildSpeed / type.buildSpeed;
|
||||
}
|
||||
|
||||
/** Uses a dynamic status effect to override drag. */
|
||||
public void statusDrag(float drag){
|
||||
//prevent divide by 0 (drag can be zero, if someone makes a broken unit)
|
||||
applyDynamicStatus().dragMultiplier = type.drag == 0f ? 0f : drag / type.drag;
|
||||
}
|
||||
|
||||
/** Uses a dynamic status effect to override armor. */
|
||||
public void statusArmor(float armor){
|
||||
applyDynamicStatus().armorOverride = armor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
Floor floor = floorOn();
|
||||
@@ -117,6 +175,7 @@ abstract class StatusComp implements Posc, Flyingc{
|
||||
}
|
||||
|
||||
applied.clear();
|
||||
armorOverride = -1f;
|
||||
speedMultiplier = damageMultiplier = healthMultiplier = reloadMultiplier = buildSpeedMultiplier = dragMultiplier = 1f;
|
||||
disarmed = false;
|
||||
|
||||
@@ -136,12 +195,24 @@ abstract class StatusComp implements Posc, Flyingc{
|
||||
}else{
|
||||
applied.set(entry.effect.id);
|
||||
|
||||
speedMultiplier *= entry.effect.speedMultiplier;
|
||||
healthMultiplier *= entry.effect.healthMultiplier;
|
||||
damageMultiplier *= entry.effect.damageMultiplier;
|
||||
reloadMultiplier *= entry.effect.reloadMultiplier;
|
||||
buildSpeedMultiplier *= entry.effect.buildSpeedMultiplier;
|
||||
dragMultiplier *= entry.effect.dragMultiplier;
|
||||
//TODO this is very ugly...
|
||||
if(entry.effect.dynamic){
|
||||
speedMultiplier *= entry.speedMultiplier;
|
||||
healthMultiplier *= entry.healthMultiplier;
|
||||
damageMultiplier *= entry.damageMultiplier;
|
||||
reloadMultiplier *= entry.reloadMultiplier;
|
||||
buildSpeedMultiplier *= entry.buildSpeedMultiplier;
|
||||
dragMultiplier *= entry.dragMultiplier;
|
||||
//armor is a special case; many units have it set it to 0, so an override at values >= 0 is used
|
||||
if(entry.armorOverride >= 0f) armorOverride = entry.armorOverride;
|
||||
}else{
|
||||
speedMultiplier *= entry.effect.speedMultiplier;
|
||||
healthMultiplier *= entry.effect.healthMultiplier;
|
||||
damageMultiplier *= entry.effect.damageMultiplier;
|
||||
reloadMultiplier *= entry.effect.reloadMultiplier;
|
||||
buildSpeedMultiplier *= entry.effect.buildSpeedMultiplier;
|
||||
dragMultiplier *= entry.effect.dragMultiplier;
|
||||
}
|
||||
|
||||
disarmed |= entry.effect.disarm;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user