mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 23:37:32 +00:00
Fix Chained Ability Icons + Chained Ability Per Cooldown Config Options
This commit is contained in:
1 parent
ac953685c8
commit
ab60fdbd12
5 files changed
+73
-12
No files matched your search
@@ -51,6 +51,16 @@ public class ChainedAbility implements IChainedAbility, IAbilityAction {
|
||||
*/
|
||||
private int cooldownTicks = 100;
|
||||
|
||||
/**
|
||||
* If true, only this chain goes on cooldown (not the global cooldown).
|
||||
*/
|
||||
private boolean perAbilityCooldown = false;
|
||||
|
||||
/**
|
||||
* If true, skip cooldown entirely after chain completes.
|
||||
*/
|
||||
private boolean ignoreCooldown = false;
|
||||
|
||||
/**
|
||||
* Minimum range for NPC eligibility check.
|
||||
*/
|
||||
@@ -159,6 +169,22 @@ public class ChainedAbility implements IChainedAbility, IAbilityAction {
|
||||
this.cooldownTicks = Math.max(0, cooldownTicks);
|
||||
}
|
||||
|
||||
public boolean isPerAbilityCooldown() {
|
||||
return perAbilityCooldown;
|
||||
}
|
||||
|
||||
public void setPerAbilityCooldown(boolean perAbilityCooldown) {
|
||||
this.perAbilityCooldown = perAbilityCooldown;
|
||||
}
|
||||
|
||||
public boolean isIgnoreCooldown() {
|
||||
return ignoreCooldown;
|
||||
}
|
||||
|
||||
public void setIgnoreCooldown(boolean ignoreCooldown) {
|
||||
this.ignoreCooldown = ignoreCooldown;
|
||||
}
|
||||
|
||||
public float getMinRange() {
|
||||
return minRange;
|
||||
}
|
||||
@@ -402,6 +428,8 @@ public class ChainedAbility implements IChainedAbility, IAbilityAction {
|
||||
nbt.setInteger("Weight", weight);
|
||||
nbt.setBoolean("WindUpAll", windUpAll);
|
||||
nbt.setInteger("CooldownTicks", cooldownTicks);
|
||||
nbt.setBoolean("PerAbilityCooldown", perAbilityCooldown);
|
||||
nbt.setBoolean("IgnoreCooldown", ignoreCooldown);
|
||||
nbt.setFloat("MinRange", minRange);
|
||||
nbt.setFloat("MaxRange", maxRange);
|
||||
|
||||
@@ -443,6 +471,8 @@ public class ChainedAbility implements IChainedAbility, IAbilityAction {
|
||||
weight = nbt.hasKey("Weight") ? nbt.getInteger("Weight") : 10;
|
||||
windUpAll = !nbt.hasKey("WindUpAll") || nbt.getBoolean("WindUpAll");
|
||||
cooldownTicks = nbt.hasKey("CooldownTicks") ? nbt.getInteger("CooldownTicks") : 100;
|
||||
perAbilityCooldown = nbt.getBoolean("PerAbilityCooldown");
|
||||
ignoreCooldown = nbt.getBoolean("IgnoreCooldown");
|
||||
minRange = nbt.getFloat("MinRange");
|
||||
maxRange = nbt.hasKey("MaxRange") ? nbt.getFloat("MaxRange") : 20;
|
||||
// AllowedBy is computed from child abilities
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
import static kamkeel.npcs.controllers.data.ability.conditions.AbilityCondition.MAX_CONDITIONS;
|
||||
|
||||
@@ -153,7 +154,11 @@ public class SubGuiChainedAbilityConfig extends SubGuiInterface implements IText
|
||||
fieldDefs.add(FieldDef.boolField("gui.enabled", chain::isEnabled, chain::setEnabled).tab("General"));
|
||||
fieldDefs.add(FieldDef.intField("ability.weight", chain::getWeight, chain::setWeight).range(1, 100).tab("General"));
|
||||
fieldDefs.add(FieldDef.boolField("ability.windUpAll", chain::isWindUpAll, chain::setWindUpAll).tab("General"));
|
||||
fieldDefs.add(FieldDef.intField("ability.cooldown", chain::getCooldownTicks, chain::setCooldownTicks).range(0, 12000).tab("General"));
|
||||
fieldDefs.add(FieldDef.row(
|
||||
FieldDef.intField("ability.cooldown", chain::getCooldownTicks, chain::setCooldownTicks).range(0, 12000),
|
||||
FieldDef.boolField("ability.perAbilityCooldown", chain::isPerAbilityCooldown, chain::setPerAbilityCooldown)
|
||||
).tab("General"));
|
||||
fieldDefs.add(FieldDef.boolField("ability.ignoreCooldown", chain::isIgnoreCooldown, chain::setIgnoreCooldown).tab("General"));
|
||||
|
||||
// ── Target tab ───────────────────────────────────────────────
|
||||
fieldDefs.add(FieldDef.row(
|
||||
@@ -163,16 +168,20 @@ public class SubGuiChainedAbilityConfig extends SubGuiInterface implements IText
|
||||
|
||||
// ── Icon tab ──────────────────────────────────────────────
|
||||
AbilityIconData chainIcon = AbilityIconData.fromChainedAbility(chain);
|
||||
BooleanSupplier isCustomIcon = chainIcon::isEnabled;
|
||||
|
||||
fieldDefs.add(FieldDef.section("ability.section.icon").tab("Icon"));
|
||||
fieldDefs.add(FieldDef.boolField("ability.hasIcon", chainIcon::isEnabled, chainIcon::setEnabled).tab("Icon"));
|
||||
fieldDefs.add(FieldDef.row(
|
||||
FieldDef.intField("gui.width", chainIcon::getWidth, chainIcon::setWidth).range(1, 256),
|
||||
FieldDef.intField("gui.height", chainIcon::getHeight, chainIcon::setHeight).range(1, 256)
|
||||
).tab("Icon"));
|
||||
fieldDefs.add(FieldDef.floatField("gui.scale", chainIcon::getScale, chainIcon::setScale).tab("Icon").range(0.1f, 10.0f));
|
||||
).tab("Icon").visibleWhen(isCustomIcon));
|
||||
fieldDefs.add(FieldDef.floatField("gui.scale", chainIcon::getScale, chainIcon::setScale).tab("Icon").range(0.1f, 10.0f).visibleWhen(isCustomIcon));
|
||||
fieldDefs.add(FieldDef.intField("ability.icon.layers", chainIcon::getLayerCount, chainIcon::setLayerCount)
|
||||
.tab("Icon").range(1, AbilityIconData.MAX_LAYERS));
|
||||
.tab("Icon").range(1, AbilityIconData.MAX_LAYERS).visibleWhen(isCustomIcon));
|
||||
for (int i = 0; i < AbilityIconData.MAX_LAYERS; i++) {
|
||||
final int idx = i;
|
||||
java.util.function.BooleanSupplier layerVisible = () -> chainIcon.getLayerCount() > idx;
|
||||
java.util.function.BooleanSupplier layerVisible = () -> isCustomIcon.getAsBoolean() && chainIcon.getLayerCount() > idx;
|
||||
String sectionLabel = net.minecraft.util.StatCollector.translateToLocal("ability.icon.layer") + " " + (idx + 1);
|
||||
fieldDefs.add(FieldDef.section(sectionLabel).tab("Icon").visibleWhen(layerVisible));
|
||||
fieldDefs.add(FieldDef.textureSubGui("gui.texture",
|
||||
@@ -194,12 +203,12 @@ public class SubGuiChainedAbilityConfig extends SubGuiInterface implements IText
|
||||
}
|
||||
|
||||
// Animation
|
||||
fieldDefs.add(FieldDef.section("Animation").tab("Icon"));
|
||||
fieldDefs.add(FieldDef.boolField("gui.animated", chainIcon::isAnimated, chainIcon::setAnimated).tab("Icon").hover("gui.animated.hover"));
|
||||
fieldDefs.add(FieldDef.section("Animation").tab("Icon").visibleWhen(isCustomIcon));
|
||||
fieldDefs.add(FieldDef.boolField("gui.animated", chainIcon::isAnimated, chainIcon::setAnimated).tab("Icon").hover("gui.animated.hover").visibleWhen(isCustomIcon));
|
||||
fieldDefs.add(FieldDef.intField("gui.frameCount", chainIcon::getFrameCount, chainIcon::setFrameCount)
|
||||
.tab("Icon").range(1, 256).visibleWhen(chainIcon::isAnimated));
|
||||
.tab("Icon").range(1, 256).visibleWhen(() -> isCustomIcon.getAsBoolean() && chainIcon.isAnimated()));
|
||||
fieldDefs.add(FieldDef.intField("gui.frameTime", chainIcon::getFrameTime, chainIcon::setFrameTime)
|
||||
.tab("Icon").range(1, 100).visibleWhen(chainIcon::isAnimated));
|
||||
.tab("Icon").range(1, 100).visibleWhen(() -> isCustomIcon.getAsBoolean() && chainIcon.isAnimated()));
|
||||
|
||||
// External field providers (e.g., DBC Addon injecting a "DBC" tab)
|
||||
if (AbilityController.Instance != null) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.AbilityController;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.data.ChainedAbility;
|
||||
import kamkeel.npcs.controllers.data.ability.data.IAbilityAction;
|
||||
import kamkeel.npcs.network.PacketHandler;
|
||||
import kamkeel.npcs.network.packets.player.ability.AbilityHotbarSelectPacket;
|
||||
@@ -638,9 +639,12 @@ public class AbilityHotbarComponent extends HudComponent {
|
||||
|
||||
String key = slots[slotIndex].abilityKey;
|
||||
Ability ability = slots[slotIndex].ability;
|
||||
IAbilityAction action = slots[slotIndex].action;
|
||||
|
||||
if (ability != null && ability.isPerAbilityCooldown()) {
|
||||
return playerData.abilityData.getPerAbilityCooldownProgress(key);
|
||||
} else if (action instanceof ChainedAbility && ((ChainedAbility) action).isPerAbilityCooldown()) {
|
||||
return playerData.abilityData.getPerAbilityCooldownProgress(key);
|
||||
} else {
|
||||
return playerData.abilityData.getGlobalCooldownProgress();
|
||||
}
|
||||
|
||||
@@ -237,9 +237,19 @@ public class PlayerAbilityData extends AbstractDataAbilities implements IPlayerA
|
||||
|
||||
@Override
|
||||
protected void rollChainCooldown(ChainedAbility chain) {
|
||||
if (chain.isIgnoreCooldown()) return;
|
||||
|
||||
int duration = chain.getCooldownTicks();
|
||||
cooldownEndTime = getWorldTime() + duration;
|
||||
globalCooldownDuration = duration;
|
||||
long endTime = getWorldTime() + duration;
|
||||
|
||||
if (chain.isPerAbilityCooldown()) {
|
||||
if (currentAbilityKey != null) {
|
||||
setPerAbilityCooldown(currentAbilityKey, endTime, duration);
|
||||
}
|
||||
} else {
|
||||
cooldownEndTime = endTime;
|
||||
globalCooldownDuration = duration;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -403,7 +413,14 @@ public class PlayerAbilityData extends AbstractDataAbilities implements IPlayerA
|
||||
|
||||
// Dispatch: chain vs ability
|
||||
if (action.isChain()) {
|
||||
if (isOnCooldown()) return false;
|
||||
ChainedAbility chain = (ChainedAbility) action;
|
||||
if (!chain.isIgnoreCooldown()) {
|
||||
if (chain.isPerAbilityCooldown()) {
|
||||
if (isOnPerAbilityCooldown(key)) return false;
|
||||
} else {
|
||||
if (isOnCooldown()) return false;
|
||||
}
|
||||
}
|
||||
|
||||
currentAbilityKey = key;
|
||||
currentTarget = null;
|
||||
|
||||
@@ -1736,6 +1736,7 @@ ability.weight=Weight
|
||||
ability.windUpTicks=Wind Up
|
||||
ability.cooldownTicks=Cooldown
|
||||
ability.perAbilityCooldown=Per-Ability
|
||||
ability.ignoreCooldown=Ignore Cooldown
|
||||
ability.freeOnCast=Free on Cast
|
||||
ability.hover.freeOnCast=Ability enters cooldown immediately after entities are spawned, allowing the caster to use other abilities while summoned entities remain active
|
||||
ability.freeAim=Free Aim
|
||||
|
||||
Reference in new issue
Block a user