Skip to content

Commit

Permalink
Implemented a custom radial version of Mekanism's "Attack Amplificati…
Browse files Browse the repository at this point in the history
…on Unit" and reworked damage/energy evaluation.

Now attack damage increases with available energy and bonus attack damage (which in turn depends on the enabled mekaweapons:attackamplification_unit(s)).
For example, let's say we have enough units installed to select "High (16)":
  - energy < defaultEnergyUsage --> attackDamage = 0
  - defaultEnergyUsage <= energy < energyNeeded --> baseDamage (=50) <= attackDamage < baseDamage * damageMultiplicator (=150)
  - energyNeeded <= energy --> attackDamage = baseDamage * damageMultiplicator (=150)
Korean(ko_kr) and Chinese(zh_cn) translations are not implemented.
  • Loading branch information
Achille004 committed Sep 22, 2024
1 parent 12462cc commit fafa50e
Show file tree
Hide file tree
Showing 19 changed files with 411 additions and 46 deletions.
2 changes: 1 addition & 1 deletion gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
Expand Down
45 changes: 39 additions & 6 deletions src/main/java/meranha/mekaweapons/MekaWeapons.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@

import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;

import com.mojang.logging.LogUtils;

import mekanism.api.MekanismIMC;
import mekanism.api.gear.config.ModuleEnumConfig;
import mekanism.client.ClientRegistrationUtil;
import mekanism.common.Mekanism;
import mekanism.common.attachments.containers.ContainerType;
Expand All @@ -24,11 +28,14 @@
import mekanism.common.registration.impl.ModuleRegistryObject;
import mekanism.common.registries.MekanismCreativeTabs;
import mekanism.common.registries.MekanismModules;
import mekanism.common.util.MekanismUtils.ResourceType;
import meranha.mekaweapons.items.ItemMagnetizer;
import meranha.mekaweapons.items.ItemMekaBow;
import meranha.mekaweapons.items.ItemMekaTana;
import meranha.mekaweapons.items.MekaArrowEntity;
import meranha.mekaweapons.items.MekaArrowRenderer;
import meranha.mekaweapons.items.ModuleWeaponAttackAmplificationUnit;
import meranha.mekaweapons.items.ModuleWeaponAttackAmplificationUnit.AttackDamage;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionHand;
Expand All @@ -48,6 +55,7 @@
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.IConfigSpec;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.fml.event.lifecycle.InterModEnqueueEvent;
import net.neoforged.neoforge.client.event.EntityRenderersEvent.RegisterRenderers;
import net.neoforged.neoforge.common.NeoForge;
Expand All @@ -61,6 +69,8 @@
@Mod(MekaWeapons.MODID)
public class MekaWeapons {
public static final String MODID = "mekaweapons";
public static final Logger logger = LogUtils.getLogger();

public static final WeaponsConfig general = new WeaponsConfig();
private static final Map<IConfigSpec, IMekanismConfig> KNOWN_CONFIGS = new HashMap<>();

Expand All @@ -70,21 +80,29 @@ public class MekaWeapons {
public static final ModuleRegistryObject<?> DRAWSPEED_UNIT = MODULES.registerMarker("drawspeed_unit", () -> MekaWeapons.MODULE_DRAWSPEED.asItem(), builder -> builder.maxStackSize(3));
public static final ModuleRegistryObject<?> GRAVITYDAMPENER_UNIT = MODULES.registerMarker("gravitydampener_unit", () -> MekaWeapons.MODULE_GRAVITYDAMPENER.asItem());
//public static final ModuleRegistryObject<?> ARROWVELOCITY_UNIT = MODULES.registerMarker("arrowvelocity_unit", () -> MekaWeapons.MODULE_ARROWVELOCITY.asItem(), builder -> builder.maxStackSize(8));
public static final ModuleRegistryObject<ModuleWeaponAttackAmplificationUnit> ATTACKAMPLIFICATION_UNIT = MODULES.register("attackamplification_unit",
ModuleWeaponAttackAmplificationUnit::new, () -> MekaWeapons.MODULE_ATTACKAMPLIFICATION.asItem(), builder -> builder.maxStackSize(AttackDamage.values().length - 2).handlesModeChange().rendersHUD()
.addInstalledCountConfig(
installed -> ModuleEnumConfig.createBounded(ModuleWeaponAttackAmplificationUnit.ATTACK_DAMAGE, AttackDamage.MED, installed + 2),
installed -> ModuleEnumConfig.codec(AttackDamage.CODEC, AttackDamage.class, installed + 2),
installed -> ModuleEnumConfig.streamCodec(AttackDamage.STREAM_CODEC, AttackDamage.class, installed + 2)
)
);

public static final ItemDeferredRegister ITEMS = new ItemDeferredRegister(MekaWeapons.MODID);
public static final ItemRegistryObject<ItemMekaTana> MEKA_TANA = ITEMS.registerUnburnable("meka_tana", ItemMekaTana::new)
.addAttachedContainerCapabilities(ContainerType.ENERGY, () -> EnergyContainersBuilder.builder()
.addContainer((type, attachedTo, containerIndex) -> new ComponentBackedNoClampEnergyContainer(attachedTo, containerIndex, BasicEnergyContainer.manualOnly,
BasicEnergyContainer.alwaysTrue, () -> ModuleEnergyUnit.getChargeRate(attachedTo, MekaWeapons.general.mekaTanaBaseChargeRate),
() -> ModuleEnergyUnit.getEnergyCapacity(attachedTo, MekaWeapons.general.mekaTanaBaseEnergyCapacity)))
.build());
.build(), MekaWeapons.general);

public static final ItemRegistryObject<ItemMekaBow> MEKA_BOW = ITEMS.registerUnburnable("meka_bow", ItemMekaBow::new)
.addAttachedContainerCapabilities(ContainerType.ENERGY, () -> EnergyContainersBuilder.builder()
.addContainer((type, attachedTo, containerIndex) -> new ComponentBackedNoClampEnergyContainer(attachedTo, containerIndex, BasicEnergyContainer.manualOnly,
BasicEnergyContainer.alwaysTrue, () -> ModuleEnergyUnit.getChargeRate(attachedTo, MekaWeapons.general.mekaBowBaseChargeRate),
() -> ModuleEnergyUnit.getEnergyCapacity(attachedTo, MekaWeapons.general.mekaBowBaseEnergyCapacity)))
.build());
.build(), MekaWeapons.general);

public static final ItemRegistryObject<ItemMagnetizer> MAGNETIZER = ITEMS.registerUnburnable("magnetizer", ItemMagnetizer::new);
public static final ItemRegistryObject<Item> KATANA_BLADE = ITEMS.register("katana_blade");
Expand All @@ -95,6 +113,8 @@ public class MekaWeapons {
public static final ItemRegistryObject<ItemModule> MODULE_DRAWSPEED = ITEMS.registerModule(MekaWeapons.DRAWSPEED_UNIT, Rarity.RARE);
public static final ItemRegistryObject<ItemModule> MODULE_GRAVITYDAMPENER = ITEMS.registerModule(MekaWeapons.GRAVITYDAMPENER_UNIT, Rarity.EPIC);
//public static final ItemRegistryObject<ItemModule> MODULE_ARROWVELOCITY = ITEMS.registerModule(MekaWeapons.ARROWVELOCITY_UNIT);
public static final ItemRegistryObject<ItemModule> MODULE_ATTACKAMPLIFICATION = ITEMS.registerModule(MekaWeapons.ATTACKAMPLIFICATION_UNIT, Rarity.UNCOMMON);
// todo add looting for meka-tana?

public static final EntityTypeDeferredRegister ENTITY_TYPES = new EntityTypeDeferredRegister(MODID);
public static final DeferredHolder<EntityType<?>, EntityType<MekaArrowEntity>> MEKA_ARROW = ENTITY_TYPES.register("meka_arrow", () -> EntityType.Builder.<MekaArrowEntity>of(MekaArrowEntity::new, MobCategory.MISC).sized(0.5F, 0.5F).clientTrackingRange(4).updateInterval(20).build(MODID + ":meka_arrow"));
Expand All @@ -104,6 +124,7 @@ public MekaWeapons(IEventBus modEventBus, ModContainer modContainer) {
MekaWeapons.MODULES.register(modEventBus);
MekaWeapons.ENTITY_TYPES.register(modEventBus);
MekanismConfigHelper.registerConfig(KNOWN_CONFIGS, modContainer, general);
modEventBus.addListener(this::commonSetup);
modEventBus.addListener(this::buildCreativeModeTabContents);
modEventBus.addListener(this::sendCustomModules);
modEventBus.addListener(this::registerRenderers);
Expand All @@ -117,7 +138,17 @@ public static ResourceLocation rl(String path) {
return ResourceLocation.fromNamespaceAndPath(MekaWeapons.MODID, path);
}

private void buildCreativeModeTabContents(BuildCreativeModeTabContentsEvent event) {
@NotNull
@Contract("_, _ -> new")
public static ResourceLocation getResource(@NotNull ResourceType type, String name) {
return MekaWeapons.rl(type.getPrefix() + name);
}

private void commonSetup(FMLCommonSetupEvent event) {
MekaWeapons.logger.info("Loaded 'Mekanism: Weapons' module.");
}

private void buildCreativeModeTabContents(@NotNull BuildCreativeModeTabContentsEvent event) {
if (event.getTab() == MekanismCreativeTabs.MEKANISM.get()) {
ITEMS.getEntries().forEach(entry -> event.accept(entry.get()));
}
Expand All @@ -128,8 +159,8 @@ private void sendCustomModules(InterModEnqueueEvent event) {
final String ADD_MEKA_BOW_MODULES = "add_meka_bow_modules";
MekanismIMC.addModuleContainer(MekaWeapons.MEKA_TANA, ADD_MEKA_TANA_MODULES);
MekanismIMC.addModuleContainer(MekaWeapons.MEKA_BOW, ADD_MEKA_BOW_MODULES);
MekanismIMC.sendModuleIMC(ADD_MEKA_TANA_MODULES, MekanismModules.ENERGY_UNIT, MekanismModules.ATTACK_AMPLIFICATION_UNIT, MekanismModules.TELEPORTATION_UNIT);
MekanismIMC.sendModuleIMC(ADD_MEKA_BOW_MODULES, MekanismModules.ENERGY_UNIT, MekanismModules.ATTACK_AMPLIFICATION_UNIT, MekaWeapons.AUTOFIRE_UNIT, MekaWeapons.ARROWENERGY_UNIT, MekaWeapons.DRAWSPEED_UNIT, MekaWeapons.GRAVITYDAMPENER_UNIT);
MekanismIMC.sendModuleIMC(ADD_MEKA_TANA_MODULES, MekanismModules.ENERGY_UNIT, ATTACKAMPLIFICATION_UNIT, MekanismModules.TELEPORTATION_UNIT);
MekanismIMC.sendModuleIMC(ADD_MEKA_BOW_MODULES, MekanismModules.ENERGY_UNIT, ATTACKAMPLIFICATION_UNIT, AUTOFIRE_UNIT, ARROWENERGY_UNIT, DRAWSPEED_UNIT, GRAVITYDAMPENER_UNIT);
}

private void mekaBowEnergyArrows(final @NotNull LivingGetProjectileEvent event) {
Expand All @@ -148,7 +179,9 @@ private void mekaBowEnergyArrows(final @NotNull LivingGetProjectileEvent event)

// small trick to prevent players from using the meka-bow to attack entities. This allows the tooltip to show attack damage without enabling actual damage.
private void disableMekaBowAttack(@NotNull AttackEntityEvent event) {
if (!(event.getEntity() instanceof Player player) || !(player.level() instanceof ServerLevel)) {
Player player = event.getEntity();

if (!(player.level() instanceof ServerLevel)) {
return;
}

Expand Down
50 changes: 50 additions & 0 deletions src/main/java/meranha/mekaweapons/MekaWeaponsUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package meranha.mekaweapons;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import mekanism.api.energy.IEnergyContainer;
import mekanism.api.gear.IModule;
import mekanism.api.math.MathUtils;
import mekanism.common.util.StorageUtils;
import meranha.mekaweapons.items.ModuleWeaponAttackAmplificationUnit;
import net.minecraft.world.item.ItemStack;

public class MekaWeaponsUtils {
public static long getTotalDamage(@NotNull ItemStack stack, @Nullable IModule<ModuleWeaponAttackAmplificationUnit> attackAmplificationUnit, int baseDamage, long energyUsage) {
IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
long energy = energyContainer != null ? energyContainer.getEnergy() : 0;
if(energy < energyUsage) {
return -1;
}

double damage = baseDamage;
if (attackAmplificationUnit != null) {
int unitDamage = attackAmplificationUnit.getCustomInstance().getDamage();
if (unitDamage > 0) {
double additionalDamage = baseDamage * attackAmplificationUnit.getCustomInstance().getDamageMultiplicator();
long energyCost = getEnergyNeeded(energyUsage, unitDamage);
// todo always max damage if in creative
if (energy < energyCost){
//If we don't have enough power use it at a reduced power level (this will be false the majority of the time)
damage += additionalDamage * MathUtils.divideToLevel(energy - energyUsage, energyCost - energyUsage);
} else {
damage += additionalDamage;
}
}
}

return Math.round(damage) - 1;
}

public static long getEnergyNeeded(@Nullable IModule<ModuleWeaponAttackAmplificationUnit> attackAmplificationUnit, long energyUsage) {
if (attackAmplificationUnit != null) {
return getEnergyNeeded(energyUsage, attackAmplificationUnit.getCustomInstance().getDamage());
}
return MekaWeapons.general.mekaBowEnergyUsage.get();
}

private static long getEnergyNeeded(double energyUsage, int unitDamage) {
return MathUtils.clampToLong(energyUsage * (1 + unitDamage / 4F));
}
}
9 changes: 8 additions & 1 deletion src/main/java/meranha/mekaweapons/WeaponsLang.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ public enum WeaponsLang implements ILangEntry {
AUTOFIRE_MODE("tooltip", "autofire_mode"),
AUTOFIRE_MODE_CHANGE("tooltip", "autofire_mode_change"),
ARROWENERGY_MODE("tooltip", "arrowenergy_mode"),
MAGNETIZER("tooltip", "magnetizer");
MAGNETIZER("tooltip", "magnetizer"),
RADIAL_ATTACK_DAMAGE("radial", "attack_damage"),
RADIAL_ATTACK_DAMAGE_OFF("radial", "attack_damage.off"),
RADIAL_ATTACK_DAMAGE_LOW("radial", "attack_damage.low"),
RADIAL_ATTACK_DAMAGE_MEDIUM("radial", "attack_damage.medium"),
RADIAL_ATTACK_DAMAGE_HIGH("radial", "attack_damage.high"),
RADIAL_ATTACK_DAMAGE_SUPER("radial", "attack_damage.super_high"),
RADIAL_ATTACK_DAMAGE_EXTREME("radial", "attack_damage.extreme");

private final String key;

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/meranha/mekaweapons/WeaponsRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ private void renderItem(ItemStack stack, @NotNull PoseStack ms, MultiBufferSourc
Minecraft.getInstance().getItemRenderer().renderStatic(stack, ItemDisplayContext.NONE, 0xF000F0, OverlayTexture.NO_OVERLAY, ms, buffer, player.level(), 1);
ms.popPose();
}

// todo Render weapon in hud?
}
Loading

0 comments on commit fafa50e

Please sign in to comment.