Skip to content

Commit

Permalink
Tweak bow stats a bit more
Browse files Browse the repository at this point in the history
Removed power, will just use velocity
Instead of average, stats are additive
Bows no longer have attack speed from materials
  • Loading branch information
KnightMiner committed Dec 13, 2022
1 parent 6370ec5 commit 5c86c34
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,11 @@ public static List<Component> getDefaultStats(IToolStackView tool, @Nullable Pla
if (tool.hasTag(TinkerTags.Items.DURABILITY)) {
builder.addDurability();
}
if (tool.hasTag(TinkerTags.Items.RANGED)) {
builder.add(ToolStats.DRAW_SPEED);
builder.add(ToolStats.VELOCITY);
builder.add(ToolStats.ACCURACY);
}
if (tool.hasTag(TinkerTags.Items.MELEE)) {
builder.addWithAttribute(ToolStats.ATTACK_DAMAGE, Attributes.ATTACK_DAMAGE);
builder.add(ToolStats.ATTACK_SPEED);
Expand All @@ -352,12 +357,6 @@ public static List<Component> getDefaultStats(IToolStackView tool, @Nullable Pla
}
builder.add(ToolStats.MINING_SPEED);
}
if (tool.hasTag(TinkerTags.Items.RANGED)) {
builder.add(ToolStats.DRAW_SPEED);
builder.add(ToolStats.VELOCITY);
builder.add(ToolStats.ACCURACY);
builder.add(ToolStats.POWER);
}

builder.addAllFreeSlots();
for (ModifierEntry entry : tool.getModifierList()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,16 @@ static Component formatColoredMultiplier(String loc, float number) {
float hue = Mth.positiveModulo(number - 0.5f, 2f);
return new TranslatableComponent(loc).append(new TextComponent(Util.MULTIPLIER_FORMAT.format(number)).withStyle(style -> style.withColor(TextColor.fromRgb(Mth.hsvToRgb(hue / 1.5f, 1.0f, 0.75f)))));
}

/**
* Formats a multiplier with hue shifting
* @param loc Prefix location
* @param number Percentage
* @return Colored percent with prefix
*/
static Component formatColoredBonus(String loc, float number, float scale) {
// 0.5 is red, 1.0 should be roughly green, 1.5 is blue
float hue = Mth.positiveModulo(0.5f + number / (2*scale), 2f);
return new TranslatableComponent(loc).append(new TextComponent(Util.BONUS_FORMAT.format(number)).withStyle(style -> style.withColor(TextColor.fromRgb(Mth.hsvToRgb(hue / 1.5f, 1.0f, 0.75f)))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ public class ToolStats {
public static final FloatToolStat VELOCITY = register(new FloatToolStat(name("velocity"), 0xFF78A0CD, 1, 0, 1024f, TinkerTags.Items.RANGED));
/** Starting velocity of the projectile launched from a ranged weapon */
public static final FloatToolStat ACCURACY = register(new FloatToolStat(name("accuracy"), 0xFF8547CC, 0.75f, 0.1f, 1f, TinkerTags.Items.RANGED));
/** Boosts the effectiveness of the projectile fired. This damage will be multiplied by velocity later, effectively making velocity a multiplier */
public static final FloatToolStat POWER = register(new FloatToolStat(name("power"), 0xFFD76464, 0, -10f, 10f, TinkerTags.Items.RANGED));


/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,18 @@ public static <T extends IMaterialStats, N extends Number> double getAverageValu
.average()
.orElse(missingValue);
}

/**
* Gets the average value from a list of stat types
* @param stats Stat list
* @param statGetter Function to get the value
* @param missingValue Default value to use for missing stats
* @param <T> Material type
* @return Average value
*/
public static <T extends IMaterialStats, N extends Number> double getTotalValue(List<T> stats, Function<T, N> statGetter) {
return stats.stream()
.mapToDouble(value -> statGetter.apply(value).doubleValue())
.sum();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,14 @@ protected void setStats(StatsNBT.Builder builder) {
builder.set(ToolStats.DURABILITY, buildDurability());
builder.set(ToolStats.DRAW_SPEED, buildDrawSpeed());
builder.set(ToolStats.VELOCITY, buildVelocity());
builder.set(ToolStats.POWER, buildPower());
builder.set(ToolStats.ACCURACY, buildAccuracy());
builder.set(ToolStats.ATTACK_DAMAGE, buildAttackDamage());
builder.set(ToolStats.ATTACK_SPEED, buildAttackSpeed());
}

@Override
protected boolean handles(IToolStat<?> stat) {
return stat == ToolStats.DURABILITY || stat == ToolStats.DRAW_SPEED
|| stat == ToolStats.VELOCITY || stat == ToolStats.ATTACK_DAMAGE
|| stat == ToolStats.ACCURACY || stat == ToolStats.ATTACK_SPEED;
return stat == ToolStats.DURABILITY || stat == ToolStats.ATTACK_DAMAGE
|| stat == ToolStats.DRAW_SPEED || stat == ToolStats.VELOCITY || stat == ToolStats.ACCURACY;
}

/** Builds durability for the tool */
Expand All @@ -78,38 +75,21 @@ public float buildDurability() {

/** Builds attack speed for the tool */
public float buildDrawSpeed() {
double averageHandleModifier = getAverageValue(limbs, LimbMaterialStats::getDrawSpeed, 1);
return (float)Math.max(0, getStatOrDefault(ToolStats.DRAW_SPEED, 1f) * averageHandleModifier);
return (float)Math.max(0, getStatOrDefault(ToolStats.DRAW_SPEED, 1f) + getTotalValue(limbs, LimbMaterialStats::getDrawSpeed));
}

/** Builds velocity for the tool */
public float buildVelocity() {
double averageHandleModifier = getAverageValue(limbs, LimbMaterialStats::getVelocity, 1);
return (float)Math.max(0, getStatOrDefault(ToolStats.VELOCITY, 1f) * averageHandleModifier);
return (float)Math.max(0, getStatOrDefault(ToolStats.VELOCITY, 1f) + getTotalValue(limbs, LimbMaterialStats::getVelocity) + getTotalValue(grips, GripMaterialStats::getVelocity));
}

/** Builds velocity for the tool */
public float buildAccuracy() {
double gripBonus = getAverageValue(grips, GripMaterialStats::getAccuracy, 1);
return (float)Math.max(0, getStatOrDefault(ToolStats.ACCURACY, 0f) + gripBonus);
}

/** Builds velocity for the tool */
public float buildPower() {
double gripBonus = getAverageValue(grips, GripMaterialStats::getPower, 1);
return (float)Math.max(0, getStatOrDefault(ToolStats.POWER, 0f) + gripBonus);
return (float)Math.max(0, getStatOrDefault(ToolStats.ACCURACY, 0.75f) + getTotalValue(limbs, LimbMaterialStats::getAccuracy) + getTotalValue(grips, GripMaterialStats::getAccuracy));
}

/** Builds attack damage for the tool */
public float buildAttackDamage() {
double averageLimbAttack = getAverageValue(limbs, LimbMaterialStats::getMeleeAttack) + getStatOrDefault(ToolStats.ATTACK_DAMAGE, 0f);
return (float)Math.max(0.0d, averageLimbAttack);
}

/** Builds attack speed for the tool */
public float buildAttackSpeed() {
float baseSpeed = toolData.getBaseStat(ToolStats.ATTACK_SPEED);
double averageHandleModifier = getAverageValue(grips, GripMaterialStats::getAttackSpeed, 1);
return (float)Math.max(0, baseSpeed * averageHandleModifier);
return (float)Math.max(0.0d, getStatOrDefault(ToolStats.ATTACK_DAMAGE, 0f) + getAverageValue(grips, GripMaterialStats::getMeleeAttack));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ public void releaseUsing(ItemStack stack, Level level, LivingEntity living, int
if (charge == 1.0F) {
arrowEntity.setCritArrow(true);
}
// half the power stat, as 0.5 is roughly 1 damage at full charge for a wooden bow
arrowEntity.setBaseDamage(arrowEntity.getBaseDamage() + 0.5 * stats.get(ToolStats.POWER));

ToolDamageUtil.damageAnimated(tool, 1, player, player.getUsedItemHand());
// if infinite, skip pickup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

import java.util.List;

import static slimeknights.tconstruct.tools.stats.LimbMaterialStats.ACCURACY_PREFIX;
import static slimeknights.tconstruct.tools.stats.LimbMaterialStats.VELOCITY_PREFIX;

/** Secondary stats for a bow */
@RequiredArgsConstructor
@Getter
Expand All @@ -25,37 +28,35 @@
@With
public class GripMaterialStats extends BaseMaterialStats {
public static final MaterialStatsId ID = new MaterialStatsId(TConstruct.getResource("grip"));
public static final GripMaterialStats DEFAULT = new GripMaterialStats(1f, 0.5f, 0f, 1f);
public static final GripMaterialStats DEFAULT = new GripMaterialStats(1f, 0f, 0f, 0f);

// tooltip prefixes
private static final String DURABILITY_PREFIX = makeTooltipKey(TConstruct.getResource("durability"));
private static final String ACCURACY_PREFIX = makeTooltipKey(TConstruct.getResource("accuracy"));
private static final String ATTACK_SPEED_PREFIX = makeTooltipKey(TConstruct.getResource("attack_speed"));
// description
private static final List<Component> DESCRIPTION = ImmutableList.of(
makeTooltip(TConstruct.getResource("handle.durability.description")),
ToolStats.ACCURACY.getDescription(),
ToolStats.POWER.getDescription(),
ToolStats.ATTACK_SPEED.getDescription());
ToolStats.VELOCITY.getDescription(),
ToolStats.ATTACK_DAMAGE.getDescription());

private final float durability;
private final float accuracy;
private final float power;
private final float attackSpeed;
private final float velocity;
private final float meleeAttack;

public GripMaterialStats(FriendlyByteBuf buffer) {
this.durability = buffer.readFloat();
this.accuracy = buffer.readFloat();
this.power = buffer.readFloat();
this.attackSpeed = buffer.readFloat();
this.velocity = buffer.readFloat();
this.meleeAttack = buffer.readFloat();
}

@Override
public void encode(FriendlyByteBuf buffer) {
buffer.writeFloat(durability);
buffer.writeFloat(accuracy);
buffer.writeFloat(power);
buffer.writeFloat(attackSpeed);
buffer.writeFloat(velocity);
buffer.writeFloat(meleeAttack);
}

@Override
Expand All @@ -67,9 +68,9 @@ public MaterialStatsId getIdentifier() {
public List<Component> getLocalizedInfo() {
List<Component> info = Lists.newArrayList();
info.add(IToolStat.formatColoredMultiplier(DURABILITY_PREFIX, this.durability));
info.add(IToolStat.formatColoredMultiplier(ACCURACY_PREFIX, this.accuracy));
info.add(ToolStats.POWER.formatValue(this.power));
info.add(ToolStats.ATTACK_SPEED.formatValue(this.attackSpeed));
info.add(IToolStat.formatColoredBonus(ACCURACY_PREFIX, this.accuracy, 0.5f));
info.add(IToolStat.formatColoredBonus(VELOCITY_PREFIX, this.velocity, 0.5f));
info.add(ToolStats.ATTACK_DAMAGE.formatValue(this.meleeAttack));
return info;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import slimeknights.tconstruct.library.materials.stats.BaseMaterialStats;
import slimeknights.tconstruct.library.materials.stats.IRepairableMaterialStats;
import slimeknights.tconstruct.library.materials.stats.MaterialStatsId;
import slimeknights.tconstruct.library.tools.stat.IToolStat;
import slimeknights.tconstruct.library.tools.stat.ToolStats;

import java.util.List;
Expand All @@ -23,28 +24,31 @@
@ToString
public class LimbMaterialStats extends BaseMaterialStats implements IRepairableMaterialStats {
public static final MaterialStatsId ID = new MaterialStatsId(TConstruct.getResource("limb"));
public static final LimbMaterialStats DEFAULT = new LimbMaterialStats(1, 1f, 1f, 1f);
public static final LimbMaterialStats DEFAULT = new LimbMaterialStats(1, 0f, 0f, 0f);
static final String ACCURACY_PREFIX = makeTooltipKey(TConstruct.getResource("accuracy"));
static final String DRAW_SPEED_PREFIX = makeTooltipKey(TConstruct.getResource("draw_speed"));
static final String VELOCITY_PREFIX = makeTooltipKey(TConstruct.getResource("velocity"));
// tooltip descriptions
private static final List<Component> DESCRIPTION = ImmutableList.of(ToolStats.DURABILITY.getDescription(), ToolStats.DRAW_SPEED.getDescription(), ToolStats.VELOCITY.getDescription(), ToolStats.ATTACK_DAMAGE.getDescription());

private final int durability;
private final float drawSpeed;
private final float velocity;
private final float meleeAttack;
private final float accuracy;

public LimbMaterialStats(FriendlyByteBuf buffer) {
this.durability = buffer.readInt();
this.drawSpeed = buffer.readFloat();
this.velocity = buffer.readFloat();
this.meleeAttack = buffer.readFloat();
this.accuracy = buffer.readFloat();
}

@Override
public void encode(FriendlyByteBuf buffer) {
buffer.writeInt(durability);
buffer.writeFloat(drawSpeed);
buffer.writeFloat(velocity);
buffer.writeFloat(meleeAttack);
buffer.writeFloat(accuracy);
}

@Override
Expand All @@ -56,9 +60,9 @@ public MaterialStatsId getIdentifier() {
public List<Component> getLocalizedInfo() {
List<Component> info = Lists.newArrayList();
info.add(ToolStats.DURABILITY.formatValue(this.durability));
info.add(ToolStats.DRAW_SPEED.formatValue(this.drawSpeed));
info.add(ToolStats.VELOCITY.formatValue(this.velocity));
info.add(ToolStats.ATTACK_DAMAGE.formatValue(this.meleeAttack));
info.add(IToolStat.formatColoredBonus(DRAW_SPEED_PREFIX, this.drawSpeed, 0.5f));
info.add(IToolStat.formatColoredBonus(VELOCITY_PREFIX, this.velocity, 0.5f));
info.add(IToolStat.formatColoredBonus(ACCURACY_PREFIX, this.accuracy, 0.5f));
return info;
}

Expand Down
7 changes: 2 additions & 5 deletions src/main/resources/assets/tconstruct/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -2378,16 +2378,13 @@
"tool_stat.tconstruct.handle.mining_speed.description": "The total mining speed of the tool will be multiplied by this.",

"stat.tconstruct.limb": "Limb",
"stat.tconstruct.grip": "Grip",
"tool_stat.tconstruct.draw_speed": "Draw Speed: ",
"tool_stat.tconsturct.draw_speed.description": "Determines the number of times this tool can be used per second.",
"tool_stat.tconstruct.velocity": "Velocity: ",
"tool_stat.tconstruct.velocity.description": "Determines how quickly arrows fly after firing. Faster arrows deal more damage.",

"stat.tconstruct.grip": "Grip",
"tool_stat.tconstruct.accuracy": "Accuracy: ",
"tool_stat.tconsturct.draw_speed.description": "Determines how close the bow aims towards the center.",
"tool_stat.tconstruct.power": "Power: ",
"tool_stat.tconstruct.power.description": "Determines the base effect of the projectile, before accounting for velocity.",
"tool_stat.tconsturct.accuracy.description": "Determines how close the bow aims towards the center.",

"stat.tconstruct.extra": "Binding",
"stat.tconstruct.bowstring": "Bowstring",
Expand Down

0 comments on commit 5c86c34

Please sign in to comment.