diff --git a/build.gradle b/build.gradle index e9856ba614..ccd1ce8b3a 100644 --- a/build.gradle +++ b/build.gradle @@ -13,17 +13,24 @@ buildscript { } dependencies { classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' - classpath "com.github.jengelman.gradle.plugins:shadow:1.2.3" - classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.2" + classpath "com.github.jengelman.gradle.plugins:shadow:2.0.4" + classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2" } } plugins { - id "org.sonarqube" version "2.2" + id "org.sonarqube" version "2.6.2" } apply plugin: 'net.minecraftforge.gradle.forge' apply plugin: 'com.github.johnrengelman.shadow' +// Needs this for IntelliJ to recognize assets folder +idea { + module { + inheritOutputDirs = true + } +} + ext.configFile = file('build.properties') ext.config = parseConfig(configFile) @@ -34,6 +41,7 @@ sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 dependencies { + //todo:Update dependencies compile files("libs/joml/joml-1.8.1.jar") compile files("libs/yaml/snakeyaml-1.16.jar"); } diff --git a/build.properties b/build.properties index 8e3e761e94..b9abdfeb30 100644 --- a/build.properties +++ b/build.properties @@ -1,3 +1,3 @@ -version=a5.4 +version=a5.9 mappings=snapshot_20171003 -forge=1.12.2-14.23.4.2712 \ No newline at end of file +forge=1.12.2-14.23.4.2751 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8e480ef5a5..073dafec98 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Aug 02 12:46:21 PDT 2018 +#Sun Sep 23 20:07:31 CEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip diff --git a/src/main/java/com/crowsofwar/avatar/AvatarMod.java b/src/main/java/com/crowsofwar/avatar/AvatarMod.java index 4c26accaad..45d2eca5c3 100644 --- a/src/main/java/com/crowsofwar/avatar/AvatarMod.java +++ b/src/main/java/com/crowsofwar/avatar/AvatarMod.java @@ -20,6 +20,7 @@ import com.crowsofwar.avatar.common.*; import com.crowsofwar.avatar.common.analytics.AvatarAnalytics; import com.crowsofwar.avatar.common.bending.Abilities; +import com.crowsofwar.avatar.common.bending.BendingAi; import com.crowsofwar.avatar.common.bending.lightning.AbilityLightningRaze; import com.crowsofwar.avatar.common.bending.BendingStyles; import com.crowsofwar.avatar.common.bending.air.*; @@ -69,6 +70,7 @@ import net.minecraftforge.fml.common.registry.EntityRegistry; import net.minecraftforge.fml.relauncher.Side; +import static com.crowsofwar.avatar.common.config.ConfigMobs.MOBS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; import static net.minecraft.init.Biomes.*; import static net.minecraftforge.fml.common.registry.EntityRegistry.registerEgg; @@ -221,10 +223,10 @@ public void init(FMLInitializationEvent e) { registerEntity(EntityFireball.class, "Fireball"); registerEntity(EntityAirblade.class, "Airblade"); registerEntity(EntityAirBubble.class, "AirBubble"); - registerEntity(EntityFirebender.class, "Firebender", 0xffffff, 0xffffff); - registerEntity(EntityAirbender.class, "Airbender", 0xffffff, 0xffffff); - registerEntity(EntitySkyBison.class, "SkyBison", 0xffffff, 0xffffff); - registerEntity(EntityOtterPenguin.class, "OtterPenguin", 0xffffff, 0xffffff); + registerEntity(EntityFirebender.class, "Firebender", 0xB0171F, 0xFFFF00); + registerEntity(EntityAirbender.class, "Airbender", 0xffffff,0xDDA0DD); + registerEntity(EntitySkyBison.class, "SkyBison", 0xffffff, 0x8B5A00); + registerEntity(EntityOtterPenguin.class, "OtterPenguin", 0xffffff, 0x104E8B); registerEntity(AvatarEntityItem.class, "Item"); registerEntity(EntityIceShield.class, "iceshield"); registerEntity(EntityIceShard.class, "iceshard"); @@ -240,18 +242,22 @@ public void init(FMLInitializationEvent e) { registerEntity(EntitySandstorm.class, "Sandstorm"); registerEntity(EntityExplosionSpawner.class, "ExplosionSpawner"); registerEntity(EntityBoulder.class, "Boulder"); - registerEntity(EntityLightningSpawner.class, "LightningSpawnerr"); + registerEntity(EntityLightningSpawner.class, "LightningSpawner"); + registerEntity(EntityShockwave.class, "Shockwave"); - EntityRegistry.addSpawn(EntitySkyBison.class, 5, 3, 6, EnumCreatureType.CREATURE, // - EXTREME_HILLS, MUTATED_SAVANNA); - EntityRegistry.addSpawn(EntityOtterPenguin.class, 4, 5, 9, EnumCreatureType.CREATURE, // + EntityRegistry.addSpawn(EntitySkyBison.class, 5, 1, 3, EnumCreatureType.CREATURE, // + SAVANNA_PLATEAU, EXTREME_HILLS, BIRCH_FOREST_HILLS, TAIGA_HILLS, ICE_MOUNTAINS, REDWOOD_TAIGA_HILLS, MUTATED_EXTREME_HILLS, + MUTATED_EXTREME_HILLS_WITH_TREES, EXTREME_HILLS_WITH_TREES, EXTREME_HILLS_EDGE); + EntityRegistry.addSpawn(EntityOtterPenguin.class, 10, 3, 6, EnumCreatureType.CREATURE, // COLD_BEACH, ICE_PLAINS, ICE_MOUNTAINS, MUTATED_ICE_FLATS); - EntityRegistry.addSpawn(EntityOstrichHorse.class, 5, 3, 6, EnumCreatureType.CREATURE, // + EntityRegistry.addSpawn(EntityOstrichHorse.class, 5, 1, 3, EnumCreatureType.CREATURE, // DESERT, DESERT_HILLS, SAVANNA, SAVANNA_PLATEAU, PLAINS); - // Second loading required since other mods blocks might not be + // Second loading required since other mods blocks and items might not be // registered STATS_CONFIG.loadBlocks(); + MOBS_CONFIG.loadLists(); + ConfigMobs.load(); proxy.init(); @@ -273,7 +279,7 @@ private > void registerPacket(Class packet, S private void registerEntity(Class entity, String name) { EntityRegistry.registerModEntity(new ResourceLocation("avatarmod", name), entity, name, - nextEntityID++, this, 128, 3, true); + nextEntityID++, this, 256, 3, true); } private void registerEntity(Class entity, String name, int primary, int secondary) { diff --git a/src/main/java/com/crowsofwar/avatar/client/AvatarClientProxy.java b/src/main/java/com/crowsofwar/avatar/client/AvatarClientProxy.java index 2a364faf58..4ed3029a96 100644 --- a/src/main/java/com/crowsofwar/avatar/client/AvatarClientProxy.java +++ b/src/main/java/com/crowsofwar/avatar/client/AvatarClientProxy.java @@ -17,54 +17,41 @@ package com.crowsofwar.avatar.client; -import com.crowsofwar.avatar.AvatarInfo; -import com.crowsofwar.avatar.AvatarLog; -import com.crowsofwar.avatar.AvatarLog.WarningType; -import com.crowsofwar.avatar.AvatarMod; -import com.crowsofwar.avatar.client.gui.AnalyticsWarningGui; -import com.crowsofwar.avatar.client.gui.AvatarUiRenderer; -import com.crowsofwar.avatar.client.gui.GuiBisonChest; -import com.crowsofwar.avatar.client.gui.PreviewWarningGui; -import com.crowsofwar.avatar.client.gui.skills.GetBendingGui; -import com.crowsofwar.avatar.client.gui.skills.SkillsGui; -import com.crowsofwar.avatar.client.particles.AvatarParticleAir; -import com.crowsofwar.avatar.client.particles.AvatarParticleFlames; -import com.crowsofwar.avatar.client.render.*; -import com.crowsofwar.avatar.client.render.iceprison.RenderIcePrison; -import com.crowsofwar.avatar.common.AvatarCommonProxy; -import com.crowsofwar.avatar.common.AvatarParticles; -import com.crowsofwar.avatar.common.controls.IControlsHandler; -import com.crowsofwar.avatar.common.controls.KeybindingWrapper; -import com.crowsofwar.avatar.common.data.AvatarPlayerData; -import com.crowsofwar.avatar.common.entity.*; -import com.crowsofwar.avatar.common.entity.mob.*; -import com.crowsofwar.avatar.common.gui.AvatarGui; -import com.crowsofwar.avatar.common.gui.AvatarGuiHandler; -import com.crowsofwar.avatar.common.network.IPacketHandler; -import com.crowsofwar.avatar.common.network.packets.PacketSRequestData; -import com.crowsofwar.avatar.common.particle.ClientParticleSpawner; -import com.crowsofwar.gorecore.data.PlayerDataFetcher; -import com.crowsofwar.gorecore.data.PlayerDataFetcherClient; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiMainMenu; -import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.*; import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.client.particle.ParticleManager; import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.IThreadListener; import net.minecraft.world.World; + import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.fml.relauncher.*; + +import com.crowsofwar.avatar.*; +import com.crowsofwar.avatar.AvatarLog.WarningType; +import com.crowsofwar.avatar.client.gui.*; +import com.crowsofwar.avatar.client.gui.skills.*; +import com.crowsofwar.avatar.client.particles.*; +import com.crowsofwar.avatar.client.render.*; +import com.crowsofwar.avatar.client.render.iceprison.RenderIcePrison; +import com.crowsofwar.avatar.common.*; +import com.crowsofwar.avatar.common.controls.*; +import com.crowsofwar.avatar.common.data.AvatarPlayerData; +import com.crowsofwar.avatar.common.entity.*; +import com.crowsofwar.avatar.common.entity.mob.*; +import com.crowsofwar.avatar.common.gui.*; +import com.crowsofwar.avatar.common.network.IPacketHandler; +import com.crowsofwar.avatar.common.network.packets.PacketSRequestData; +import com.crowsofwar.avatar.common.particle.ClientParticleSpawner; +import com.crowsofwar.gorecore.data.*; import java.lang.reflect.Field; -import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import static com.crowsofwar.avatar.common.config.ConfigAnalytics.ANALYTICS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigClient.CLIENT_CONFIG; @@ -78,7 +65,7 @@ public class AvatarClientProxy implements AvatarCommonProxy { private ClientInput inputHandler; private PlayerDataFetcher clientFetcher; private boolean displayedMainMenu; - private List allKeybindings; + private Map allKeybindings; @Override public void preInit() { @@ -106,8 +93,7 @@ public void preInit() { registerEntityRenderingHandler(EntityWaterArc.class, RenderWaterArc::new); registerEntityRenderingHandler(EntityAirGust.class, RenderAirGust::new); registerEntityRenderingHandler(EntityRavine.class, RenderRavine::new); - registerEntityRenderingHandler(EntityFlames.class, - rm -> new RenderFlames(rm, new ClientParticleSpawner())); + registerEntityRenderingHandler(EntityFlames.class, rm -> new RenderFlames(rm, new ClientParticleSpawner())); registerEntityRenderingHandler(EntityWave.class, RenderWave::new); registerEntityRenderingHandler(EntityWaterBubble.class, RenderWaterBubble::new); registerEntityRenderingHandler(EntityWallSegment.class, RenderWallSegment::new); @@ -132,14 +118,11 @@ public void preInit() { registerEntityRenderingHandler(EntityExplosionSpawner.class, RenderNothing::new); registerEntityRenderingHandler(EntityLightningSpawner.class, RenderLightningSpawner::new); registerEntityRenderingHandler(EntityAvatarLightning.class, RenderAvatarLightning::new); + registerEntityRenderingHandler(EntityShockwave.class, RenderNothing::new); - - registerEntityRenderingHandler(EntityAirbender.class, - rm -> new RenderHumanBender(rm, "airbender", 7)); - registerEntityRenderingHandler(EntityFirebender.class, - rm -> new RenderHumanBender(rm, "firebender", 1)); - registerEntityRenderingHandler(EntityWaterbender.class, - rm -> new RenderHumanBender(rm, "waterbender", 1)); + registerEntityRenderingHandler(EntityAirbender.class, rm -> new RenderHumanBender(rm, "airbender", 7)); + registerEntityRenderingHandler(EntityFirebender.class, rm -> new RenderHumanBender(rm, "firebender", 1)); + //registerEntityRenderingHandler(EntityWaterbender.class, rm -> new RenderHumanBender(rm, "waterbender", 1)); } @@ -167,9 +150,10 @@ public void init() { ParticleManager pm = mc.effectRenderer; if (CLIENT_CONFIG.useCustomParticles) { - pm.registerParticle(AvatarParticles.getParticleFlames().getParticleID(), - AvatarParticleFlames::new); + pm.registerParticle(AvatarParticles.getParticleFlames().getParticleID(), AvatarParticleFlames::new); pm.registerParticle(AvatarParticles.getParticleAir().getParticleID(), AvatarParticleAir::new); + pm.registerParticle(AvatarParticles.getParticleRestore().getParticleID(), AvatarParticleRestore::new); + pm.registerParticle(AvatarParticles.getParticleElectricity().getParticleID(), AvatarParticleElectricity::new); } } @@ -189,8 +173,7 @@ public AvatarGui createClientGui(int id, EntityPlayer player, World world, int x return new GuiBisonChest(player.inventory, bison); } else { - AvatarLog.warn(WarningType.WEIRD_PACKET, player.getName() - + " tried to open skybison inventory, was not found. BisonId: " + bisonId); + AvatarLog.warn(WarningType.WEIRD_PACKET, player.getName() + " tried to open skybison inventory, was not found. BisonId: " + bisonId); } } if (id == AvatarGuiHandler.GUI_ID_GET_BENDING) { @@ -235,19 +218,11 @@ public void onMainMenu(GuiOpenEvent e) { @Override public KeybindingWrapper createKeybindWrapper(String keybindName) { - if (allKeybindings == null) { initAllKeybindings(); } - KeyBinding kb = null; - for (KeyBinding candidate : allKeybindings) { - if (candidate.getKeyDescription().equals(keybindName)) { - kb = candidate; - break; - } - } - + KeyBinding kb = allKeybindings.get(keybindName); return kb == null ? new KeybindingWrapper() : new ClientKeybindWrapper(kb); } @@ -266,18 +241,16 @@ public boolean isOptifinePresent() { * Finds all keybindings list via reflection. Performance-wise this is ok * since only supposed to be called once, after keybindings are registered */ + @SuppressWarnings("unchecked") private void initAllKeybindings() { try { Field field = KeyBinding.class.getDeclaredFields()[0]; field.setAccessible(true); - Map kbMap = (Map) field.get(null); - this.allKeybindings = kbMap.entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toList()); + allKeybindings = (Map) field.get(null); } catch (Exception ex) { - AvatarLog.error( - "Could not load all keybindings list by using reflection. Will probably have serious problems", - ex); + AvatarLog.error("Could not load all keybindings list by using reflection. Will probably have serious problems", ex); } } diff --git a/src/main/java/com/crowsofwar/avatar/client/AvatarItemRenderRegister.java b/src/main/java/com/crowsofwar/avatar/client/AvatarItemRenderRegister.java index d8f7d10d72..5af433d538 100644 --- a/src/main/java/com/crowsofwar/avatar/client/AvatarItemRenderRegister.java +++ b/src/main/java/com/crowsofwar/avatar/client/AvatarItemRenderRegister.java @@ -61,6 +61,7 @@ public static void register() { register(AvatarItems.itemWaterPouch, i); } register(AvatarItems.itemBisonWhistle); + register(AvatarItems.airbenderStaff); for (int i = 0; i <= 3; i++) { register(AvatarItems.itemBisonArmor, i); register(AvatarItems.itemBisonSaddle, i); diff --git a/src/main/java/com/crowsofwar/avatar/client/ClientInput.java b/src/main/java/com/crowsofwar/avatar/client/ClientInput.java index f9508f8de8..5a4c3611d5 100644 --- a/src/main/java/com/crowsofwar/avatar/client/ClientInput.java +++ b/src/main/java/com/crowsofwar/avatar/client/ClientInput.java @@ -17,33 +17,27 @@ package com.crowsofwar.avatar.client; -import com.crowsofwar.avatar.AvatarLog; -import com.crowsofwar.avatar.AvatarMod; -import com.crowsofwar.avatar.client.gui.AvatarUiRenderer; -import com.crowsofwar.avatar.common.bending.Abilities; -import com.crowsofwar.avatar.common.bending.Ability; -import com.crowsofwar.avatar.common.bending.BendingStyle; -import com.crowsofwar.avatar.common.bending.StatusControl; -import com.crowsofwar.avatar.common.controls.AvatarControl; -import com.crowsofwar.avatar.common.controls.IControlsHandler; -import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.network.packets.*; -import com.crowsofwar.avatar.common.util.Raytrace; -import com.crowsofwar.gorecore.format.FormattedMessageProcessor; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.I18n; -import net.minecraft.client.settings.GameSettings; -import net.minecraft.client.settings.KeyBinding; +import net.minecraft.client.settings.*; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.text.TextComponentString; + import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.InputEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; +import net.minecraftforge.fml.common.gameevent.*; +import net.minecraftforge.fml.relauncher.*; + +import com.crowsofwar.avatar.*; +import com.crowsofwar.avatar.client.gui.AvatarUiRenderer; +import com.crowsofwar.avatar.common.bending.*; +import com.crowsofwar.avatar.common.controls.*; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.network.packets.*; +import com.crowsofwar.avatar.common.util.Raytrace; +import com.crowsofwar.avatar.common.util.Raytrace.Result; +import com.crowsofwar.gorecore.format.FormattedMessageProcessor; +import org.lwjgl.input.*; import java.util.*; @@ -66,8 +60,8 @@ public class ClientInput implements IControlsHandler { private final boolean[] wasAbilityDown; private GameSettings gameSettings; private Map keybindings; - private boolean mouseLeft, mouseRight, mouseMiddle, space; - private boolean wasLeft, wasRight, wasMiddle, wasSpace; + private boolean mouseLeft, mouseRight, mouseMiddle; + private boolean wasLeft, wasRight, wasMiddle; private boolean press; public ClientInput() { @@ -84,7 +78,7 @@ public ClientInput() { addKeybinding("Skills", Keyboard.KEY_K, "main"); addKeybinding("TransferBison", Keyboard.KEY_O, "main"); - this.wasAbilityDown = new boolean[Abilities.all().size()]; + wasAbilityDown = new boolean[Abilities.all().size()]; } @@ -105,8 +99,6 @@ public boolean isControlPressed(AvatarControl control) { if (control == CONTROL_LEFT_CLICK_DOWN) return mouseLeft && !wasLeft; if (control == CONTROL_RIGHT_CLICK_DOWN) return mouseRight && !wasRight; if (control == CONTROL_MIDDLE_CLICK_DOWN) return mouseMiddle && !wasMiddle; - if (control == CONTROL_SPACE) return space; - if (control == CONTROL_SPACE_DOWN) return space && !wasSpace; if (control == CONTROL_LEFT_CLICK_UP) return !mouseLeft && wasLeft; if (control == CONTROL_RIGHT_CLICK_UP) return !mouseRight && wasRight; if (control == CONTROL_MIDDLE_CLICK_UP) return !mouseMiddle && wasMiddle; @@ -125,8 +117,6 @@ public boolean isControlDown(AvatarControl control) { if (control == CONTROL_LEFT_CLICK_DOWN) return mouseLeft; if (control == CONTROL_RIGHT_CLICK_DOWN) return mouseRight; if (control == CONTROL_MIDDLE_CLICK_DOWN) return mouseMiddle; - if (control == CONTROL_SPACE) return space; - if (control == CONTROL_SPACE_DOWN) return space; if (control == CONTROL_LEFT_CLICK_UP) return !mouseLeft; if (control == CONTROL_RIGHT_CLICK_UP) return !mouseRight; if (control == CONTROL_MIDDLE_CLICK_UP) return !mouseMiddle; @@ -179,7 +169,7 @@ private boolean isAbilityPressed(Ability ability) { Integer key = CLIENT_CONFIG.keymappings.get(ability); if (key != null) { if (key < 0 && Mouse.isButtonDown(key + 100)) return true; - if (key >= 0 && Keyboard.isKeyDown(key)) return true; + return key >= 0 && Keyboard.isKeyDown(key); } return false; } @@ -195,11 +185,12 @@ private void tryOpenBendingMenu() { AvatarUiRenderer.openBendingGui(data.getActiveBendingId()); } else { - String message = I18n.format(MSG_DONT_HAVE_BENDING.getTranslateKey()); - message = FormattedMessageProcessor.formatText(MSG_DONT_HAVE_BENDING, message, - mc.player.getName()); - mc.ingameGUI.getChatGUI().printChatMessage(new TextComponentString(message)); + if (CLIENT_CONFIG.displayGetBendingMessage) { + String message = I18n.format(MSG_DONT_HAVE_BENDING.getTranslateKey()); + message = FormattedMessageProcessor.formatText(MSG_DONT_HAVE_BENDING, message, mc.player.getName()); + mc.ingameGUI.getChatGUI().printChatMessage(new TextComponentString(message)); + } } } @@ -207,7 +198,6 @@ private void tryOpenBendingMenu() { } private void tryCycleBending() { - BendingData data = BendingData.get(mc.player); if (AvatarControl.KEY_BENDING_CYCLE_LEFT.isPressed() && !AvatarUiRenderer.hasBendingGui()) { AvatarMod.network.sendToServer(new PacketSCycleBending(false)); } @@ -221,7 +211,6 @@ public void onTick(TickEvent.ClientTickEvent e) { wasLeft = mouseLeft; wasRight = mouseRight; wasMiddle = mouseMiddle; - wasSpace = space; if (mc.inGameHasFocus) { mouseLeft = Mouse.isButtonDown(0); @@ -231,31 +220,21 @@ public void onTick(TickEvent.ClientTickEvent e) { mouseLeft = mouseRight = mouseMiddle = false; } - space = Keyboard.isKeyDown(Keyboard.KEY_SPACE); - EntityPlayer player = mc.player; if (player != null && player.world != null) { // Send any input to the server BendingData data = BendingData.get(player); - if (data != null) { - - if (mc.inGameHasFocus) { - Collection pressed = getAllPressed(); - Collection statusControls = data.getAllStatusControls(); - - Iterator sci = statusControls.iterator(); - while (sci.hasNext()) { - StatusControl sc = sci.next(); - if (pressed.contains(sc.getSubscribedControl())) { - Raytrace.Result raytrace = Raytrace.getTargetBlock(player, sc.getRaytrace()); - - AvatarMod.network.sendToServer(new PacketSUseStatusControl(sc, raytrace)); - } + if (mc.inGameHasFocus) { + Collection pressed = getAllPressed(); + Collection statusControls = data.getAllStatusControls(); + for (StatusControl sc : statusControls) { + if (pressed.contains(sc.getSubscribedControl())) { + Result raytrace = Raytrace.getTargetBlock(player, sc.getRaytrace()); + AvatarMod.network.sendToServer(new PacketSUseStatusControl(sc, raytrace)); } } - } List allAbilities = Abilities.all(); @@ -263,12 +242,10 @@ public void onTick(TickEvent.ClientTickEvent e) { Ability ability = allAbilities.get(i); boolean down = isAbilityPressed(ability); - if (!CLIENT_CONFIG.conflicts.containsKey(ability)) - CLIENT_CONFIG.conflicts.put(ability, false); + if (!CLIENT_CONFIG.conflicts.containsKey(ability)) CLIENT_CONFIG.conflicts.put(ability, false); boolean conflict = CLIENT_CONFIG.conflicts.get(ability); - if (!conflict && mc.inGameHasFocus && mc.currentScreen == null && down - && !wasAbilityDown[i]) { + if (!conflict && mc.inGameHasFocus && mc.currentScreen == null && down && !wasAbilityDown[i]) { Raytrace.Result raytrace = Raytrace.getTargetBlock(mc.player, ability.getRaytrace()); AvatarMod.network.sendToServer(new PacketSUseAbility(ability, raytrace)); } diff --git a/src/main/java/com/crowsofwar/avatar/client/ClientKeybindWrapper.java b/src/main/java/com/crowsofwar/avatar/client/ClientKeybindWrapper.java index 40707dbbb3..a9766ce241 100644 --- a/src/main/java/com/crowsofwar/avatar/client/ClientKeybindWrapper.java +++ b/src/main/java/com/crowsofwar/avatar/client/ClientKeybindWrapper.java @@ -16,17 +16,20 @@ */ package com.crowsofwar.avatar.client; -import com.crowsofwar.avatar.common.controls.KeybindingWrapper; import net.minecraft.client.settings.KeyBinding; +import com.crowsofwar.avatar.common.controls.KeybindingWrapper; + +import javax.annotation.Nonnull; + /** * @author CrowsOfWar */ public class ClientKeybindWrapper extends KeybindingWrapper { - + @Nonnull private final KeyBinding kb; - public ClientKeybindWrapper(KeyBinding kb) { + public ClientKeybindWrapper(@Nonnull KeyBinding kb) { this.kb = kb; } diff --git a/src/main/java/com/crowsofwar/avatar/client/PacketHandlerClient.java b/src/main/java/com/crowsofwar/avatar/client/PacketHandlerClient.java index 01bf2fa4d5..1d616310e8 100644 --- a/src/main/java/com/crowsofwar/avatar/client/PacketHandlerClient.java +++ b/src/main/java/com/crowsofwar/avatar/client/PacketHandlerClient.java @@ -34,10 +34,7 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.UUID; +import java.util.*; /** * Handles packets addressed to the client. Packets like this have a C in their @@ -107,7 +104,7 @@ private IMessage handlePacketPowerRating(PacketCPowerRating packet, MessageConte Set> entrySet = powerRatings.entrySet(); for (Map.Entry entry : entrySet) { - data.getPowerRatingManager(entry.getKey()).setCachedRatingValue(entry.getValue()); + Objects.requireNonNull(data.getPowerRatingManager(entry.getKey())).setCachedRatingValue(entry.getValue()); } diff --git a/src/main/java/com/crowsofwar/avatar/client/gui/AvatarUiRenderer.java b/src/main/java/com/crowsofwar/avatar/client/gui/AvatarUiRenderer.java index 660e86c55f..fa05161179 100644 --- a/src/main/java/com/crowsofwar/avatar/client/gui/AvatarUiRenderer.java +++ b/src/main/java/com/crowsofwar/avatar/client/gui/AvatarUiRenderer.java @@ -24,6 +24,7 @@ import com.crowsofwar.avatar.common.bending.StatusControl; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.Chi; +import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.Vision; import com.crowsofwar.avatar.common.entity.AvatarEntity; import com.crowsofwar.avatar.common.entity.EntityAirBubble; @@ -64,9 +65,6 @@ @SideOnly(Side.CLIENT) public class AvatarUiRenderer extends Gui { - private static final ResourceLocation PURIFY_VISION_SHADER = new ResourceLocation - ("avatarmod", "shaders/post/purify_weak.json"); - public static AvatarUiRenderer instance; private final Minecraft mc; private RadialMenu currentBendingMenu; @@ -187,126 +185,147 @@ private void renderStatusControls(ScaledResolution resolution) { } private void renderChiBar(ScaledResolution resolution) { + if (CLIENT_CONFIG.chiBarSettings.shouldChibarRender) { - GlStateManager.color(1, 1, 1, CLIENT_CONFIG.chiBarAlpha); + GlStateManager.color(1, 1, 1, CLIENT_CONFIG.chiBarAlpha); - BendingData data = BendingData.get(mc.player); + BendingData data = BendingData.get(mc.player); - if (data.getAllBending().isEmpty()) return; + if (data.getAllBending().isEmpty()) return; - Chi chi = data.chi(); - float total = chi.getTotalChi(); - float max = chi.getMaxChi(); - float available = chi.getAvailableChi(); - float unavailable = total - available; + Chi chi = data.chi(); + float total = chi.getTotalChi(); + float max = chi.getMaxChi(); + float available = chi.getAvailableChi(); + float unavailable = total - available; - // Dimensions of end result in pixels - float scale = 1.1f; - float width = 100 * scale; - float height = 9 * scale; + // Dimensions of end result in pixels + float scale = 1.1f; + float width = 100 * scale; + float height = 9 * scale; - mc.getTextureManager().bindTexture(AvatarUiTextures.CHI_BAR); + mc.getTextureManager().bindTexture(AvatarUiTextures.CHI_BAR); - pushMatrix(); + pushMatrix(); - translate(3, resolution.getScaledHeight() - height - 3, 0); - scale(scale, scale, 1); + translate(3, resolution.getScaledHeight() - height - 3, 0); + scale(scale, scale, 1); - // Background of chi bar - drawTexturedModalRect(0, 0, 0, 36, 100, 9); + // Background of chi bar + drawTexturedModalRect(0, 0, 0, 36, 100, 9); - // Available chi + // Available chi - float unadjustedU = 100 * unavailable / max; - int adjustedU = (int) Math.floor(unadjustedU / 8f) * 8; - float uDiff = unadjustedU - adjustedU; + float unadjustedU = 100 * unavailable / max; + int adjustedU = (int) Math.floor(unadjustedU / 8f) * 8; + float uDiff = unadjustedU - adjustedU; - drawTexturedModalRect(adjustedU, 0, 1, 27, (int) (100 * available / max + uDiff), 9); + drawTexturedModalRect(adjustedU, 0, 1, 27, (int) (100 * available / max + uDiff), 9); - // Unavailable chi - drawTexturedModalRect(0, 0, 0, 45, (int) (100 * unavailable / max), 9); + // Unavailable chi + drawTexturedModalRect(0, 0, 0, 45, (int) (100 * unavailable / max), 9); - drawString(mc.fontRenderer, ((int) total) + "/" + ((int) max) + "," + ((int) available), 0, -20, - 0xffffff | ((int) (CLIENT_CONFIG.chiBarAlpha * 255) << 24)); + drawString(mc.fontRenderer, ((int) total) + "/" + ((int) max) + "," + ((int) available), 0, -20, + 0xffffff | ((int) (CLIENT_CONFIG.chiBarAlpha * 255) << 24)); - popMatrix(); + popMatrix(); + } } private void renderChiMsg(ScaledResolution res) { + if (CLIENT_CONFIG.chiBarSettings.shouldChiNumbersRender) { + if (errorMsgFade != -1) { - if (errorMsgFade != -1) { + float seconds = (System.currentTimeMillis() - errorMsgFade) / 1000f; + float alpha = seconds < 1 ? 1 : 1 - (seconds - 1); + int alphaI = (int) (alpha * 255); + // For some reason, any alpha below 4 is displayed at alpha 255 + if (alphaI < 4) alphaI = 4; - float seconds = (System.currentTimeMillis() - errorMsgFade) / 1000f; - float alpha = seconds < 1 ? 1 : 1 - (seconds - 1); - int alphaI = (int) (alpha * 255); - // For some reason, any alpha below 4 is displayed at alpha 255 - if (alphaI < 4) alphaI = 4; + String text = TextFormatting.BOLD + I18n.format(errorMsg); - String text = TextFormatting.BOLD + I18n.format(errorMsg); + //@formatter:off + drawString(mc.fontRenderer, text, + (res.getScaledWidth() - mc.fontRenderer.getStringWidth(text)) / 2, + res.getScaledHeight() - mc.fontRenderer.FONT_HEIGHT - 40, + 0xffffff | (alphaI << 24)); + //@formatter:on - //@formatter:off - drawString(mc.fontRenderer, text, - (res.getScaledWidth() - mc.fontRenderer.getStringWidth(text)) / 2, - res.getScaledHeight() - mc.fontRenderer.FONT_HEIGHT - 40, - 0xffffff | (alphaI << 24)); - //@formatter:on + if (seconds >= 2) errorMsgFade = -1; - if (seconds >= 2) errorMsgFade = -1; + } } - } private void renderActiveBending(ScaledResolution res) { - BendingData data = BendingData.get(mc.player); + if (CLIENT_CONFIG.activeBendingSettings.shouldBendingMenuRender) { + BendingData data = BendingData.get(mc.player); - if (data.getActiveBending() != null) { + /*if (CLIENT_CONFIG.activeBendingSettings.shouldBendingMenuDisappear) { + data.addTickHandler(RENDER_ELEMENT_HANDLER); + }**/ - GlStateManager.color(1, 1, 1, CLIENT_CONFIG.bendingCycleAlpha); - drawBendingIcon(0, 0, data.getActiveBending()); + //boolean shouldRender = !CLIENT_CONFIG.activeBendingSettings.shouldBendingMenuDisappear || data.hasTickHandler(RENDER_ELEMENT_HANDLER); - GlStateManager.color(1, 1, 1, CLIENT_CONFIG.bendingCycleAlpha * 0.5f); + if (data.getActiveBending() != null) { + //float alpha = data.hasTickHandler(RENDER_ELEMENT_HANDLER) ? + // ((float) CLIENT_CONFIG.activeBendingSettings.bendingMenuDuration - data.getTickHandlerDuration(RENDER_ELEMENT_HANDLER)) / 200 : CLIENT_CONFIG.bendingCycleAlpha; + GlStateManager.color(1, 1, 1, CLIENT_CONFIG.bendingCycleAlpha); + drawBendingIcon(0, 0, data.getActiveBending(), 50.0, 50.0); - List allBending = data.getAllBending(); - allBending.sort(Comparator.comparing(BendingStyle::getName)); - // Draw next - int indexNext = allBending.indexOf(data.getActiveBending()) + 1; - if (indexNext == allBending.size()) indexNext = 0; + List allBending = data.getAllBending(); + allBending.sort(Comparator.comparing(BendingStyle::getName)); - if (allBending.size() > 1) { - GlStateManager.pushMatrix(); - GlStateManager.translate(0, 0, -1); - drawBendingIcon(25, 25, allBending.get(indexNext)); - GlStateManager.popMatrix(); - } + // Draw next + int indexNext = allBending.indexOf(data.getActiveBending()) + 1; + if (indexNext == allBending.size()) indexNext = 0; + + if (allBending.size() > 1) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, -1); + drawBendingIcon(50, 25, allBending.get(indexNext), 35.0, 35.0); + //float alpha = data.hasTickHandler(RENDER_ELEMENT_HANDLER) ? + // ((float) CLIENT_CONFIG.activeBendingSettings.bendingMenuDuration - data.getTickHandlerDuration(RENDER_ELEMENT_HANDLER)) / 200 : CLIENT_CONFIG.bendingCycleAlpha; + GlStateManager.color(1, 1, 1, CLIENT_CONFIG.bendingCycleAlpha * 0.5f); + + GlStateManager.popMatrix(); + } + + // Draw previous + int indexPrevious = allBending.indexOf(data.getActiveBending()) - 1; + if (indexPrevious <= -1) indexPrevious = allBending.size() - 1; - // Draw previous - int indexPrevious = allBending.indexOf(data.getActiveBending()) - 1; - if (indexPrevious <= -1) indexPrevious = allBending.size() - 1; + if (allBending.size() > 2) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, -1); + drawBendingIcon(-35, 25, allBending.get(indexPrevious), 35.0, 35.0); + //float alpha = data.hasTickHandler(RENDER_ELEMENT_HANDLER) ? + // ((float) CLIENT_CONFIG.activeBendingSettings.bendingMenuDuration - data.getTickHandlerDuration(RENDER_ELEMENT_HANDLER)) / 200 : CLIENT_CONFIG.bendingCycleAlpha; + GlStateManager.color(1, 1, 1, CLIENT_CONFIG.bendingCycleAlpha * 0.5f); + + GlStateManager.popMatrix(); + } - if (allBending.size() > 2) { - GlStateManager.pushMatrix(); - GlStateManager.translate(0, 0, -1); - drawBendingIcon(-25, 25, allBending.get(indexPrevious)); - GlStateManager.popMatrix(); } } - } - private void drawBendingIcon(int xOff, int yOff, BendingStyle controller) { - int x = screenWidth() / scaleFactor() - 85 + xOff; - int y = screenHeight() / scaleFactor() - 60 + yOff; - mc.renderEngine.bindTexture(AvatarUiTextures.getBendingIconTexture(controller.getId())); - GlStateManager.pushMatrix(); - GlStateManager.translate(x, y, 0); - GlStateManager.scale(50.0 / 256, 50.0 / 256, 1); - drawTexturedModalRect(0, 0, 0, 0, 256, 256); - GlStateManager.popMatrix(); + + private void drawBendingIcon(int xOff, int yOff, BendingStyle controller, double width, double height) { + refreshDimensions(); + int x = screenWidth() / scaleFactor() - 85 + xOff; + int y = screenHeight() / scaleFactor() - 60 + yOff; + mc.renderEngine.bindTexture(AvatarUiTextures.getBendingIconTexture(controller.getId())); + GlStateManager.pushMatrix(); + GlStateManager.translate(x, y, 0); + GlStateManager.scale(width / 256F, height / 256F, 1); + drawTexturedModalRect(0, 0, 0, 0, 256, 256); + GlStateManager.popMatrix(); } private void renderAirBubbleHealth(ScaledResolution res) { diff --git a/src/main/java/com/crowsofwar/avatar/client/gui/AvatarUiTextures.java b/src/main/java/com/crowsofwar/avatar/client/gui/AvatarUiTextures.java index 6c808f55a7..b68612f720 100644 --- a/src/main/java/com/crowsofwar/avatar/client/gui/AvatarUiTextures.java +++ b/src/main/java/com/crowsofwar/avatar/client/gui/AvatarUiTextures.java @@ -31,6 +31,8 @@ import java.util.Map; import java.util.UUID; +import static com.crowsofwar.avatar.common.config.ConfigClient.CLIENT_CONFIG; + /** * @author CrowsOfWar */ @@ -96,6 +98,7 @@ public static ResourceLocation getBendingIconTexture(UUID bendingId) { public static ResourceLocation getBendingBackgroundTexture(UUID bendingId) { String bendingName = BendingStyles.getName(bendingId); String location = "textures/gui/background/" + bendingName + ".png"; + return getCachedImage(bendingBackgrounds, bendingId, location); } diff --git a/src/main/java/com/crowsofwar/avatar/client/gui/RenderElementTickHandler.java b/src/main/java/com/crowsofwar/avatar/client/gui/RenderElementTickHandler.java new file mode 100644 index 0000000000..9be5be2520 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/client/gui/RenderElementTickHandler.java @@ -0,0 +1,21 @@ +package com.crowsofwar.avatar.client.gui; + +import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.TickHandlerController; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; + +import static com.crowsofwar.avatar.common.config.ConfigClient.CLIENT_CONFIG; + +public class RenderElementTickHandler extends TickHandler { + + public RenderElementTickHandler(int id) { + super(id); + } + + @Override + public boolean tick(BendingContext ctx) { + int duration = ctx.getData().getTickHandlerDuration(this); + return duration >= 200; + //return duration >= CLIENT_CONFIG.activeBendingSettings.bendingMenuDuration; + } +} diff --git a/src/main/java/com/crowsofwar/avatar/client/gui/skills/WindowAbility.java b/src/main/java/com/crowsofwar/avatar/client/gui/skills/WindowAbility.java index d10135b9bd..a601f8edc4 100644 --- a/src/main/java/com/crowsofwar/avatar/client/gui/skills/WindowAbility.java +++ b/src/main/java/com/crowsofwar/avatar/client/gui/skills/WindowAbility.java @@ -72,7 +72,7 @@ public WindowAbility(Ability ability, SkillsGui gui) { frame = new Frame(); frame.setDimensions(fromPercent(80, 80)); - frame.setPosition(fromPercent((100 - 80) / 2, (100 - 80) / 2)); + frame.setPosition(fromPercent((100F - 80) / 2, (100F - 80) / 2)); Frame frameLeft = new Frame(frame); frameLeft.setDimensions(fromPercent(frame, 30, 100)); diff --git a/src/main/java/com/crowsofwar/avatar/client/particles/AvatarParticleElectricity.java b/src/main/java/com/crowsofwar/avatar/client/particles/AvatarParticleElectricity.java new file mode 100644 index 0000000000..104842053a --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/client/particles/AvatarParticleElectricity.java @@ -0,0 +1,47 @@ +package com.crowsofwar.avatar.client.particles; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +public class AvatarParticleElectricity extends AvatarParticle { + + private static final ResourceLocation TEXTURE = new ResourceLocation("avatarmod", + "textures/particles/electricity.png"); + + private static final ParticleFrame[] FRAMES = new ParticleFrame[8]; + + static { + for (int i = 0; i < FRAMES.length; i++) { + FRAMES[i] = new ParticleFrame(TEXTURE, 256, (i % 4) * 64, i / 64, 64, 64); + } + } + + /** + * @param world + * @param x + * @param y + * @param z + * @param velX + * @param velY + * @param velZ + */ + public AvatarParticleElectricity(int particleID, World world, double x, double y, double z, double velX, + double velY, double velZ, int... parameters) { + super(world, x, y, z, velX, velY, velZ); + + particleScale = 4f; + particleMaxAge *= 2; + + motionX = velX; + motionY = velY; + motionZ = velZ; + + } + + @Override + protected ParticleFrame[] getTextureFrames() { + return FRAMES; + } + +} + diff --git a/src/main/java/com/crowsofwar/avatar/client/particles/AvatarParticleRestore.java b/src/main/java/com/crowsofwar/avatar/client/particles/AvatarParticleRestore.java new file mode 100644 index 0000000000..fe2ab99067 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/client/particles/AvatarParticleRestore.java @@ -0,0 +1,46 @@ +package com.crowsofwar.avatar.client.particles; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +public class AvatarParticleRestore extends AvatarParticle { + + private static final ResourceLocation TEXTURE = new ResourceLocation("avatarmod", + "textures/particles/restore.png"); + + private static final ParticleFrame[] FRAMES = new ParticleFrame[6]; + + static { + for (int i = 0; i < FRAMES.length; i++) { + FRAMES[i] = new ParticleFrame(TEXTURE, 256, (i % 4) * 64, i / 64, 64, 64); + } + } + + /** + * @param world + * @param x + * @param y + * @param z + * @param velX + * @param velY + * @param velZ + */ + public AvatarParticleRestore(int particleID, World world, double x, double y, double z, double velX, + double velY, double velZ, int... parameters) { + super(world, x, y, z, velX, velY, velZ); + + particleScale = 4f; + particleMaxAge *= 2; + + motionX = velX; + motionY = velY; + motionZ = velZ; + + } + + @Override + protected ParticleFrame[] getTextureFrames() { + return FRAMES; + } + +} diff --git a/src/main/java/com/crowsofwar/avatar/client/render/ModelBisonSaddle.java b/src/main/java/com/crowsofwar/avatar/client/render/ModelBisonSaddle.java index cf6f0b3d94..7ad4a63132 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/ModelBisonSaddle.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/ModelBisonSaddle.java @@ -23,11 +23,10 @@ import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; -import java.util.Arrays; -import java.util.List; - /** - * BisonSaddle - Captn_Dubz Created using Tabula 5.1.0 + * BisonSaddle - Captn_Dubz & Mnesikos Created using Tabula 5.1.0 + * Note: This model + texture were edited by Mnesikos to better fit the new Bison model altogether, + * heavily based on original model + texture by Captn_Dubz. */ public class ModelBisonSaddle extends ModelBase { @@ -45,65 +44,56 @@ public class ModelBisonSaddle extends ModelBase { public ModelRenderer wallSide2; public ModelBisonSaddle() { - this.textureWidth = 192; - this.textureHeight = 128; - this.wall2 = new ModelRenderer(this, 2, 48); - this.wall2.setRotationPoint(0.0F, 0.0F, 0.0F); - this.wall2.addBox(18.0F, -6.0F, -20.0F, 1, 6, 42, 0.0F); - this.wall1 = new ModelRenderer(this, 2, 48); - this.wall1.setRotationPoint(0.0F, 0.0F, 0.0F); - this.wall1.addBox(-19.0F, -6.0F, -20.0F, 1, 6, 42, 0.0F); - this.wallSide2 = new ModelRenderer(this, 2, 2); - this.wallSide2.setRotationPoint(0.0F, 0.0F, 0.0F); - this.wallSide2.addBox(14.0F, -1.5F, -18.0F, 5, 6, 1, 0.0F); - this.setRotateAngle(wallSide2, 0.0F, 0.0F, -0.8203047484373349F); - this.wallSide1 = new ModelRenderer(this, 2, 2); - this.wallSide1.setRotationPoint(0.0F, 0.0F, 0.0F); - this.wallSide1.addBox(-19.0F, -1.5F, -18.0F, 5, 6, 1, 0.0F); - this.setRotateAngle(wallSide1, 0.0F, 0.0F, 0.8203047484373349F); - this.wall3 = new ModelRenderer(this, 90, 66); - this.wall3.setRotationPoint(0.0F, 0.0F, 0.0F); - this.wall3.addBox(-18.0F, -6.0F, 21.0F, 36, 6, 1, 0.0F); - this.cargo = new ModelRenderer(this, 2, 100); - this.cargo.setRotationPoint(0.0F, 0.0F, 0.0F); - this.cargo.addBox(-14.0F, -8.0F, 18.0F, 28, 10, 8, 0.0F); - this.wallTop = new ModelRenderer(this, 96, 88); - this.wallTop.setRotationPoint(0.0F, 0.0F, 0.0F); - this.wallTop.addBox(-12.0F, -15.0F, -18.0F, 24, 5, 1, 0.0F); - this.setRotateAngle(wallTop, 0.2617993877991494F, 0.0F, 0.0F); - this.saddleBase = new ModelRenderer(this, 2, 2); - this.saddleBase.setRotationPoint(0.0F, 0.0F, 0.0F); - this.saddleBase.addBox(-19.0F, 0.0F, -20.0F, 38, 2, 42, 0.0F); - this.wall4 = new ModelRenderer(this, 54, 54); - this.wall4.setRotationPoint(0.0F, 0.0F, 0.0F); - this.wall4.addBox(-18.0F, -6.0F, -20.0F, 36, 6, 1, 0.0F); - this.saddleBase.addChild(this.wall2); - this.saddleBase.addChild(this.wall1); - this.wallTop.addChild(this.wallSide2); - this.wallTop.addChild(this.wallSide1); + this.textureWidth = 112; + this.textureHeight = 96; + this.wall3 = new ModelRenderer(this, 58, 5); + this.wall3.mirror = true; + this.wall3.setRotationPoint(0.0F, -0.5F, 11.5F); + this.wall3.addBox(-7.5F, -3.0F, -0.5F, 15, 3, 1, 0.0F); + this.wallTop = new ModelRenderer(this, 0, 0); + this.wallTop.setRotationPoint(0.0F, -3.5F, -11.1F); + this.wallTop.addBox(-4.5F, -2.0F, -1.0F, 9, 3, 1, 0.0F); + this.setRotateAngle(wallTop, 0.20943951023931953F, 0.0F, 0.0F); + this.wallSide2 = new ModelRenderer(this, 0, 4); + this.wallSide2.setRotationPoint(4.5F, -2.0F, -0.5F); + this.wallSide2.addBox(0.0F, 0.0F, -0.5F, 3, 2, 1, 0.0F); + this.setRotateAngle(wallSide2, 0.0F, 0.0F, 0.8726646259971648F); + this.cargo = new ModelRenderer(this, 26, 25); + this.cargo.setRotationPoint(0.0F, -2.02F, 11.75F); + this.cargo.addBox(-5.5F, -2.5F, -2.0F, 11, 5, 4, 0.0F); + this.saddleBase = new ModelRenderer(this, 0, 0); + this.saddleBase.setRotationPoint(0.0F, -3.5F, 4.0F); + this.saddleBase.addBox(-8.5F, -0.5F, -12.0F, 17, 1, 24, 0.0F); + this.wallSide1 = new ModelRenderer(this, 0, 4); + this.wallSide1.mirror = true; + this.wallSide1.setRotationPoint(-4.5F, -2.0F, -0.5F); + this.wallSide1.addBox(-3.0F, 0.0F, -0.5F, 3, 2, 1, 0.0F); + this.setRotateAngle(wallSide1, 0.0F, 0.0F, -0.8726646259971648F); + this.wall2 = new ModelRenderer(this, 0, 25); + this.wall2.setRotationPoint(8.0F, -0.5F, 0.0F); + this.wall2.addBox(-0.5F, -3.0F, -12.0F, 1, 3, 24, 0.0F); + this.wall1 = new ModelRenderer(this, 0, 25); + this.wall1.mirror = true; + this.wall1.setRotationPoint(-8.0F, -0.5F, 0.0F); + this.wall1.addBox(-0.5F, -3.0F, -12.0F, 1, 3, 24, 0.0F); + this.wall4 = new ModelRenderer(this, 58, 0); + this.wall4.setRotationPoint(0.0F, -0.5F, -11.5F); + this.wall4.addBox(-7.5F, -3.0F, -0.5F, 15, 3, 2, 0.0F); this.saddleBase.addChild(this.wall3); - this.saddleBase.addChild(this.cargo); this.saddleBase.addChild(this.wallTop); + this.wallTop.addChild(this.wallSide2); + this.saddleBase.addChild(this.cargo); + this.wallTop.addChild(this.wallSide1); + this.saddleBase.addChild(this.wall2); + this.saddleBase.addChild(this.wall1); this.saddleBase.addChild(this.wall4); - // CrowsOfWar: Slightly adjust position of saddle to make it more - // on-center on the bison - List allBoxes = Arrays.asList(saddleBase, wall1, wall2, wall3, wall4, cargo, wallTop, - wallSide1, wallSide2); - for (ModelRenderer box : allBoxes) { - box.rotationPointX += 2; - if (box != saddleBase) { - box.rotationPointX -= 2; - } - } - } @Override public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { Minecraft.getMinecraft().renderEngine.bindTexture(texture); this.saddleBase.render(f5); - } /** diff --git a/src/main/java/com/crowsofwar/avatar/client/render/ModelEarthspikes.java b/src/main/java/com/crowsofwar/avatar/client/render/ModelEarthspikes.java index 815561fe3a..e862752659 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/ModelEarthspikes.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/ModelEarthspikes.java @@ -1,7 +1,9 @@ package com.crowsofwar.avatar.client.render; +import com.crowsofwar.avatar.common.entity.EntityEarthspike; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.Entity; /** @@ -141,6 +143,10 @@ public ModelEarthspikes() { @Override public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { + EntityEarthspike spike = (EntityEarthspike) entity; + GlStateManager.pushMatrix(); + GlStateManager.translate(0, -1.5 * spike.getSize(), 0); + GlStateManager.scale(spike.getSize(), spike.getSize(), spike.getSize()); this.shape25.render(f5); this.shape10.render(f5); this.shape7.render(f5); @@ -150,6 +156,7 @@ public void render(Entity entity, float f, float f1, float f2, float f3, float f this.shape22.render(f5); this.shape19.render(f5); this.shape1.render(f5); + GlStateManager.popMatrix(); } /** diff --git a/src/main/java/com/crowsofwar/avatar/client/render/ModelFlyingBison.java b/src/main/java/com/crowsofwar/avatar/client/render/ModelFlyingBison.java index 18273e1ac7..f9a1fff3e8 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/ModelFlyingBison.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/ModelFlyingBison.java @@ -18,125 +18,129 @@ package com.crowsofwar.avatar.client.render; import com.crowsofwar.avatar.common.entity.mob.EntitySkyBison; +import net.minecraft.block.Block; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -import java.util.Arrays; -import java.util.List; - import static net.minecraft.client.renderer.GlStateManager.*; /** - * FlyingBison - Captn_Dubz Created using Tabula 5.1.0 + * FlyingBison - Captn_Dubz & Mnesikos Created using Tabula 5.1.0 + + * + * Note: This model + texture were edited by Mnesikos, heavily based on original model + texture by Captn_Dubz. *

* (Note: Fields originally were pascal case but modified to camel case by * CrowsOfWar) * - * @author Captn_Dubz (unless otherwise specified) + * @author Mnesikos (unless otherwise specified) */ public class ModelFlyingBison extends ModelBase { public ModelBisonSaddle saddle; - public ModelRenderer body; - public ModelRenderer leg1; - public ModelRenderer leg2; - public ModelRenderer leg3; - public ModelRenderer leg4; - public ModelRenderer leg5; - public ModelRenderer leg6; - public ModelRenderer head; - public ModelRenderer upTail; - public ModelRenderer lowTail; - public ModelRenderer hair; - public ModelRenderer ear1; - public ModelRenderer ear2; - public ModelRenderer nose; - public ModelRenderer horn1; - public ModelRenderer horn2; - - public ModelFlyingBison() { - this.textureWidth = 128; - this.textureHeight = 128; - this.leg2 = new ModelRenderer(this, 0, 0); - this.leg2.setRotationPoint(8.0F, 6.0F, 2.0F); - this.leg2.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); - - this.leg4 = new ModelRenderer(this, 0, 0); - this.leg4.setRotationPoint(-6.0F, 6.0F, -7.0F); - this.leg4.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); - this.body = new ModelRenderer(this, 0, 0); - this.body.setRotationPoint(1.0F, 0.0F, 3.0F); - this.body.addBox(-10.0F, -6.0F, -13.0F, 20, 12, 24, 0.0F); - this.hair = new ModelRenderer(this, 0, 74); - this.hair.setRotationPoint(0.0F, 0.0F, 0.0F); - this.hair.addBox(-6.0F, -6.1F, -11.5F, 12, 5, 11, 0.0F); - - this.upTail = new ModelRenderer(this, 0, 57); - this.upTail.setRotationPoint(1.0F, -4.4F, 12.0F); - this.upTail.addBox(-9.5F, -2.0F, 0.0F, 19, 3, 14, 0.0F); - this.setRotateAngle(upTail, 0, 0.0F, 0.0F); - - this.lowTail = new ModelRenderer(this, 52, 60); - this.lowTail.setRotationPoint(1.0F, -0.5F, 14.0F); - this.lowTail.addBox(-9.5F, -1.5F, 0F, 19, 3, 14, 0.0F); - this.setRotateAngle(lowTail, 0, 0.0F, 0.0F); - - this.upTail.addChild(lowTail); - - this.leg1 = new ModelRenderer(this, 0, 0); - this.leg1.setRotationPoint(8.0F, 6.0F, -7.0F); - this.leg1.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); - this.leg5 = new ModelRenderer(this, 0, 0); - this.leg5.setRotationPoint(-6.0F, 6.0F, 2.0F); - this.leg5.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); - this.ear1 = new ModelRenderer(this, 82, 0); - this.ear1.setRotationPoint(0.0F, 0.0F, -4.0F); - this.ear1.addBox(4.0F, 1.0F, -2.0F, 2, 4, 2, 0.0F); - this.setRotateAngle(ear1, 0.0F, 0.0F, -0.3839724354387525F); - this.horn1 = new ModelRenderer(this, 114, 3); - this.horn1.setRotationPoint(0.0F, 0.0F, 0.0F); - this.horn1.addBox(5.5F, -9.0F, -9.0F, 2, 9, 2, 0.0F); - this.setRotateAngle(horn1, -0.20943951023931953F, 0.0F, 0.03490658503988659F); - this.leg6 = new ModelRenderer(this, 0, 0); - this.leg6.setRotationPoint(-6.0F, 6.0F, 11.0F); - this.leg6.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); - this.nose = new ModelRenderer(this, 114, 0); - this.nose.setRotationPoint(0.0F, 0.0F, 0.0F); - this.nose.addBox(-2.0F, 1.5F, -11.5F, 4, 2, 1, 0.0F); - this.leg3 = new ModelRenderer(this, 0, 0); - this.leg3.setRotationPoint(8.0F, 6.0F, 11.0F); - this.leg3.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); - this.ear2 = new ModelRenderer(this, 106, 0); - this.ear2.setRotationPoint(0.0F, 0.0F, -4.0F); - this.ear2.addBox(-6.0F, 1.0F, -2.0F, 2, 4, 2, 0.0F); - this.setRotateAngle(ear2, 0.0F, 0.0F, 0.3839724354387525F); - this.horn2 = new ModelRenderer(this, 112, 14); - this.horn2.setRotationPoint(0.0F, 0.0F, 0.0F); - this.horn2.addBox(-7.5F, -9.0F, -9.0F, 2, 9, 2, 0.0F); - this.setRotateAngle(horn2, -0.20943951023931953F, 0.0F, -0.03490658503988659F); - this.head = new ModelRenderer(this, 48, 36); - this.head.setRotationPoint(1.0F, -2.0F, -8.0F); - this.head.addBox(-5.5F, -6.0F, -11.0F, 11, 11, 10, 0.0F); - this.head.addChild(this.hair); - this.head.addChild(this.ear1); - this.head.addChild(this.horn1); - this.head.addChild(this.nose); - this.head.addChild(this.ear2); - this.head.addChild(this.horn2); - - // CrowsOfWar: Adjust bottom-of-feet pos to be at 0, which prevents - // weird issues while scaling - List allBoxes = Arrays.asList(body, leg1, leg2, leg3, leg4, leg5, leg6, head, upTail); - for (ModelRenderer box : allBoxes) { - box.rotationPointY -= 18; - } + public ModelRenderer leg2; + public ModelRenderer leg4; + public ModelRenderer body; + public ModelRenderer upTail; + public ModelRenderer leg1; + public ModelRenderer leg5; + public ModelRenderer leg6; + public ModelRenderer leg3; + public ModelRenderer head; + public ModelRenderer lowTail; + public ModelRenderer hair; + public ModelRenderer ear1; + public ModelRenderer ear2; + public ModelRenderer horn1; + public ModelRenderer horn2; + public ModelRenderer nose; + public ModelRenderer cheeks; + public ModelRenderer jaw; + + private int state = 1; // This is a little helper to check when the bison is on the ground + sitting in order to adjust the saddle + + public ModelFlyingBison() { + this.textureWidth = 112; + this.textureHeight = 96; + this.leg1 = new ModelRenderer(this, 0, 0); + this.leg1.setRotationPoint(5.98F, 11.98F, -7.98F); + this.leg1.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); + this.cheeks = new ModelRenderer(this, 0, 80); + this.cheeks.setRotationPoint(0.0F, 4.5F, -9.99F); + this.cheeks.addBox(-5.5F, 0.0F, 0.0F, 11, 1, 3, 0.0F); + this.leg2 = new ModelRenderer(this, 0, 0); + this.leg2.setRotationPoint(5.98F, 11.98F, 3.0F); + this.leg2.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); + this.leg4 = new ModelRenderer(this, 0, 0); + this.leg4.setRotationPoint(-5.98F, 11.98F, -7.98F); + this.leg4.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); + this.lowTail = new ModelRenderer(this, 32, 72); + this.lowTail.setRotationPoint(0.0F, 1.52F, 13.5F); + this.lowTail.addBox(-8.0F, -1.5F, 0.0F, 16, 3, 14, 0.0F); + this.head = new ModelRenderer(this, 0, 43); + this.head.setRotationPoint(0.0F, 2.5F, -10.0F); + this.head.addBox(-5.5F, -6.0F, -10.0F, 11, 11, 10, 0.0F); + this.upTail = new ModelRenderer(this, 35, 55); + this.upTail.setRotationPoint(0.0F, -2.8F, 15.0F); + this.upTail.addBox(-8.5F, 0.0F, 0.0F, 17, 3, 14, 0.0F); + this.nose = new ModelRenderer(this, 40, 43); + this.nose.setRotationPoint(0.0F, 2.5F, -10.0F); + this.nose.addBox(-2.5F, -1.0F, -1.0F, 5, 2, 1, 0.0F); + this.jaw = new ModelRenderer(this, 42, 43); + this.jaw.setRotationPoint(0.0F, 4.98F, -4.7F); + this.jaw.addBox(-5.0F, 0.0F, -5.0F, 10, 2, 10, 0.0F); + this.body = new ModelRenderer(this, 0, 0); + this.body.setRotationPoint(0.0F, 4.5F, 3.0F); + this.body.addBox(-9.0F, -7.5F, -14.0F, 18, 15, 28, 0.0F); + this.hair = new ModelRenderer(this, 0, 64); + this.hair.setRotationPoint(0.0F, -3.6F, -5.0F); + this.hair.addBox(-6.0F, -2.5F, -5.5F, 12, 5, 11, 0.0F); + this.horn2 = new ModelRenderer(this, 0, 64); + this.horn2.mirror = true; + this.horn2.setRotationPoint(-6.5F, -2.0F, -7.0F); + this.horn2.addBox(-1.0F, -9.0F, -1.0F, 2, 9, 2, 0.0F); + this.setRotateAngle(horn2, -0.20943951023931953F, 0.0F, -0.03490658503988659F); + this.leg6 = new ModelRenderer(this, 0, 0); + this.leg6.setRotationPoint(-5.98F, 11.98F, 13.98F); + this.leg6.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); + this.ear2 = new ModelRenderer(this, 32, 43); + this.ear2.mirror = true; + this.ear2.setRotationPoint(-4.0F, -1.0F, -5.0F); + this.ear2.addBox(-2.0F, 0.0F, 0.0F, 2, 4, 2, 0.0F); + this.setRotateAngle(ear2, 0.0F, 0.0F, 0.3839724354387525F); + this.ear1 = new ModelRenderer(this, 32, 43); + this.ear1.setRotationPoint(4.0F, -1.0F, -5.0F); + this.ear1.addBox(0.0F, 0.0F, 0.0F, 2, 4, 2, 0.0F); + this.setRotateAngle(ear1, 0.0F, 0.0F, -0.3839724354387525F); + this.leg5 = new ModelRenderer(this, 0, 0); + this.leg5.setRotationPoint(-5.98F, 11.98F, 3.0F); + this.leg5.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); + this.leg3 = new ModelRenderer(this, 0, 0); + this.leg3.setRotationPoint(5.98F, 11.98F, 13.98F); + this.leg3.addBox(-3.0F, 0.0F, -3.0F, 6, 12, 6, 0.0F); + this.horn1 = new ModelRenderer(this, 0, 64); + this.horn1.setRotationPoint(6.5F, -2.0F, -7.0F); + this.horn1.addBox(-1.0F, -9.0F, -1.0F, 2, 9, 2, 0.0F); + this.setRotateAngle(horn1, -0.20943951023931953F, 0.0F, 0.03490658503988659F); + this.head.addChild(this.cheeks); + this.upTail.addChild(this.lowTail); + this.head.addChild(this.nose); + this.head.addChild(this.jaw); + this.head.addChild(this.hair); + this.head.addChild(this.horn2); + this.head.addChild(this.ear2); + this.head.addChild(this.ear1); + this.head.addChild(this.horn1); this.saddle = new ModelBisonSaddle(); - } /** @@ -147,89 +151,168 @@ public ModelFlyingBison() { @Override public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { - - float pi = (float) Math.PI; - EntitySkyBison bison = (EntitySkyBison) entity; - float degToRad = pi / 180; - - head.rotateAngleX = headPitch * degToRad - + MathHelper.cos(limbSwing * 0.6662f / 3) * 0.1f * limbSwingAmount; - head.rotateAngleY = netHeadYaw * degToRad; - - if (bison.isSitting()) { - - float lower = 3; - - body.rotationPointY = lower + 0 - 18; - head.rotationPointY = lower - 2 - 18; - upTail.rotationPointY = lower - 4.4f - 18; - - limbSwing = 2.87f; - limbSwingAmount = 0.3f; - - } else { - body.rotationPointY = 0 - 18; - head.rotationPointY = -2 - 18; - upTail.rotationPointY = -4.4f - 18; - } - - leg2.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; - leg4.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; - leg6.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; - - leg1.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + pi) * 1.4F * limbSwingAmount; - leg3.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + pi) * 1.4F * limbSwingAmount; - leg5.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + pi) * 1.4F * limbSwingAmount; - - upTail.rotateAngleX = (MathHelper.cos(limbSwing * 0.3331f) - 2f) * 0.2f * limbSwingAmount - - 20 * degToRad; - lowTail.rotateAngleX = (MathHelper.cos(limbSwing * 0.3331f) - 2f) * -0.25f * limbSwingAmount; - - if (bison.isEatingGrass()) { - head.rotateAngleX = (MathHelper.cos(bison.getEatGrassTime() / 2f) * 15 + 65) * degToRad; - } - + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + float pi = (float) Math.PI; + EntitySkyBison bison = (EntitySkyBison) entity; + float degToRad = pi / 180; + BlockPos below = bison.getPosition().offset(EnumFacing.DOWN); + Block belowBlock = bison.world.getBlockState(below).getBlock(); + + + // These set up the head rotations for looking positions + head.rotateAngleX = headPitch * degToRad + MathHelper.cos(limbSwing * 0.6662f / 3) * 0.1f * limbSwingAmount; + head.rotateAngleY = netHeadYaw * degToRad; + + if (!bison.isSitting()) { + if (belowBlock == Blocks.AIR) { + // This sets each leg's rotation point further up (-1f) than default for the flying animation + leg1.rotationPointY = leg4.rotationPointY = leg2.rotationPointY = leg5.rotationPointY = + leg3.rotationPointY = leg6.rotationPointY = 11.98F - 1f; + } else { + // This sets each leg's rotation point to the model's default when on the ground for the walking animation + leg1.rotationPointY = leg4.rotationPointY = leg2.rotationPointY = leg5.rotationPointY = + leg3.rotationPointY = leg6.rotationPointY = 11.98F; + } + // These reset the body, head, + tail positions in case they were adjusted by another animation (eating, sitting, etc) + // The leg rotations are also reset here for when the bison is not moving + + body.rotationPointY = 4.5f; + head.rotationPointY = 2.5f; + upTail.rotationPointY = -2.8f; + leg1.rotateAngleY = leg4.rotateAngleY = leg2.rotateAngleY = leg5.rotateAngleY = + leg3.rotateAngleY = leg6.rotateAngleY = 0.0f; + + + // These are bases for easy editing of how an animation looks + float globalSpeed; + float globalDegree; + float globalWeight; + if (belowBlock != Blocks.AIR || bison.isEatingGrass()) { + + // Bases for walking animation + globalSpeed = 0.5F; + globalDegree = 0.2F; + globalWeight = 0F; + } else { + + // Bases for flying animation + globalSpeed = 0.14F; + globalDegree = 0.076F; + globalWeight = 0.2F; + } + + // These swing the legs + tail pieces based on the speed, degree, and weight set above + leg2.rotateAngleX = 1 * limbSwingAmount * globalDegree * MathHelper.cos(limbSwing * globalSpeed) + globalWeight; + leg4.rotateAngleX = 1 * limbSwingAmount * globalDegree * MathHelper.cos(limbSwing * globalSpeed) + globalWeight; + leg6.rotateAngleX = 1 * limbSwingAmount * globalDegree * MathHelper.cos(limbSwing * globalSpeed) + globalWeight; + + leg1.rotateAngleX = -1 * limbSwingAmount * globalDegree * MathHelper.cos(limbSwing * globalSpeed) + globalWeight; + leg3.rotateAngleX = -1 * limbSwingAmount * globalDegree * MathHelper.cos(limbSwing * globalSpeed) + globalWeight; + leg5.rotateAngleX = -1 * limbSwingAmount * globalDegree * MathHelper.cos(limbSwing * globalSpeed) + globalWeight; + + upTail.rotateAngleX = 1 * limbSwingAmount * 0.4f * MathHelper.cos(limbSwing * 0.2f) - 12 * degToRad; + lowTail.rotateAngleX = 1 * limbSwingAmount * 0.2f * MathHelper.cos(limbSwing * 0.2f + 0.6f); + } + + if (bison.isEatingGrass()) { + float lower = 3; + + // These adjust the body, head, + tail positions to be lower when the bison is eating grass + body.rotationPointY = lower + 4.5f; + upTail.rotationPointY = lower - 2.8f; + head.rotationPointY = 8f; + // These rotate the head + jaw pieces accordingly + head.rotateAngleX = 24 * degToRad; + jaw.rotateAngleX = (MathHelper.cos(bison.getEatGrassTime() / 2f) * 15 + 20) * degToRad; + } else { + // This resets the jaw's position + jaw.rotateAngleX = 0f; + } } - /** + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTickTime) { + super.setLivingAnimations(entity, limbSwing, limbSwingAmount, partialTickTime); + float pi = (float) Math.PI; + EntitySkyBison bison = (EntitySkyBison) entity; + float degToRad = pi / 180; + + BlockPos below = bison.getPosition().offset(EnumFacing.DOWN); + Block belowBlock = bison.world.getBlockState(below).getBlock(); + + + // This sets up the bison flop animation for sitting only when they are grounded + if (bison.isSitting() && belowBlock != Blocks.AIR) { + this.state = 2; // Saddle adjustment helper cont. + float lower = 9; + // These move the body, head, tail, + leg pieces lower + body.rotationPointY = lower + 4.5f; + head.rotationPointY = lower + 2.5f; + upTail.rotationPointY = lower - 2.8f; + leg1.rotationPointY = leg4.rotationPointY = leg2.rotationPointY = leg5.rotationPointY = + leg3.rotationPointY = leg6.rotationPointY = lower + 11.98F; + + // These rotate each of the legs + tail pieces + leg1.rotateAngleX = leg4.rotateAngleX = leg2.rotateAngleX = leg5.rotateAngleX = + leg3.rotateAngleX = leg6.rotateAngleX = -90 * degToRad; + leg1.rotateAngleY = -32 * degToRad; + leg4.rotateAngleY = 32 * degToRad; + leg2.rotateAngleY = -90 * degToRad; + leg5.rotateAngleY = 90 * degToRad; + leg3.rotateAngleY = -148 * degToRad; + leg6.rotateAngleY = 148 * degToRad; + + upTail.rotateAngleX = -40 * degToRad; + lowTail.rotateAngleX = 16 * degToRad; + } else { + + this.state = 1; // Saddle adjustment helper cont. + } + } + + /** * glStateManager calls and 'float scale' lines by CrowsOfWar, all else by - * Captn_Dubz + * Captn_Dubz + edited by Mnesikos */ @Override public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { - - EntitySkyBison bison = (EntitySkyBison) entity; - float size = bison.getCondition().getSizeMultiplier(); - - pushMatrix(); - float scale = 1.5f * size; - translate(0, 1.5, 0); - GlStateManager.scale(scale, scale, scale); - - this.leg2.render(f5); - this.leg4.render(f5); - this.body.render(f5); - this.upTail.render(f5); - this.leg1.render(f5); - this.leg5.render(f5); - this.leg6.render(f5); - this.leg3.render(f5); - this.head.render(f5); - - if (bison.getSaddle() != null) { - pushMatrix(); - translate(0, -1.55, 0.2); - - if (bison.isSitting()) { - translate(0, 0.20, 0); - } - - scale(0.5, 0.5, 0.5); - this.saddle.render(entity, f, f1, f2, f3, f4, f5); - popMatrix(); - } - - popMatrix(); + + setRotationAngles(f, f1, f2, f3, f4, f5, entity); + EntitySkyBison bison = (EntitySkyBison) entity; + float size = bison.getCondition().getSizeMultiplier(); + + pushMatrix(); + float scale = (float) 2.0 * size; + + // This makes sure the bison stays level with the ground despite any scaling + translate(0f, 1.5f - 1.5f * scale, -0.1f * scale); + GlStateManager.scale(scale, scale, scale); + + this.leg2.render(f5); + this.leg4.render(f5); + this.body.render(f5); + this.upTail.render(f5); + this.leg1.render(f5); + this.leg5.render(f5); + this.leg6.render(f5); + this.leg3.render(f5); + this.head.render(f5); + + if (bison.getSaddle() != null) { + pushMatrix(); + if (this.state == 2) { + // Adjusts saddle if the bison is sitting + on the ground + GlStateManager.translate(0f, 0.56f, 0f); + } else if (bison.isEatingGrass()) { + // Adjusts saddle if the bison is eating grass + GlStateManager.translate(0f, 0.186f, 0f); + } + // Otherwise the saddle does not need adjusting + this.saddle.render(entity, f, f1, f2, f3, f4, f5); + popMatrix(); + } + + popMatrix(); } diff --git a/src/main/java/com/crowsofwar/avatar/client/render/ModelLightningSpear.java b/src/main/java/com/crowsofwar/avatar/client/render/ModelLightningSpear.java index 1592f2d6fd..07268a8be0 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/ModelLightningSpear.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/ModelLightningSpear.java @@ -5,36 +5,47 @@ import net.minecraft.entity.Entity; /** - * ModelLightningSpear - CrowsOfWar - * Created using Tabula 7.0.0 + * Spear - Undefined + * Created using Tabula 5.1.0 */ public class ModelLightningSpear extends ModelBase { - public ModelRenderer shape1; - public ModelRenderer shape2; + public ModelRenderer Spear4; + public ModelRenderer Spear1; + public ModelRenderer Spear2; + public ModelRenderer Spear3; - public ModelLightningSpear() { - this.textureWidth = 64; - this.textureHeight = 64; - this.shape1 = new ModelRenderer(this, 0, 0); - this.shape1.setRotationPoint(0.0F, 0.0F, 0.0F); - this.shape1.addBox(0.0F, 0.0F, 0.0F, 2, 2, 16, 0.0F); - this.shape2 = new ModelRenderer(this, 0, 18); - this.shape2.setRotationPoint(-1.0F, -1.0F, -2.0F); - this.shape2.addBox(0.0F, 0.0F, 0.0F, 4, 4, 20, 0.0F); - } + public ModelLightningSpear() { + this.textureWidth = 64; + this.textureHeight = 48; + this.Spear2 = new ModelRenderer(this, 16, 1); + this.Spear2.setRotationPoint(0.0F, -1.0F, 0.0F); + this.Spear2.addBox(-2.0F, -18.0F, -2.0F, 4, 18, 4, 0.0F); + this.Spear3 = new ModelRenderer(this, 33, 0); + this.Spear3.setRotationPoint(0.0F, -2.0F, 0.0F); + this.Spear3.addBox(-2.5F, -10.0F, -2.5F, 5, 10, 5, 0.0F); + this.Spear1 = new ModelRenderer(this, 3, 2); + this.Spear1.setRotationPoint(0.0F, 0.1F, 0.0F); + this.Spear1.addBox(-1.5F, -30.0F, -1.5F, 3, 30, 3, 0.0F); + this.Spear4 = new ModelRenderer(this, 54, 3); + this.Spear4.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Spear4.addBox(-1.0F, -35.0F, -1.0F, 2, 35, 2, 0.0F); + this.setRotateAngle(Spear4, 1.5707963267948966F, -0.0F, 0.0F); + this.Spear1.addChild(this.Spear2); + this.Spear1.addChild(this.Spear3); + this.Spear4.addChild(this.Spear1); + } - @Override - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { - this.shape1.render(f5); - this.shape2.render(f5); - } + @Override + public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { + this.Spear4.render(f5); + } - /** - * This is a helper function from Tabula to set the rotation of model parts - */ - public void setRotateAngle(ModelRenderer modelRenderer, float x, float y, float z) { - modelRenderer.rotateAngleX = x; - modelRenderer.rotateAngleY = y; - modelRenderer.rotateAngleZ = z; - } + /** + * This is a helper function from Tabula to set the rotation of model parts + */ + public void setRotateAngle(ModelRenderer modelRenderer, float x, float y, float z) { + modelRenderer.rotateAngleX = x; + modelRenderer.rotateAngleY = y; + modelRenderer.rotateAngleZ = z; + } } diff --git a/src/main/java/com/crowsofwar/avatar/client/render/ModelOtterPenguin.java b/src/main/java/com/crowsofwar/avatar/client/render/ModelOtterPenguin.java index abfaf9ef46..d054cd64a6 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/ModelOtterPenguin.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/ModelOtterPenguin.java @@ -22,150 +22,248 @@ import net.minecraft.client.model.ModelRenderer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.math.MathHelper; /** - * TheOtterpenguin - talhanation
+ * Otter Penguin - talhanation & edited by Mnesikos * Created using Tabula 5.1.0 * - * @author talhanation + * @author Mnesikos (unless otherwise specified) */ public class ModelOtterPenguin extends ModelBase { - - public ModelRenderer leftarm2; - public ModelRenderer leftarm1; - public ModelRenderer rightarm2; - public ModelRenderer rightarm1; - public ModelRenderer tail2; - public ModelRenderer tail1; public ModelRenderer body; - public ModelRenderer leftleg; public ModelRenderer head; - public ModelRenderer rightleg; - public ModelRenderer leftfoot; - public ModelRenderer leftshin; - public ModelRenderer nose; + public ModelRenderer leftArm1; + public ModelRenderer leftArm2; + public ModelRenderer rightArm1; + public ModelRenderer rightArm2; + public ModelRenderer leftLeg; + public ModelRenderer rightLeg; + public ModelRenderer tail1; public ModelRenderer beard1; public ModelRenderer beard2; - public ModelRenderer rightshin; - public ModelRenderer rightfoot; + public ModelRenderer nose; + public ModelRenderer leftShin; + public ModelRenderer leftFoot; + public ModelRenderer rightShin; + public ModelRenderer rightFoot; + public ModelRenderer tail2; + private int state = 1; // This is a little helper to check when the penguin is being ridden, sprinting, or at its default public ModelOtterPenguin() { - this.textureWidth = 128; - this.textureHeight = 64; - this.leftarm2 = new ModelRenderer(this, 73, 0); - this.leftarm2.mirror = true; - this.leftarm2.setRotationPoint(3.0F, 6.0F, 1.0F); - this.leftarm2.addBox(0.5F, 4.0F, -3.0F, 1, 10, 4, 0.0F); - this.setRotateAngle(leftarm2, 0.0F, -0.0F, -0.03490658476948738F); - this.tail1 = new ModelRenderer(this, 54, 33); - this.tail1.setRotationPoint(0.0F, 18.0F, 4.0F); - this.tail1.addBox(-3.0F, -3.0F, -1.0F, 6, 7, 2, 0.0F); - this.setRotateAngle(tail1, 0.3839724361896515F, -0.0F, 0.0F); - this.rightshin = new ModelRenderer(this, 58, 16); - this.rightshin.setRotationPoint(0.0F, 0.0F, 0.0F); - this.rightshin.addBox(-1.0F, 2.0F, -1.0F, 2, 2, 2, 0.0F); - this.beard2 = new ModelRenderer(this, 120, 4); - this.beard2.setRotationPoint(0.0F, 0.0F, 0.0F); - this.beard2.addBox(-2.0F, -1.6F, -3.6F, 1, 3, 0, 0.0F); + this.textureWidth = 64; + this.textureHeight = 48; this.head = new ModelRenderer(this, 0, 0); - this.head.setRotationPoint(0.0F, 6.999999999999996F, 0.0F); - this.head.addBox(-4.0F, -8.0F, -3.5F, 8, 8, 8, 0.0F); - this.rightarm1 = new ModelRenderer(this, 73, 0); - this.rightarm1.setRotationPoint(-3.0F, 6.0F, 1.0F); - this.rightarm1.addBox(-1.5F, 4.0F, -3.0F, 1, 10, 4, 0.0F); - this.setRotateAngle(rightarm1, 0.0F, -0.0F, 0.03490658476948738F); - this.leftarm1 = new ModelRenderer(this, 85, 0); - this.leftarm1.setRotationPoint(3.0F, 7.0F, 1.0F); - this.leftarm1.addBox(0.800000011920929F, 0.0F, -3.0F, 1, 10, 4, 0.0F); - this.setRotateAngle(leftarm1, 0.0F, -0.0F, -0.15707963705062866F); - this.rightarm2 = new ModelRenderer(this, 73, 0); - this.rightarm2.setRotationPoint(-3.0F, 7.0F, 1.0F); - this.rightarm2.addBox(-1.7999999523162842F, 0.0F, -3.0F, 1, 10, 4, 0.0F); - this.setRotateAngle(rightarm2, 0.0F, -0.0F, 0.15707963705062866F); - this.beard1 = new ModelRenderer(this, 120, 4); - this.beard1.setRotationPoint(0.0F, 0.0F, 0.0F); - this.beard1.addBox(1.0F, -1.6F, -3.6F, 1, 3, 0, 0.0F); - this.rightleg = new ModelRenderer(this, 0, 16); - this.rightleg.setRotationPoint(-2.0000000000000004F, 18.999999999999996F, 0.0F); - this.rightleg.addBox(-2.0F, 0.0F, -2.0F, 4, 2, 4, 0.0F); - this.leftshin = new ModelRenderer(this, 58, 16); - this.leftshin.setRotationPoint(0.0F, 0.0F, 0.0F); - this.leftshin.addBox(-1.0F, 2.0F, -1.0F, 2, 2, 2, 0.0F); - this.leftleg = new ModelRenderer(this, 0, 16); - this.leftleg.setRotationPoint(2.1000000000000005F, 18.999999999999975F, 0.0F); - this.leftleg.addBox(-2.0F, 0.0F, -2.0F, 4, 2, 4, 0.0F); - this.body = new ModelRenderer(this, 1, 29); + this.head.setRotationPoint(0.0F, 0.01F, 0.5F); + this.head.addBox(-3.5F, -7.0F, -4.0F, 7, 7, 8, 0.0F); + this.leftArm2 = new ModelRenderer(this, 33, 7); + this.leftArm2.mirror = true; + this.leftArm2.setRotationPoint(3.5F, 3.0F, -1.5F); + this.leftArm2.addBox(-0.5F, 0.0F, 0.0F, 1, 10, 4, 0.0F); + this.setRotateAngle(leftArm2, 0.0F, 0.0F, -0.12217304763960307F); + this.beard1 = new ModelRenderer(this, 0, 2); + this.beard1.mirror = true; + this.beard1.setRotationPoint(1.5F, -1.6F, -4.02F); + this.beard1.addBox(-0.5F, 0.0F, 0.0F, 1, 3, 0, 0.0F); + this.rightArm2 = new ModelRenderer(this, 33, 7); + this.rightArm2.setRotationPoint(-3.5F, 3.0F, -1.5F); + this.rightArm2.addBox(-0.5F, 0.0F, 0.0F, 1, 10, 4, 0.0F); + this.setRotateAngle(rightArm2, 0.0F, 0.0F, 0.12217304763960307F); + this.beard2 = new ModelRenderer(this, 0, 2); + this.beard2.setRotationPoint(-1.5F, -1.6F, -4.02F); + this.beard2.addBox(-0.5F, 0.0F, 0.0F, 1, 3, 0, 0.0F); + this.rightFoot = new ModelRenderer(this, 41, 0); + this.rightFoot.setRotationPoint(0.0F, 2.0F, -1.5F); + this.rightFoot.addBox(-1.5F, 0.0F, -2.5F, 3, 1, 4, 0.0F); + this.tail1 = new ModelRenderer(this, 31, 22); + this.tail1.setRotationPoint(0.0F, 8.0F, 4.0F); + this.tail1.addBox(-3.0F, 0.0F, -2.0F, 6, 7, 2, 0.0F); + this.setRotateAngle(tail1, 0.3839724354387525F, 0.0F, 0.0F); + this.leftShin = new ModelRenderer(this, 37, 0); + this.leftShin.mirror = true; + this.leftShin.setRotationPoint(0.0F, 2.0F, 1.0F); + this.leftShin.addBox(-1.0F, 0.0F, -2.0F, 2, 2, 2, 0.0F); + this.leftFoot = new ModelRenderer(this, 41, 0); + this.leftFoot.mirror = true; + this.leftFoot.setRotationPoint(0.0F, 2.0F, -1.5F); + this.leftFoot.addBox(-1.5F, 0.0F, -2.5F, 3, 1, 4, 0.0F); + this.leftArm1 = new ModelRenderer(this, 33, 7); + this.leftArm1.mirror = true; + this.leftArm1.setRotationPoint(4.3F, 0.0F, -1.5F); + this.leftArm1.addBox(-0.5F, 0.0F, 0.0F, 1, 10, 4, 0.0F); + this.setRotateAngle(leftArm1, 0.0F, 0.0F, -0.10471975511965977F); + this.nose = new ModelRenderer(this, 0, 0); + this.nose.setRotationPoint(0.0F, -2.5F, -3.6F); + this.nose.addBox(-1.0F, -0.5F, -1.0F, 2, 1, 1, 0.0F); + this.rightShin = new ModelRenderer(this, 37, 0); + this.rightShin.setRotationPoint(0.0F, 2.0F, 1.0F); + this.rightShin.addBox(-1.0F, 0.0F, -2.0F, 2, 2, 2, 0.0F); + this.leftLeg = new ModelRenderer(this, 25, 0); + this.leftLeg.mirror = true; + this.leftLeg.setRotationPoint(2.1F, 11.99F, 0.2F); + this.leftLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 2, 4, 0.0F); + this.tail2 = new ModelRenderer(this, 47, 22); + this.tail2.setRotationPoint(0.0F, 7.0F, -1.3F); + this.tail2.addBox(-2.5F, 0.0F, 0.0F, 5, 6, 1, 0.0F); + this.setRotateAngle(tail2, 0.6981317007977318F, 0.0F, 0.0F); + this.rightArm1 = new ModelRenderer(this, 33, 7); + this.rightArm1.setRotationPoint(-4.3F, 0.0F, -1.5F); + this.rightArm1.addBox(-0.5F, 0.0F, 0.0F, 1, 10, 4, 0.0F); + this.setRotateAngle(rightArm1, 0.0F, 0.0F, 0.10471975511965977F); + this.body = new ModelRenderer(this, 0, 17); this.body.setRotationPoint(0.0F, 7.0F, 0.0F); this.body.addBox(-4.0F, 0.0F, -3.0F, 8, 12, 7, 0.0F); - this.tail2 = new ModelRenderer(this, 40, 34); - this.tail2.setRotationPoint(0.0F, 18.0F, 4.0F); - this.tail2.addBox(-2.5F, 3.0F, -2.799999952316284F, 5, 6, 1, 0.0F); - this.setRotateAngle(tail2, 1.0995573997497559F, -0.0F, 0.0F); - this.rightfoot = new ModelRenderer(this, 43, 16); - this.rightfoot.setRotationPoint(0.0F, 0.0F, 0.0F); - this.rightfoot.addBox(-1.5F, 4.0F, -3.0F, 3, 1, 4, 0.0F); - this.leftfoot = new ModelRenderer(this, 43, 16); - this.leftfoot.setRotationPoint(0.0F, 0.0F, 0.0F); - this.leftfoot.addBox(-1.5F, 4.0F, -3.0F, 3, 1, 4, 0.0F); - this.nose = new ModelRenderer(this, 0, 0); - this.nose.setRotationPoint(0.0F, 0.0F, 0.0F); - this.nose.addBox(-1.0F, -3.0F, -4.0F, 2, 1, 1, 0.0F); - this.rightleg.addChild(this.rightshin); - this.head.addChild(this.beard2); + this.rightLeg = new ModelRenderer(this, 25, 0); + this.rightLeg.setRotationPoint(-2.1F, 11.99F, 0.2F); + this.rightLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 2, 4, 0.0F); + this.body.addChild(this.head); + this.body.addChild(this.leftArm2); this.head.addChild(this.beard1); - this.leftleg.addChild(this.leftshin); - this.rightleg.addChild(this.rightfoot); - this.leftleg.addChild(this.leftfoot); + this.body.addChild(this.rightArm2); + this.head.addChild(this.beard2); + this.rightShin.addChild(this.rightFoot); + this.body.addChild(this.tail1); + this.leftLeg.addChild(this.leftShin); + this.leftShin.addChild(this.leftFoot); + this.body.addChild(this.leftArm1); this.head.addChild(this.nose); - + this.rightLeg.addChild(this.rightShin); + this.body.addChild(this.leftLeg); + this.tail1.addChild(this.tail2); + this.body.addChild(this.rightArm1); + this.body.addChild(this.rightLeg); } @Override - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { - // this part authored by CrowsOfWar - + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + this.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); EntityOtterPenguin penguin = (EntityOtterPenguin) entity; - if (penguin.isChild()) { - GlStateManager.pushMatrix(); - GlStateManager.scale(0.7f, 0.7f, 0.7f); - GlStateManager.translate(0, 0.62f, 0); - } - // end CrowsOfWar - this.leftarm2.render(f5); - this.tail1.render(f5); - this.head.render(f5); - this.rightarm1.render(f5); - this.leftarm1.render(f5); - this.rightarm2.render(f5); - this.rightleg.render(f5); - this.leftleg.render(f5); - this.body.render(f5); - this.tail2.render(f5); - // this part authored by CrowsOfWar - if (penguin.isChild()) { + if (penguin.isChild()) { // Half the original model size for all baby penguins + translation to keep them flush with the ground + GlStateManager.pushMatrix(); + GlStateManager.scale(0.5f, 0.5f, 0.5f); + GlStateManager.translate(0, 1.48f, 0); + this.body.render(scale); + GlStateManager.popMatrix(); + } else if (penguin.isBeingRidden()) { // Translation to keep this particular animation flush with the ground + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0.88f, 0); + this.body.render(scale); GlStateManager.popMatrix(); + } else { + // With every other part parented to this piece, this is the only thing needing rendered! Otherwise they would be rendered twice. + this.body.render(scale); } - // end CrowsOfWar - } - /** - * This method made by CrowsOfWar - */ @Override public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + EntityOtterPenguin penguin = (EntityOtterPenguin) entity; + + if (this.state < 3) { // State 1 and 2 are the default and sprinting states respectively + // These set up the head rotations for looking positions + head.rotateAngleY = (float) Math.toRadians(netHeadYaw); + head.rotateAngleX = (float) Math.toRadians(headPitch); + + // These are bases for easy editing of how an animation looks + float globalSpeed = 2.0F; + float globalDegree = 1.8F; + float globalHeight = 1.6F; + if (penguin.isChild()) { // Setting all child model animation speeds to be half of the adult's + globalSpeed = 1.0F; + } + + // This moves the entire model up and down for a bounce effect in their walk + body.rotationPointY = (float) -Math.abs((Math.sin(limbSwing * (0.5f * globalSpeed)) * limbSwingAmount * (0.4f * globalHeight))) + 7.0f; + // This moves the entire model side to side for a waddle effect in their walk + body.rotateAngleZ = 1 * limbSwingAmount * (0.06F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)); + // These two rotate the entire model around the Y axis, and the head is rotated to offset the rest of the model + body.rotateAngleY = 1 * limbSwingAmount * (0.08F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)); + head.rotateAngleY = -1 * limbSwingAmount * (0.08F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)); + + // These rotate the arms to give them a sort of flap when moving (while sprinting they are raised higher to give a frantic look) + if (this.state == 2) { // If this entity is sprinting + leftArm1.rotateAngleZ = 1 * limbSwingAmount * (0.2F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)) - 0.6F; + leftArm2.rotateAngleZ = 1 * limbSwingAmount * (0.2F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)) - 0.2F; + rightArm1.rotateAngleZ = -1 * limbSwingAmount * (0.2F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)) + 0.6F; + rightArm2.rotateAngleZ = -1 * limbSwingAmount * (0.2F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)) + 0.2F; + } else { + leftArm1.rotateAngleZ = 1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (1.0F * globalSpeed)) - 0.12F; + leftArm2.rotateAngleZ = 1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (1.0F * globalSpeed)) - 0.12F; + rightArm1.rotateAngleZ = -1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (1.0F * globalSpeed)) + 0.12F; + rightArm2.rotateAngleZ = -1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (1.0F * globalSpeed)) + 0.12F; + } + + // These rotate the legs back and forth + the feet to give a "step" look while walking + rightLeg.rotateAngleX = 1 * limbSwingAmount * (0.3F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)); + rightFoot.rotateAngleX = 1 * limbSwingAmount * (0.1F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed) + 2.6F); + leftLeg.rotateAngleX = -1 * limbSwingAmount * (0.3F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)); + leftFoot.rotateAngleX = -1 * limbSwingAmount * (0.1F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed) + 2.6F); + + // These rotate the tail pieces up and down slightly, giving the overall animation more life + tail1.rotateAngleX = 1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (1.0F * globalSpeed)) + 0.3839724354387525F; + tail2.rotateAngleX = -1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (1.0F * globalSpeed)) + 0.6981317007977318F; - float pi = (float) Math.PI; + } else if (this.state == 3) { // If this entity is being ridden + // These set up the head rotations for looking positions, again. + // This time with an offset for Angle X to make sure they're looking up instead of in the ground + head.rotateAngleY = (float) Math.toRadians(netHeadYaw); + head.rotateAngleX = (float) Math.toRadians(headPitch) + -1.4660765716752369F; - head.rotateAngleY = (float) Math.toRadians(netHeadYaw); - head.rotateAngleX = (float) Math.toRadians(headPitch); + // More bases for easy editing of how the new animation looks + float globalSpeed = 0.5F; + float globalDegree = 1.8F; + // These rotate the arms to give them a very small flap when moving + leftArm1.rotateAngleZ = 1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)) - 0.8377580409572781F; + leftArm2.rotateAngleZ = 1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)) - 0.6981317007977318F; + rightArm1.rotateAngleZ = -1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)) + 0.8377580409572781F; + rightArm2.rotateAngleZ = -1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)) + 0.6981317007977318F; - rightleg.rotateAngleX = MathHelper.cos(limbSwing * 2) * limbSwingAmount; - leftleg.rotateAngleX = MathHelper.cos(limbSwing * 2 + pi) * limbSwingAmount; + // These are set to the model's defaults so another animation will not affect them while in state 3 + body.rotationPointY = 7.0F; + leftLeg.rotateAngleX = rightLeg.rotateAngleX = 0.0F; + // These rotate the tail pieces up and down, giving the overall animation more life + tail1.rotateAngleX = 1 * limbSwingAmount * (0.01F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)) + 0.06981317007977318F; + tail2.rotateAngleX = 1 * limbSwingAmount * (0.02F * globalDegree) * MathHelper.cos(limbSwing * (0.5F * globalSpeed)) + 0.06981317007977318F; + } + } + + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTickTime) { + EntityOtterPenguin penguin = (EntityOtterPenguin) entity; + // These set the model's default, that way they will revert when no animation is changing them + body.rotateAngleX = head.rotateAngleX = leftFoot.rotateAngleX = rightFoot.rotateAngleX = 0.0F; + tail1.rotateAngleX = 0.3839724354387525F; + tail2.rotateAngleX = 0.6981317007977318F; + leftArm1.rotateAngleY = leftArm2.rotateAngleY = rightArm1.rotateAngleY = rightArm2.rotateAngleY = 0.0F; + leftArm1.rotateAngleZ = -0.10471975511965977F; + leftArm2.rotateAngleZ = -0.12217304763960307F; + rightArm1.rotateAngleZ = 0.10471975511965977F; + rightArm2.rotateAngleZ = 0.12217304763960307F; + + if (penguin.isBeingRidden()) { + // These all adjust each piece's rotations for the new riding pose/animation + this.setRotateAngle(body, 1.53588974175501F, 0.0F, 0.0F); + this.setRotateAngle(head, -1.4660765716752369F, 0.0F, 0.0F); + this.setRotateAngle(leftArm1, 0.0F, -0.8377580409572781F, -0.8377580409572781F); + this.setRotateAngle(leftArm2, 0.0F, -0.9773843811168246F, -0.6981317007977318F); + this.setRotateAngle(rightArm1, 0.0F, 0.8377580409572781F, 0.8377580409572781F); + this.setRotateAngle(rightArm2, 0.0F, 0.9773843811168246F, 0.6981317007977318F); + this.setRotateAngle(leftFoot, 1.2566370614359172F, 0.0F, 0.0F); + this.setRotateAngle(rightFoot, 1.2566370614359172F, 0.0F, 0.0F); + this.setRotateAngle(tail1, 0.06981317007977318F, 0.0F, 0.0F); + this.setRotateAngle(tail2, 0.06981317007977318F, 0.0F, 0.0F); + this.state = 3; // Little helper cont. + + } else if (penguin.isSprinting()) { + this.state = 2; // Little helper cont. + + } else { + this.state = 1; // Little helper cont. + } } /** diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderAvatarLightning.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderAvatarLightning.java index 2cadce844b..4c3c716be5 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderAvatarLightning.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderAvatarLightning.java @@ -1,18 +1,16 @@ package com.crowsofwar.avatar.client.render; import com.crowsofwar.avatar.common.entity.EntityAvatarLightning; - -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.RenderManager; - import net.minecraft.client.renderer.vertex.DefaultVertexFormats; - import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; +import javax.annotation.Nullable; import java.util.Random; @@ -25,125 +23,130 @@ public RenderAvatarLightning(RenderManager renderManagerIn) { super(renderManagerIn); } - /** - * Renders the desired {@code T} type Entity. - */ public void doRender(EntityAvatarLightning entity, double x, double y, double z, float entityYaw, float partialTicks) { - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferbuilder = tessellator.getBuffer(); - GlStateManager.disableTexture2D(); - GlStateManager.disableLighting(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE); - double[] adouble = new double[8]; - double[] adouble1 = new double[8]; - double d0 = 0.0D; - double d1 = 0.0D; - Random random = new Random(entity.boltVertex); - Minecraft.getMinecraft().renderEngine.bindTexture(TEXTURE); - - for (int i = 7; i >= 0; --i) { - adouble[i] = d0; - adouble1[i] = d1; - d0 += (double) (random.nextInt(11) - 5); - d1 += (double) (random.nextInt(11) - 5); - } - for (int k1 = 0; k1 < 4; ++k1) { - Random random1 = new Random(entity.boltVertex); - - for (int j = 0; j < 3; ++j) { - int k = 7; - int l = 0; - - if (j > 0) { - k = 7 - j; - } + GlStateManager.pushMatrix(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + GlStateManager.disableTexture2D(); + GlStateManager.disableLighting(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE); + double[] adouble = new double[8]; + double[] adouble1 = new double[8]; + double d0 = 0.0D; + double d1 = 0.0D; + Random random = new Random(entity.boltVertex); + GL11.glColor3f(0, 0, 1); + //Minecraft.getMinecraft().renderEngine.bindTexture(TEXTURE); + + for (int i = 7; i >= 0; --i) { + adouble[i] = d0; + adouble1[i] = d1; + d0 += (double) (random.nextInt(11) - 5); + d1 += (double) (random.nextInt(11) - 5); + } - if (j > 0) { - l = k - 2; - } + for (int k1 = 0; k1 < 4; ++k1) { + Random random1 = new Random(entity.boltVertex); - double d2 = adouble[k] - d0; - double d3 = adouble1[k] - d1; + for (int j = 0; j < 3; ++j) { + int k = 7; + int l = 0; - for (int i1 = k; i1 >= l; --i1) { - double d4 = d2; - double d5 = d3; + if (j > 0) { + k = 7 - j; + } - if (j == 0) { - d2 += (double) (random1.nextInt(11) - 5); - d3 += (double) (random1.nextInt(11) - 5); - } else { - d2 += (double) (random1.nextInt(31) - 15); - d3 += (double) (random1.nextInt(31) - 15); + if (j > 0) { + l = k - 2; } - bufferbuilder.begin(5, DefaultVertexFormats.POSITION_COLOR); - float f = 0.5F; - float f1 = 0.45F; - float f2 = 0.45F; - float f3 = 0.5F; - double d6 = 0.1D + (double) k1 * 0.2D; + double d2 = adouble[k] - d0; + double d3 = adouble1[k] - d1; - if (j == 0) { - d6 *= (double) i1 * 0.1D + 1.0D; - } + for (int i1 = k; i1 >= l; --i1) { + double d4 = d2; + double d5 = d3; - double d7 = 0.1D + (double) k1 * 0.2D; + if (j == 0) { + d2 += (double) (random1.nextInt(11) - 5); + d3 += (double) (random1.nextInt(11) - 5); + } else { + d2 += (double) (random1.nextInt(31) - 15); + d3 += (double) (random1.nextInt(31) - 15); + } - if (j == 0) { - d7 *= (double) (i1 - 1) * 0.1D + 1.0D; - } + bufferbuilder.begin(5, DefaultVertexFormats.POSITION_COLOR); - for (int j1 = 0; j1 < 5; ++j1) { - double d8 = x + 0.5D - d6; - double d9 = z + 0.5D - d6; + float f = 0.5F; + float f1 = 0.45F; + float f2 = 0.45F; + float f3 = 0.5F; + double d6 = 0.1D + (double) k1 * 0.2D; - if (j1 == 1 || j1 == 2) { - d8 += d6 * 2.0D; + if (j == 0) { + d6 *= (double) i1 * 0.1D + 1.0D; } - if (j1 == 2 || j1 == 3) { - d9 += d6 * 2.0D; + double d7 = 0.1D + (double) k1 * 0.2D; + + if (j == 0) { + d7 *= (double) (i1 - 1) * 0.1D + 1.0D; } - double d10 = x + 0.5D - d7; - double d11 = z + 0.5D - d7; + for (int j1 = 0; j1 < 5; ++j1) { + double d8 = x + 0.5D - d6; + double d9 = z + 0.5D - d6; - if (j1 == 1 || j1 == 2) { - d10 += d7 * 2.0D; - } + if (j1 == 1 || j1 == 2) { + d8 += d6 * 2.0D; + } - if (j1 == 2 || j1 == 3) { - d11 += d7 * 2.0D; - } + if (j1 == 2 || j1 == 3) { + d9 += d6 * 2.0D; + } - bufferbuilder.pos(d10 + d2, y + (double) (i1 * 16), d11 + d3).color(0F, 1F, 1F, 0.3F).endVertex(); - bufferbuilder.pos(d8 + d4, y + (double) ((i1 + 1) * 16), d9 + d5).color(0F, 1F, 1F, 0.3F).endVertex(); - bufferbuilder.color(0F, 1F, 1F, 0.3F); - GlStateManager.color(0F, 1F, 1F, 0.3F); + double d10 = x + 0.5D - d7; + double d11 = z + 0.5D - d7; - } + if (j1 == 1 || j1 == 2) { + d10 += d7 * 2.0D; + } + + if (j1 == 2 || j1 == 3) { + d11 += d7 * 2.0D; + } + + //Minecraft.getMinecraft().renderEngine.bindTexture(TEXTURE); + GlStateManager.color(0F, 0, 1F, 0.3F); + GlStateManager.color(0, 0,1); + GL11.glColor3f(0, 0, 1); + bufferbuilder.pos(d10 + d2, y + (double) (i1 * 16), d11 + d3).color(0F, 0, 255F, 0.3F).endVertex(); + bufferbuilder.pos(d8 + d4, y + (double) ((i1 + 1) * 16), d9 + d5).color(0F, 0, 255F, 0.3F).endVertex(); + bufferbuilder.color(0F, 0, 255F, 0.3F); + + + } - tessellator.draw(); + tessellator.draw(); + } } } - } - GlStateManager.disableBlend(); - GlStateManager.enableLighting(); - GlStateManager.enableTexture2D(); - } + GlStateManager.disableBlend(); + GlStateManager.enableLighting(); + GlStateManager.enableTexture2D(); + GlStateManager.popMatrix(); + + } - @Override - /** - * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. - */ + @Nullable protected ResourceLocation getEntityTexture(EntityAvatarLightning entity) { return TEXTURE; } + } diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderBoulder.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderBoulder.java index c69fce7b3b..d67070c793 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderBoulder.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderBoulder.java @@ -1,19 +1,13 @@ package com.crowsofwar.avatar.client.render; import com.crowsofwar.avatar.common.entity.EntityBoulder; -import com.crowsofwar.avatar.common.entity.EntityCloudBall; -import com.crowsofwar.avatar.common.entity.EntityFloatingBlock; -import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.entity.Entity; -import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.World; @@ -22,12 +16,9 @@ import org.joml.Vector4f; import org.lwjgl.opengl.GL11; -import javax.annotation.Nullable; import java.util.Random; import static net.minecraft.client.renderer.GlStateManager.*; -import static net.minecraft.client.renderer.GlStateManager.disableBlend; -import static net.minecraft.client.renderer.GlStateManager.enableLighting; import static net.minecraft.util.math.MathHelper.cos; public class RenderBoulder extends Render { diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderCloudburst.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderCloudburst.java index 1f3b14cb41..53a46b9691 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderCloudburst.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderCloudburst.java @@ -12,7 +12,6 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.World; -import net.minecraftforge.client.MinecraftForgeClient; import org.joml.Matrix4f; import org.joml.Vector4f; import org.lwjgl.opengl.GL11; @@ -48,13 +47,13 @@ public void doRender(EntityCloudBall entity, double xx, double yy, double zz, fl size *= Math.sqrt(entity.getSize() / 30f); enableBlend(); - if (entity.ticksExisted % 3 == 0) { + if (entity.ticksExisted % 5 == 0) { World world = entity.world; AxisAlignedBB boundingBox = entity.getEntityBoundingBox(); double spawnX = boundingBox.minX + random.nextDouble() * (boundingBox.maxX - boundingBox.minX); double spawnY = boundingBox.minY + random.nextDouble() * (boundingBox.maxY - boundingBox.minY); double spawnZ = boundingBox.minZ + random.nextDouble() * (boundingBox.maxZ - boundingBox.minZ); - world.spawnParticle(EnumParticleTypes.CLOUD, spawnX, spawnY, spawnZ, 0, 0, 0); + world.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, spawnX, spawnY, spawnZ, 0, 0.06, 0); } // if (MinecraftForgeClient.getRenderPass() == 0) { @@ -63,7 +62,7 @@ public void doRender(EntityCloudBall entity, double xx, double yy, double zz, fl renderCube(x, y, z, // 0, 8 / 256.0, 0, 8 / 256.0, // .5f, // - 0, ticks / 25f, 0); + ticks / 25F, ticks / 25f, ticks / 25F); int i = 15728880; int j = i % 65536; @@ -71,13 +70,14 @@ public void doRender(EntityCloudBall entity, double xx, double yy, double zz, fl OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, j, k); // } else { + disableLight(entity.world.getSkylightSubtracted()); - pushMatrix(); - renderCube(x, y, z, // + pushMatrix(); + renderCube(x, y, z, // 8 / 256.0, 16 / 256.0, 0 / 256.0, 8 / 256.0, // size, // rotation * .2f, rotation, rotation * -.4f); - popMatrix(); + popMatrix(); // } disableBlend(); diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderEarthspikes.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderEarthspikes.java index a6427035e6..44cf8ba2e0 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderEarthspikes.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderEarthspikes.java @@ -17,20 +17,23 @@ package com.crowsofwar.avatar.client.render; import com.crowsofwar.avatar.common.entity.EntityEarthspike; +import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; /** * @author CrowsOfWar */ public class RenderEarthspikes extends RenderModel { - private static final ResourceLocation TEXTURE = new ResourceLocation("avatarmod", - "textures/entity/earthspike.png"); + + public static ResourceLocation TEXTURE; private ModelBase model; @@ -46,8 +49,29 @@ public RenderEarthspikes(RenderManager renderManager) { public void doRender(EntityEarthspike entity, double x, double y, double z, float entityYaw, float partialTicks) { - Minecraft.getMinecraft().renderEngine.bindTexture(TEXTURE); + BlockPos below = entity.getPosition().offset(EnumFacing.DOWN); + Block belowBlock = entity.world.getBlockState(below).getBlock(); + if (belowBlock == Blocks.GRASS) { + TEXTURE = new ResourceLocation("avatarmod", "textures/entity/earthspike" + ".png"); + } + else if (belowBlock == Blocks.DIRT) { + TEXTURE = new ResourceLocation("avatarmod", "textures/entity/earthspike_dirt" + ".png"); + } + else if (belowBlock == Blocks.SAND) { + TEXTURE = new ResourceLocation("avatarmod", "textures/entity/earthspike_sand" + ".png"); + } + else if (belowBlock == Blocks.SANDSTONE) { + TEXTURE = new ResourceLocation("avatarmod", "textures/entity/earthspike_sandstone" + ".png"); + } + else if (belowBlock == Blocks.STONE) { + TEXTURE = new ResourceLocation("avatarmod", "textures/entity/earthspike_stone" + ".png"); + } else { + TEXTURE = new ResourceLocation("avatarmod", "textures/entity/earthspike_stone" + ".png"); + } + + + Minecraft.getMinecraft().renderEngine.bindTexture(TEXTURE); GlStateManager.enableBlend(); GlStateManager.pushMatrix(); @@ -55,7 +79,7 @@ public void doRender(EntityEarthspike entity, double x, double y, double z, floa GlStateManager.rotate(180, 1, 0, 0); GlStateManager.rotate(entity.rotationPitch, 1, 0, 0); - GlStateManager.translate(0, -1.5, 0); + model.render(entity, 0, 0, 0, 0, 0, 0.0625f); GlStateManager.popMatrix(); @@ -64,6 +88,12 @@ public void doRender(EntityEarthspike entity, double x, double y, double z, floa } + @Override + protected void performGlTransforms(EntityEarthspike entity, double x, double y, double z, float entityYaw, float partialTicks) { + GlStateManager.pushMatrix(); + GlStateManager.scale(entity.getSize(), entity.getSize(), entity.getSize()); + GlStateManager.popMatrix(); + } @Override protected ResourceLocation getEntityTexture(EntityEarthspike entity) { diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderFireball.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderFireball.java index f482843b8d..aa667d952e 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderFireball.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderFireball.java @@ -16,13 +16,9 @@ */ package com.crowsofwar.avatar.client.render; -import com.crowsofwar.avatar.common.data.AbilityData; -import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.entity.EntityFireball; -import javafx.scene.effect.Glow; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.Render; @@ -32,8 +28,6 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.World; -import net.minecraft.world.WorldServer; -import net.minecraftforge.client.MinecraftForgeClient; import org.joml.Matrix4f; import org.joml.Vector4f; import org.lwjgl.opengl.GL11; @@ -76,7 +70,6 @@ public void doRender(EntityFireball entity, double xx, double yy, double zz, flo enableBlend(); - entity.getBrightnessForRender(); if (entity.ticksExisted % 3 == 0) { World world = entity.world; AxisAlignedBB boundingBox = entity.getEntityBoundingBox(); @@ -92,7 +85,7 @@ public void doRender(EntityFireball entity, double xx, double yy, double zz, flo renderCube(x, y, z, // 0, 8 / 256.0, 0, 8 / 256.0, // .5f, // - 0, ticks / 25f, 0); + ticks / 25F, ticks / 25f, ticks / 25F); int i = 15728880; int j = i % 65536; @@ -102,7 +95,6 @@ public void doRender(EntityFireball entity, double xx, double yy, double zz, flo // } else { pushMatrix(); - disableLighting(); renderCube(x, y, z, // 8 / 256.0, 16 / 256.0, 0 / 256.0, 8 / 256.0, // size, // @@ -110,6 +102,7 @@ public void doRender(EntityFireball entity, double xx, double yy, double zz, flo popMatrix(); // } + enableLighting(); disableBlend(); } diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderLightningSpear.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderLightningSpear.java index 1ae0a04315..6491c451fe 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderLightningSpear.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderLightningSpear.java @@ -17,6 +17,7 @@ package com.crowsofwar.avatar.client.render; import com.crowsofwar.avatar.common.entity.EntityLightningSpear; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; @@ -41,8 +42,13 @@ public RenderLightningSpear(RenderManager renderManager) { protected void performGlTransforms(EntityLightningSpear entity, double x, double y, double z, float entityYaw, float partialTicks) { // Should be rotating in degrees here...? // radians doesn't work + Minecraft.getMinecraft().renderEngine.bindTexture(TEXTURE); GlStateManager.rotate(-entity.rotationYaw, 0, 1, 0); GlStateManager.rotate(entity.rotationPitch, 1, 0, 0); + GlStateManager.scale(entity.getSize()/2, entity.getSize()/2, entity.getSize()/2); + GlStateManager.translate(0, entity.getSize() / 4, 0); + GlStateManager.rotate((float) (entity.ticksExisted / 20.0 * entity.getDegreesPerSecond()), 0, 0, 1); + } @Override diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderNothing.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderNothing.java index 7b2762fb20..205041142d 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderNothing.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderNothing.java @@ -18,6 +18,11 @@ public RenderNothing(RenderManager renderManager) { super(renderManager); } + @Override + public void doRender(Entity entity, double x, double y, double z, float entityYaw, float partialTicks) { + + } + @Nullable @Override protected ResourceLocation getEntityTexture(Entity entity) { diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderSkyBison.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderSkyBison.java index 8ca15457b6..387ef46e3d 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderSkyBison.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderSkyBison.java @@ -31,7 +31,7 @@ public class RenderSkyBison extends RenderLiving { "textures/mob/flyingbison.png"); /** - * @param rendermanager + * @param rm (RenderManager) */ public RenderSkyBison(RenderManager rm) { super(rm, new ModelFlyingBison(), 0); @@ -52,5 +52,4 @@ public void doRenderShadowAndFire(Entity entity, double x, double y, double z, f super.doRenderShadowAndFire(entity, x, y, z, yaw, partialTicks); } - } diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderWaterArc.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderWaterArc.java index 7955a57af2..55325eacd9 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderWaterArc.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderWaterArc.java @@ -28,8 +28,8 @@ public class RenderWaterArc extends RenderArc { - private static final ResourceLocation water = new ResourceLocation("avatarmod", - "textures/entity/water-ribbon.png"); + private static final ResourceLocation water = new ResourceLocation("minecraft", + "textures/blocks/water_overlay.png"); /** * @param renderManager diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderWaterCannon.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderWaterCannon.java index ea7828bad8..6a139c572e 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderWaterCannon.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderWaterCannon.java @@ -1,8 +1,8 @@ package com.crowsofwar.avatar.client.render; +import com.crowsofwar.avatar.common.entity.ControlPoint; +import com.crowsofwar.avatar.common.entity.EntityArc; import com.crowsofwar.avatar.common.entity.EntityWaterCannon; -import com.crowsofwar.avatar.common.particle.ClientParticleSpawner; -import com.crowsofwar.avatar.common.particle.ParticleSpawner; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderManager; @@ -11,15 +11,12 @@ import net.minecraft.util.ResourceLocation; public class RenderWaterCannon extends RenderArc { - private static final ResourceLocation TEXTURE = new ResourceLocation("avatarmod", - "textures/entity/water-ribbon.png"); + private static final ResourceLocation TEXTURE = new ResourceLocation("minecraft", + "textures/blocks/water_overlay.png"); - private final ParticleSpawner particleSpawner; public RenderWaterCannon(RenderManager renderManager) { super(renderManager, true); - enableFullBrightness(); - particleSpawner = new ClientParticleSpawner(); } @Override @@ -28,27 +25,28 @@ public void doRender(Entity entity, double xx, double yy, double zz, float p_769 EntityWaterCannon cannon = (EntityWaterCannon) entity; renderArc(cannon, partialTicks, 3f, 3f * cannon.getSizeMultiplier()); - /*Vector vector = cannon.velocity().normalize(); - //double yaw = Math.atan(vector.x()/(-vector.y())); - //double pitch = Math.atan(Math.sqrt(vector.x() * vector.x() + vector.y() * vector.y())/vector.z()); - for (int degree = 0; degree < 360; degree++) { - double radians = Math.toRadians(degree); - double x = Math.cos(radians); - double z = Math.sin(radians); - //double y = cannon.posY - cannon.getSizeMultiplier(); - /*if (y >= cannon.posY + cannon.getSizeMultiplier()) { - y -= 1; - } - else if (y<= cannon.posY - cannon.getSizeMultiplier()) { - y -= 1; - } - cannon.world.spawnParticle(EnumParticleTypes.WATER_SPLASH, x + cannon.getOwner().posX, cannon.getOwner().posY, - z + cannon.getOwner().posZ, 0, 0, 0); - - }**/ } + @Override + protected void renderArc(EntityArc arc, float partialTicks, float alpha, float scale) { + super.renderArc(arc, partialTicks, alpha, scale); + } + + @Override + protected void onDrawSegment(EntityArc arc, ControlPoint first, ControlPoint second) { + // Parametric equation + + Vector from = new Vector(0, 0, 0); + Vector to = second.position().minus(first.position()); + Vector diff = to.minus(from); + Vector offset = first.position(); + Vector direction = diff.normalize(); + Vector spawnAt = offset.plus(direction.times(Math.random())); + Vector velocity = first.velocity(); + arc.world.spawnParticle(EnumParticleTypes.WATER_SPLASH, spawnAt.x(), spawnAt.y(), spawnAt.z(), + velocity.x(), velocity.y(), velocity.z()); + } @Override protected ResourceLocation getTexture() { diff --git a/src/main/java/com/crowsofwar/avatar/client/render/RenderWave.java b/src/main/java/com/crowsofwar/avatar/client/render/RenderWave.java index f74fb45db5..2936d89537 100644 --- a/src/main/java/com/crowsofwar/avatar/client/render/RenderWave.java +++ b/src/main/java/com/crowsofwar/avatar/client/render/RenderWave.java @@ -20,7 +20,6 @@ import com.crowsofwar.avatar.common.bending.water.AbilityCreateWave; import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.entity.EntityWave; -import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; @@ -32,7 +31,6 @@ public class RenderWave extends RenderModel { private static final ResourceLocation TEXTURE = new ResourceLocation("avatarmod", "textures/entity/wave.png"); - private ModelBase model; /** * @param renderManager @@ -40,7 +38,6 @@ public class RenderWave extends RenderModel { public RenderWave(RenderManager renderManager) { super(renderManager, new ModelWave()); - this.model = new ModelWave(); } @Override diff --git a/src/main/java/com/crowsofwar/avatar/common/AvatarChatMessages.java b/src/main/java/com/crowsofwar/avatar/common/AvatarChatMessages.java index ba1ffd7a40..74a3a19c87 100644 --- a/src/main/java/com/crowsofwar/avatar/common/AvatarChatMessages.java +++ b/src/main/java/com/crowsofwar/avatar/common/AvatarChatMessages.java @@ -36,38 +36,30 @@ public class AvatarChatMessages { public static final FormattedMessage MSG_BENDING_LIST_NONBENDER = newChatMessage(CFG, "avatar.cmd.bending.list.nonbender", "player"); public static final FormattedMessage MSG_BENDING_LIST_ITEM = newChatMessage(CFG, "avatar.cmd.bending.list.item", "bending"); public static final FormattedMessage MSG_BENDING_LIST_TOP = newChatMessage(CFG, "avatar.cmd.bending.list.top", "player", "amount"); - + public static final FormattedMessage MSG_BENDING_ADD_ALREADY_HAS = newChatMessage(CFG, "avatar.cmd.bending.add.alreadyHas", "player", "bending"); public static final FormattedMessage MSG_BENDING_ADD_SUCCESS = newChatMessage(CFG, "avatar.cmd.bending.add.success", "player", "bending"); - + public static final FormattedMessage MSG_BENDING_REMOVE_DOESNT_HAVE = newChatMessage(CFG, "avatar.cmd.bending.remove.doesntHave", "player", "bending"); public static final FormattedMessage MSG_BENDING_REMOVE_SUCCESS = newChatMessage(CFG, "avatar.cmd.bending.remove.success", "player", "bending"); - - public static final FormattedMessage MSG_EARTHBENDING = newChatMessage(CFG, "avatar.earthbending"); - public static final FormattedMessage MSG_FIREBENDING = newChatMessage(CFG, "avatar.firebending"); - public static final FormattedMessage MSG_WATERBENDING = newChatMessage(CFG, "avatar.waterbending"); - + public static final FormattedMessage MSG_CONFIG_EXCEPTION_1 = newChatMessage(CFG, "avatar.cmd.cfg.exception1"); public static final FormattedMessage MSG_CONFIG_EXCEPTION_2 = newChatMessage(CFG, "avatar.cmd.cfg.exception2", "details"); public static final FormattedMessage MSG_CONFIG_SUCCESS = newChatMessage(CFG, "avatar.cmd.cfg.successful"); - + public static final FormattedMessage MSG_ABILITY_SET_RANGE = newChatMessage(CFG, "avatar.cmd.ability.set.range"); public static final FormattedMessage MSG_ABILITY_SET_SUCCESS = newChatMessage(CFG, "avatar.cmd.ability.set.success", "player", "ability", "amount"); - + public static final FormattedMessage MSG_ABILITY_GET = newChatMessage(CFG, "avatar.cmd.ability.get", "player", "ability", "amount"); - + public static final FormattedMessage MSG_XPSET_SUCCESS = newChatMessage(CFG, "avatar.cmd.xpset", "player", "ability", "spec"); - - public static final FormattedMessage MSG_PROGRESS_POINT_ADDED = newChatMessage(CFG, "avatar.cmd.pp.add", "player", "pps", "bending"); - public static final FormattedMessage MSG_PROGRESS_POINT_GET = newChatMessage(CFG, "avatar.cmd.pp.get", "player", "pps", "bending"); - public static final FormattedMessage MSG_PROGRESS_POINT_SET = newChatMessage(CFG, "avatar.cmd.pp.set", "player", "pps", "bending"); - public static final FormattedMessage MSG_PROGRESS_POINT_SET_RANGE = newChatMessage(CFG, "avatar.cmd.pp.set.range"); - + + public static final FormattedMessage MSG_DONT_HAVE_BENDING = newChatMessage(CFG, "avatar.donthavebending", "username"); - + public static final FormattedMessage MSG_BISON_WHISTLE_SUMMON = newChatMessage(CFG, "avatar.bisonWhistle.summon", "time"); public static final FormattedMessage MSG_BISON_WHISTLE_ASSIGN = newChatMessage(CFG, "avatar.bisonWhistle.assign", "bison"); public static final FormattedMessage MSG_BISON_WHISTLE_NOSUMMON = newChatMessage(CFG, "avatar.bisonWhistle.notAssigned"); @@ -75,6 +67,8 @@ public class AvatarChatMessages { public static final FormattedMessage MSG_BISON_WHISTLE_NOTOWNED = newChatMessage(CFG, "avatar.bisonWhistle.notOwned"); public static final FormattedMessage MSG_BISON_WHISTLE_UNTAMED = newChatMessage(CFG, "avatar.bisonWhistle.untamed"); public static final FormattedMessage MSG_BISON_WHISTLE_NEARBY = newChatMessage(CFG, "avatar.bisonWhistle.nearby"); + public static final FormattedMessage MSG_BISON_NO_FOOD = newChatMessage(CFG, "avatar.bisonNoFood"); + public static final FormattedMessage MSG_BISON_SITTING = newChatMessage(CFG, "avatar.bisonSitting"); public static final FormattedMessage MSG_BISON_WHISTLE_FOLLOW_ON = newChatMessage(CFG, "avatar.bisonWhistle.followOn"); public static final FormattedMessage MSG_BISON_WHISTLE_FOLLOW_OFF = newChatMessage(CFG, "avatar.bisonWhistle.followOff"); @@ -88,9 +82,26 @@ public class AvatarChatMessages { public static final FormattedMessage MSG_BISON_TRANSFER_OLD_IGNORE = newChatMessage(CFG, "avatar.bisonWhistle.transferAway.ignore", "newOwner"); public static final FormattedMessage MSG_BISON_TRANSFER_NEW_IGNORE = newChatMessage(CFG, "avatar.bisonWhistle.transferTo.ignore", "oldOwner"); public static final FormattedMessage MSG_BISON_TRANSFER_OFFLINE = newChatMessage(CFG, "avatar.bisonWhistle.transferOffline", "owner"); - + public static final FormattedMessage MSG_HUMANBENDER_NO_SCROLLS = newChatMessage(CFG, "avatar.outOfScrolls"); + public static final FormattedMessage MSG_NEED_TRADE_ITEM = newChatMessage(CFG, "avatar.needTradeItem"); + + public static final FormattedMessage MSG_NEED_AIR_TRADE_ITEM = newChatMessage(CFG, "avatar.needAirTradeItem"); + + public static final FormattedMessage MSG_NEED_FIRE_TRADE_ITEM = newChatMessage(CFG, "avatar.needFireTradeItem"); + + public static final FormattedMessage MSG_AIR_STAFF_COOLDOWN = newChatMessage(CFG, "avatar.staffCooldown"); + + public static final FormattedMessage MSG_SLIPSTREAM_COOLDOWN = newChatMessage(CFG, "avatar.slipstreamCooldown"); + + public static final FormattedMessage MSG_CLEANSE_COOLDOWN = newChatMessage(CFG, "avatar.cleanseCooldown"); + + public static final FormattedMessage MSG_PURIFY_COOLDOWN = newChatMessage(CFG, "avatar.purifyCooldown"); + + public static final FormattedMessage MSG_RESTORE_COOLDOWN = newChatMessage(CFG, "avatar.restoreCooldown"); + + public static final FormattedMessage MSG_SKATING_BENDING_DISABLED = newChatMessage(CFG, "avatar.skatingBendingDisabled"); @@ -116,6 +127,7 @@ public class AvatarChatMessages { /** * Call the static initializers */ - public static void loadAll() {} - + public static void loadAll() { + } + } diff --git a/src/main/java/com/crowsofwar/avatar/common/AvatarDamageSource.java b/src/main/java/com/crowsofwar/avatar/common/AvatarDamageSource.java index 4f0d729f48..34f783a0a0 100644 --- a/src/main/java/com/crowsofwar/avatar/common/AvatarDamageSource.java +++ b/src/main/java/com/crowsofwar/avatar/common/AvatarDamageSource.java @@ -31,6 +31,15 @@ */ public class AvatarDamageSource { + public static final DamageSource WATER = new DamageSource("avatar_Water"); + public static final DamageSource FIRE = new DamageSource("avatar_Fire"); + public static final DamageSource EARTH = new DamageSource("avatar_Earth"); + public static final DamageSource AIR = new DamageSource("avatar_Air"); + public static final DamageSource LIGHTNING = new DamageSource("avatar_Lightning"); + public static final DamageSource COMBUSTION = new DamageSource("avatar_Combustion"); + public static final DamageSource SAND = new DamageSource("avatar_Sand"); + public static final DamageSource ICE = new DamageSource("avatar_Ice"); + /** * Returns whether the given damage was inflicted using an Avatar damage source. */ @@ -58,7 +67,7 @@ public static DamageSource causeFloatingBlockDamage(Entity hit, @Nullable Entity */ public static DamageSource causeAirDamage(Entity hit, @Nullable Entity owner) { - return new EntityDamageSourceIndirect("avatar_Air", hit, owner); + return new EntityDamageSourceIndirect("avatar_AirDamage", hit, owner); } /** @@ -80,8 +89,7 @@ public static DamageSource causeWaterDamage(Entity hit, @Nullable Entity owner) * @return DamageSource for the fire arc */ public static DamageSource causeFireDamage(Entity hit, @Nullable Entity owner) { - return new EntityDamageSourceIndirect("avatar_fireArc", hit, owner).setProjectile() - .setFireDamage(); + return new EntityDamageSourceIndirect("avatar_fireArc", hit, owner).setProjectile(); } /** @@ -112,7 +120,7 @@ public static DamageSource causeWaveDamage(Entity hit, @Nullable Entity owner) { */ public static DamageSource causeFireballDamage(Entity hit, @Nullable Entity owner) { return new EntityDamageSourceIndirect("avatar_fireball", hit, owner).setProjectile() - .setFireDamage().setExplosion(); + .setExplosion(); } /** @@ -142,8 +150,7 @@ public static DamageSource causeAirbladeDamage(Entity hit, @Nullable Entity owne * @param owner Who created the flames */ public static DamageSource causeFlamethrowerDamage(Entity hit, @Nullable Entity owner) { - return new EntityDamageSourceIndirect("avatar_flamethrower", hit, owner).setProjectile() - .setFireDamage(); + return new EntityDamageSourceIndirect("avatar_flamethrower", hit, owner).setProjectile(); } /** @@ -185,17 +192,7 @@ public static DamageSource causeRedirectedLightningDamage(Entity hit, @Nullable * @param owner Who created the water cannon */ public static DamageSource causeWaterCannonDamage(Entity hit, @Nullable Entity owner) { - return new EntityDamageSourceIndirect("avatar_watercannon", hit, owner); - } - - /** - * Create a DamageSource for damage caused by a cloudburst. - * - * @param hit Who was hit by the cloudburst - * @param owner Who created the cloudburst - */ - public static DamageSource causeCloudburstDamage(Entity hit, @Nullable Entity owner) { - return new EntityDamageSourceIndirect("avatar_cloudburst", hit, owner).setProjectile(); + return new EntityDamageSourceIndirect("avatar_waterCannon", hit, owner); } /** @@ -238,4 +235,8 @@ public static DamageSource causeSandstormDamage(Entity hit, @Nullable Entity own return new EntityDamageSourceIndirect("avatar_sandstorm", hit, owner); } + public static DamageSource causeShockwaveDamage(Entity hit, @Nullable Entity owner) { + return new EntityDamageSourceIndirect("avatar_shockWave", hit, owner).setExplosion(); + } + } diff --git a/src/main/java/com/crowsofwar/avatar/common/AvatarParticles.java b/src/main/java/com/crowsofwar/avatar/common/AvatarParticles.java index 148d718046..f93fe3f7a0 100644 --- a/src/main/java/com/crowsofwar/avatar/common/AvatarParticles.java +++ b/src/main/java/com/crowsofwar/avatar/common/AvatarParticles.java @@ -32,13 +32,16 @@ */ public class AvatarParticles { - private static EnumParticleTypes particleFlames, particleAir; + private static EnumParticleTypes particleFlames, particleAir, particleRestore, particleElectricity; private static Map lookup; public static void register() { lookup = new HashMap<>(); particleFlames = addParticle("flames"); particleAir = addParticle("air"); + particleRestore = addParticle("restore"); + particleElectricity = addParticle("electricity"); + } private static EnumParticleTypes addParticle(String particleName) { @@ -74,6 +77,14 @@ public static EnumParticleTypes getParticleAir() { return CLIENT_CONFIG.useCustomParticles ? particleAir : EnumParticleTypes.CLOUD; } + public static EnumParticleTypes getParticleRestore() { + return CLIENT_CONFIG.useCustomParticles ? particleRestore : EnumParticleTypes.VILLAGER_HAPPY; + } + + public static EnumParticleTypes getParticleElectricity() { + return CLIENT_CONFIG.useCustomParticles ? particleElectricity : EnumParticleTypes.ENCHANTMENT_TABLE; + } + /** * Looks up that particle. Returns null if none found. */ diff --git a/src/main/java/com/crowsofwar/avatar/common/HumanBenderSpawner.java b/src/main/java/com/crowsofwar/avatar/common/HumanBenderSpawner.java index 3ae069c4e0..72c51c9d2d 100644 --- a/src/main/java/com/crowsofwar/avatar/common/HumanBenderSpawner.java +++ b/src/main/java/com/crowsofwar/avatar/common/HumanBenderSpawner.java @@ -20,12 +20,15 @@ import com.crowsofwar.avatar.common.entity.mob.EntityAirbender; import com.crowsofwar.avatar.common.entity.mob.EntityFirebender; import com.crowsofwar.avatar.common.entity.mob.EntityHumanBender; +import net.minecraft.entity.Entity; +import net.minecraft.entity.monster.EntityZombieVillager; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.ChunkPos; import net.minecraft.village.Village; import net.minecraft.world.World; import net.minecraft.world.gen.structure.MapGenVillage; +import net.minecraftforge.event.entity.living.LivingSpawnEvent; import net.minecraftforge.event.terraingen.InitMapGenEvent; import net.minecraftforge.event.terraingen.InitMapGenEvent.EventType; import net.minecraftforge.fml.common.Mod; @@ -35,20 +38,49 @@ import java.util.Map; import java.util.Random; +import static com.crowsofwar.avatar.common.config.ConfigMobs.MOBS_CONFIG; + /** * @author CrowsOfWar */ @Mod.EventBusSubscriber(modid = AvatarInfo.MOD_ID) public class HumanBenderSpawner { - @SubscribeEvent +/* @SubscribeEvent public static void modifyVillageSpawner(InitMapGenEvent e) { if (e.getType() == EventType.VILLAGE) { // TODO See if this messes up superflat world options e.setNewGen(new MapGenVillageWithHumanbenders()); + + } + }**/ + + @SubscribeEvent + public static void modifyVillagerSpawns(LivingSpawnEvent event) { + Entity e = event.getEntity(); + World world = e.getEntityWorld(); + if (event.getEntity() == e && e instanceof EntityVillager) { + + AxisAlignedBB box = new AxisAlignedBB(e.posX + 200, + e.posY + 200, e.posZ + 200, + e.posX - 200, e.posY - 200, + e.posZ - 200); + List nearbyBenders = world.getEntitiesWithinAABB(EntityHumanBender.class, box); + List nearbyVillagers = world.getEntitiesWithinAABB(EntityVillager.class, box); + int villagerSize = nearbyVillagers.size(); + int size = nearbyBenders.size(); + Random rand = new Random(); + boolean bender = rand.nextBoolean(); + //Will be changed when more benders are added + if (size < MOBS_CONFIG.maxNumberOfBenders && villagerSize >= 5) { + EntityHumanBender b = bender ? new EntityAirbender(world) : new EntityFirebender(world); + b.copyLocationAndAnglesFrom(e); + world.spawnEntity(b); + } + } } private static class MapGenVillageWithHumanbenders extends MapGenVillage { @@ -66,25 +98,43 @@ public synchronized boolean generateStructure(World worldIn, Random randomIn, Ch boolean result = super.generateStructure(worldIn, randomIn, chunkCoord); if (result) { + // This list contains villagers in that structure List villagers = worldIn.getEntities(EntityVillager.class, villager -> { + assert villager != null; return new ChunkPos(villager.getPosition()).equals(chunkCoord); }); + // To attempt to have all humanbenders be same type, check if // there are nearby humanbenders // If there are just copy their type - AxisAlignedBB aabb = new AxisAlignedBB(chunkCoord.getBlock(-30, 50, -30), - chunkCoord.getBlock(30, 150, 30)); + AxisAlignedBB aabb = new AxisAlignedBB(villagers.get(0).posX + 100, villagers.get(0).posY + 100, villagers.get(0).posZ + 100, + villagers.get(0).posX - 100, villagers.get(0).posY - 100, villagers.get(0).posZ - 100); List nearbyBenders = worldIn.getEntitiesWithinAABB(EntityHumanBender.class, aabb); + Village village = worldIn.getVillageCollection() + .getNearestVillage(chunkCoord.getBlock(0, 0, 0), 200); + + if (village != null) { + EntityHumanBender airbender = new EntityAirbender(worldIn); + airbender.setPosition(village.getCenter().getX(), village.getCenter().getY(), village.getCenter().getZ()); + } + + + for (Entity e : villagers) { + int i = rand.nextInt(3) + 1; + if (i == 3) { + EntityHumanBender b = new EntityAirbender(worldIn); + b.setPosition(villagers.get(0).posX, villagers.get(0).posY, villagers.get(0).posZ); + } + } + double chance = 100; Random rand = new Random(); - if (!villagers.isEmpty() && rand.nextDouble() * 100 < chance) { + if (!villagers.isEmpty()/* && rand.nextDouble() * 100 < chance**/) { - Village village = worldIn.getVillageCollection() - .getNearestVillage(chunkCoord.getBlock(0, 0, 0), 200); boolean firebender; @@ -94,15 +144,20 @@ public synchronized boolean generateStructure(World worldIn, Random randomIn, Ch firebender = nearbyBenders.get(0) instanceof EntityFirebender; } - EntityHumanBender bender = firebender ? new EntityFirebender(worldIn) - : new EntityAirbender(worldIn); - bender.copyLocationAndAnglesFrom(villagers.get(0)); - worldIn.spawnEntity(bender); + for (Entity e : villagers) { + int i = rand.nextInt(3) + 1; + if (i == 3) { + EntityHumanBender bender = firebender ? new EntityFirebender(worldIn) + : new EntityAirbender(worldIn); + bender.copyLocationAndAnglesFrom(e); + worldIn.spawnEntity(bender); + } + } } - } - return result; + + return false; } } diff --git a/src/main/java/com/crowsofwar/avatar/common/analytics/AvatarAnalytics.java b/src/main/java/com/crowsofwar/avatar/common/analytics/AvatarAnalytics.java index 4b2a4314b5..9135c69a76 100644 --- a/src/main/java/com/crowsofwar/avatar/common/analytics/AvatarAnalytics.java +++ b/src/main/java/com/crowsofwar/avatar/common/analytics/AvatarAnalytics.java @@ -31,7 +31,10 @@ public void init() { // Send initial analytics to server boolean isServer = AvatarMod.proxy instanceof AvatarServerProxy; - String language = isServer ? "server" : FMLCommonHandler.instance().getCurrentLanguage(); + String language = "server"; + if (FMLCommonHandler.instance().getCurrentLanguage() != null) { + language = isServer ? "server" : FMLCommonHandler.instance().getCurrentLanguage(); + } int mods = Loader.instance().getModList().size() - 5; String params = AnalyticsUtils.getBasicParameters(); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/BattlePerformanceScore.java b/src/main/java/com/crowsofwar/avatar/common/bending/BattlePerformanceScore.java index fff0bbe6ad..2bbe9fba79 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/BattlePerformanceScore.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/BattlePerformanceScore.java @@ -37,6 +37,13 @@ public BattlePerformanceScore(BendingData data, double score) { this.score = score; } + public static void addScore(EntityLivingBase entity, int amount) { + BendingData bendingData = BendingData.get(entity); + if (bendingData != null) { + bendingData.getPerformance().modifyScore(amount); + } + } + public static void addSmallScore(EntityLivingBase entity) { BendingData bendingData = BendingData.get(entity); if (bendingData != null) { @@ -92,7 +99,7 @@ public void update() { * Add or subtract a certain amount of score from the bender. */ public void modifyScore(double amount) { - setScore(MathHelper.clamp(score + amount, -100, 100)); + setScore(MathHelper.clamp(score + amount, -500, 500)); } /** diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/BendingStyle.java b/src/main/java/com/crowsofwar/avatar/common/bending/BendingStyle.java index 97cd6aeb8e..c6b3c6deeb 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/BendingStyle.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/BendingStyle.java @@ -84,6 +84,14 @@ public void write(NBTTagCompound nbt, BendingStyle object, Object[] methodsExtra @Nullable private UUID parentBendingId; + + //This is so player-specific custom elements can't be used by other players when using commands. + //This also means if you aren't the right player, you can't obtain it. + //Ex: Eternal Dragonbending is usable by me (FavouriteDragon) only + public boolean canEntityUse() { + return true; + } + /** * Constructor used for main bending styles (i.e. non-specialty), like firebending */ diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/BuffPowerModifier.java b/src/main/java/com/crowsofwar/avatar/common/bending/BuffPowerModifier.java index a5152f4523..01b59c387c 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/BuffPowerModifier.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/BuffPowerModifier.java @@ -29,27 +29,48 @@ public abstract class BuffPowerModifier extends PowerRatingModifier { protected abstract String getAbilityName(); + /*private boolean useSlipstreamShaders = CLIENT_CONFIG.shaderSettings.useSlipstreamShaders; + + private boolean useCleanseShaders = CLIENT_CONFIG.shaderSettings.useCleanseShaders; + + private boolean useRestoreShaders = CLIENT_CONFIG.shaderSettings.useRestoreShaders; + + private boolean usePurifyShaders = CLIENT_CONFIG.shaderSettings.usePurifyShaders;**/ + private Vision getVision(BendingContext ctx) { AbilityData abilityData = ctx.getData().getAbilityData(getAbilityName()); + switch (abilityData.getLevel()) { case -1: case 0: case 1: - return getVisions()[0]; + if (getVisions()[0] != null) { + return getVisions()[0]; + } case 2: - return getVisions()[1]; + if (getVisions()[1] != null) { + return getVisions()[1]; + } case 3: default: - return getVisions()[2]; + if (getVisions()[2] != null) { + return getVisions()[2]; + } + else return getVisions()[0]; } + } + @Override public boolean onUpdate(BendingContext ctx) { if (ctx.getData().getVision() == null) { - ctx.getData().setVision(getVision(ctx)); + if (getVision(ctx) != null && getVisions()[0] != null && getVisions()[1] != null && getVisions()[2] != null) { + ctx.getData().setVision(getVision(ctx)); + } + } return super.onUpdate(ctx); } @@ -58,10 +79,12 @@ public boolean onUpdate(BendingContext ctx) { public void onRemoval(BendingContext ctx) { Vision[] visions = getVisions(); Vision vision = ctx.getData().getVision(); - if (vision == visions[0] || vision == visions[1] || vision == visions[2]) { - ctx.getData().setVision(null); + if (vision != null && visions != null) { + if (vision == visions[0] || vision == visions[1] || vision == visions[2]) { + ctx.getData().setVision(null); + } + super.onRemoval(ctx); } - super.onRemoval(ctx); } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirBubble.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirBubble.java index 45e0ae7931..acfd27f0e2 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirBubble.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirBubble.java @@ -23,7 +23,6 @@ import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import com.crowsofwar.avatar.common.entity.EntityAirBubble; -import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Items; @@ -62,17 +61,19 @@ public void execute(AbilityContext ctx) { if (!bender.consumeChi(STATS_CONFIG.chiAirBubble)) return; - float size = 1.5f; - float health = 12; - if (ctx.getLevel() > 0) { - size = 2.5f; - health = 18; + float powerRating = (float) bender.calcPowerRating(Airbending.ID)/100; + + float size = 1.5f + powerRating; + float health = 12 + powerRating; + if (ctx.getLevel() > 1) { + size = 2.5f + powerRating; + health = 18 + powerRating; } if (ctx.isMasterLevel(FIRST)) { - size = 4f; - health = 24; + size = 4f + powerRating; + health = 24 + powerRating; } - if (ctx.isMasterLevel(SECOND)) health = 10f; + if (ctx.isMasterLevel(SECOND)) health = 10f + powerRating; EntityAirBubble bubble = new EntityAirBubble(world); bubble.setOwner(entity); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirBurst.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirBurst.java index 46796af302..4628444ba9 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirBurst.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirBurst.java @@ -4,14 +4,11 @@ import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.world.World; - -import java.util.UUID; +import static com.crowsofwar.avatar.common.data.TickHandlerController.AIRBURST_CHARGE_HANDLER; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; public class AbilityAirBurst extends Ability { @@ -28,7 +25,7 @@ public void execute(AbilityContext ctx) { float chi = 6; //6 - boolean hasAirCharge = data.hasTickHandler(TickHandler.AIRBURST_CHARGE_HANDLER); + boolean hasAirCharge = data.hasTickHandler(AIRBURST_CHARGE_HANDLER); if (ctx.getLevel() == 1) { chi = 7; @@ -39,20 +36,20 @@ public void execute(AbilityContext ctx) { //7 } if (ctx.isMasterLevel(AbilityData.AbilityTreePath.FIRST)) { - chi = STATS_CONFIG.chiWaterCannon * 1.6F; + chi = STATS_CONFIG.chiAirBurst * 1.6F; //11 } if (ctx.isMasterLevel(AbilityData.AbilityTreePath.SECOND)) { - chi = STATS_CONFIG.chiWaterCannon * 1.4F; + chi = STATS_CONFIG.chiAirBurst * 1.4F; //11 } if (bender.consumeChi(chi) && !hasAirCharge) { - data.addTickHandler(TickHandler.AIRBURST_CHARGE_HANDLER); + data.addTickHandler(AIRBURST_CHARGE_HANDLER); } else if (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative()) { if (!hasAirCharge) { - data.addTickHandler(TickHandler.AIRBURST_CHARGE_HANDLER); + data.addTickHandler(AIRBURST_CHARGE_HANDLER); } } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirGust.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirGust.java index dd5b7b5b6a..74cf24422c 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirGust.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirGust.java @@ -19,15 +19,12 @@ import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.BendingAi; -import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import com.crowsofwar.avatar.common.entity.EntityAirGust; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.world.World; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; @@ -59,7 +56,7 @@ public void execute(AbilityContext ctx) { EntityAirGust gust = new EntityAirGust(world); gust.setVelocity(look.times(25)); - gust.setPosition(pos.x(), pos.y(), pos.z()); + gust.setPosition(Vector.getLookRectangular(entity).plus(Vector.getEntityPos(entity).withY(entity.getEyeHeight() + entity.getEntityBoundingBox().minY))); gust.setOwner(entity); gust.setDestroyProjectiles(ctx.isMasterLevel(FIRST)); gust.setAirGrab(ctx.isMasterLevel(SECOND)); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirJump.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirJump.java index fd2c2992d3..a8a0fade60 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirJump.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirJump.java @@ -18,20 +18,14 @@ package com.crowsofwar.avatar.common.bending.air; import com.crowsofwar.avatar.common.bending.Ability; -import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import com.crowsofwar.avatar.common.data.ctx.BendingContext; import com.crowsofwar.avatar.common.util.Raytrace; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; - -import javax.swing.text.html.parser.Entity; import static com.crowsofwar.avatar.common.bending.StatusControl.AIR_JUMP; +import static com.crowsofwar.avatar.common.data.TickHandlerController.AIR_PARTICLE_SPAWNER; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; /** @@ -55,9 +49,8 @@ public void execute(AbilityContext ctx) { Bender bender = ctx.getBender(); if (!data.hasStatusControl(AIR_JUMP) && bender.consumeChi(STATS_CONFIG.chiAirJump)) { - data.addStatusControl(AIR_JUMP); - if (data.hasTickHandler(TickHandler.AIR_PARTICLE_SPAWNER)) { + if (data.hasTickHandler(AIR_PARTICLE_SPAWNER)) { Raytrace.Result raytrace = Raytrace.getTargetBlock(ctx.getBenderEntity(), -1); if (AIR_JUMP.execute( new BendingContext(data, ctx.getBenderEntity(), ctx.getBender(), raytrace))) { diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirblade.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirblade.java index 35f83e5510..cc606a8598 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirblade.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityAirblade.java @@ -20,13 +20,11 @@ import com.crowsofwar.avatar.common.bending.BendingAi; import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; -import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import com.crowsofwar.avatar.common.entity.EntityAirblade; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; @@ -49,22 +47,20 @@ public void execute(AbilityContext ctx) { EntityLivingBase entity = ctx.getBenderEntity(); Bender bender = ctx.getBender(); World world = ctx.getWorld(); - BendingData data = ctx.getData(); if (!bender.consumeChi(STATS_CONFIG.chiAirblade)) return; - double pitchDeg = entity.rotationPitch; + /*double pitchDeg = entity.rotationPitch; if (abs(pitchDeg) > 30) { pitchDeg = pitchDeg / abs(pitchDeg) * 30; } - float pitch = (float) Math.toRadians(pitchDeg); + float pitch = (float) Math.toRadians(pitchDeg);**/ - Vector look = Vector.toRectangular(Math.toRadians(entity.rotationYaw), pitch); - Vector spawnAt = Vector.getEntityPos(entity).plus(look.times(2)).plus(0, 1, 0); + Vector look = Vector.getLookRectangular(entity); + Vector spawnAt = Vector.getEyePos(entity).plus(look).minusY(0.2); AbilityData abilityData = ctx.getData().getAbilityData(this); float xp = abilityData.getTotalXp(); - float damage = STATS_CONFIG.airbladeSettings.damage; damage *= 1 + xp * .015f; damage *= ctx.getPowerRatingDamageMod(); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityCloudBurst.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityCloudBurst.java index 83d000f922..8b623d3152 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityCloudBurst.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilityCloudBurst.java @@ -12,8 +12,6 @@ import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.world.World; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; @@ -37,7 +35,7 @@ public void execute(AbilityContext ctx) { if (data.hasStatusControl(StatusControl.THROW_CLOUDBURST)) return; - float chi = STATS_CONFIG.chiCloudburst; + float chi = STATS_CONFIG.chiCloudburst; //2.5F if (ctx.getLevel() == 1) { @@ -67,36 +65,36 @@ public void execute(AbilityContext ctx) { } double damage = STATS_CONFIG.cloudburstSettings.damage; - //1.5 + //2 EntityCloudBall cloudball = new EntityCloudBall(world); - if (ctx.isMasterLevel(AbilityData.AbilityTreePath.SECOND)) { + if (ctx.isMasterLevel(AbilityData.AbilityTreePath.FIRST)) { cloudball.setSize(20); damage = STATS_CONFIG.cloudburstSettings.damage * 4; - //6 + //8 cloudball.canchiSmash(true); } - if (ctx.isMasterLevel(AbilityData.AbilityTreePath.FIRST)) { + if (ctx.isMasterLevel(AbilityData.AbilityTreePath.SECOND)) { damage = STATS_CONFIG.cloudburstSettings.damage * 2; - //3 + //4 cloudball.canAbsorb(true); } if (ctx.getLevel() == 1) { damage = STATS_CONFIG.cloudburstSettings.damage * 1.5; - //2.25 + //3 } if (ctx.getLevel() == 2) { damage = STATS_CONFIG.cloudburstSettings.damage * 2.25; - //3.375 + //4.5 } damage *= ctx.getPowerRatingDamageMod(); + damage += ctx.getAbilityData().getTotalXp() / 800; cloudball.setPosition(target); cloudball.setOwner(entity); - cloudball.setStartingPosition(entity.getPosition()); cloudball.setBehavior(new CloudburstBehavior.PlayerControlled()); cloudball.setDamage((float) damage); cloudball.setAbility(this); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilitySlipstream.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilitySlipstream.java index feb1ebeaa6..8390f418af 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilitySlipstream.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AbilitySlipstream.java @@ -7,10 +7,13 @@ import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.MobEffects; import net.minecraft.potion.PotionEffect; +import java.util.Objects; + +import static com.crowsofwar.avatar.common.AvatarChatMessages.MSG_SLIPSTREAM_COOLDOWN; +import static com.crowsofwar.avatar.common.data.TickHandlerController.SLIPSTREAM_COOLDOWN_HANDLER; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; @@ -42,11 +45,15 @@ public void execute(AbilityContext ctx) { chi = STATS_CONFIG.chiBuffLvl4; } - if (bender.consumeChi(chi)) { + if (data.hasTickHandler(SLIPSTREAM_COOLDOWN_HANDLER) && entity instanceof EntityPlayer) { + MSG_SLIPSTREAM_COOLDOWN.send(entity); + } + + if (bender.consumeChi(chi) && !data.hasTickHandler(SLIPSTREAM_COOLDOWN_HANDLER)) { float xp = SKILLS_CONFIG.buffUsed; // 4s base + 1s per level - int duration = 80 + 20 * abilityData.getLevel(); + int duration = abilityData.getLevel() > 0 ? 80 + 20 * abilityData.getLevel() : 80; int effectLevel = abilityData.getLevel() >= 2 ? 1 : 0; if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { @@ -66,35 +73,14 @@ public void execute(AbilityContext ctx) { SlipstreamPowerModifier modifier = new SlipstreamPowerModifier(); modifier.setTicks(duration); - data.getPowerRatingManager(getBendingId()).addModifier(modifier, ctx); + Objects.requireNonNull(data.getPowerRatingManager(getBendingId())).addModifier(modifier, ctx); + data.addTickHandler(SLIPSTREAM_COOLDOWN_HANDLER); } - } - - @Override - public int getCooldown(AbilityContext ctx) { - EntityLivingBase entity = ctx.getBenderEntity(); - int coolDown = 160; - - if (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative()) { - coolDown = 0; - } - if (ctx.getLevel() == 1) { - coolDown = 140; - } - if (ctx.getLevel() == 2) { - coolDown = 120; - } - if (ctx.isMasterLevel(AbilityData.AbilityTreePath.FIRST)) { - coolDown = 100; - } - if (ctx.isMasterLevel(AbilityData.AbilityTreePath.SECOND)) { - coolDown = 100; - } - return coolDown; } + } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AiAirBubble.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AiAirBubble.java index 7a8fd13e1a..1c133d01bf 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AiAirBubble.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AiAirBubble.java @@ -18,6 +18,7 @@ import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.BendingAi; +import com.crowsofwar.avatar.common.bending.StatusControl; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.entity.AvatarEntity; import com.crowsofwar.avatar.common.entity.EntityAirBubble; @@ -50,14 +51,25 @@ protected void startExec() { @Override protected boolean shouldExec() { - boolean underAttack = entity.getCombatTracker().getCombatDuration() <= 100 || true; + boolean underAttack = entity.getCombatTracker().getCombatDuration() <= 100; boolean already = AvatarEntity.lookupEntity(entity.world, EntityAirBubble.class, bubble -> bubble.getOwner() == entity) != null; - boolean lowHealth = entity.getHealth() / entity.getMaxHealth() <= 0.25f || entity.getHealth() < 10; + boolean lowHealth = entity.getHealth() / entity.getMaxHealth() <= 0.25f; - // 2% chance to get air bubble every tick - return !already && underAttack && lowHealth && random.nextDouble() <= 0.02; + if (timeExecuting > 200) { + execStatusControl(StatusControl.BUBBLE_EXPAND); + return false; + + } + // 50% chance to get air bubble every tick + return !already && (underAttack && lowHealth && random.nextDouble() < 0.5); } + @Override + public void updateTask() { + timeExecuting++; + } + + } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AiAirGust.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AiAirGust.java index 9344b996e7..3299aae1ac 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AiAirGust.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AiAirGust.java @@ -48,15 +48,12 @@ protected void startExec() { EntityLivingBase target = entity.getAttackTarget(); BendingData data = bender.getData(); - if (target != null && target.getHealth() >= 10) { + if (target != null) { Vector rotations = getRotationTo(getEntityPos(entity), getEntityPos(target)); entity.rotationYaw = (float) toDegrees(rotations.y()); entity.rotationPitch = (float) toDegrees(rotations.x()); - data.chi().setMaxChi(10); - data.chi().setTotalChi(10); - data.chi().setAvailableChi(10); execAbility(); data.getMiscData().setAbilityCooldown(20); @@ -67,7 +64,7 @@ protected void startExec() { @Override protected boolean shouldExec() { return entity.getAttackTarget() != null - && entity.getDistanceSq(entity.getAttackTarget()) < 4 * 4; + && entity.getDistanceSq(entity.getAttackTarget()) < 6 * 6; } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AirBurstHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AirBurstHandler.java index 05470efb37..90a60b7776 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AirBurstHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AirBurstHandler.java @@ -1,7 +1,5 @@ package com.crowsofwar.avatar.common.bending.air; -import com.crowsofwar.avatar.common.AvatarDamageSource; -import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; @@ -32,14 +30,57 @@ import java.util.List; import java.util.UUID; -import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; public class AirBurstHandler extends TickHandler { - private static final UUID MOVEMENT_MODIFIER_ID = UUID.fromString ("f82d325c-9828-11e8-9eb6-529269fb1459"); + public AirBurstHandler(int id) { + super(id); + } + + @SubscribeEvent + public static void onDragonHurt(LivingHurtEvent event) { + if (event.getSource().getTrueSource() instanceof EntityLivingBase) { + EntityLivingBase attacker = (EntityLivingBase) event.getSource().getTrueSource(); + Entity target = event.getEntity(); + DamageSource source = event.getSource(); + if (source.getDamageType().equals("avatar_Air")) { + if (attacker instanceof EntityPlayer || attacker instanceof EntityBender) { + Bender ctx = Bender.get(attacker); + if (ctx != null) { + if (ctx.getData() != null) { + AbilityData aD = AbilityData.get(attacker, "air_burst"); + float powerRating = (float) (ctx.calcPowerRating(Airbending.ID) / 100); + float damage = 0.5F + powerRating; + if (aD.getLevel() == 1) { + damage = 0.75F + powerRating; + } + + if (aD.getLevel() >= 2) { + damage = 1 + powerRating; + } + + if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + //Piercing Winds + damage = 5 + powerRating; + } + + if (aD.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + //Maximum Pressure + //Pulls enemies in then blasts them out + damage = 2.5f + powerRating; + } + event.setAmount(damage); + + + } + } + } + } + } + } @Override public boolean tick(BendingContext ctx) { @@ -57,7 +98,7 @@ public boolean tick(BendingContext ctx) { float powerRating = (float) (bender.calcPowerRating(Airbending.ID) / 100); int duration = data.getTickHandlerDuration(this); double damage = STATS_CONFIG.airBurstSettings.damage + powerRating; - //0.5 + //1 float movementMultiplier = 0.6f - 0.7f * MathHelper.sqrt(duration / 40F); double knockBack = STATS_CONFIG.AirBurstSettings.knockback + powerRating; //Default 2 + Power rating @@ -66,119 +107,103 @@ public boolean tick(BendingContext ctx) { float durationToFire = STATS_CONFIG.AirBurstSettings.durationToFire - (powerRating * 10); //Default 40 double upwardKnockback = STATS_CONFIG.airBurstSettings.push / 7; - float knockbackDivider = 1.2F; + double suction = 0.05; + int performanceAmount = STATS_CONFIG.AirBurstSettings.performanceAmount; if (abilityData.getLevel() == 1) { - damage = (STATS_CONFIG.airBurstSettings.damage * (3F / 2)) + powerRating; - //0.75 + damage = (STATS_CONFIG.airBurstSettings.damage * 1.5) + powerRating; + //1.5 knockBack = 3 + powerRating; radius = (STATS_CONFIG.AirBurstSettings.radius * 4 / 3) + powerRating; //4 durationToFire = STATS_CONFIG.AirBurstSettings.durationToFire * 0.75F; //30 upwardKnockback = STATS_CONFIG.airBurstSettings.push / 5; - knockbackDivider = 1.5F; + performanceAmount += 3; } if (abilityData.getLevel() >= 2) { damage = (STATS_CONFIG.airBurstSettings.damage * 2) + powerRating; - //1 + //2 knockBack = 5 + powerRating; radius = (STATS_CONFIG.AirBurstSettings.radius * 5 / 3) + powerRating; //5 durationToFire = STATS_CONFIG.AirBurstSettings.durationToFire * 0.5F; //20 upwardKnockback = STATS_CONFIG.airBurstSettings.push / 3; - knockbackDivider = 2; + performanceAmount += 5; } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { //Piercing Winds - damage = 3 + powerRating; + damage = (STATS_CONFIG.airBurstSettings.damage * 6) + powerRating; + //Default: 6 + //Blinds enemies } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { //Maximum Pressure //Pulls enemies in then blasts them out - damage = 1.5 + powerRating; + damage = (STATS_CONFIG.airBurstSettings.damage * 3) + powerRating; + //Default: 3 radius = (STATS_CONFIG.AirBurstSettings.radius * 7 / 3) + powerRating; //7 upwardKnockback = STATS_CONFIG.airBurstSettings.push / 2.5F; - knockbackDivider = 1.5F; + durationToFire = STATS_CONFIG.AirBurstSettings.durationToFire * 0.75F; + //30 + performanceAmount += 8; } applyMovementModifier(entity, MathHelper.clamp(movementMultiplier, 0.1f, 1)); - double inverseRadius = ((float) durationToFire - duration) / 10; + double inverseRadius = (durationToFire - duration) / 10; //gets smaller + suction -= (float) duration / 400; if (world instanceof WorldServer) { WorldServer World = (WorldServer) world; - for (int i = 0; i < 9; i++) { + for (int i = 0; i < 12; i++) { Vector lookpos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + - i * 40), 0).times(inverseRadius).withY(entity.getEyeHeight() / 2); + i * 30), 0).times(inverseRadius).withY(entity.getEyeHeight() / 2); World.spawnParticle(EnumParticleTypes.CLOUD, lookpos.x() + entity.posX, lookpos.y() + entity.getEntityBoundingBox().minY, lookpos.z() + entity.posZ, 1, 0, 0, 0, 0.005); } } - - if (duration >= durationToFire) { - if (world instanceof WorldServer) { - WorldServer World = (WorldServer) world; - double x, y, z; - - for (double theta = 0; theta <= 180; theta += 1) { - double dphi = 10 / Math.sin(Math.toRadians(theta)); - - for (double phi = 0; phi < 360; phi += dphi) { - double rphi = Math.toRadians(phi); - double rtheta = Math.toRadians(theta); - - x = radius * Math.cos(rphi) * Math.sin(rtheta); - y = radius * Math.sin(rphi) * Math.sin(rtheta); - z = radius * Math.cos(rtheta); - //Decrease radius so you can use particle speed - - World.spawnParticle(EnumParticleTypes.CLOUD, x + entity.posX, y + entity.getEntityBoundingBox().minY, - z + entity.posZ, 1, 0, 0, 0, (double) radius / 100); - - } - }//Creates a sphere. Courtesy of Project Korra's Air Burst! - - for (int i = 0; i < radius; i++) { - for (int j = 0; j < 90; j++) { - Vector lookPos; - if (i >= 1) { - lookPos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + - j * 4), 0).times(i); - } else { - lookPos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + - j * 4), 0); - } - World.spawnParticle(EnumParticleTypes.CLOUD, lookPos.x() + entity.posX, entity.getEntityBoundingBox().minY, - lookPos.z() + entity.posZ, 2, 0, 0, 0, (double) radius / 50); - } - } - } - + if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { AxisAlignedBB box = new AxisAlignedBB(entity.posX + radius, entity.posY + radius, entity.posZ + radius, entity.posX - radius, entity.posY - radius, entity.posZ - radius); List collided = world.getEntitiesWithinAABB(Entity.class, box, entity1 -> entity1 != entity); - float xp = abilityData.getLevel() > 0 ? SKILLS_CONFIG.airBurstHit - abilityData.getLevel() : SKILLS_CONFIG.airBurstHit; if (!collided.isEmpty()) { for (Entity e : collided) { if (e.canBePushed() && e.canBeCollidedWith() && e != entity) { - if (canDamageEntity(e)) { - e.attackEntityFrom(AvatarDamageSource.causeAirDamage(e, entity), (float) damage); - } - abilityData.addXp(xp); - BattlePerformanceScore.addLargeScore(entity); - applyKnockback(e, entity, knockBack, radius, upwardKnockback, knockbackDivider); + pullEntities(e, entity, suction); } } } + } + + if (duration >= durationToFire) { + + int particleController = abilityData.getLevel() >= 1 ? 37 - (5 * abilityData.getLevel()) : 37; + EntityShockwave shockwave = new EntityShockwave(world); + shockwave.setOwner(entity); + shockwave.setPosition(entity.posX, entity.getEntityBoundingBox().minY, entity.posZ); + shockwave.setParticle(EnumParticleTypes.EXPLOSION_NORMAL); + shockwave.setParticleSpeed(0.08F); + shockwave.setKnockbackHeight(upwardKnockback); + shockwave.setDamage((float) damage); + shockwave.setRange(radius); + shockwave.setPerformanceAmount(performanceAmount); + shockwave.setParticleController(particleController); + shockwave.setParticleAmount(2); + shockwave.setSphere(true); + shockwave.setAbility(new AbilityAirBurst()); + shockwave.setSpeed(knockBack / 4); + world.spawnEntity(shockwave); + + entity.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(MOVEMENT_MODIFIER_ID); world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, @@ -202,15 +227,9 @@ private void applyMovementModifier(EntityLivingBase entity, float multiplier) { } - private void applyKnockback(Entity collided, Entity attacker, double knockBack, float radius, double upwardKnockback, float knockbackDivider) { - knockBack *= STATS_CONFIG.airBurstSettings.push; - - //Divide the result of the position difference to make entities fly - //further the closer they are to the player. + private void pullEntities(Entity collided, Entity attacker, double suction) { Vector velocity = Vector.getEntityPos(collided).minus(Vector.getEntityPos(attacker)); - double distance = Vector.getEntityPos(collided).dist(Vector.getEntityPos(attacker)); - double direction = (radius - distance) * (knockBack / knockbackDivider) / radius; - velocity = velocity.times(direction).withY(upwardKnockback); + velocity = velocity.times(suction).times(-1); double x = (velocity.x()); double y = (velocity.y()); @@ -229,48 +248,11 @@ private void applyKnockback(Entity collided, Entity attacker, double knockBack, } } - } - @SubscribeEvent - public static void onDragonHurt(LivingHurtEvent event) { - EntityLivingBase attacker = (EntityLivingBase) event.getSource().getTrueSource(); - Entity target = event.getEntity(); - DamageSource source = event.getSource(); - if (source.getDamageType().equals("avatar_Air")) { - if (attacker instanceof EntityPlayer || attacker instanceof EntityBender) { - Bender ctx = Bender.get(attacker); - if (ctx.getData() != null) { - AbilityData aD = AbilityData.get(attacker, "air_burst"); - float powerRating = (float) (ctx.calcPowerRating(Airbending.ID) / 100); - float damage = 0.5F + powerRating; - if (aD.getLevel() == 1) { - damage = 0.75F + powerRating; - } - - if (aD.getLevel() >= 2) { - damage = 1 + powerRating; - } - - if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { - //Piercing Winds - damage = 5 + powerRating; - } - - if (aD.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { - //Maximum Pressure - //Pulls enemies in then blasts them out - damage = 2.5f + powerRating; - } - event.setAmount(damage); - - - } - } - } } private boolean canDamageEntity(Entity entity) { - if (entity instanceof AvatarEntity && ((AvatarEntity) entity).getOwner() != entity) { + if (entity instanceof AvatarEntity && ((AvatarEntity) entity).getOwner() == entity) { return false; } if (entity instanceof EntityHanging || entity instanceof EntityXPOrb || entity instanceof EntityItem || diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AirDodgeHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AirDodgeHandler.java index 3f52b0bc5f..c1a554e46e 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AirDodgeHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AirDodgeHandler.java @@ -1,61 +1,58 @@ package com.crowsofwar.avatar.common.bending.air; -import com.crowsofwar.avatar.AvatarInfo; -import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; -import com.crowsofwar.avatar.common.data.ctx.BendingContext; -import com.crowsofwar.avatar.common.util.AvatarUtils; -import com.crowsofwar.gorecore.util.Vector; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; + import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.InputEvent; -import org.lwjgl.input.Keyboard; -@Mod.EventBusSubscriber(modid = AvatarInfo.MOD_ID) - -public class AirDodgeHandler extends TickHandler { +import com.crowsofwar.avatar.common.data.*; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import com.crowsofwar.avatar.common.util.AvatarUtils; +import com.crowsofwar.gorecore.util.Vector; +//@Mod.EventBusSubscriber(modid = AvatarInfo.MOD_ID) - public static final int MAX_CoolDown = 20; +public class AirDodgeHandler extends TickHandler { + public static final int maxCoolDown = 20; private int leftDown, rightDown, cooldown; - @Override - public boolean tick(BendingContext ctx) { - BendingData data = ctx.getData(); - int duration = data.getTickHandlerDuration(this); - if(FMLCommonHandler.instance().getSide().isClient()) - MinecraftForge.EVENT_BUS.register(this); - return duration <= 10; - + public AirDodgeHandler(int id) { + super(id); } - +/* @SubscribeEvent public static void onAPress(InputEvent.KeyInputEvent event) { Minecraft mc = Minecraft.getMinecraft(); EntityPlayer player = mc.player; BendingData data = BendingData.get(player); - if (data != null) { - if (data.hasBendingId(Airbending.ID)) { - if (!data.hasTickHandler(AIR_DODGE)) { - if (mc.gameSettings.keyBindLeft.isKeyDown()) { - data.addTickHandler(AIR_DODGE); - } + if (data.hasBendingId(Airbending.ID)) { + if (!data.hasTickHandler(TickHandlerController.AIR_DODGE)) { + if (mc.gameSettings.keyBindLeft.isKeyDown()) { + data.addTickHandler(TickHandlerController.AIR_DODGE); } - if (data.hasTickHandler(AIR_DODGE)) { - if (mc.gameSettings.keyBindLeft.isKeyDown()) { - float yaw = player.rotationYaw - 90; - Vector velocity = Vector.toRectangular(Math.toRadians(yaw), 0); - velocity = velocity.times(20); - player.addVelocity(velocity.x(), velocity.y(), velocity.z()); - AvatarUtils.afterVelocityAdded(player); - data.removeTickHandler(AIR_DODGE); - } + } + if (data.hasTickHandler(TickHandlerController.AIR_DODGE)) { + if (mc.gameSettings.keyBindLeft.isKeyDown()) { + float yaw = player.rotationYaw - 90; + Vector velocity = Vector.toRectangular(Math.toRadians(yaw), 0); + velocity = velocity.times(20); + player.addVelocity(velocity.x(), velocity.y(), velocity.z()); + AvatarUtils.afterVelocityAdded(player); + data.removeTickHandler(TickHandlerController.AIR_DODGE); } } } + }**/ + + @Override + public boolean tick(BendingContext ctx) { + BendingData data = ctx.getData(); + int duration = data.getTickHandlerDuration(this); + // if (FMLCommonHandler.instance().getSide().isClient()) MinecraftForge.EVENT_BUS.register(this); + return duration <= 10; + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AirParticleSpawner.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AirParticleSpawner.java index a61de26556..63f3d95634 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AirParticleSpawner.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AirParticleSpawner.java @@ -19,8 +19,9 @@ import com.crowsofwar.avatar.common.AvatarParticles; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.TickHandlerController; import com.crowsofwar.avatar.common.data.ctx.BendingContext; -import com.crowsofwar.avatar.common.particle.ClientParticleSpawner; +import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; import com.crowsofwar.avatar.common.particle.ParticleSpawner; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLivingBase; @@ -29,8 +30,11 @@ * @author CrowsOfWar */ public class AirParticleSpawner extends TickHandler { + private static final ParticleSpawner particles = new NetworkParticleSpawner(); - private static final ParticleSpawner particles = new ClientParticleSpawner(); + public AirParticleSpawner(int id) { + super(id); + } @Override public boolean tick(BendingContext ctx) { diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/AirStatusControlHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/AirStatusControlHandler.java index 993ed02c51..4fcfecbcee 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/AirStatusControlHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/AirStatusControlHandler.java @@ -1,19 +1,21 @@ package com.crowsofwar.avatar.common.bending.air; -import com.crowsofwar.avatar.common.bending.StatusControl; -import com.crowsofwar.avatar.common.data.AbilityData; -import com.crowsofwar.avatar.common.data.Bender; -import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; -import com.crowsofwar.avatar.common.data.ctx.BendingContext; -import com.crowsofwar.avatar.common.entity.AvatarEntity; -import com.crowsofwar.avatar.common.entity.EntityCloudBall; import net.minecraft.entity.EntityLivingBase; import net.minecraft.world.World; +import com.crowsofwar.avatar.common.bending.StatusControl; +import com.crowsofwar.avatar.common.data.*; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import com.crowsofwar.avatar.common.entity.*; + public class AirStatusControlHandler extends TickHandler { private int ticks = 0; + + public AirStatusControlHandler(int id) { + super(id); + } + @Override public boolean tick(BendingContext ctx) { World world = ctx.getWorld(); @@ -21,7 +23,6 @@ public boolean tick(BendingContext ctx) { BendingData data = ctx.getData(); int duration = data.getTickHandlerDuration(this); - EntityCloudBall ball = AvatarEntity.lookupControlledEntity(world, EntityCloudBall.class, entity); if (ball == null && data.hasStatusControl(StatusControl.THROW_CLOUDBURST)) { ticks++; diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/Airbending.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/Airbending.java index b7b5062627..47ccaed482 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/Airbending.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/Airbending.java @@ -28,7 +28,7 @@ public class Airbending extends BendingStyle { - public static final UUID ID = UUID.fromString("231edc16-639e-4dc4-92f5-924e9102df0f"); + public static UUID ID = UUID.fromString("231edc16-639e-4dc4-92f5-924e9102df0f"); private BendingMenuInfo menu; @@ -56,6 +56,8 @@ public void readFromNBT(NBTTagCompound nbt) { } + + @Override public void writeToNBT(NBTTagCompound nbt) { diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/FallDamageHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/FallDamageHandler.java index 892e954a80..892a2c0c2a 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/FallDamageHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/FallDamageHandler.java @@ -1,28 +1,26 @@ package com.crowsofwar.avatar.common.bending.air; import com.crowsofwar.avatar.AvatarInfo; -import com.crowsofwar.avatar.common.bending.BendingStyles; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.entity.mob.EntityBender; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.DamageSource; import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import org.lwjgl.Sys; @Mod.EventBusSubscriber(modid = AvatarInfo.MOD_ID) public class FallDamageHandler { - //TODO: ADD SLOW FALL WHEN SNEAKING FOR 1.13 INSTEAD OF CANCELLING 1.13 + //TODO: ADD SLOW FALL WHEN SNEAKING FOR 1.13 INSTEAD OF CANCELLING THE DAMAGE @SubscribeEvent public static void noFallDamage(LivingHurtEvent event) { EntityLivingBase entity = (EntityLivingBase) event.getEntity(); - if (entity instanceof EntityBender || entity instanceof EntityPlayerMP) { + if (entity instanceof EntityBender || entity instanceof EntityPlayer) { Bender bender = Bender.get(entity); - if (bender.getData() != null) { + if (bender != null) { BendingData ctx = BendingData.get(entity); if (ctx.hasBendingId(Airbending.ID)) { if (event.getSource() == DamageSource.FALL) { diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/SlipstreamCooldownHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/SlipstreamCooldownHandler.java new file mode 100644 index 0000000000..4b1a6ee717 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/SlipstreamCooldownHandler.java @@ -0,0 +1,46 @@ +package com.crowsofwar.avatar.common.bending.air; + +import com.crowsofwar.avatar.common.data.AbilityData; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.TickHandlerController; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; + + +public class SlipstreamCooldownHandler extends TickHandler { + + public SlipstreamCooldownHandler(int id) { + super(id); + } + + @Override + public boolean tick(BendingContext ctx) { + EntityLivingBase entity = ctx.getBenderEntity(); + BendingData data = ctx.getData(); + int duration = data.getTickHandlerDuration(this); + int coolDown = 160; + AbilityData aD = data.getAbilityData("slipstream"); + + if (aD.getLevel() == 1) { + coolDown = 140; + } + if (aD.getLevel() == 2) { + coolDown = 120; + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + coolDown = 130; + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + coolDown = 110; + } + + if (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative()) { + coolDown = 0; + } + + + return duration >= coolDown; + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/SlipstreamPowerModifier.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/SlipstreamPowerModifier.java index f12c9d3b80..7ed259c915 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/SlipstreamPowerModifier.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/SlipstreamPowerModifier.java @@ -56,8 +56,8 @@ public boolean onUpdate(BendingContext ctx) { @Override protected Vision[] getVisions() { - return new Vision[]{Vision.SLIPSTREAM_WEAK, Vision.SLIPSTREAM_MEDIUM, - Vision.SLIPSTREAM_POWERFUL}; + return new Vision[]{Vision.SLIPSTREAM_WEAK, Vision.SLIPSTREAM_MEDIUM, + Vision.SLIPSTREAM_POWERFUL}; } @Override diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/SmashGroundHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/SmashGroundHandler.java index 38d7b17a38..abff10b8af 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/SmashGroundHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/SmashGroundHandler.java @@ -16,110 +16,98 @@ */ package com.crowsofwar.avatar.common.bending.air; -import com.crowsofwar.avatar.common.AvatarDamageSource; -import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; -import com.crowsofwar.avatar.common.data.Bender; -import com.crowsofwar.avatar.common.data.TickHandler; -import com.crowsofwar.avatar.common.data.ctx.BendingContext; -import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.SoundEvents; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.SoundEvent; -import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.*; import net.minecraft.world.World; -import net.minecraft.world.WorldServer; -import java.util.List; +import com.crowsofwar.avatar.common.bending.Ability; +import com.crowsofwar.avatar.common.data.*; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import com.crowsofwar.avatar.common.entity.EntityShockwave; /** * @author CrowsOfWar */ public class SmashGroundHandler extends TickHandler { + public SmashGroundHandler(int id) { + super(id); + } @Override public boolean tick(BendingContext ctx) { EntityLivingBase entity = ctx.getBenderEntity(); Bender bender = ctx.getBender(); + World world = ctx.getWorld(); if (entity.isInWater() || entity.onGround || bender.isFlying()) { if (entity.onGround) { + smashEntity(entity); + world.playSound(null, entity.posX, entity.posY, entity.posZ, getSound(), getSoundCategory(), 4F, 0.5F); - double range = getRange(); - - World world = entity.world; - AxisAlignedBB box = new AxisAlignedBB(entity.posX - range, entity.getEntityBoundingBox().minY, - entity.posZ - range, entity.posX + range, entity.posY + entity.getEyeHeight(), entity.posZ + range); - - - if (!world.isRemote) { - WorldServer World = (WorldServer) world; - for (double i = 0; i < range; ) { - for (int j = 0; j < 90; j++) { - Vector lookPos; - if (i >= 1) { - lookPos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + - j * 4), 0).times(i); - } else { - lookPos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + - j * 4), 0); - } - World.spawnParticle(getParticle(), lookPos.x() + entity.posX, entity.getEntityBoundingBox().minY, - lookPos.z() + entity.posZ, getNumberOfParticles(), 0, 0, 0, getParticleSpeed() / 4); - } - i = i + range / 10; - } - } - entity.world.playSound(null, entity.posX, entity.posY, entity.posZ, getSound(), getSoundCategory(), 4F, 0.5F); - - - List nearby = world.getEntitiesWithinAABB(EntityLivingBase.class, box); - for (EntityLivingBase target : nearby) { - if (target != entity) { - smashEntity(target, entity); - } - } } - return true; } return false; } - protected void smashEntity(EntityLivingBase target, EntityLivingBase entity) { - if (target.attackEntityFrom(AvatarDamageSource.causeSmashDamage(target, entity), getDamage())) { - BattlePerformanceScore.addLargeScore(entity); - } + protected void smashEntity(EntityLivingBase entity) { + World world = entity.world; + EntityShockwave shockwave = new EntityShockwave(world); + shockwave.setDamage(getDamage()); + shockwave.setOwner(entity); + shockwave.setPosition(entity.posX, entity.getEntityBoundingBox().minY, entity.posZ); + shockwave.setKnockbackHeight(getKnockbackHeight()); + shockwave.setSpeed(getSpeed() / 5); + shockwave.setRange(getRange()); + shockwave.setParticle(getParticle()); + shockwave.setParticleAmount(getParticleAmount()); + shockwave.setParticleSpeed(getParticleSpeed()); + shockwave.setFireTime(fireTime()); + shockwave.setFire(isFire()); + shockwave.setAbility(getAbility()); + shockwave.setPerformanceAmount(getPerformanceAmount()); + world.spawnEntity(shockwave); + } + + protected boolean isFire() { + return false; + } - Vector velocity = Vector.getEntityPos(target).minus(Vector.getEntityPos(entity)); - double distance = Vector.getEntityPos(target).dist(Vector.getEntityPos(entity)); - double direction = (getRange() - distance) * (getSpeed() / 2) / getRange(); - velocity = velocity.times(direction).withY(getKnockbackHeight() / 4); - target.addVelocity(velocity.x(), velocity.y(), velocity.z()); + protected int fireTime() { + return 0; } protected double getRange() { - return 3; + return 4; } - /** - * The speed applied to hit entities, in m/s - */ - protected double getSpeed() { - return 5; + protected EnumParticleTypes getParticle() { + return EnumParticleTypes.EXPLOSION_NORMAL; } - protected float getKnockbackHeight() { - return 0.75F; + protected int getParticleAmount() { + return 2; } - protected EnumParticleTypes getParticle() { - return EnumParticleTypes.CLOUD; + protected Ability getAbility() { + return new AbilityAirJump(); + } + + protected double getParticleSpeed() { + return 0.1F; + } + + protected double getSpeed() { + return 4; + } + + protected float getKnockbackHeight() { + return 0.1F; } protected SoundEvent getSound() { @@ -130,16 +118,12 @@ protected SoundCategory getSoundCategory() { return SoundCategory.BLOCKS; } - protected int getNumberOfParticles() { - return 2; - } - - protected float getParticleSpeed() { - return 0.1F; + protected int getPerformanceAmount() { + return 10; } protected float getDamage() { - return 3; + return 2.5F; } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/StaffGustCooldown.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/StaffGustCooldown.java new file mode 100644 index 0000000000..c30c82b68d --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/StaffGustCooldown.java @@ -0,0 +1,17 @@ +package com.crowsofwar.avatar.common.bending.air; + +import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.TickHandlerController; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; + +public class StaffGustCooldown extends TickHandler { + + public StaffGustCooldown(int id) { + super(id); + } + + @Override + public boolean tick(BendingContext ctx) { + return ctx.getData().getTickHandlerDuration(this) >= 150; + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/StaffPowerModifier.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/StaffPowerModifier.java new file mode 100644 index 0000000000..d63b3b92ca --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/StaffPowerModifier.java @@ -0,0 +1,11 @@ +package com.crowsofwar.avatar.common.bending.air; + +import com.crowsofwar.avatar.common.data.PowerRatingModifier; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; + +public class StaffPowerModifier extends PowerRatingModifier { + @Override + public double get(BendingContext ctx) { + return 40; + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/StatCtrlAirJump.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/StatCtrlAirJump.java index e275785c1c..aa8a581d37 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/StatCtrlAirJump.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/StatCtrlAirJump.java @@ -17,28 +17,28 @@ package com.crowsofwar.avatar.common.bending.air; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.SoundEvents; +import net.minecraft.network.play.server.SPacketEntityVelocity; +import net.minecraft.util.*; +import net.minecraft.util.math.*; +import net.minecraft.world.*; + import com.crowsofwar.avatar.common.AvatarParticles; import com.crowsofwar.avatar.common.bending.StatusControl; import com.crowsofwar.avatar.common.controls.AvatarControl; import com.crowsofwar.avatar.common.data.*; import com.crowsofwar.avatar.common.data.AbilityData.AbilityTreePath; import com.crowsofwar.avatar.common.data.ctx.BendingContext; -import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; -import com.crowsofwar.avatar.common.particle.ParticleSpawner; +import com.crowsofwar.avatar.common.particle.*; import com.crowsofwar.gorecore.util.Vector; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.SoundEvents; -import net.minecraft.network.play.server.SPacketEntityVelocity; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; import java.util.List; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; +import static com.crowsofwar.avatar.common.data.TickHandlerController.*; /** * @author CrowsOfWar @@ -58,13 +58,11 @@ public boolean execute(BendingContext ctx) { World world = ctx.getWorld(); AbilityData abilityData = data.getAbilityData("air_jump"); - boolean allowDoubleJump = abilityData.getLevel() == 3 - && abilityData.getPath() == AbilityTreePath.FIRST; + boolean allowDoubleJump = abilityData.getLevel() == 3 && abilityData.getPath() == AbilityTreePath.FIRST; // Figure out whether entity is on ground by finding collisions with // ground - if found a collision box, then is not on ground - List collideWithGround = world.getCollisionBoxes(entity, - entity.getEntityBoundingBox().grow(0.4, 1, 0.4)); + List collideWithGround = world.getCollisionBoxes(entity, entity.getEntityBoundingBox().grow(0.4, 1, 0.4)); boolean onGround = !collideWithGround.isEmpty() || entity.collidedVertically; if (onGround || (allowDoubleJump && bender.consumeChi(STATS_CONFIG.chiAirJump))) { @@ -73,24 +71,39 @@ public boolean execute(BendingContext ctx) { double multiplier = 0.65; double powerModifier = 10; double powerDuration = 3; + int numberOfParticles = 40; + double particleSpeed = 0.2; if (lvl >= 1) { multiplier = 1; powerModifier = 15; powerDuration = 4; + numberOfParticles = 50; + particleSpeed = 0.3; } if (lvl >= 2) { multiplier = 1.2; powerModifier = 20; powerDuration = 5; + numberOfParticles = 60; + particleSpeed = 0.35; } if (lvl >= 3) { multiplier = 1.4; powerModifier = 25; powerDuration = 6; } + if (abilityData.isMasterPath(AbilityTreePath.SECOND)) { + numberOfParticles = 70; + particleSpeed = 0.5; + } + + if (world instanceof WorldServer) { + WorldServer World = (WorldServer) world; + World.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, entity.posX, entity.getEntityBoundingBox().minY + 0.1, entity.posZ, + numberOfParticles, 0, 0, 0, particleSpeed); + } - Vector rotations = new Vector(Math.toRadians((entity.rotationPitch) / 1), - Math.toRadians(entity.rotationYaw), 0); + Vector rotations = new Vector(Math.toRadians((entity.rotationPitch) / 1), Math.toRadians(entity.rotationYaw), 0); Vector velocity = rotations.toRectangular(); velocity = velocity.withY(Math.pow(velocity.y(), .1)); @@ -107,8 +120,7 @@ public boolean execute(BendingContext ctx) { } ParticleSpawner spawner = new NetworkParticleSpawner(); - spawner.spawnParticles(entity.world, AvatarParticles.getParticleAir(), 2, 6, - new Vector(entity), new Vector(1, 0, 1)); + spawner.spawnParticles(entity.world, AvatarParticles.getParticleAir(), 2, 6, new Vector(entity), new Vector(1, 0, 1)); float fallAbsorption = 0; if (lvl == 0) { @@ -123,14 +135,13 @@ public boolean execute(BendingContext ctx) { data.getMiscData().setFallAbsorption(fallAbsorption); - data.addTickHandler(TickHandler.AIR_PARTICLE_SPAWNER); + data.addTickHandler(AIR_PARTICLE_SPAWNER); if (abilityData.getLevel() == 3 && abilityData.getPath() == AbilityTreePath.SECOND) { - data.addTickHandler(TickHandler.SMASH_GROUND); + data.addTickHandler(SMASH_GROUND); } abilityData.addXp(SKILLS_CONFIG.airJump); - entity.world.playSound(null, new BlockPos(entity), SoundEvents.ENTITY_FIREWORK_LAUNCH, - SoundCategory.PLAYERS, 1, .7f); + entity.world.playSound(null, new BlockPos(entity), SoundEvents.ENTITY_FIREWORK_LAUNCH, SoundCategory.PLAYERS, 1, .7f); PowerRatingModifier powerRatingModifier = new AirJumpPowerModifier(powerModifier); powerRatingModifier.setTicks((int) (powerDuration * 20)); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/air/StatCtrlThrowCloudBall.java b/src/main/java/com/crowsofwar/avatar/common/bending/air/StatCtrlThrowCloudBall.java index 73b9066441..632dc7f111 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/air/StatCtrlThrowCloudBall.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/air/StatCtrlThrowCloudBall.java @@ -45,11 +45,9 @@ public boolean execute(BendingContext ctx) { EntityCloudBall cloudBall = AvatarEntity.lookupControlledEntity(world, EntityCloudBall.class, entity); if (cloudBall != null) { - cloudBall.addVelocity(cloudBall.velocity().dividedBy(-1)); - cloudBall.addVelocity(Vector.getLookRectangular(entity).times(speed).times(2)); - //Necessary so that you can't increase speed by moving your mouse really fast; additionally, - //using setVelocity sometimes makes the cloudburst go invisible. Weird. cloudBall.setBehavior(new CloudburstBehavior.Thrown()); + cloudBall.setVelocity(Vector.getLookRectangular(entity).times(speed).times(2)); + //ctx.getData().addTickHandler(AIR_STATCTRL_HANDLER); } return true; diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/combustion/AbilityExplosivePillar.java b/src/main/java/com/crowsofwar/avatar/common/bending/combustion/AbilityExplosivePillar.java index 6cacc6f394..fcb0f2c0a5 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/combustion/AbilityExplosivePillar.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/combustion/AbilityExplosivePillar.java @@ -30,17 +30,14 @@ public void execute(AbilityContext ctx) { if (bender.consumeChi(chi)) { EntityExplosionSpawner spawner = new EntityExplosionSpawner(world); Vector look = Vector.toRectangular(Math.toRadians(entity.rotationYaw), 0); - double mult = ctx.getLevel() >= 0.5 ? 7 : 4; - if (abilityData.getLevel() <= 0) { + double mult = ctx.getLevel() >= 1 ? 10 : 8; spawner.setOwner(entity); spawner.setExplosionFrequency(10F); spawner.setExplosionStrength(1F); spawner.setPosition(entity.posX, entity.posY, entity.posZ); spawner.setVelocity(look.times(mult)); spawner.maxTicks(ticks); - data.getAbilityData("explosive_pillar").addXp(xp); - } if (abilityData.getLevel() == 1) { spawner.setOwner(entity); spawner.setExplosionFrequency(8F); @@ -69,6 +66,7 @@ public void execute(AbilityContext ctx) { spawner.setVelocity(look.times(mult)); spawner.maxTicks(ticks * 2.5F); } + data.getAbilityData("explosive_pillar").addXp(xp); if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { for (int i = 0; i < 3; i++) { diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/dev/LightningDeflectHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/dev/LightningDeflectHandler.java new file mode 100644 index 0000000000..bb14dde647 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/dev/LightningDeflectHandler.java @@ -0,0 +1,30 @@ +package com.crowsofwar.avatar.common.bending.dev; + +import com.crowsofwar.avatar.AvatarInfo; +import com.crowsofwar.avatar.common.entity.EntityLightningArc; +import com.crowsofwar.gorecore.util.Vector; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.event.entity.player.AttackEntityEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +@Mod.EventBusSubscriber(modid = AvatarInfo.MOD_ID) +public class LightningDeflectHandler { + + @SubscribeEvent + public static void onLightningArcPunch (AttackEntityEvent event) { + Entity e = event.getTarget(); + EntityPlayer p = event.getEntityPlayer(); + if (p.getUniqueID().toString().equals("01535a73-ff8d-4d6c-851e-c71f89e936aa") || p.getName().equals("FavouriteDragon")) { + if (e instanceof EntityLightningArc) { + EntityLightningArc arc = (EntityLightningArc) event.getTarget(); + arc.setOwner(p); + arc.setVelocity(Vector.getLookRectangular(p).times(arc.velocity().magnitude())); + + } + } + + } + +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityEarthspikes.java b/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityEarthspikes.java index f39aa5b3f6..6840a616a7 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityEarthspikes.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityEarthspikes.java @@ -1,21 +1,17 @@ package com.crowsofwar.avatar.common.bending.earth; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.world.*; + import com.crowsofwar.avatar.common.bending.Ability; -import com.crowsofwar.avatar.common.data.AbilityData; -import com.crowsofwar.avatar.common.data.Bender; -import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.*; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; -import com.crowsofwar.avatar.common.entity.EntityEarthspike; -import com.crowsofwar.avatar.common.entity.EntityEarthspikeSpawner; +import com.crowsofwar.avatar.common.entity.*; import com.crowsofwar.gorecore.util.Vector; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.world.World; -import net.minecraft.world.WorldServer; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; +import static com.crowsofwar.avatar.common.data.TickHandlerController.SPAWN_EARTHSPIKES_HANDLER; public class AbilityEarthspikes extends Ability { @@ -60,6 +56,17 @@ public void execute(AbilityContext ctx) { chi = STATS_CONFIG.chiEarthspike * 2; //7 } + double damage = STATS_CONFIG.earthspikeSettings.damage * 2; + //6 + double size = STATS_CONFIG.earthspikeSettings.size * 1.25F; + size += abilityData.getTotalXp() / 400; + + damage += abilityData.getTotalXp() / 400; + damage *= ctx.getPowerRatingDamageMod(); + + ticks += abilityData.getTotalXp() / 400; + speed += abilityData.getTotalXp() / 400; + chi -= abilityData.getTotalXp() / 400; if (bender.consumeChi(chi)) { @@ -79,12 +86,11 @@ public void execute(AbilityContext ctx) { } else { if (entity.onGround) { for (int i = 0; i < 8; i++) { - Vector direction1 = Vector.toRectangular(Math.toRadians(entity.rotationYaw + - i * 45), 0).withY(0); + Vector direction1 = Vector.toRectangular(Math.toRadians(entity.rotationYaw + i * 45), 0).times(1.4).withY(0); EntityEarthspike earthspike = new EntityEarthspike(world); earthspike.setPosition(direction1.x() + entity.posX, entity.posY, direction1.z() + entity.posZ); - earthspike.setDamage(STATS_CONFIG.earthspikeSettings.damage * 3); - earthspike.setSize(STATS_CONFIG.earthspikeSettings.size * 1.25F); + earthspike.setDamage(damage); + earthspike.setSize((float) size); earthspike.setOwner(entity); earthspike.setAbility(this); world.spawnEntity(earthspike); @@ -104,8 +110,10 @@ public void execute(AbilityContext ctx) { } } } - data.addTickHandler(TickHandler.SPAWN_EARTHSPIKES_HANDLER); - + if (data.hasTickHandler(SPAWN_EARTHSPIKES_HANDLER)) { + data.removeTickHandler(SPAWN_EARTHSPIKES_HANDLER); + } + data.addTickHandler(SPAWN_EARTHSPIKES_HANDLER); } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityPickUpBlock.java b/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityPickUpBlock.java index 9e060e80c5..79d9772f96 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityPickUpBlock.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityPickUpBlock.java @@ -32,8 +32,6 @@ import net.minecraft.block.SoundType; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.init.SoundEvents; import net.minecraft.util.SoundCategory; @@ -66,9 +64,9 @@ public boolean isUtility() { public void execute(AbilityContext ctx) { BendingData data = ctx.getData(); - EntityLivingBase entity = ctx.getBenderEntity(); - Bender bender = ctx.getBender(); - World world = ctx.getWorld(); + //EntityLivingBase entity = ctx.getBenderEntity(); + //Bender bender = ctx.getBender(); + //World world = ctx.getWorld(); EntityFloatingBlock currentBlock = AvatarEntity.lookupEntity(ctx.getWorld(), EntityFloatingBlock.class, diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityRestore.java b/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityRestore.java index 1c1ea82fce..32fbbb2168 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityRestore.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityRestore.java @@ -7,10 +7,12 @@ import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.MobEffects; import net.minecraft.potion.PotionEffect; +import static com.crowsofwar.avatar.common.AvatarChatMessages.MSG_RESTORE_COOLDOWN; +import static com.crowsofwar.avatar.common.data.TickHandlerController.RESTORE_COOLDOWN_HANDLER; +import static com.crowsofwar.avatar.common.data.TickHandlerController.RESTORE_PARTICLE_SPAWNER; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; @@ -44,12 +46,16 @@ public void execute(AbilityContext ctx) { chi = STATS_CONFIG.chiBuffLvl4; } - if (bender.consumeChi(chi)) { + if (data.hasTickHandler(RESTORE_COOLDOWN_HANDLER) && entity instanceof EntityPlayer) { + MSG_RESTORE_COOLDOWN.send(entity); + } + + if (bender.consumeChi(chi) && !data.hasTickHandler(RESTORE_COOLDOWN_HANDLER)) { abilityData.addXp(SKILLS_CONFIG.buffUsed); - // 3s + 2.5s per level - int duration = 60 + 50 * abilityData.getLevel(); + // 3s + 1.5s per level + int duration = ctx.getLevel() > 0 ? 60 + 30 * ctx.getLevel() : 60; int effectLevel = 0; int slownessLevel = abilityData.getLevel() >= 2 ? 1 : 2; int regenLevel = abilityData.getLevel() >= 2 ? 1 : 0; @@ -64,13 +70,13 @@ public void execute(AbilityContext ctx) { entity.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, duration, slownessLevel)); if (abilityData.getLevel() >= 1) { - entity.addPotionEffect(new PotionEffect(MobEffects.REGENERATION, 50, regenLevel)); + entity.addPotionEffect(new PotionEffect(MobEffects.REGENERATION, duration, regenLevel)); } if (abilityData.getLevel() >= 2) { entity.addPotionEffect(new PotionEffect(MobEffects.STRENGTH, duration, effectLevel)); } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { - entity.addPotionEffect(new PotionEffect(MobEffects.INSTANT_HEALTH, duration)); + entity.addPotionEffect(new PotionEffect(MobEffects.INSTANT_HEALTH)); entity.addPotionEffect(new PotionEffect(MobEffects.SATURATION, duration)); } @@ -82,35 +88,12 @@ public void execute(AbilityContext ctx) { // Ignore warning; we know manager != null if they have the bending style //noinspection ConstantConditions data.getPowerRatingManager(getBendingId()).addModifier(modifier, ctx); + data.addTickHandler(RESTORE_PARTICLE_SPAWNER); + data.addTickHandler(RESTORE_COOLDOWN_HANDLER); } } - - @Override - public int getCooldown(AbilityContext ctx) { - EntityLivingBase entity = ctx.getBenderEntity(); - - int coolDown = 200; - - if (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative()) { - coolDown = 0; - } - - if (ctx.getLevel() == 1) { - coolDown = 180; - } - if (ctx.getLevel() == 2) { - coolDown = 160; - } - if (ctx.isMasterLevel(AbilityData.AbilityTreePath.FIRST)) { - coolDown = 140; - } - if (ctx.isMasterLevel(AbilityData.AbilityTreePath.SECOND)) { - coolDown = 135; - } - return coolDown; - } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityWall.java b/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityWall.java index 22160415ba..215a6677b2 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityWall.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/earth/AbilityWall.java @@ -28,12 +28,12 @@ import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import java.util.Objects; import java.util.Random; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; @@ -64,10 +64,11 @@ public void execute(AbilityContext ctx) { int whMin, whMax; Random random = new Random(); - if (power == 100) { - whMin = whMax = 5; - } else if (power >= 75) { + if (power >= 100) { whMin = 4; + whMax = 6; + } else if (power >= 75) { + whMin = 3; whMax = 5; } else if (power >= 50) { whMin = 3; @@ -76,14 +77,17 @@ public void execute(AbilityContext ctx) { whMin = 2; whMax = 4; } else { - whMin = 2; + whMin = 1; whMax = 3; } + if (ctx.getLevel() >= 2) { + whMax += 2; + } abilityData.addXp(SKILLS_CONFIG.wallRaised); if (!ctx.isLookingAtBlock()) return; - BlockPos lookPos = ctx.getLookPosI().toBlockPos(); + BlockPos lookPos = Objects.requireNonNull(ctx.getLookPosI()).toBlockPos(); EntityWall wall = new EntityWall(world); Block lookBlock = world.getBlockState(lookPos).getBlock(); @@ -92,65 +96,66 @@ public void execute(AbilityContext ctx) { } else if (lookBlock == Blocks.DOUBLE_PLANT) { lookPos = lookPos.down(2); } + if (STATS_CONFIG.bendableBlocks.contains(lookBlock) || STATS_CONFIG.plantBendableBlocks.contains(lookBlock)) { + wall.setPosition(lookPos.getX() + .5, lookPos.getY(), lookPos.getZ() + .5); + wall.setOwner(entity); + for (int i = 0; i < 5; i++) { + + int wallHeight = whMin + random.nextInt(whMax - whMin + 1); + + int horizMod = -2 + i; + int x = lookPos.getX() + + (cardinal == EnumFacing.NORTH || cardinal == EnumFacing.SOUTH ? horizMod : 0); + int y = lookPos.getY() - 4; + int z = lookPos.getZ() + + (cardinal == EnumFacing.EAST || cardinal == EnumFacing.WEST ? horizMod : 0); + + EntityWallSegment seg = new EntityWallSegment(world); + seg.attachToWall(wall); + seg.setPosition(x + .5, y, z + .5); + seg.setDirection(cardinal); + seg.setOwner(entity); + seg.setAbility(this); + + boolean foundAir = false, dontBreakMore = false; + for (int j = EntityWallSegment.SEGMENT_HEIGHT - 1; j >= 0; j--) { + BlockPos pos = new BlockPos(x, y + j, z); + IBlockState state = world.getBlockState(pos); + boolean bendable = STATS_CONFIG.bendableBlocks.contains(state.getBlock()); + if (!bendable || dontBreakMore) { + state = Blocks.AIR.getDefaultState(); + dontBreakMore = true; + } + + if (!foundAir && state.getBlock() == Blocks.AIR) { + seg.setSize(seg.width, 5 - j - 1); + seg.setBlocksOffset(-(j + 1)); + seg.setPosition(seg.position().withY(y + j + 1)); + foundAir = true; + } + if (foundAir && state.getBlock() != Blocks.AIR) { + // Extend bounding box + seg.setSize(seg.width, 5 - j); + seg.setBlocksOffset(-j); + seg.setPosition(seg.position().withY(y + j)); + } + + seg.setBlock(j, state); + if (bendable && !dontBreakMore) world.setBlockToAir(pos); + + if (j == 5 - wallHeight) { + dontBreakMore = true; + } - wall.setPosition(lookPos.getX() + .5, lookPos.getY(), lookPos.getZ() + .5); - wall.setOwner(entity); - for (int i = 0; i < 5; i++) { - - int wallHeight = whMin + random.nextInt(whMax - whMin + 1); - - int horizMod = -2 + i; - int x = lookPos.getX() - + (cardinal == EnumFacing.NORTH || cardinal == EnumFacing.SOUTH ? horizMod : 0); - int y = lookPos.getY() - 4; - int z = lookPos.getZ() - + (cardinal == EnumFacing.EAST || cardinal == EnumFacing.WEST ? horizMod : 0); - - EntityWallSegment seg = new EntityWallSegment(world); - seg.attachToWall(wall); - seg.setPosition(x + .5, y, z + .5); - seg.setDirection(cardinal); - seg.setOwner(entity); - seg.setAbility(this); - - boolean foundAir = false, dontBreakMore = false; - for (int j = EntityWallSegment.SEGMENT_HEIGHT - 1; j >= 0; j--) { - BlockPos pos = new BlockPos(x, y + j, z); - IBlockState state = world.getBlockState(pos); - boolean bendable = STATS_CONFIG.bendableBlocks.contains(state.getBlock()); - if (!bendable || dontBreakMore) { - state = Blocks.AIR.getDefaultState(); - dontBreakMore = true; - } - - if (!foundAir && state.getBlock() == Blocks.AIR) { - seg.setSize(seg.width, 5 - j - 1); - seg.setBlocksOffset(-(j + 1)); - seg.setPosition(seg.position().withY(y + j + 1)); - foundAir = true; - } - if (foundAir && state.getBlock() != Blocks.AIR) { - // Extend bounding box - seg.setSize(seg.width, 5 - j); - seg.setBlocksOffset(-j); - seg.setPosition(seg.position().withY(y + j)); - } - - seg.setBlock(j, state); - if (bendable && !dontBreakMore) world.setBlockToAir(pos); - - if (j == 5 - wallHeight) { - dontBreakMore = true; } + world.spawnEntity(seg); } + world.spawnEntity(wall); - world.spawnEntity(seg); - } - world.spawnEntity(wall); - - ctx.getData().addStatusControl(StatusControl.DROP_WALL); + ctx.getData().addStatusControl(StatusControl.DROP_WALL); + } } } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/earth/EarthbendingPerformanceBonus.java b/src/main/java/com/crowsofwar/avatar/common/bending/earth/EarthbendingPerformanceBonus.java index 3fd2297332..19c167137a 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/earth/EarthbendingPerformanceBonus.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/earth/EarthbendingPerformanceBonus.java @@ -19,20 +19,20 @@ public static void onPlayerTick(TickEvent.PlayerTickEvent e) { if (e.phase == TickEvent.Phase.START && e.side == Side.SERVER) { - EntityPlayer player = e.player; - BendingData data = BendingData.get(player); - - BattlePerformanceScore performance = data.getPerformance(); - double score = performance.getScore(); - - if (score >= 80) { - player.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, 30, 0)); - performance.modifyScore(-20); - } - if (score >= 100) { - player.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, 60, 1)); - performance.modifyScore(-60); - } + EntityPlayer player = e.player; + BendingData data = BendingData.get(player); + + BattlePerformanceScore performance = data.getPerformance(); + double score = performance.getScore(); + + if (score >= 80) { + player.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, 30, 0)); + performance.modifyScore(-20); + } + if (score >= 100) { + player.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, 60, 1)); + performance.modifyScore(-60); + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/earth/RestoreCooldownHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/earth/RestoreCooldownHandler.java new file mode 100644 index 0000000000..5d7cc4e234 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/earth/RestoreCooldownHandler.java @@ -0,0 +1,46 @@ +package com.crowsofwar.avatar.common.bending.earth; + +import com.crowsofwar.avatar.common.data.AbilityData; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.TickHandlerController; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; + +public class RestoreCooldownHandler extends TickHandler { + + public RestoreCooldownHandler(int id) { + super(id); + } + + @Override + public boolean tick(BendingContext ctx) { + EntityLivingBase entity = ctx.getBenderEntity(); + BendingData data = ctx.getData(); + int duration = data.getTickHandlerDuration(this); + int coolDown = 160; + AbilityData aD = data.getAbilityData("restore"); + + if (aD.getLevel() == 1) { + coolDown = 150; + } + if (aD.getLevel() == 2) { + coolDown = 140; + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + coolDown = 130; + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + coolDown = 140; + } + + if (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative()) { + coolDown = 0; + } + + + return duration >= coolDown; + } +} + diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/earth/RestoreParticleHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/earth/RestoreParticleHandler.java new file mode 100644 index 0000000000..332ec3c0d1 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/earth/RestoreParticleHandler.java @@ -0,0 +1,57 @@ +package com.crowsofwar.avatar.common.bending.earth; + +import com.crowsofwar.avatar.common.AvatarParticles; +import com.crowsofwar.avatar.common.data.AbilityData; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.TickHandlerController; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; +import com.crowsofwar.avatar.common.particle.ParticleSpawner; +import com.crowsofwar.gorecore.util.Vector; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import java.util.Random; + +import static com.crowsofwar.avatar.common.config.ConfigClient.CLIENT_CONFIG; + +public class RestoreParticleHandler extends TickHandler { + private final ParticleSpawner particles; + + public RestoreParticleHandler(int id) { + super(id); + particles = new NetworkParticleSpawner(); + } + + @Override + public boolean tick(BendingContext ctx) { + EntityLivingBase entity = ctx.getBenderEntity(); + BendingData data = ctx.getData(); + AbilityData aD = data.getAbilityData("restore"); + World world = ctx.getWorld(); + int duration = data.getTickHandlerDuration(this); + int restoreDuration = aD.getLevel() > 0 ? 40 + 30 * aD.getLevel() : 40; + //The particles take a while to disappear after the ability finishes- so you decrease the time the particles can spawn + Random rand = new Random(); + double r = rand.nextDouble(); + if (!world.isRemote) { + for (int i = 0; i < 40; i++) { + WorldServer World = (WorldServer) world; + int random = rand.nextInt(2) + 1; + r = random == 1 ? r : r * -1; + Vector location = Vector.toRectangular(Math.toRadians(entity.rotationYaw + (i * 9) + (r * 2)), 0).times(0.5).withY(0); + if (!CLIENT_CONFIG.useCustomParticles) { + World.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, location.x() + entity.posX, location.y() + entity.getEntityBoundingBox().minY + (r * 2), + location.z() + entity.posZ, 1, 0, 0, 0, 10D); + } else { + particles.spawnParticles(world, AvatarParticles.getParticleRestore(), 1, 2, location.plus(Vector.getEntityPos(entity)), + new Vector(0.2, 0.65, 0.2)); + } + } + } + return duration >= restoreDuration; + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/earth/RestorePowerModifier.java b/src/main/java/com/crowsofwar/avatar/common/bending/earth/RestorePowerModifier.java index 55dfaab029..c3eada468a 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/earth/RestorePowerModifier.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/earth/RestorePowerModifier.java @@ -25,7 +25,12 @@ public double get(BendingContext ctx) { @Override protected Vision[] getVisions() { - return new Vision[]{Vision.RESTORE_WEAK, Vision.RESTORE_MEDIUM, Vision.RESTORE_POWERFUL}; + //if (CLIENT_CONFIG.shaderSettings.useRestoreShaders) { + return new Vision[]{Vision.RESTORE_WEAK, Vision.RESTORE_MEDIUM, Vision.RESTORE_POWERFUL}; + //} + /*else { + return null; + }**/ } @Override diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/earth/SpawnEarthspikesHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/earth/SpawnEarthspikesHandler.java index 1823a8ff41..2548f29842 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/earth/SpawnEarthspikesHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/earth/SpawnEarthspikesHandler.java @@ -1,28 +1,16 @@ package com.crowsofwar.avatar.common.bending.earth; -import com.crowsofwar.avatar.common.data.AbilityData; -import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; +import net.minecraft.block.Block; +import net.minecraft.entity.*; +import net.minecraft.entity.ai.attributes.*; +import net.minecraft.util.*; +import net.minecraft.util.math.*; +import net.minecraft.world.*; + +import com.crowsofwar.avatar.common.data.*; import com.crowsofwar.avatar.common.data.ctx.BendingContext; -import com.crowsofwar.avatar.common.entity.AvatarEntity; -import com.crowsofwar.avatar.common.entity.EntityEarthspike; -import com.crowsofwar.avatar.common.entity.EntityEarthspikeSpawner; -import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; -import com.crowsofwar.avatar.common.particle.ParticleSpawner; +import com.crowsofwar.avatar.common.entity.*; import com.crowsofwar.gorecore.util.Vector; -import net.minecraft.block.Block; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.attributes.AttributeModifier; -import net.minecraft.entity.ai.attributes.IAttributeInstance; -import net.minecraft.init.SoundEvents; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.world.World; -import net.minecraft.world.WorldServer; import java.util.UUID; @@ -30,8 +18,11 @@ public class SpawnEarthspikesHandler extends TickHandler { - private static final UUID MOVEMENT_MODIFIER_ID = UUID.fromString - ("78723aa8-8d42-11e8-9eb6-529269fb1459"); + private static final UUID MOVEMENT_MODIFIER_ID = UUID.fromString("78723aa8-8d42-11e8-9eb6-529269fb1459"); + + public SpawnEarthspikesHandler(int id) { + super(id); + } @Override public boolean tick(BendingContext ctx) { @@ -47,14 +38,14 @@ public boolean tick(BendingContext ctx) { //4 (by default) double damage = STATS_CONFIG.earthspikeSettings.damage; //3 (by default) - float size = STATS_CONFIG.earthspikeSettings.size; - //1 (by default) - + float size = STATS_CONFIG.earthspikeSettings.size * 0.75F; + //0.5 (by default) + float xpModifier = abilityData.getTotalXp() / 400; if (abilityData.getLevel() == 1) { damage = STATS_CONFIG.earthspikeSettings.damage * 1.33; //4 - //size = STATS_CONFIG.earthspikeSettings.size * 1.25F; + size = STATS_CONFIG.earthspikeSettings.size * 1F; //1.25 } @@ -63,32 +54,38 @@ public boolean tick(BendingContext ctx) { //3 damage = STATS_CONFIG.earthspikeSettings.damage * 1.66; //5 - //size = STATS_CONFIG.earthspikeSettings.size * 1.5F; + size = STATS_CONFIG.earthspikeSettings.size * 1.25F; //1.5 } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + //Flash Fissure frequency = STATS_CONFIG.earthspikeSettings.frequency * 0.5F; //2 - damage = STATS_CONFIG.earthspikeSettings.damage * 2; - //6 - //size = STATS_CONFIG.earthspikeSettings.size * 2F; + damage = STATS_CONFIG.earthspikeSettings.damage * 2.25; + //7.5 + size = STATS_CONFIG.earthspikeSettings.size * 1.75F; //2 } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { - damage = STATS_CONFIG.earthspikeSettings.damage * 1.66; - //5 - //size = STATS_CONFIG.earthspikeSettings.size; + //Octopus Fissure + damage = STATS_CONFIG.earthspikeSettings.damage * 2.5; + //6 + size = STATS_CONFIG.earthspikeSettings.size * 1.5F; + //1.75 } + //For some reason using *= or += seems to glitch out everything- that's why I'm using tedious equations. - //For some reason using *= or += seems to glitch out everything- that's why - //I'm using tedious equations. + size += duration / 45F; + size += xpModifier; + + damage += xpModifier; + damage *= ctx.getBender().getDamageMult(Earthbending.ID); - size += duration / 20; EntityEarthspikeSpawner entity = AvatarEntity.lookupControlledEntity(world, EntityEarthspikeSpawner.class, owner); if (!abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { @@ -98,7 +95,7 @@ public boolean tick(BendingContext ctx) { earthspike.posX = entity.posX; earthspike.posY = entity.posY; earthspike.posZ = entity.posZ; - earthspike.setAbility(abilityData.getAbility()); + earthspike.setAbility(new AbilityEarthspikes()); earthspike.setDamage(damage); earthspike.setSize(size); earthspike.setLifetime(entity.getDuration()); @@ -107,45 +104,36 @@ public boolean tick(BendingContext ctx) { BlockPos below = earthspike.getPosition().offset(EnumFacing.DOWN); Block belowBlock = world.getBlockState(below).getBlock(); - world.playSound(null, earthspike.posX, earthspike.posY, earthspike.posZ, - belowBlock.getSoundType().getBreakSound(), - SoundCategory.BLOCKS, 1, 1); + world.playSound(null, earthspike.posX, earthspike.posY, earthspike.posZ, belowBlock.getSoundType().getBreakSound(), + SoundCategory.BLOCKS, 1, 1); if (!world.isRemote) { WorldServer World = (WorldServer) world; - for (int degree = 0; degree < 360; degree++) { - double radians = Math.toRadians(degree); - double x = Math.cos(radians) / 2 + earthspike.posX; - double y = earthspike.posY; - double z = Math.sin(radians) / 2 + earthspike.posZ; - World.spawnParticle(EnumParticleTypes.CRIT, x, y, z, 1, 0, 0, 0, 0.5); - - } + World.spawnParticle(EnumParticleTypes.CRIT, earthspike.posX, earthspike.posY, earthspike.posZ, 100, 0, 0, 0, 0.5); } } return false; } } else { applyMovementModifier(owner, MathHelper.clamp(movementMultiplier, 0.1f, 1)); - if (duration % 10 == 0 && owner.onGround) { + if (duration % 15 == 0 && owner.onGround) { //Try using rotation yaw instead of circle particles for (int i = 0; i < 8; i++) { - Vector direction1 = Vector.toRectangular(Math.toRadians(owner.rotationYaw + - i * 45), 0).withY(0).times(duration / 5); + Vector direction1 = Vector.toRectangular(Math.toRadians(owner.rotationYaw + i * 45), 0).withY(0).times(duration / 5F); EntityEarthspike earthspike = new EntityEarthspike(world); if (direction1.x() + owner.posX != owner.posX && direction1.z() + owner.posZ != owner.posZ) { earthspike.setPosition(direction1.x() + owner.posX, owner.posY, direction1.z() + owner.posZ); } + //Necessary so that the player doesn't spawn a center earthspike earthspike.setDamage(damage); earthspike.setSize(size); - earthspike.setLifetime(20); + earthspike.setLifetime(20 + size * 2); earthspike.setOwner(owner); world.spawnEntity(earthspike); BlockPos below = earthspike.getPosition().offset(EnumFacing.DOWN); Block belowBlock = world.getBlockState(below).getBlock(); - world.playSound(null, earthspike.posX, earthspike.posY, earthspike.posZ, - belowBlock.getSoundType().getBreakSound(), - SoundCategory.BLOCKS, 1, 1); + world.playSound(null, earthspike.posX, earthspike.posY, earthspike.posZ, belowBlock.getSoundType().getBreakSound(), + SoundCategory.BLOCKS, 1, 1); if (!world.isRemote) { WorldServer World = (WorldServer) world; for (int degree = 0; degree < 360; degree++) { @@ -160,7 +148,7 @@ public boolean tick(BendingContext ctx) { } } } - if (duration >= 20 && entity == null) { + if (duration >= 30 && entity == null) { owner.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(MOVEMENT_MODIFIER_ID); stop = true; } @@ -169,13 +157,11 @@ public boolean tick(BendingContext ctx) { private void applyMovementModifier(EntityLivingBase entity, float multiplier) { - IAttributeInstance moveSpeed = entity.getEntityAttribute(SharedMonsterAttributes - .MOVEMENT_SPEED); + IAttributeInstance moveSpeed = entity.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); moveSpeed.removeModifier(MOVEMENT_MODIFIER_ID); - moveSpeed.applyModifier(new AttributeModifier(MOVEMENT_MODIFIER_ID, - "Earthspike modifier", multiplier - 1, 1)); + moveSpeed.applyModifier(new AttributeModifier(MOVEMENT_MODIFIER_ID, "Earthspike modifier", multiplier - 1, 1)); } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireArc.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireArc.java index 5eaa93de73..0ecff88475 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireArc.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireArc.java @@ -20,7 +20,6 @@ import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.BendingAi; import com.crowsofwar.avatar.common.bending.StatusControl; -import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.AbilityData.AbilityTreePath; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; @@ -28,12 +27,15 @@ import com.crowsofwar.avatar.common.entity.AvatarEntity; import com.crowsofwar.avatar.common.entity.EntityFireArc; import com.crowsofwar.avatar.common.entity.data.FireArcBehavior; +import com.crowsofwar.avatar.common.util.Raytrace; import com.crowsofwar.gorecore.util.Vector; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; +import java.util.List; + import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; /** @@ -68,9 +70,32 @@ public void execute(AbilityContext ctx) { removeExisting(ctx); + + float damageMult = ctx.getLevel() >= 2 ? 2 : 1; damageMult *= ctx.getPowerRatingDamageMod(); + List fireArc = Raytrace.entityRaytrace(world, Vector.getEntityPos(entity).withY(entity.getEyeHeight()), Vector.getLookRectangular(entity).times(10), 3, + entity1 -> entity1 != entity); + + if (fireArc.isEmpty()) { + if (ctx.getLevel() >= 2) { + for (Entity a : fireArc) { + if (a instanceof AvatarEntity) { + if (((AvatarEntity) a).getOwner() != entity) { + if (a instanceof EntityFireArc) { + ((EntityFireArc) a).setOwner(entity); + ((EntityFireArc) a).setBehavior(new FireArcBehavior.PlayerControlled()); + ((EntityFireArc) a).setAbility(this); + ((EntityFireArc) a).setPosition(Vector.getLookRectangular(entity).times(1.5F)); + ((EntityFireArc) a).setDamageMult(damageMult); + } + } + } + } + } + } + EntityFireArc fire = new EntityFireArc(world); if (lookPos != null) { fire.setPosition(lookPos.x(), lookPos.y(), lookPos.z()); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireJump.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireJump.java index f5ffd6b8a3..46b1f07a58 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireJump.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireJump.java @@ -2,18 +2,15 @@ import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.StatusControl; -import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import com.crowsofwar.avatar.common.data.ctx.BendingContext; import com.crowsofwar.avatar.common.util.Raytrace; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; import static com.crowsofwar.avatar.common.bending.StatusControl.FIRE_JUMP; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; +import static com.crowsofwar.avatar.common.data.TickHandlerController.FIRE_PARTICLE_SPAWNER; public class AbilityFireJump extends Ability { public AbilityFireJump() { @@ -34,7 +31,7 @@ public void execute(AbilityContext ctx) { if (!data.hasStatusControl(FIRE_JUMP) && bender.consumeChi(STATS_CONFIG.chiAirJump)) { data.addStatusControl(FIRE_JUMP); - if (data.hasTickHandler(TickHandler.FIRE_PARTICLE_SPAWNER)) { + if (data.hasTickHandler(FIRE_PARTICLE_SPAWNER)) { StatusControl sc = FIRE_JUMP; Raytrace.Result raytrace = Raytrace.getTargetBlock(ctx.getBenderEntity(), -1); if (FIRE_JUMP.execute( diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireball.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireball.java index b751d7583d..5887b65da6 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireball.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFireball.java @@ -19,7 +19,6 @@ import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.BendingAi; import com.crowsofwar.avatar.common.bending.StatusControl; -import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.AbilityData.AbilityTreePath; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; @@ -29,11 +28,7 @@ import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; -import net.minecraft.util.SoundCategory; import net.minecraft.world.World; -import org.lwjgl.Sys; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; import static com.crowsofwar.gorecore.util.Vector.getEyePos; diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFlamethrower.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFlamethrower.java index c94a1a7bd4..4001c27a30 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFlamethrower.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityFlamethrower.java @@ -20,13 +20,10 @@ import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.BendingAi; import com.crowsofwar.avatar.common.bending.StatusControl; -import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; /** * @author CrowsOfWar diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityInfernoPunch.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityInfernoPunch.java index 10f08f0a26..306f173f48 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityInfernoPunch.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityInfernoPunch.java @@ -2,15 +2,16 @@ import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.BendingAi; -import com.crowsofwar.avatar.common.data.*; +import com.crowsofwar.avatar.common.data.AbilityData; +import com.crowsofwar.avatar.common.data.Bender; +import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import static com.crowsofwar.avatar.common.bending.StatusControl.INFERNO_PUNCH; +import static com.crowsofwar.avatar.common.bending.fire.StatCtrlInfernoPunch.INFERNO_PUNCH; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; -import static com.crowsofwar.avatar.common.data.TickHandler.INFERNO_PARTICLE_SPAWNER; +import static com.crowsofwar.avatar.common.data.TickHandlerController.INFERNO_PARTICLE_SPAWNER; public class AbilityInfernoPunch extends Ability { public AbilityInfernoPunch() { @@ -26,11 +27,11 @@ public void execute(AbilityContext ctx) { float chi = STATS_CONFIG.chiInfernoPunch; if (ctx.getLevel() >= 1) { - chi = STATS_CONFIG.chiInfernoPunch * 4/3; + chi = STATS_CONFIG.chiInfernoPunch * 4 / 3; //4 } if (ctx.getLevel() >= 2) { - chi = STATS_CONFIG.chiInfernoPunch * 5/3; + chi = STATS_CONFIG.chiInfernoPunch * 5 / 3; //5 } if (ctx.isMasterLevel(AbilityData.AbilityTreePath.FIRST)) { @@ -50,6 +51,6 @@ public void execute(AbilityContext ctx) { @Override public BendingAi getAi(EntityLiving entity, Bender bender) { - return super.getAi(entity, bender); + return new AiInfernoPunch(this, entity, bender); } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityLightFire.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityLightFire.java index 76c1877da9..59bd33946c 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityLightFire.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityLightFire.java @@ -18,10 +18,8 @@ package com.crowsofwar.avatar.common.bending.fire; import com.crowsofwar.avatar.common.bending.Ability; -import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.AbilityData.AbilityTreePath; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; -import com.crowsofwar.avatar.common.data.ctx.PlayerBender; import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; import com.crowsofwar.avatar.common.particle.ParticleSpawner; import com.crowsofwar.gorecore.util.Vector; @@ -62,50 +60,53 @@ public boolean isUtility() { public void execute(AbilityContext ctx) { World world = ctx.getWorld(); - EntityLivingBase entity = ctx.getBenderEntity(); + // EntityLivingBase entity = ctx.getBenderEntity(); VectorI looking = ctx.getLookPosI(); EnumFacing side = ctx.getLookSide(); - if (ctx.isLookingAtBlock()) { - VectorI setAt = new VectorI(looking.x(), looking.y(), looking.z()); - setAt.offset(side); - BlockPos blockPos = setAt.toBlockPos(); - - double chance = 20 * ctx.getLevel() + 40; - chance += ctx.getPowerRating() / 10; - if (ctx.isMasterLevel(AbilityTreePath.FIRST)) { + if (ctx.isLookingAtBlock()) { + if (looking != null) { + VectorI setAt = new VectorI(looking.x(), looking.y(), looking.z()); + setAt.offset(side); + BlockPos blockPos = setAt.toBlockPos(); + + double chance = 20 * ctx.getLevel() + 40; + chance += ctx.getPowerRating() / 10; + + if (ctx.isMasterLevel(AbilityTreePath.FIRST)) { + + int yaw = (int) floor((ctx.getBenderEntity().rotationYaw * 8 / 360) + 0.5) & 7; + int x = 0, z = 0; + if (yaw == 1 || yaw == 2 || yaw == 3) x = -1; + if (yaw == 5 || yaw == 6 || yaw == 7) x = 1; + if (yaw == 3 || yaw == 4 || yaw == 5) z = -1; + if (yaw == 0 || yaw == 1 || yaw == 7) z = 1; + + if (spawnFire(world, blockPos, ctx, true, chance)) { + for (int i = 1; i < 5; i++) { + spawnFire(world, blockPos.add(x * i, 0, z * i), ctx, false, 100); + } + ctx.getAbilityData().addXp(SKILLS_CONFIG.litFire); + } - int yaw = (int) floor((ctx.getBenderEntity().rotationYaw * 8 / 360) + 0.5) & 7; - int x = 0, z = 0; - if (yaw == 1 || yaw == 2 || yaw == 3) x = -1; - if (yaw == 5 || yaw == 6 || yaw == 7) x = 1; - if (yaw == 3 || yaw == 4 || yaw == 5) z = -1; - if (yaw == 0 || yaw == 1 || yaw == 7) z = 1; + } else if (ctx.isMasterLevel(AbilityTreePath.SECOND)) { - if (spawnFire(world, blockPos, ctx, true, chance)) { - for (int i = 1; i < 5; i++) { - spawnFire(world, blockPos.add(x * i, 0, z * i), ctx, false, 100); + if (spawnFire(world, blockPos, ctx, true, chance)) { + spawnFire(world, blockPos.add(1, 0, 0), ctx, false, 100); + spawnFire(world, blockPos.add(-1, 0, 0), ctx, false, 100); + spawnFire(world, blockPos.add(0, 0, 1), ctx, false, 100); + spawnFire(world, blockPos.add(0, 0, -1), ctx, false, 100); + ctx.getAbilityData().addXp(SKILLS_CONFIG.litFire); } - ctx.getAbilityData().addXp(SKILLS_CONFIG.litFire); - } - } else if (ctx.isMasterLevel(AbilityTreePath.SECOND)) { - - if (spawnFire(world, blockPos, ctx, true, chance)) { - spawnFire(world, blockPos.add(1, 0, 0), ctx, false, 100); - spawnFire(world, blockPos.add(-1, 0, 0), ctx, false, 100); - spawnFire(world, blockPos.add(0, 0, 1), ctx, false, 100); - spawnFire(world, blockPos.add(0, 0, -1), ctx, false, 100); - ctx.getAbilityData().addXp(SKILLS_CONFIG.litFire); + } else { + if (spawnFire(world, blockPos, ctx, true, chance)) { + ctx.getAbilityData().addXp(SKILLS_CONFIG.litFire); + } } - } else { - if (spawnFire(world, blockPos, ctx, true, chance)) { - ctx.getAbilityData().addXp(SKILLS_CONFIG.litFire); - } } - } } @@ -114,7 +115,6 @@ private boolean spawnFire(World world, BlockPos blockPos, AbilityContext ctx, bo EntityLivingBase entity = ctx.getBenderEntity(); - if (world.isRainingAt(blockPos)) { particles.spawnParticles(world, EnumParticleTypes.CLOUD, 3, 7, ctx.getLookPos(), diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityPurify.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityPurify.java index a8b4fe8867..99c1ee7ac6 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityPurify.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AbilityPurify.java @@ -5,13 +5,15 @@ import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; -import com.google.common.math.Stats; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.potion.PotionEffect; +import static com.crowsofwar.avatar.common.AvatarChatMessages.MSG_PURIFY_COOLDOWN; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; +import static com.crowsofwar.avatar.common.data.TickHandlerController.PURIFY_COOLDOWN_HANDLER; +import static com.crowsofwar.avatar.common.data.TickHandlerController.PURIFY_PARTICLE_SPAWNER; import static net.minecraft.init.MobEffects.*; public class AbilityPurify extends Ability { @@ -42,10 +44,14 @@ public void execute(AbilityContext ctx) { chi = STATS_CONFIG.chiBuffLvl4; } - if (bender.consumeChi(chi)) { + if (data.hasTickHandler(PURIFY_COOLDOWN_HANDLER) && entity instanceof EntityPlayer) { + MSG_PURIFY_COOLDOWN.send(entity); + } + + if (bender.consumeChi(chi) && !data.hasTickHandler(PURIFY_COOLDOWN_HANDLER)) { // 3s base + 2s per level - int duration = 60 + 40 * abilityData.getLevel(); + int duration = abilityData.getLevel() > 0 ? 60 + 40 * abilityData.getLevel() : 60; if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { duration = 200; } @@ -81,32 +87,10 @@ public void execute(AbilityContext ctx) { } abilityData.addXp(SKILLS_CONFIG.buffUsed); + data.addTickHandler(PURIFY_PARTICLE_SPAWNER); } - } - - @Override - public int getCooldown(AbilityContext ctx) { - EntityLivingBase entity = ctx.getBenderEntity(); - - int coolDown = 200; - - if (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative()) { - coolDown = 0; - } - if (ctx.getLevel() == 1) { - coolDown = 180; - } - if (ctx.getLevel() == 2) { - coolDown = 160; - } - if (ctx.isMasterLevel(AbilityData.AbilityTreePath.FIRST)) { - coolDown = 120; - } - if (ctx.isMasterLevel(AbilityData.AbilityTreePath.SECOND)) { - coolDown = 120; - } - return coolDown; } + } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFireArc.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFireArc.java index 7ea2591c4b..f8e554449a 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFireArc.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFireArc.java @@ -56,8 +56,11 @@ protected AiFireArc(Ability ability, EntityLiving entity, Bender bender) { @Override protected void startExec() { + BendingData data = bender.getData(); velocityYaw = 0; velocityPitch = 0; + execAbility(); + data.getMiscData().setAbilityCooldown(80); } @Override @@ -88,16 +91,9 @@ public boolean shouldContinueExecuting() { entity.rotationPitch = targetPitch; } - if (timeExecuting == 20) { - BendingData data = bender.getData(); - data.chi().setMaxChi(10); - data.chi().setTotalChi(10); - data.chi().setAvailableChi(10); - execAbility(); - data.getMiscData().setAbilityCooldown(80); - } - if (timeExecuting >= 80) { + + if (timeExecuting >= 20) { BendingData data = bender.getData(); execStatusControl(StatusControl.THROW_FIRE); timeExecuting = 0; @@ -134,4 +130,4 @@ public void resetTask() { } -} +} \ No newline at end of file diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFireball.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFireball.java index 721d2fd70f..8f2dbcae60 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFireball.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFireball.java @@ -53,11 +53,8 @@ protected AiFireball(Ability ability, EntityLiving entity, Bender bender) { @Override protected void startExec() { BendingData data = bender.getData(); - data.chi().setMaxChi(10); - data.chi().setTotalChi(10); - data.chi().setAvailableChi(10); execAbility(); - data.getMiscData().setAbilityCooldown(100); + data.getMiscData().setAbilityCooldown(120); } @Override @@ -69,8 +66,7 @@ public boolean shouldContinueExecuting() { entity.rotationYaw = (float) toDegrees(rotations.y()); entity.rotationPitch = (float) toDegrees(rotations.x()); - if (timeExecuting >= 40) { - BendingData data = bender.getData(); + if (timeExecuting >= 15) { execStatusControl(StatusControl.THROW_FIREBALL); timeExecuting = 0; return false; @@ -83,7 +79,7 @@ public boolean shouldContinueExecuting() { @Override protected boolean shouldExec() { EntityLivingBase target = entity.getAttackTarget(); - return target != null && entity.getDistanceSq(target) > 4 * 4 + return target != null && entity.getDistance(target) > 4 && bender.getData().getMiscData().getAbilityCooldown() == 0 && entity.getRNG().nextBoolean(); } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFlamethrower.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFlamethrower.java index ef2836a313..97a0ff48df 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFlamethrower.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiFlamethrower.java @@ -20,14 +20,13 @@ import com.crowsofwar.avatar.common.bending.BendingAi; import com.crowsofwar.avatar.common.bending.StatusControl; import com.crowsofwar.avatar.common.data.Bender; -import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.BendingContext; import com.crowsofwar.avatar.common.util.Raytrace; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import static com.crowsofwar.avatar.common.data.TickHandlerController.FLAMETHROWER; import static com.crowsofwar.gorecore.util.Vector.getEntityPos; import static com.crowsofwar.gorecore.util.Vector.getRotationTo; import static java.lang.Math.toDegrees; @@ -42,9 +41,19 @@ protected AiFlamethrower(Ability ability, EntityLiving entity, Bender bender) { setMutexBits(2); } + @Override + public void resetTask() { + super.resetTask(); + bender.getData().removeStatusControl(StatusControl.START_FLAMETHROW); + bender.getData().removeTickHandler(FLAMETHROWER); + bender.getData().addStatusControl(StatusControl.STOP_FLAMETHROW); + } + @Override public boolean shouldContinueExecuting() { + + if (entity.getAttackTarget() == null) return false; Vector rotations = getRotationTo(getEntityPos(entity), getEntityPos(entity.getAttackTarget())); @@ -60,13 +69,15 @@ public boolean shouldContinueExecuting() { } - if (timeExecuting > 20) { + if (timeExecuting > 20 && timeExecuting < 60) { BendingContext ctx = new BendingContext(bender.getData(), entity, bender, new Raytrace.Result()); - TickHandler.FLAMETHROWER.tick(ctx); + FLAMETHROWER.tick(ctx); } - if (timeExecuting >= 80) { - BendingData data = bender.getData(); + if (timeExecuting >= 60) { + bender.getData().removeStatusControl(StatusControl.START_FLAMETHROW); + bender.getData().removeTickHandler(FLAMETHROWER); execStatusControl(StatusControl.STOP_FLAMETHROW); + return false; } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiInfernoPunch.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiInfernoPunch.java index 9e971e5125..c000e5f0bd 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiInfernoPunch.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/AiInfernoPunch.java @@ -3,8 +3,11 @@ import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.BendingAi; import com.crowsofwar.avatar.common.data.Bender; +import com.crowsofwar.avatar.common.data.BendingData; import net.minecraft.entity.EntityLiving; +import static com.crowsofwar.avatar.common.bending.fire.StatCtrlInfernoPunch.INFERNO_PUNCH; + public class AiInfernoPunch extends BendingAi { protected AiInfernoPunch(Ability ability, EntityLiving entity, Bender bender) { @@ -13,11 +16,23 @@ protected AiInfernoPunch(Ability ability, EntityLiving entity, Bender bender) { @Override protected boolean shouldExec() { - return false; + return timeExecuting < 5; } @Override protected void startExec() { + BendingData data = bender.getData(); + execAbility(); + data.addStatusControl(INFERNO_PUNCH); + data.getMiscData().setAbilityCooldown(60); + + } + @Override + public void updateTask() { + timeExecuting++; } + + + } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireDevourHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireDevourHandler.java new file mode 100644 index 0000000000..c04a56b850 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireDevourHandler.java @@ -0,0 +1,40 @@ +package com.crowsofwar.avatar.common.bending.fire; + +import com.crowsofwar.avatar.AvatarInfo; +import com.crowsofwar.avatar.common.data.Bender; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.entity.mob.EntityBender; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; +import net.minecraftforge.event.entity.living.LivingEvent; +import net.minecraftforge.fml.common.Mod; + +import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; +import static com.crowsofwar.avatar.common.data.TickHandlerController.FIRE_DEVOUR_HANDLER; + + +@Mod.EventBusSubscriber(modid = AvatarInfo.MOD_ID) +public class FireDevourHandler { + + //@SubscribeEvent + public static void onShift(LivingEvent.LivingUpdateEvent event) { + Entity e = event.getEntity(); + World world = e.getEntityWorld(); + if (e == event.getEntity()) { + if (e instanceof EntityPlayer || e instanceof EntityBender) { + BendingData data = BendingData.get((EntityLivingBase) e); + Bender b = Bender.get((EntityLivingBase) e); + if (b != null) { + if (e.isSneaking() && STATS_CONFIG.shiftActivateFireDevour) { + if (data.hasBendingId(Firebending.ID)) { + data.addTickHandler(FIRE_DEVOUR_HANDLER); + } + + } + } + } + } + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireDevourPowerModifier.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireDevourPowerModifier.java new file mode 100644 index 0000000000..3b05c3684a --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireDevourPowerModifier.java @@ -0,0 +1,17 @@ +package com.crowsofwar.avatar.common.bending.fire; + +import com.crowsofwar.avatar.common.data.PowerRatingModifier; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; + +public class FireDevourPowerModifier extends PowerRatingModifier { + private double powerRating; + + public void setPowerRating(double rating) { + this.powerRating = rating; + } + + @Override + public double get(BendingContext ctx) { + return powerRating; + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireDevourTickHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireDevourTickHandler.java new file mode 100644 index 0000000000..598937b289 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireDevourTickHandler.java @@ -0,0 +1,94 @@ +package com.crowsofwar.avatar.common.bending.fire; + +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import com.crowsofwar.avatar.common.util.Raytrace; +import com.crowsofwar.gorecore.util.Vector; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import java.util.Objects; +import java.util.function.BiPredicate; + +import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; +import static java.lang.Math.toRadians; + +public class FireDevourTickHandler extends TickHandler { + + private int fireConsumed = 0; + private int handlerLength = 20; + + public FireDevourTickHandler(int id) { + super(id); + } + + @Override + public boolean tick(BendingContext ctx) { + World world = ctx.getWorld(); + EntityLivingBase entity = ctx.getBenderEntity(); + BendingData data = ctx.getData(); + if (data.getTickHandlerDuration(this) < 2) { + fireConsumed = 0; + } + + double inverseRadius = (20F - ctx.getData().getTickHandlerDuration(this)) / 10; + Vector eye = Vector.getEyePos(entity); + double range = STATS_CONFIG.fireSearchRadius; + for (int i = 0; i < STATS_CONFIG.fireAngles; i++) { + for (int j = 0; j < STATS_CONFIG.fireAngles; j++) { + + double yaw = entity.rotationYaw + i * 360.0 / STATS_CONFIG.fireAngles; + double pitch = entity.rotationPitch + j * 360.0 / STATS_CONFIG.fireAngles; + + BiPredicate isFire = (pos, state) -> state.getBlock() == Blocks.FIRE; + + Vector angle = Vector.toRectangular(toRadians(yaw), toRadians(pitch)); + Raytrace.Result result = Raytrace.predicateRaytrace(world, eye, angle, range, isFire); + + if (result.hitSomething() && result.getPosPrecise() != null) { + if (world instanceof WorldServer) { + WorldServer World = (WorldServer) world; + for (double k = 1.2; k > 0; k -= 0.2) { + for (int h = 0; h < 12; h++) { + Vector lookpos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + + h * 30), 0).times(k).withY(entity.getEyeHeight() / 2); + World.spawnParticle(EnumParticleTypes.FLAME, lookpos.x() + entity.posX, lookpos.y() + entity.getEntityBoundingBox().minY, + lookpos.z() + entity.posZ, 2, 0, 0, 0, 0.05); + } + } + + } + world.setBlockToAir(result.getPosPrecise().toBlockPos()); + fireConsumed++; + handlerLength += 10; + FireDevourPowerModifier modifier = new FireDevourPowerModifier(); + /*if (data.getPowerRatingManager(Firebending.ID).hasModifier(FireDevourPowerModifier.class)) { + if (data.getPowerRatingManager(Firebending.ID).getModifiers() != null) { + if (data.getPowerRatingManager(Firebending.ID).getModifiers().contains(new FireDevourPowerModifier())) { + data.getPowerRatingManager(Firebending.ID).removeModifier(new FireDevourPowerModifier(), ctx); + } + } + }**/ + + Objects.requireNonNull(data.getPowerRatingManager(Firebending.ID)).clearModifiers(ctx); + double power = Objects.requireNonNull(data.getPowerRatingManager(Firebending.ID)).getRating(ctx); + modifier.setTicks(handlerLength); + modifier.setPowerRating((fireConsumed * 5) + power); + Objects.requireNonNull(data.getPowerRatingManager(Firebending.ID)).addModifier(modifier, ctx); + + } + + } + } + if (entity instanceof EntityPlayer) { + return !entity.isSneaking(); + } else return data.getTickHandlerDuration(this) >= handlerLength; + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireParticleSpawner.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireParticleSpawner.java index 6e6f761d63..0514ff07de 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireParticleSpawner.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireParticleSpawner.java @@ -4,13 +4,17 @@ import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.BendingContext; -import com.crowsofwar.avatar.common.particle.ClientParticleSpawner; +import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; import com.crowsofwar.avatar.common.particle.ParticleSpawner; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLivingBase; public class FireParticleSpawner extends TickHandler { - private static final ParticleSpawner particles = new ClientParticleSpawner(); + private static final ParticleSpawner particles = new NetworkParticleSpawner(); + + public FireParticleSpawner(int id) { + super(id); + } @Override public boolean tick(BendingContext ctx) { diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FirePassiveHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FirePassiveHandler.java new file mode 100644 index 0000000000..e13ce03ca3 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FirePassiveHandler.java @@ -0,0 +1,41 @@ +package com.crowsofwar.avatar.common.bending.fire; + +import com.crowsofwar.avatar.AvatarInfo; +import com.crowsofwar.avatar.common.data.Bender; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.entity.mob.EntityBender; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.MobEffects; +import net.minecraft.potion.PotionEffect; +import net.minecraftforge.event.entity.living.LivingEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +@Mod.EventBusSubscriber(modid = AvatarInfo.MOD_ID) +public class FirePassiveHandler { + + @SubscribeEvent + public static void fireResistance(LivingEvent.LivingUpdateEvent event) { + if (event.getEntity() instanceof EntityLivingBase) { + EntityLivingBase entity = event.getEntityLiving(); + if (entity instanceof EntityBender || entity instanceof EntityPlayer) { + Bender b = Bender.get(entity); + if (b != null) { + BendingData data = b.getData(); + if (data != null) { + if (data.hasBendingId(Firebending.ID)) { + if (entity.ticksExisted % 400 == 0) { + if (entity.world.isDaytime()) { + if (b.calcPowerRating(Firebending.ID) >= 35) { + entity.addPotionEffect(new PotionEffect(MobEffects.FIRE_RESISTANCE, 400, -1)); + } + } + } + } + } + } + } + } + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireResistanceHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireResistanceHandler.java new file mode 100644 index 0000000000..ea5174a0c9 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireResistanceHandler.java @@ -0,0 +1,35 @@ +package com.crowsofwar.avatar.common.bending.fire; + +import com.crowsofwar.avatar.AvatarInfo; +import com.crowsofwar.avatar.common.entity.AvatarEntity; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.MobEffects; +import net.minecraftforge.event.entity.living.LivingHurtEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.util.Objects; + +@Mod.EventBusSubscriber(modid = AvatarInfo.MOD_ID) +public class FireResistanceHandler { + + @SubscribeEvent + public static void onEntityHurtWithFire(LivingHurtEvent event) { + Entity e = event.getEntity(); + Entity source = event.getSource().getImmediateSource(); + float amount = event.getAmount(); + if (e instanceof EntityLivingBase) { + EntityLivingBase entity = (EntityLivingBase) e; + if (source != null) { + if (source instanceof AvatarEntity) { + if (entity.isPotionActive(MobEffects.FIRE_RESISTANCE)) { + if (((AvatarEntity) source).getElement() instanceof Firebending) { + event.setAmount(amount - (Objects.requireNonNull(entity.getActivePotionEffect(MobEffects.FIRE_RESISTANCE)).getAmplifier() + 1) / 2F); + } + } + } + } + } + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireSmashGroundHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireSmashGroundHandler.java index bd4efe4e91..cd84cbe7cd 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireSmashGroundHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireSmashGroundHandler.java @@ -16,12 +16,13 @@ */ package com.crowsofwar.avatar.common.bending.fire; - +import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.air.SmashGroundHandler; +import net.minecraft.block.Block; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.Blocks; import net.minecraft.init.SoundEvents; import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; /** @@ -29,16 +30,33 @@ */ public class FireSmashGroundHandler extends SmashGroundHandler { + public FireSmashGroundHandler(int id) { + super(id); + } + + @Override + protected EnumParticleTypes getParticle() { + return EnumParticleTypes.FLAME; + } + + @Override + protected int getParticleAmount() { + return 4; + } + @Override - protected void smashEntity(EntityLivingBase target, EntityLivingBase entity) { - super.smashEntity(target, entity); - entity.world.playSound(null, target.posX, target.posY, target.posZ, - SoundEvents.ITEM_FIRECHARGE_USE, SoundCategory.PLAYERS, 1, 1); + protected int getPerformanceAmount() { + return 7; } @Override protected double getRange() { - return 2; + return 3; + } + + @Override + protected double getParticleSpeed() { + return 1.5; } @Override @@ -47,27 +65,35 @@ protected SoundEvent getSound() { } @Override - protected int getNumberOfParticles() { - return 10; + protected float getKnockbackHeight() { + return 0.075F; } @Override - protected EnumParticleTypes getParticle() { - return EnumParticleTypes.FLAME; + protected double getSpeed() { + return 3.5; } @Override - protected float getParticleSpeed() { - return 0.1F; + protected Ability getAbility() { + return new AbilityFireJump(); } @Override - protected float getKnockbackHeight() { - return 0.25F; + protected boolean isFire() { + return true; } @Override - protected double getSpeed() { - return 2; + protected int fireTime() { + return 5; + } + + @Override + protected void smashEntity(EntityLivingBase entity) { + Block currentBlock = entity.world.getBlockState(entity.getPosition()).getBlock(); + if (currentBlock == Blocks.AIR) { + super.smashEntity(entity); + } } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireSmashGroundHandlerBig.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireSmashGroundHandlerBig.java index dd84c846c7..3975ed48f0 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireSmashGroundHandlerBig.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireSmashGroundHandlerBig.java @@ -16,8 +16,11 @@ */ package com.crowsofwar.avatar.common.bending.fire; +import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.air.SmashGroundHandler; +import net.minecraft.block.Block; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.Blocks; import net.minecraft.init.SoundEvents; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.SoundCategory; @@ -28,27 +31,23 @@ */ public class FireSmashGroundHandlerBig extends SmashGroundHandler { - @Override - protected void smashEntity(EntityLivingBase target, EntityLivingBase entity) { - super.smashEntity(target, entity); - target.setFire(4); - entity.world.playSound(null, target.posX, target.posY, target.posZ, - SoundEvents.ITEM_FIRECHARGE_USE, SoundCategory.PLAYERS, 1, 1); + public FireSmashGroundHandlerBig(int id) { + super(id); } @Override protected double getRange() { - return 4; + return 5; } @Override protected double getSpeed() { - return 8; + return 6; } @Override - protected int getNumberOfParticles() { - return 10; + protected int getParticleAmount() { + return 8; } @Override @@ -67,8 +66,8 @@ protected SoundCategory getSoundCategory() { } @Override - protected float getParticleSpeed() { - return 0.175F; + protected double getParticleSpeed() { + return 2.25; } @Override @@ -78,7 +77,34 @@ protected float getDamage() { @Override protected float getKnockbackHeight() { - return 0.75F; + return 0.15F; + } + + @Override + protected Ability getAbility() { + return new AbilityFireJump(); + } + + @Override + protected boolean isFire() { + return true; } + @Override + protected int getPerformanceAmount() { + return 15; + } + + @Override + protected int fireTime() { + return 15; + } + + @Override + protected void smashEntity(EntityLivingBase entity) { + Block currentBlock = entity.world.getBlockState(entity.getPosition()).getBlock(); + if (currentBlock == Blocks.AIR) { + super.smashEntity(entity); + } + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireStatusControlHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireStatusControlHandler.java index 5e7935d004..8eebd25802 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireStatusControlHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FireStatusControlHandler.java @@ -7,13 +7,17 @@ import com.crowsofwar.avatar.common.entity.AvatarEntity; import com.crowsofwar.avatar.common.entity.EntityFireArc; import com.crowsofwar.avatar.common.entity.EntityFireball; -import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.world.World; public class FireStatusControlHandler extends TickHandler { private int ticks = 0; + + public FireStatusControlHandler(int id) { + super(id); + } + @Override public boolean tick(BendingContext ctx) { World world = ctx.getWorld(); @@ -21,7 +25,6 @@ public boolean tick(BendingContext ctx) { BendingData data = ctx.getData(); int duration = data.getTickHandlerDuration(this); - EntityFireball ball = AvatarEntity.lookupControlledEntity(world, EntityFireball.class, entity); if (ball == null && data.hasStatusControl(StatusControl.THROW_FIREBALL)) { ticks++; diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FlamethrowerUpdateTick.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FlamethrowerUpdateTick.java index 1513ba6195..c8b3ef1a9f 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/FlamethrowerUpdateTick.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/FlamethrowerUpdateTick.java @@ -39,9 +39,12 @@ */ public class FlamethrowerUpdateTick extends TickHandler { + public FlamethrowerUpdateTick(int id) { + super(id); + } + @Override public boolean tick(BendingContext ctx) { - BendingData data = ctx.getData(); EntityLivingBase entity = ctx.getBenderEntity(); Bender bender = ctx.getBender(); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/InfernoPunchParticleSpawner.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/InfernoPunchParticleSpawner.java index bbd89bca04..ee98d7d56a 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/InfernoPunchParticleSpawner.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/InfernoPunchParticleSpawner.java @@ -1,27 +1,57 @@ package com.crowsofwar.avatar.common.bending.fire; -import com.crowsofwar.avatar.common.bending.StatusControl; +import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import com.crowsofwar.avatar.common.util.AvatarUtils; +import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumHandSide; import net.minecraft.util.EnumParticleTypes; import net.minecraft.world.World; import net.minecraft.world.WorldServer; +import static com.crowsofwar.avatar.common.bending.fire.StatCtrlInfernoPunch.INFERNO_PUNCH; + public class InfernoPunchParticleSpawner extends TickHandler { + + public InfernoPunchParticleSpawner(int id) { + super(id); + } + @Override public boolean tick(BendingContext ctx) { EntityLivingBase entity = ctx.getBenderEntity(); BendingData data = ctx.getData(); World world = ctx.getWorld(); - if (data.hasStatusControl(StatusControl.INFERNO_PUNCH) && !world.isRemote) { + AbilityData abilityData = AbilityData.get(entity, "inferno_punch"); + + int particleCount = 1; + if (abilityData.getLevel() == 1) { + particleCount = 2; + } + if (abilityData.getLevel() == 2) { + particleCount = 3; + } + if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + particleCount = 5; + } + if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + particleCount = 4; + } + if (data.hasStatusControl(INFERNO_PUNCH) && !world.isRemote) { WorldServer World = (WorldServer) world; - if (data.getTickHandlerDuration(this) % 5 == 0) { - double y = entity.posY + entity.getEyeHeight() - 0.65; - World.spawnParticle(EnumParticleTypes.FLAME, entity.posX, y, entity.posZ, 20, 0, 0, 0, 0.015); + Vector pos = AvatarUtils.getRightSide(entity, 0.55).plus(0, 0.8, 0); + Vector direction = Vector.getLookRectangular(entity); + + if (entity instanceof EntityPlayer && entity.getPrimaryHand() == EnumHandSide.LEFT) { + pos = AvatarUtils.getLeftSide(entity, 0.55).plus(0, 1.8, 0); } + Vector hand = pos.plus(direction.times(0.6)); + World.spawnParticle(EnumParticleTypes.FLAME, hand.x(), hand.y(), hand.z(), particleCount, 0, 0, 0, 0.015); return false; } else return true; diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/PurifyCooldownHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/PurifyCooldownHandler.java new file mode 100644 index 0000000000..cf7b2307e9 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/PurifyCooldownHandler.java @@ -0,0 +1,45 @@ +package com.crowsofwar.avatar.common.bending.fire; + +import com.crowsofwar.avatar.common.data.AbilityData; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; + +public class PurifyCooldownHandler extends TickHandler { + + public PurifyCooldownHandler(int id) { + super(id); + } + + @Override + public boolean tick(BendingContext ctx) { + EntityLivingBase entity = ctx.getBenderEntity(); + BendingData data = ctx.getData(); + int duration = data.getTickHandlerDuration(this); + int coolDown = 140; + AbilityData aD = data.getAbilityData("purify"); + + if (aD.getLevel() == 1) { + coolDown = 130; + } + if (aD.getLevel() == 2) { + coolDown = 120; + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + coolDown = 130; + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + coolDown = 110; + } + + if (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative()) { + coolDown = 0; + } + + + return duration >= coolDown; + } +} + diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/PurifyParticleHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/PurifyParticleHandler.java new file mode 100644 index 0000000000..d5fc468879 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/PurifyParticleHandler.java @@ -0,0 +1,50 @@ +package com.crowsofwar.avatar.common.bending.fire; + +import com.crowsofwar.avatar.common.data.AbilityData; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; +import com.crowsofwar.avatar.common.particle.ParticleSpawner; +import com.crowsofwar.gorecore.util.Vector; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import java.util.Random; + + +public class PurifyParticleHandler extends TickHandler { + private final ParticleSpawner particles; + + public PurifyParticleHandler(int id) { + super(id); + particles = new NetworkParticleSpawner(); + } + + @Override + public boolean tick(BendingContext ctx) { + EntityLivingBase entity = ctx.getBenderEntity(); + BendingData data = ctx.getData(); + AbilityData aD = data.getAbilityData("purify"); + World world = ctx.getWorld(); + int duration = data.getTickHandlerDuration(this); + int immolateDuration = aD.getLevel() > 0 ? 60 + 40 * aD.getLevel() : 40; + //The particles take a while to disappear after the ability finishes- so you decrease the time the particles can spawn + Random rand = new Random(); + double r = rand.nextDouble(); + if (!world.isRemote) { + for (int i = 0; i < 18; i++) { + WorldServer World = (WorldServer) world; + int random = rand.nextInt(2) + 1; + r = random == 1 ? r : r * -1; + Vector location = Vector.toRectangular(Math.toRadians(entity.rotationYaw + (i * 20) + (r * 2)), 0).times(0.5).withY(entity.getEyeHeight() - 0.7); + particles.spawnParticles(world, EnumParticleTypes.FLAME, 1, 1, location.plus(Vector.getEntityPos(entity)), + new Vector(0.6, 1.8, 0.6)); + } + } + return duration >= immolateDuration; + } +} + diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlFireJump.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlFireJump.java index be5ba2b6e2..48225e6fc2 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlFireJump.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlFireJump.java @@ -9,12 +9,12 @@ import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.BendingContext; import com.crowsofwar.avatar.common.entity.AvatarEntity; import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; import com.crowsofwar.avatar.common.particle.ParticleSpawner; import com.crowsofwar.gorecore.util.Vector; +import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityAreaEffectCloud; import net.minecraft.entity.EntityHanging; @@ -23,6 +23,7 @@ import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityXPOrb; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; import net.minecraft.init.SoundEvents; import net.minecraft.network.play.server.SPacketEntityVelocity; import net.minecraft.util.EnumParticleTypes; @@ -35,7 +36,7 @@ import java.util.List; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; -import static com.crowsofwar.avatar.common.data.TickHandler.FIRE_PARTICLE_SPAWNER; +import static com.crowsofwar.avatar.common.data.TickHandlerController.*; public class StatCtrlFireJump extends StatusControl { public StatCtrlFireJump() { @@ -51,19 +52,17 @@ public boolean execute(BendingContext ctx) { World world = ctx.getWorld(); AbilityData abilityData = data.getAbilityData("fire_jump"); - boolean allowDoubleJump = abilityData.getLevel() == 3 - && abilityData.getPath() == AbilityData.AbilityTreePath.SECOND; + boolean allowDoubleJump = abilityData.getLevel() == 3 && abilityData.getPath() == AbilityData.AbilityTreePath.SECOND; // Figure out whether entity is on ground by finding collisions with // ground - if found a collision box, then is not on ground - List collideWithGround = world.getCollisionBoxes(entity, - entity.getEntityBoundingBox().grow(0.2, 1, 0.2)); + List collideWithGround = world.getCollisionBoxes(entity, entity.getEntityBoundingBox().grow(0.2, 1, 0.2)); boolean onGround = !collideWithGround.isEmpty() || entity.collidedVertically; if (onGround || (allowDoubleJump && bender.consumeChi(STATS_CONFIG.chiFireJump))) { int lvl = abilityData.getLevel(); - double jumpMultiplier = 0.2; + double jumpMultiplier = 0.4; float fallAbsorption = 3; double range = 2; double speed = 1; @@ -71,7 +70,7 @@ public boolean execute(BendingContext ctx) { int numberOfParticles = 5; double particleSpeed = 0.1; if (lvl >= 1) { - jumpMultiplier = 0.3; + jumpMultiplier = 0.5; fallAbsorption = 4; range = 2.5; damage = 1.5F; @@ -80,7 +79,7 @@ public boolean execute(BendingContext ctx) { particleSpeed = 0.125; } if (lvl >= 2) { - jumpMultiplier = 0.4; + jumpMultiplier = 0.65; fallAbsorption = 5; speed = 2; range = 3; @@ -89,7 +88,7 @@ public boolean execute(BendingContext ctx) { particleSpeed = 0.15; } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { - jumpMultiplier = 0.6; + jumpMultiplier = 0.8; fallAbsorption = 8; speed = 4; range = 5; @@ -100,7 +99,7 @@ public boolean execute(BendingContext ctx) { } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { - jumpMultiplier = 0.3; + jumpMultiplier = 0.4; fallAbsorption = 15; speed = 2.5; range = 3; @@ -108,17 +107,16 @@ public boolean execute(BendingContext ctx) { } if (abilityData.getLevel() == 2 || abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { - data.addTickHandler(TickHandler.SMASH_GROUND_FIRE); + data.addTickHandler(SMASH_GROUND_FIRE); } else if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { - data.addTickHandler(TickHandler.SMASH_GROUND_FIRE_BIG); + data.addTickHandler(SMASH_GROUND_FIRE_BIG); } // Calculate direction to jump -- in the direction the player is currently already going // For some reason, velocity is 0 here when player is walking, so must instead // calculate using delta position - Vector deltaPos = new Vector(entity.posX - entity.lastTickPosX, 0, entity.posZ - - entity.lastTickPosZ); + Vector deltaPos = new Vector(entity.posX - entity.lastTickPosX, 0, entity.posZ - entity.lastTickPosZ); double currentYaw = Vector.getRotationTo(Vector.ZERO, deltaPos).y(); // Just go forwards if not moving right now @@ -153,20 +151,20 @@ public boolean execute(BendingContext ctx) { ((EntityPlayerMP) entity).connection.sendPacket(new SPacketEntityVelocity(entity)); } - damageNearbyEntities(ctx, range, speed, damage, numberOfParticles, particleSpeed); + Block currentBlock = world.getBlockState(entity.getPosition()).getBlock(); + if (currentBlock == Blocks.AIR) { + damageNearbyEntities(ctx, range, speed, damage, numberOfParticles, particleSpeed); + } ParticleSpawner spawner = new NetworkParticleSpawner(); - spawner.spawnParticles(entity.world, AvatarParticles.getParticleFlames(), 15, 20, - new Vector(entity), new Vector(1, 0, 1)); + spawner.spawnParticles(entity.world, AvatarParticles.getParticleFlames(), 15, 20, new Vector(entity), new Vector(1, 0, 1)); data.addTickHandler(FIRE_PARTICLE_SPAWNER); data.getMiscData().setFallAbsorption(fallAbsorption); - abilityData.addXp(ConfigSkills.SKILLS_CONFIG.fireJump); - entity.world.playSound(null, new BlockPos(entity), SoundEvents.ENTITY_GHAST_SHOOT, - SoundCategory.PLAYERS, 1, .7f); + entity.world.playSound(null, new BlockPos(entity), SoundEvents.ENTITY_GHAST_SHOOT, SoundCategory.PLAYERS, 1, .7f); return true; @@ -181,9 +179,8 @@ private void damageNearbyEntities(BendingContext ctx, double range, double speed EntityLivingBase entity = ctx.getBenderEntity(); World world = entity.world; - AxisAlignedBB box = new AxisAlignedBB(entity.posX - range, entity.getEntityBoundingBox().minY, - entity.posZ - range, entity.posX + range, entity.posY + entity.getEyeHeight(), entity.posZ + range); - + AxisAlignedBB box = new AxisAlignedBB(entity.posX - range, entity.getEntityBoundingBox().minY, entity.posZ - range, entity.posX + range, + entity.posY + entity.getEyeHeight(), entity.posZ + range); if (!world.isRemote) { WorldServer World = (WorldServer) world; @@ -191,14 +188,12 @@ private void damageNearbyEntities(BendingContext ctx, double range, double speed for (int j = 0; j < 90; j++) { Vector lookPos; if (i >= 1) { - lookPos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + - j * 4), 0).times(i); + lookPos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + j * 4), 0).times(i); } else { - lookPos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + - j * 4), 0); + lookPos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + j * 4), 0); } World.spawnParticle(EnumParticleTypes.FLAME, lookPos.x() + entity.posX, entity.getEntityBoundingBox().minY, - lookPos.z() + entity.posZ, numberOfParticles, 0, 0, 0, particleSpeed / 4); + lookPos.z() + entity.posZ, numberOfParticles, 0, 0, 0, particleSpeed / 4); } i += range / 10; } @@ -229,8 +224,8 @@ private boolean canDamageEntity(Entity entity) { if (entity instanceof AvatarEntity && ((AvatarEntity) entity).getOwner() != entity) { return false; } - if (entity instanceof EntityHanging || entity instanceof EntityXPOrb || entity instanceof EntityItem || - entity instanceof EntityArmorStand || entity instanceof EntityAreaEffectCloud) { + if (entity instanceof EntityHanging || entity instanceof EntityXPOrb || entity instanceof EntityItem || entity instanceof EntityArmorStand + || entity instanceof EntityAreaEffectCloud) { return false; } else return entity.canBeCollidedWith() && entity.canBePushed(); } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlFirePulse.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlFirePulse.java new file mode 100644 index 0000000000..b91d0ee27b --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlFirePulse.java @@ -0,0 +1,4 @@ +package com.crowsofwar.avatar.common.bending.fire; + +public class StatCtrlFirePulse { +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlInfernoPunch.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlInfernoPunch.java index d6b5a11854..4f0fed3bc4 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlInfernoPunch.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlInfernoPunch.java @@ -8,24 +8,27 @@ import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.ctx.BendingContext; import com.crowsofwar.avatar.common.entity.AvatarEntity; +import com.crowsofwar.avatar.common.entity.EntityShockwave; import com.crowsofwar.avatar.common.entity.mob.EntityBender; import com.crowsofwar.avatar.common.util.AvatarUtils; import com.crowsofwar.avatar.common.util.Raytrace; -import com.crowsofwar.avatar.common.world.AvatarFireExplosion; import com.crowsofwar.gorecore.util.Vector; -import net.minecraft.entity.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityAreaEffectCloud; +import net.minecraft.entity.EntityHanging; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.boss.EntityDragon; import net.minecraft.entity.item.EntityArmorStand; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityXPOrb; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.MobEffects; import net.minecraft.init.SoundEvents; import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.event.entity.living.LivingAttackEvent; @@ -34,6 +37,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import java.util.List; +import java.util.Objects; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; import static com.crowsofwar.avatar.common.controls.AvatarControl.CONTROL_LEFT_CLICK; @@ -42,7 +46,7 @@ public class StatCtrlInfernoPunch extends StatusControl { public StatCtrlInfernoPunch() { - super(15, CONTROL_LEFT_CLICK, CrosshairPosition.LEFT_OF_CROSSHAIR); + super(18, CONTROL_LEFT_CLICK, CrosshairPosition.LEFT_OF_CROSSHAIR); } @@ -84,8 +88,8 @@ public boolean execute(BendingContext ctx) { living.attackEntityFrom(AvatarDamageSource.causeFireDamage(living, entity), damage - (i / 2F)); living.setFire(fireTime - (i / 2)); living.motionX += direction.x() * (knockBack - (i / 2F)); - living.motionY += direction.y() * knockBack >= 0 ? (direction.y() * knockBack / 3) : knockBack / 3; - living.motionZ += direction.z() * knockBack; + living.motionY += direction.y() * knockBack >= 0 ? (direction.y() * (knockBack / 10)) : knockBack / 10; + living.motionZ += direction.x() * (knockBack - (i / 2F)); living.isAirBorne = true; // this line is needed to prevent a bug where players will not be pushed in multiplayer AvatarUtils.afterVelocityAdded(e); @@ -96,9 +100,9 @@ public boolean execute(BendingContext ctx) { } e.attackEntityFrom(AvatarDamageSource.causeFireDamage(e, entity), damage - (i / 2F)); - e.setFire(fireTime - (i / 2)); - e.motionX += direction.x() * (knockBack - (i / 2F)); - e.motionY += direction.y() * knockBack >= 0 ? (direction.y() * knockBack / 2) : knockBack / 2; + e.setFire(fireTime); + e.motionX += direction.x() * knockBack; + e.motionY += direction.y() * knockBack >= 0 ? (direction.y() * (knockBack / 8)) : knockBack / 8; e.motionZ += direction.z() * knockBack; e.isAirBorne = true; // this line is needed to prevent a bug where players will not be pushed in multiplayer @@ -122,111 +126,141 @@ public static void onInfernoPunch(LivingAttackEvent event) { Entity target = event.getEntity(); DamageSource source = event.getSource(); World world = target.getEntityWorld(); - if (entity instanceof EntityLivingBase) { - if (event.getSource().getTrueSource() == entity && (entity instanceof EntityBender || entity instanceof EntityPlayer)) { - Bender ctx = Bender.get((EntityLivingBase) entity); - if (ctx.getData() != null) { - Vector direction = Vector.getLookRectangular(entity); - AbilityData abilityData = ctx.getData().getAbilityData("inferno_punch"); - float knockBack = 1F; - int fireTime = 5; - float damageModifier = (float) (ctx.calcPowerRating(Firebending.ID) / 100); - float damage = STATS_CONFIG.InfernoPunchDamage + (2 * damageModifier); - - if (abilityData.getLevel() >= 1) { - damage = 4 + (2 * damageModifier); - knockBack = 1.125F; - fireTime = 6; - } else if (abilityData.getLevel() >= 2) { - damage = 5 + (2 * damageModifier); - knockBack = 1.25F; - fireTime = 8; - } - if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { - damage = 10 + (2 * damageModifier); - knockBack = 1.5F; - fireTime = 15; - } - if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { - damage = STATS_CONFIG.InfernoPunchDamage * 1.333F + (2 * damageModifier); - knockBack = 0.75F; - fireTime = 4; - } - if (ctx.getData().hasStatusControl(INFERNO_PUNCH)) { - if (((EntityLivingBase) entity).getHeldItemMainhand() == ItemStack.EMPTY && !(source.getDamageType().startsWith("avatar_"))) { + if (entity instanceof EntityLivingBase) { + if (event.getSource().getTrueSource() == entity && (entity instanceof EntityBender || entity instanceof EntityPlayer)) { + Bender ctx = Bender.get((EntityLivingBase) entity); + if (ctx != null) { + if (ctx.getData() != null) { + Vector direction = Vector.getLookRectangular(entity); + AbilityData abilityData = ctx.getData().getAbilityData("inferno_punch"); + float powerModifier = (float) (ctx.calcPowerRating(Firebending.ID) / 100); + float damage = STATS_CONFIG.InfernoPunchDamage + (2 * powerModifier); + float knockBack = 1 + powerModifier; + int fireTime = 5 + (int) (powerModifier * 10); + + if (abilityData.getLevel() >= 1) { + damage = 4 + (2 * powerModifier); + knockBack = 1.125F + powerModifier; + fireTime = 6; + } + if (abilityData.getLevel() >= 2) { + damage = 5 + (2 * powerModifier); + knockBack = 1.25F + powerModifier; + fireTime = 8 + (int) (powerModifier * 10); + } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { - BlockPos blockPos = target.getPosition(); - AvatarFireExplosion fireExplosion = new AvatarFireExplosion(target.world, target, blockPos.getX(), blockPos.getY(), blockPos.getZ(), 3F, true, false); - fireExplosion.doExplosionA(); - if (world instanceof WorldServer) { - WorldServer World = (WorldServer) target.getEntityWorld(); - World.spawnParticle(EnumParticleTypes.FLAME, target.posX, target.posY, target.posZ, 200, 0.05, 0.05, 0.05, 0.75); - fireExplosion.doExplosionB(true); - } + damage = 7 + (2 * powerModifier); + knockBack = 1.5F + powerModifier; + fireTime = 15 + (int) (powerModifier * 10); } - if (world instanceof WorldServer) { - WorldServer World = (WorldServer) target.getEntityWorld(); - World.spawnParticle(EnumParticleTypes.FLAME, target.posX, target.posY + target.getEyeHeight(), target.posZ, 50, 0.05, 0.05, 0.05, 0.05); - + if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + damage = STATS_CONFIG.InfernoPunchDamage * 1.333F + (2 * powerModifier); + knockBack = 0.75F + powerModifier; + fireTime = 4 + (int) (powerModifier * 10); } - world.playSound(null, target.posX, target.posY, target.posZ, SoundEvents.ENTITY_GHAST_SHOOT, - SoundCategory.HOSTILE, 4.0F, (1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F); - - if (target.canBePushed() && target.canBeCollidedWith()) { - target.attackEntityFrom(DamageSource.IN_FIRE, damage); - target.setFire(fireTime); - target.motionX += direction.x() * knockBack; - target.motionY += direction.y() * knockBack >= 0 ? knockBack / 2 + (direction.y() * knockBack / 2) : knockBack / 2; - target.motionZ += direction.z() * knockBack; - target.isAirBorne = true; - abilityData.addXp(4 - abilityData.getLevel()); - // this line is needed to prevent a bug where players will not be pushed in multiplayer - AvatarUtils.afterVelocityAdded(target); + if (((EntityLivingBase) entity).isPotionActive(MobEffects.STRENGTH)) { + damage += (Objects.requireNonNull(((EntityLivingBase) entity).getActivePotionEffect(MobEffects.STRENGTH)).getAmplifier() + 1) / 2F; } - if (!(target instanceof EntityDragon)) { - ctx.getData().removeStatusControl(INFERNO_PUNCH); + + if (ctx.getData().hasStatusControl(INFERNO_PUNCH)) { + if (((EntityLivingBase) entity).getHeldItemMainhand() == ItemStack.EMPTY && !(source.getDamageType().startsWith("avatar_"))) { + if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + EntityShockwave wave = new EntityShockwave(world); + wave.setPerformanceAmount(15); + wave.setFire(true); + wave.setFireTime(15); + wave.setSphere(true); + wave.setParticle(EnumParticleTypes.FLAME); + wave.setParticleSpeed(1.1); + //Since particles are spawned with the custom particle system, you need a higher speed than normal. Using + //Mincraft's World.spawnParticle, however, would require a much lower speed: ~10x lower + wave.setParticleAmount(1); + wave.setParticleController(20); + //Used for spheres + wave.setSpeed(0.8); + wave.setParticleAmount(2); + wave.setAbility(new AbilityInfernoPunch()); + wave.setDamage(3); + wave.setOwner((EntityLivingBase) entity); + wave.setPosition(target.posX, target.getEntityBoundingBox().minY, target.posZ); + wave.setRange(4); + wave.setKnockbackHeight(0.2); + world.spawnEntity(wave); + } + if (world instanceof WorldServer) { + WorldServer World = (WorldServer) target.getEntityWorld(); + for (double angle = 0; angle < 360; angle += 15) { + Vector pos = AvatarUtils.getOrthogonalVector(Vector.getLookRectangular(entity), angle, 0.2); + World.spawnParticle(EnumParticleTypes.FLAME, target.posX + pos.x(), (target.posY + (target.getEyeHeight() / 1.25)) + pos.y(), target.posZ + pos.z(), + 4 + abilityData.getLevel(), 0.0, 0.0, 0.0, 0.03 + (abilityData.getLevel()/100F)); + } + + + } + + world.playSound(null, target.posX, target.posY, target.posZ, SoundEvents.ENTITY_GHAST_SHOOT, + SoundCategory.HOSTILE, 4.0F, (1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F); + + if (target.canBePushed() && target.canBeCollidedWith()) { + target.attackEntityFrom(AvatarDamageSource.FIRE, damage); + target.setFire(fireTime); + target.motionX += direction.x() * knockBack; + target.motionY += direction.y() * knockBack >= 0 ? knockBack / 2 + (direction.y() * knockBack / 2) : knockBack / 2; + target.motionZ += direction.z() * knockBack; + target.isAirBorne = true; + abilityData.addXp(4 - abilityData.getLevel()); + // this line is needed to prevent a bug where players will not be pushed in multiplayer + AvatarUtils.afterVelocityAdded(target); + } + if (!(target instanceof EntityDragon)) { + ctx.getData().removeStatusControl(INFERNO_PUNCH); + } + } } } } } } } - } + @SubscribeEvent public static void onDragonHurt(LivingHurtEvent event) { - EntityLivingBase entity = (EntityLivingBase) event.getSource().getTrueSource(); - Entity target = event.getEntity(); - if (entity instanceof EntityPlayer || entity instanceof EntityBender) { - BendingData data = BendingData.get(entity); - if (data != null) { - AbilityData aD = AbilityData.get(entity, "inferno_punch"); - Bender ctx = Bender.get(entity); - float damageModifier = (float) (ctx.calcPowerRating(Firebending.ID) / 100); - float damage = STATS_CONFIG.InfernoPunchDamage + (2 * damageModifier); - if (data.hasStatusControl(INFERNO_PUNCH) && !(event.getSource().getDamageType().equals("avatar_groundSmash")) && - !(event.getSource().getDamageType().equals("avatar_Air"))) { - if (entity.getHeldItemMainhand() == ItemStack.EMPTY) { - if (aD.getLevel() >= 1) { - damage = 4 + (2 * damageModifier); - } else if (aD.getLevel() >= 2) { - damage = 5 + (2 * damageModifier); - } - if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { - damage = 10 + (2 * damageModifier); - } - if (aD.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { - damage = STATS_CONFIG.InfernoPunchDamage * 1.333F + (2 * damageModifier); - } - if (target instanceof EntityDragon) { - event.setAmount(damage); - data.removeStatusControl(INFERNO_PUNCH); + if (event.getSource().getTrueSource() instanceof EntityLivingBase) { + EntityLivingBase entity = (EntityLivingBase) event.getSource().getTrueSource(); + Entity target = event.getEntity(); + if (entity instanceof EntityPlayer || entity instanceof EntityBender) { + BendingData data = BendingData.get(entity); + AbilityData aD = AbilityData.get(entity, "inferno_punch"); + Bender ctx = Bender.get(entity); + if (ctx != null) { + float damageModifier = (float) (ctx.calcPowerRating(Firebending.ID) / 100); + float damage = STATS_CONFIG.InfernoPunchDamage + (2 * damageModifier); + if (data.hasStatusControl(INFERNO_PUNCH) && !(event.getSource().getDamageType().equals("avatar_groundSmash")) && + !(event.getSource().getDamageType().equals("avatar_Air"))) { + if (entity.getHeldItemMainhand() == ItemStack.EMPTY) { + if (aD.getLevel() >= 1) { + damage = 4 + (2 * damageModifier); + } else if (aD.getLevel() >= 2) { + damage = 5 + (2 * damageModifier); + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + damage = 7 + (2 * damageModifier); + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + damage = STATS_CONFIG.InfernoPunchDamage * 1.333F + (2 * damageModifier); + } + if (target instanceof EntityDragon) { + event.setAmount(damage); + data.removeStatusControl(INFERNO_PUNCH); + } + } } } } } - } } + private boolean canDamageEntity(Entity entity) { if (entity instanceof AvatarEntity && ((AvatarEntity) entity).getOwner() != entity) { return false; diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlSetFlamethrowing.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlSetFlamethrowing.java index 6f105c03b5..a57db60481 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlSetFlamethrowing.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlSetFlamethrowing.java @@ -19,7 +19,6 @@ import com.crowsofwar.avatar.common.bending.StatusControl; import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.BendingContext; import net.minecraft.entity.EntityLivingBase; import net.minecraft.world.World; @@ -27,6 +26,7 @@ import static com.crowsofwar.avatar.common.bending.StatusControl.CrosshairPosition.RIGHT_OF_CROSSHAIR; import static com.crowsofwar.avatar.common.controls.AvatarControl.CONTROL_RIGHT_CLICK_DOWN; import static com.crowsofwar.avatar.common.controls.AvatarControl.CONTROL_RIGHT_CLICK_UP; +import static com.crowsofwar.avatar.common.data.TickHandlerController.FLAMETHROWER; /** * @author CrowsOfWar @@ -51,9 +51,9 @@ public boolean execute(BendingContext ctx) { if (data.hasBendingId(Firebending.ID)) { if (setting) { data.addStatusControl(STOP_FLAMETHROW); - data.addTickHandler(TickHandler.FLAMETHROWER); + data.addTickHandler(FLAMETHROWER); } else { - data.removeTickHandler(TickHandler.FLAMETHROWER); + data.removeTickHandler(FLAMETHROWER); } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlThrowFire.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlThrowFire.java index e8d8116f6a..960acd3426 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlThrowFire.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlThrowFire.java @@ -55,14 +55,14 @@ public boolean execute(BendingContext ctx) { AbilityData abilityData = data.getAbilityData("fire_arc"); double powerRating = bender.calcPowerRating(Firebending.ID); - double velocity = abilityData.getLevel() >= 1 ? 12 : 8; + double velocity = abilityData.getLevel() >= 1 ? 22 : 16; velocity += powerRating / 30; + fire.setBehavior(new FireArcBehavior.Thrown()); Vector force = Vector.toRectangular(Math.toRadians(entity.rotationYaw), Math.toRadians(entity.rotationPitch)); force = force.times(velocity); - fire.addVelocity(force); - fire.setBehavior(new FireArcBehavior.Thrown()); + fire.setVelocity(force); } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlThrowFireball.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlThrowFireball.java index a0e47a94cf..f73a714e96 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlThrowFireball.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatCtrlThrowFireball.java @@ -52,12 +52,10 @@ public boolean execute(BendingContext ctx) { if (fireball != null) { AbilityData abilityData = ctx.getData().getAbilityData("fireball"); - double speedMult = abilityData.getLevel() >= 2 ? 27.5 : 22.5; - fireball.addVelocity(fireball.velocity().dividedBy(-1)); - fireball.addVelocity(Vector.getLookRectangular(entity).times(speedMult)); - //Necessary so that you can't increase speed by moving your mouse really fast; additionally, - //using setVelocity sometimes makes the fireball go invisible. Weird. + double speedMult = abilityData.getLevel() >= 2 ? 32.5 : 27.5; fireball.setBehavior(new FireballBehavior.Thrown()); + fireball.setVelocity(Vector.getLookRectangular(entity).times(speedMult)); + } return true; diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatlCtrlFireShield.java b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatlCtrlFireShield.java new file mode 100644 index 0000000000..6da3a67dc3 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/fire/StatlCtrlFireShield.java @@ -0,0 +1,4 @@ +package com.crowsofwar.avatar.common.bending.fire; + +public class StatlCtrlFireShield { +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AbilityLightningArc.java b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AbilityLightningArc.java index 5e3cb666c2..89a8d8bacc 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AbilityLightningArc.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AbilityLightningArc.java @@ -1,12 +1,11 @@ package com.crowsofwar.avatar.common.bending.lightning; import com.crowsofwar.avatar.common.bending.Ability; -import com.crowsofwar.avatar.common.data.Bender; -import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.*; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; +import static com.crowsofwar.avatar.common.data.TickHandlerController.LIGHTNING_CHARGE; /** * @author CrowsOfWar @@ -24,10 +23,10 @@ public void execute(AbilityContext ctx) { BendingData data = ctx.getData(); boolean hasChi = bender.consumeChi(STATS_CONFIG.chiLightning); - boolean hasLightningCharge = data.hasTickHandler(TickHandler.LIGHTNING_CHARGE); + boolean hasLightningCharge = data.hasTickHandler(LIGHTNING_CHARGE); if (hasChi && !hasLightningCharge) { - ctx.getData().addTickHandler(TickHandler.LIGHTNING_CHARGE); + ctx.getData().addTickHandler(LIGHTNING_CHARGE); } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AbilityLightningSpear.java b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AbilityLightningSpear.java index c972c36da6..b3009f021d 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AbilityLightningSpear.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AbilityLightningSpear.java @@ -32,6 +32,7 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.world.World; +import static com.crowsofwar.avatar.common.bending.lightning.StatCtrlThrowLightningSpear.THROW_LIGHTNINGSPEAR; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; import static com.crowsofwar.gorecore.util.Vector.getEyePos; import static com.crowsofwar.gorecore.util.Vector.getLookRectangular; @@ -42,8 +43,8 @@ public class AbilityLightningSpear extends Ability { public AbilityLightningSpear() { - super(Firebending.ID, "lightning_spear"); - requireRaytrace(2.5, false); + super(Lightningbending.ID, "lightning_spear"); + requireRaytrace(-1, false); } @Override @@ -55,25 +56,51 @@ public void execute(AbilityContext ctx) { BendingData data = ctx.getData(); AbilityData abilityData = ctx.getAbilityData(); - if (data.hasStatusControl(StatusControl.THROW_LIGHTNINGSPEAR)) return; + if (data.hasStatusControl(THROW_LIGHTNINGSPEAR)) return; - if (bender.consumeChi(STATS_CONFIG.chiCloudburst)) { + if (bender.consumeChi(STATS_CONFIG.chiLightningSpear)) { + + + float size = 1.2F; + float damage = 2F; + if (abilityData.getLevel() >= 2) { + damage = 8; + } + + if (ctx.getLevel() == 1) { + size = 1.4F; + damage = 3; + } + + if (ctx.getLevel() == 2) { + size = 1.6F; + damage = 4; + } + + if (ctx.isMasterLevel(AbilityTreePath.FIRST)) { + size = 1.2F; + damage = 6; + } + + if (ctx.isMasterLevel(AbilityTreePath.SECOND)) { + size = 2.2F; + damage = 5; + } + + damage *= ctx.getPowerRatingDamageMod(); + + EntityLightningSpear spear = new EntityLightningSpear(world); + spear.setSize(size); Vector target; if (ctx.isLookingAtBlock()) { target = ctx.getLookPos(); } else { Vector playerPos = getEyePos(entity); - target = playerPos.plus(getLookRectangular(entity).times(2.5)); + target = playerPos.plus(getLookRectangular(entity).times(spear.getSize())); } - float damage = 5F; - if (abilityData.getLevel() >= 2) { - damage = 8; - } - damage *= ctx.getPowerRatingDamageMod(); - EntityLightningSpear spear = new EntityLightningSpear(world); spear.setPosition(target); spear.setOwner(entity); spear.setBehavior(new LightningSpearBehavior.PlayerControlled()); @@ -82,13 +109,11 @@ public void execute(AbilityContext ctx) { spear.rotationYaw = entity.rotationYaw; spear.setPiercing(abilityData.isMasterPath(AbilityTreePath.FIRST)); spear.setAbility(this); - if (ctx.isMasterLevel(AbilityTreePath.SECOND)) { - spear.setSize(20); - spear.setGroupAttack(true); - } + spear.setDegreesPerSecond(400); + spear.setGroupAttack(abilityData.isMasterPath(AbilityTreePath.SECOND)); world.spawnEntity(spear); - data.addStatusControl(StatusControl.THROW_LIGHTNINGSPEAR); + data.addStatusControl(THROW_LIGHTNINGSPEAR); } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AiLightningSpear.java b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AiLightningSpear.java index 25903feadc..955361f0c0 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AiLightningSpear.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/AiLightningSpear.java @@ -12,6 +12,7 @@ import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import static com.crowsofwar.avatar.common.bending.lightning.StatCtrlThrowLightningSpear.THROW_LIGHTNINGSPEAR; import static com.crowsofwar.gorecore.util.Vector.getEntityPos; import static com.crowsofwar.gorecore.util.Vector.getRotationTo; import static java.lang.Math.toDegrees; @@ -51,7 +52,7 @@ public boolean shouldContinueExecuting() { if (timeExecuting >= 40) { BendingData data = bender.getData(); - execStatusControl(StatusControl.THROW_LIGHTNINGSPEAR); + execStatusControl(THROW_LIGHTNINGSPEAR); timeExecuting = 0; return false; } else { @@ -81,7 +82,7 @@ public void resetTask() { if (spear != null) { spear.setDead(); - bender.getData().removeStatusControl(StatusControl.THROW_LIGHTNINGSPEAR); + bender.getData().removeStatusControl(THROW_LIGHTNINGSPEAR); } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningChargeHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningChargeHandler.java index b3eb36038c..617dbd5df9 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningChargeHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningChargeHandler.java @@ -1,10 +1,13 @@ package com.crowsofwar.avatar.common.bending.lightning; +import com.crowsofwar.avatar.common.AvatarParticles; import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.BendingContext; import com.crowsofwar.avatar.common.entity.EntityLightningArc; +import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; +import com.crowsofwar.avatar.common.particle.ParticleSpawner; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; @@ -27,9 +30,13 @@ * @author CrowsOfWar */ public abstract class LightningChargeHandler extends TickHandler { + private static final UUID MOVEMENT_MODIFIER_ID = UUID.fromString("dfb6235c-82b6-407e-beaf-a48045735a82"); + private ParticleSpawner particleSpawner; - private static final UUID MOVEMENT_MODIFIER_ID = UUID.fromString - ("dfb6235c-82b6-407e-beaf-a48045735a82"); + LightningChargeHandler(int id) { + super(id); + this.particleSpawner = new NetworkParticleSpawner(); + } /** * Gets AbilityData to be used for determining lightning strength. This is normally the @@ -55,6 +62,16 @@ public boolean tick(BendingContext ctx) { float movementMultiplier = 0.6f - 0.7f * MathHelper.sqrt(duration / 40f); applyMovementModifier(entity, MathHelper.clamp(movementMultiplier, 0.1f, 1)); + double inverseRadius = (40F - duration) / 10; + + if (duration % 3 == 0) { + for (int i = 0; i < 8; i++) { + Vector lookpos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + + i * 45), 0).times(inverseRadius).withY(entity.getEyeHeight() / 2); + particleSpawner.spawnParticles(world, AvatarParticles.getParticleElectricity(), 1, 2, lookpos.x() + entity.posX, + lookpos.y() + entity.getEntityBoundingBox().minY, lookpos.z() + entity.posZ, 2, 1.2, 2); + } + } if (duration >= 40) { @@ -66,12 +83,12 @@ public boolean tick(BendingContext ctx) { double speed = abilityData.getLevel() >= 1 ? 20 : 30; float damage = abilityData.getLevel() >= 2 ? 8 : 6; float size = 1; - float[] turbulenceValues = {0.6f, 1.2f}; + float[] turbulenceValues = { 0.6f, 1.2f }; if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { damage = 12; size = 0.75f; - turbulenceValues = new float[]{0.6f, 1.2f, 0.8f}; + turbulenceValues = new float[] { 0.6f, 1.2f, 0.8f }; } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { size = 1.5f; @@ -84,8 +101,7 @@ public boolean tick(BendingContext ctx) { entity.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(MOVEMENT_MODIFIER_ID); - world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.ENTITY_GENERIC_EXPLODE, - SoundCategory.PLAYERS, 1, 2); + world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.PLAYERS, 1, 2); return true; @@ -95,8 +111,7 @@ public boolean tick(BendingContext ctx) { } - private void fireLightning(World world, EntityLivingBase entity, float damage, double speed, - float size, float[] turbulenceValues) { + private void fireLightning(World world, EntityLivingBase entity, float damage, double speed, float size, float[] turbulenceValues) { for (float turbulence : turbulenceValues) { @@ -105,8 +120,9 @@ private void fireLightning(World world, EntityLivingBase entity, float damage, d lightning.setTurbulence(turbulence); lightning.setDamage(damage); lightning.setSizeMultiplier(size); + lightning.setAbility(new AbilityLightningArc()); lightning.setMainArc(turbulence == turbulenceValues[0]); - + lightning.setPosition(Vector.getEyePos(entity)); lightning.setEndPos(Vector.getEyePos(entity)); @@ -122,13 +138,11 @@ private void fireLightning(World world, EntityLivingBase entity, float damage, d private void applyMovementModifier(EntityLivingBase entity, float multiplier) { - IAttributeInstance moveSpeed = entity.getEntityAttribute(SharedMonsterAttributes - .MOVEMENT_SPEED); + IAttributeInstance moveSpeed = entity.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); moveSpeed.removeModifier(MOVEMENT_MODIFIER_ID); - moveSpeed.applyModifier(new AttributeModifier(MOVEMENT_MODIFIER_ID, - "Lightning charge modifier", multiplier - 1, 1)); + moveSpeed.applyModifier(new AttributeModifier(MOVEMENT_MODIFIER_ID, "Lightning charge modifier", multiplier - 1, 1)); } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningCreateHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningCreateHandler.java index 778acf642a..71323fd03a 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningCreateHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningCreateHandler.java @@ -10,6 +10,10 @@ */ public class LightningCreateHandler extends LightningChargeHandler { + public LightningCreateHandler(int id) { + super(id); + } + @Override @Nullable protected AbilityData getLightningData(BendingContext ctx) { diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningRedirectHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningRedirectHandler.java index 7f712bc793..276e0e0899 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningRedirectHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/LightningRedirectHandler.java @@ -1,11 +1,10 @@ package com.crowsofwar.avatar.common.bending.lightning; -import com.crowsofwar.avatar.common.data.AbilityData; -import com.crowsofwar.avatar.common.data.BenderInfo; -import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.ctx.BendingContext; import net.minecraft.entity.EntityLivingBase; import net.minecraft.world.World; + +import com.crowsofwar.avatar.common.data.*; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; import org.joml.SimplexNoise; import javax.annotation.Nullable; @@ -17,6 +16,10 @@ */ public class LightningRedirectHandler extends LightningChargeHandler { + public LightningRedirectHandler(int id) { + super(id); + } + @Override @Nullable protected AbilityData getLightningData(BendingContext ctx) { @@ -33,8 +36,7 @@ protected AbilityData getLightningData(BendingContext ctx) { // No nullable warning here needed because if the originalShooter entity is present (as // guaranteed above), BendingData#get won't return null //noinspection ConstantConditions - return BendingData.get(world, originalShooter).getAbilityData - ("lightning_arc"); + return BendingData.get(world, originalShooter).getAbilityData("lightning_arc"); } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/StatCtrlThrowLightningSpear.java b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/StatCtrlThrowLightningSpear.java index b3250d0b2e..216d046815 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/lightning/StatCtrlThrowLightningSpear.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/lightning/StatCtrlThrowLightningSpear.java @@ -27,15 +27,16 @@ public boolean execute(BendingContext ctx) { if (spear != null) { AbilityData abilityData = ctx.getData().getAbilityData("lightning_spear"); - double speedMult = abilityData.getLevel() >= 1 ? 40 : 30; + double speedMult = abilityData.getLevel() >= 1 ? 60 : 50; if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { - speedMult = 70; + speedMult = 90; } - - spear.addVelocity(spear.velocity().times(-1)); - spear.addVelocity(Vector.getLookRectangular(entity).times(speedMult)); spear.setBehavior(new LightningSpearBehavior.Thrown()); + spear.setVelocity(Vector.getLookRectangular(entity).times(speedMult)); + Vector direction = spear.velocity().toSpherical(); + spear.rotationYaw = (float) Math.toDegrees(direction.y()); + spear.rotationPitch = (float) Math.toDegrees(direction.x()); } return true; diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityCleanse.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityCleanse.java index d237e593af..ded31638da 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityCleanse.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityCleanse.java @@ -12,9 +12,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; -import net.minecraft.init.Items; import net.minecraft.init.MobEffects; -import net.minecraft.item.ItemStack; import net.minecraft.potion.PotionEffect; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; @@ -25,8 +23,10 @@ import java.util.function.BiPredicate; import java.util.function.Consumer; +import static com.crowsofwar.avatar.common.AvatarChatMessages.MSG_CLEANSE_COOLDOWN; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; +import static com.crowsofwar.avatar.common.data.TickHandlerController.CLEANSE_COOLDOWN_HANDLER; import static java.lang.Math.toRadians; public class AbilityCleanse extends Ability { @@ -59,8 +59,8 @@ public void execute(AbilityContext ctx) { Vector targetPos = getClosestWaterBlock(entity, ctx.getLevel() * 3); - if ((bender.consumeChi(chi) && targetPos != null) || (entity instanceof EntityPlayerMP && ((EntityPlayerMP) entity).isCreative()) - || ctx.consumeWater(4)) { + if ((bender.consumeChi(chi) && targetPos != null && !data.hasTickHandler(CLEANSE_COOLDOWN_HANDLER)) || (entity instanceof EntityPlayerMP && ((EntityPlayerMP) entity).isCreative()) + || (ctx.consumeWater(4) && !data.hasTickHandler(CLEANSE_COOLDOWN_HANDLER))) { // Duration: 5-10s int duration = abilityData.getLevel() < 2 ? 100 : 200; @@ -85,6 +85,7 @@ public void execute(AbilityContext ctx) { if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { entity.addPotionEffect(new PotionEffect(MobEffects.WATER_BREATHING, duration)); entity.addPotionEffect(new PotionEffect(MobEffects.SPEED, duration, 1)); + entity.addPotionEffect(new PotionEffect(MobEffects.STRENGTH, duration)); } // Perform group heal? @@ -111,10 +112,12 @@ public void execute(AbilityContext ctx) { //noinspection ConstantConditions data.getPowerRatingManager(getBendingId()).addModifier(modifier, ctx); - } - else { + } else { bender.sendMessage("avatar.cleanseFail"); } + if (data.hasTickHandler(CLEANSE_COOLDOWN_HANDLER) && entity instanceof EntityPlayer) { + MSG_CLEANSE_COOLDOWN.send(entity); + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityCreateWave.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityCreateWave.java index 1bff999c47..477d099c6c 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityCreateWave.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityCreateWave.java @@ -26,12 +26,10 @@ import com.crowsofwar.avatar.common.util.Raytrace; import com.crowsofwar.gorecore.util.Vector; import com.crowsofwar.gorecore.util.VectorI; -import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Blocks; -import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; @@ -48,15 +46,69 @@ public void execute(AbilityContext ctx) { Bender bender = ctx.getBender(); World world = ctx.getWorld(); - Vector look = Vector.getLookRectangular(entity).withY(0); + Vector look = Vector.getLookRectangular(entity); Raytrace.Result result = Raytrace.predicateRaytrace(world, Vector.getEntityPos(entity).minusY(1) , look, 4 + ctx.getLevel(), (pos, blockState) -> blockState.getBlock() == Blocks .WATER); - Raytrace.Result extraResult = Raytrace.predicateRaytrace(world, Vector.getEntityPos(entity).minusY(1), look, + /*Raytrace.Result extraResult = Raytrace.predicateRaytrace(world, Vector.getEntityPos(entity).minusY(1), look, 4 + ctx.getLevel(), (blockPos, iBlockState) -> iBlockState.getBlock() == Blocks.SNOW || iBlockState.getBlock() == Blocks.FLOWING_WATER - || iBlockState.getBlock() == Blocks.ICE); + || iBlockState.getBlock() == Blocks.ICE);**/ - if (result.hitSomething() || extraResult.hitSomething()) { + /*Raytrace.Result rayTraceResult = Raytrace.getTargetBlock(entity, 4 + ctx.getLevel(), true); + + if (rayTraceResult.hitSomething() && rayTraceResult.getPos() != null) { + Block hitBlock = world.getBlockState(rayTraceResult.getPos().toBlockPos()).getBlock(); + if (STATS_CONFIG.waterBendableBlocks.contains(hitBlock)) { + VectorI pos = rayTraceResult.getPos(); + assert pos != null; + IBlockState up = world.getBlockState(pos.toBlockPos().up()); + if (up.getBlock() == Blocks.AIR) { + if (bender.consumeChi(STATS_CONFIG.chiWave)) { + + float size = 2; + double speed = 6.5; + if (ctx.isMasterLevel(AbilityTreePath.FIRST)) { + speed = 12.5; + size = 5F; + } + if (ctx.isMasterLevel(AbilityTreePath.SECOND)) { + speed = 17; + size = 2.75F; + } + if (ctx.getLevel() == 1) { + size = 2.5F; + speed = 8; + } + if (ctx.getLevel() == 2) { + size = 3; + speed = 10; + } + + size += ctx.getPowerRating() / 100; + + speed += ctx.getPowerRating() / 100 * 8; + + EntityWave wave = new EntityWave(world); + wave.setOwner(entity); + wave.setVelocity(look.times(speed)); + wave.setPosition(pos.x(), pos.y(), pos.z()); + wave.setAbility(this); + wave.rotationYaw = (float) Math.toDegrees(look.toSpherical().y()); + + float damageMult = ctx.getLevel() >= 1 ? 1.5f : 1; + damageMult *= ctx.getPowerRatingDamageMod(); + wave.setDamageMultiplier(damageMult); + wave.setWaveSize(size); + + wave.setCreateExplosion(ctx.isMasterLevel(AbilityTreePath.SECOND)); + world.spawnEntity(wave); + + } + } + } + + }**/ + if (result.hitSomething()) { VectorI pos = result.getPos(); //IBlockState hitBlockState = world.getBlockState(pos.toBlockPos()); @@ -114,7 +166,7 @@ public void execute(AbilityContext ctx) { pos.add(0, 1, 0); } - } else if (ctx.consumeWater(2)) { + } /*else if (ctx.consumeWater(2)) { for (int i = 0; i < 3; i++) { if (bender.consumeChi(STATS_CONFIG.chiWave)) { @@ -160,7 +212,7 @@ public void execute(AbilityContext ctx) { } } - } + }**/ } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterArc.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterArc.java index c9188d0de2..100b172727 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterArc.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterArc.java @@ -29,15 +29,15 @@ import com.crowsofwar.avatar.common.util.Raytrace; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import java.util.List; import java.util.function.BiPredicate; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; @@ -64,6 +64,28 @@ public void execute(AbilityContext ctx) { Vector targetPos = getClosestWaterbendableBlock(entity, ctx.getLevel() * 2); + List waterArc = Raytrace.entityRaytrace(world, Vector.getEntityPos(entity).withY(entity.getEyeHeight()), Vector.getLookRectangular(entity).times(10), 3, + entity1 -> entity1 != entity); + + if (waterArc.isEmpty()) { + if (ctx.getLevel() >= 2) { + for (Entity a : waterArc) { + if (a instanceof AvatarEntity) { + if (((AvatarEntity) a).getOwner() != entity) { + if (a instanceof EntityWaterArc) { + ((EntityWaterArc) a).setOwner(entity); + ((EntityWaterArc) a).setBehavior(new WaterArcBehavior.PlayerControlled()); + ((EntityWaterArc) a).setAbility(this); + ((EntityWaterArc) a).setStartingPosition(entity.getPosition()); + ((EntityWaterArc) a).setSize(0.5F); + ((EntityWaterArc) a).setGravity(9.82F); + ((EntityWaterArc) a).setPosition(Vector.getLookRectangular(entity).times(1.5F)); + } + } + } + } + } + } if (targetPos != null || ctx.consumeWater(1) || (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative())) { if (targetPos == null) { @@ -73,28 +95,28 @@ public void execute(AbilityContext ctx) { world.setBlockToAir(targetPos.toBlockPos()); } + float damageMult = 1F; float gravity = 8; - float size = 0.5F; + float size = 0.4F; //The water arc number in the combo. if (ctx.getLevel() == 1) { damageMult = 1.25F; gravity = 7.5F; - size = 0.75F; + size = 0.5F; } if (ctx.getLevel() == 2) { damageMult = 1.5F; gravity = 7; - size = 1F; + size = 0.6F; } if (ctx.isMasterLevel(AbilityData.AbilityTreePath.SECOND)) { damageMult = 3F; gravity = 3; - size = 1.25F; + size = 0.4F; } if (ctx.isMasterLevel(AbilityData.AbilityTreePath.FIRST)) { - damageMult = comboNumber >= 3 ? 1 : 2; gravity = 9.81F; size = 0.5F; } @@ -102,7 +124,6 @@ public void execute(AbilityContext ctx) { if (bender.consumeChi(STATS_CONFIG.chiWaterArc)) { removeExisting(ctx); - damageMult *= ctx.getPowerRatingDamageMod(); if (ctx.isMasterLevel(AbilityData.AbilityTreePath.FIRST)) { EntityWaterArc water = new EntityWaterArc(world); @@ -111,28 +132,34 @@ public void execute(AbilityContext ctx) { comboNumber = 1; } + if (comboNumber <= 1) { + size = 0.5F; + } + if (comboNumber == 3) { //Massive Singular water arc; kinda like airgust - size = 1.5F; + size = 1F; gravity = 2; comboNumber = 1; - } - else { + } else { comboNumber++; } if (comboNumber == 2) { gravity = -9.81F; - size = 1F; + size = 0.5F; } - System.out.println(comboNumber); + damageMult = comboNumber >= 3 ? 1.25F : 0.5F; + damageMult *= ctx.getPowerRatingDamageMod(); + Vector playerEye = Vector.getEyePos(entity); Vector look = playerEye.plus(getLookRectangular(entity).times(1.5)); Vector force = Vector.toRectangular(Math.toRadians(entity.rotationYaw), Math.toRadians(entity.rotationPitch)); force = force.times(15 + comboNumber); + water.setOwner(entity); water.setPosition(look); water.setSize(size); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterBubble.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterBubble.java index 58d23d8876..5e7b07b4dd 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterBubble.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterBubble.java @@ -148,7 +148,7 @@ public void execute(AbilityContext ctx) { }**/ } - private Vector getClosestWaterbendableBlock (EntityLivingBase entity, int level) { + private Vector getClosestWaterbendableBlock(EntityLivingBase entity, int level) { World world = entity.world; Vector eye = Vector.getEyePos(entity); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterCannon.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterCannon.java index 2489f4dd02..e87a1a8954 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterCannon.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterCannon.java @@ -4,23 +4,21 @@ import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; -import com.crowsofwar.avatar.common.entity.EntityEarthspike; import com.crowsofwar.avatar.common.util.Raytrace; import com.crowsofwar.gorecore.util.Vector; -import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import org.lwjgl.Sys; import java.util.function.BiPredicate; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; +import static com.crowsofwar.avatar.common.data.TickHandlerController.WATER_CHARGE; +import static com.crowsofwar.avatar.common.data.TickHandlerController.WATER_PARTICLE_SPAWNER; import static java.lang.Math.toRadians; public class AbilityWaterCannon extends Ability { @@ -40,11 +38,11 @@ public void execute(AbilityContext ctx) { Vector targetPos = getClosestWaterbendableBlock(entity, ctx.getLevel() * 2); float chi = STATS_CONFIG.chiWaterCannon; //5 - boolean hasWaterCharge = data.hasTickHandler(TickHandler.WATER_CHARGE); + boolean hasWaterCharge = data.hasTickHandler(WATER_CHARGE); int waterAmount = 2; - if(ctx.getLevel() >= 2) { - waterAmount = 3; + if (ctx.getLevel() >= 2) { + waterAmount = 3; } if (ctx.getLevel() == 2) { @@ -60,32 +58,31 @@ public void execute(AbilityContext ctx) { //7 } - if (ctx.consumeWater(waterAmount)) { if (bender.consumeChi(chi) && !hasWaterCharge) { - ctx.getData().addTickHandler(TickHandler.WATER_CHARGE); - data.addTickHandler(TickHandler.WATER_PARTICLE_SPAWNER); + ctx.getData().addTickHandler(WATER_CHARGE); + data.addTickHandler(WATER_PARTICLE_SPAWNER); } } else if (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative()) { if (!hasWaterCharge) { - ctx.getData().addTickHandler(TickHandler.WATER_CHARGE); - data.addTickHandler(TickHandler.WATER_PARTICLE_SPAWNER); + ctx.getData().addTickHandler(WATER_CHARGE); + data.addTickHandler(WATER_PARTICLE_SPAWNER); } } else if (targetPos != null && ctx.getLevel() >= 2) { if (bender.consumeChi(chi) && !hasWaterCharge) { world.setBlockToAir(targetPos.toBlockPos()); //Vector look = Vector.toRectangular(Math.toRadians(entity.rotationYaw), 0); - ctx.getData().addTickHandler(TickHandler.WATER_CHARGE); - data.addTickHandler(TickHandler.WATER_PARTICLE_SPAWNER); + ctx.getData().addTickHandler(WATER_CHARGE); + data.addTickHandler(WATER_PARTICLE_SPAWNER); } } else { bender.sendMessage("avatar.waterCannonFail"); - } } + } //Is broken; will investigate later. - private Vector getClosestWaterbendableBlock (EntityLivingBase entity, int level) { + private Vector getClosestWaterbendableBlock(EntityLivingBase entity, int level) { World world = entity.world; Vector eye = Vector.getEyePos(entity); @@ -102,9 +99,9 @@ private Vector getClosestWaterbendableBlock (EntityLivingBase entity, int level) double yaw = entity.rotationYaw + i * 360.0 / STATS_CONFIG.waterCannonAngles; double pitch = entity.rotationPitch + j * 360.0 / STATS_CONFIG.waterCannonAngles; - BiPredicate isWater = (pos, state) -> (STATS_CONFIG.waterBendableBlocks.contains(state.getBlock()) - || STATS_CONFIG.plantBendableBlocks.contains(state.getBlock())) && state.getBlock() != Blocks.AIR; - + BiPredicate isWater = (pos, state) -> + (STATS_CONFIG.waterBendableBlocks.contains(state.getBlock()) || STATS_CONFIG.plantBendableBlocks + .contains(state.getBlock())) && state.getBlock() != Blocks.AIR; Vector angle = Vector.toRectangular(toRadians(yaw), toRadians(pitch)); Raytrace.Result result = Raytrace.predicateRaytrace(world, eye, angle, range, isWater); @@ -155,6 +152,5 @@ private Vector getClosestWaterBlock(EntityLivingBase entity, int level) { } - } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterSkate.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterSkate.java index 7186c85ebc..449652af36 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterSkate.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/AbilityWaterSkate.java @@ -19,9 +19,10 @@ import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.StatusControl; import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; +import static com.crowsofwar.avatar.common.data.TickHandlerController.WATER_SKATE; + /** * @author CrowsOfWar */ @@ -40,7 +41,7 @@ public boolean isUtility() { public void execute(AbilityContext ctx) { BendingData data = ctx.getData(); data.addStatusControl(StatusControl.SKATING_START); - ctx.getData().addTickHandler(TickHandler.WATER_SKATE); + ctx.getData().addTickHandler(WATER_SKATE); } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/CleanseCooldownHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/CleanseCooldownHandler.java new file mode 100644 index 0000000000..7eccbbd848 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/CleanseCooldownHandler.java @@ -0,0 +1,44 @@ +package com.crowsofwar.avatar.common.bending.water; + +import com.crowsofwar.avatar.common.data.AbilityData; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.data.TickHandler; +import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; + +public class CleanseCooldownHandler extends TickHandler { + + public CleanseCooldownHandler(int id) { + super(id); + } + + @Override + public boolean tick(BendingContext ctx) { + EntityLivingBase entity = ctx.getBenderEntity(); + BendingData data = ctx.getData(); + int duration = data.getTickHandlerDuration(this); + int coolDown = 160; + AbilityData aD = data.getAbilityData("cleanse"); + + if (aD.getLevel() == 1) { + coolDown = 140; + } + if (aD.getLevel() == 2) { + coolDown = 120; + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + coolDown = 130; + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + coolDown = 110; + } + + if (entity instanceof EntityPlayer && ((EntityPlayer) entity).isCreative()) { + coolDown = 0; + } + + + return duration >= coolDown; + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/CleansePowerModifier.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/CleansePowerModifier.java index e8642d4934..923e4abfdb 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/CleansePowerModifier.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/CleansePowerModifier.java @@ -28,7 +28,10 @@ public double get(BendingContext ctx) { @Override protected Vision[] getVisions() { + //if (CLIENT_CONFIG.shaderSettings.useCleanseShaders) { return new Vision[]{Vision.CLEANSE_WEAK, Vision.CLEANSE_MEDIUM, Vision.CLEANSE_POWERFUL}; + //} + //else return null; } @Override diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/StatCtrlSkateJump.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/StatCtrlSkateJump.java index 6bb9976836..84f86b25d1 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/StatCtrlSkateJump.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/StatCtrlSkateJump.java @@ -20,7 +20,6 @@ import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.AbilityData.AbilityTreePath; import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.BendingContext; import com.crowsofwar.avatar.common.util.AvatarUtils; import com.crowsofwar.gorecore.util.Vector; @@ -28,6 +27,8 @@ import static com.crowsofwar.avatar.common.bending.StatusControl.CrosshairPosition.BELOW_CROSSHAIR; import static com.crowsofwar.avatar.common.controls.AvatarControl.CONTROL_JUMP; +import static com.crowsofwar.avatar.common.data.TickHandlerController.SMASH_GROUND_WATER; +import static com.crowsofwar.avatar.common.data.TickHandlerController.WATER_SKATE; /** * @author CrowsOfWar @@ -42,8 +43,8 @@ public StatCtrlSkateJump() { public boolean execute(BendingContext ctx) { BendingData data = ctx.getData(); EntityLivingBase entity = ctx.getBenderEntity(); - if (data.hasTickHandler(TickHandler.WATER_SKATE)) { - data.removeTickHandler(TickHandler.WATER_SKATE); + if (data.hasTickHandler(WATER_SKATE)) { + data.removeTickHandler(WATER_SKATE); data.getMiscData().setCanUseAbilities(true); Vector velocity = Vector.getLookRectangular(entity).times(1.5); @@ -56,7 +57,7 @@ public boolean execute(BendingContext ctx) { AbilityData abilityData = data.getAbilityData("water_skate"); if (abilityData.isMasterPath(AbilityTreePath.SECOND)) { - data.addTickHandler(TickHandler.SMASH_GROUND_WATER); + data.addTickHandler(SMASH_GROUND_WATER); } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/StatCtrlThrowWater.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/StatCtrlThrowWater.java index 8261af04f5..2d1921b1a9 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/StatCtrlThrowWater.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/StatCtrlThrowWater.java @@ -20,18 +20,15 @@ import com.crowsofwar.avatar.common.bending.StatusControl; import com.crowsofwar.avatar.common.controls.AvatarControl; import com.crowsofwar.avatar.common.data.AbilityData; -import com.crowsofwar.avatar.common.data.AbilityData.AbilityTreePath; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import com.crowsofwar.avatar.common.entity.AvatarEntity; import com.crowsofwar.avatar.common.entity.EntityWaterArc; import com.crowsofwar.avatar.common.entity.data.WaterArcBehavior; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.World; -import java.util.List; - /** * @author CrowsOfWar */ @@ -50,25 +47,24 @@ public boolean execute(BendingContext ctx) { AbilityData abilityData = data.getAbilityData("water_arc"); int lvl = abilityData.getLevel(); - double velocity = 16; + double velocity = 14; - if (lvl == 1){ - velocity = 20; + if (lvl == 1) { + velocity = 16; } if (lvl == 2) { - velocity = 22; + velocity = 18; } if (lvl == 3) { - velocity = 30; + velocity = 22; } - AxisAlignedBB boundingBox = new AxisAlignedBB(entity.posX - 5, entity.posY - 5, entity.posZ - 5, - entity.posX + 5, entity.posY + 5, entity.posZ + 5); - List existing = world.getEntitiesWithinAABB(EntityWaterArc.class, boundingBox, - arc -> arc.getOwner() == entity - && arc.getBehavior() instanceof WaterArcBehavior.PlayerControlled); + EntityWaterArc arc = AvatarEntity.lookupEntity(ctx.getWorld(), EntityWaterArc.class, // + water -> water.getBehavior() instanceof WaterArcBehavior.PlayerControlled + && water.getOwner() == ctx.getBenderEntity()); + - for (EntityWaterArc arc : existing) { + if (arc != null) { Vector force = Vector.toRectangular(Math.toRadians(entity.rotationYaw), Math.toRadians(entity.rotationPitch)); diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterChargeHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterChargeHandler.java index 6099650a70..307de0c7d4 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterChargeHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterChargeHandler.java @@ -21,8 +21,11 @@ import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; public class WaterChargeHandler extends TickHandler { - private static final UUID MOVEMENT_MODIFIER_ID = UUID.fromString - ("87a0458a-38ea-4d7a-be3b-0fee10217aa6"); + private static final UUID MOVEMENT_MODIFIER_ID = UUID.fromString("87a0458a-38ea-4d7a-be3b-0fee10217aa6"); + + public WaterChargeHandler(int id) { + super(id); + } @Override public boolean tick(BendingContext ctx) { @@ -46,13 +49,12 @@ public boolean tick(BendingContext ctx) { durationToFire = 60; } + if (world.isRemote) { return false; } - applyMovementModifier(entity, MathHelper.clamp(movementMultiplier, 0.1f, 1)); - if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { size = 0.1F; @@ -64,8 +66,7 @@ public boolean tick(BendingContext ctx) { if (duration >= 40 && duration % 10 == 0) { fireCannon(world, entity, damage, speed, size, ticks); - world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.BLOCK_WATER_AMBIENT, - SoundCategory.PLAYERS, 1, 2); + world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.BLOCK_WATER_AMBIENT, SoundCategory.PLAYERS, 1, 2); entity.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(MOVEMENT_MODIFIER_ID); return duration >= 100; @@ -82,18 +83,17 @@ public boolean tick(BendingContext ctx) { if (abilityData.getLevel() >= 1) { damage = (float) (STATS_CONFIG.waterCannonDamage * 1.25 * bender.getDamageMult(Waterbending.ID)); - size = 0.5f; + size = 0.4f; ticks = 75; } if (abilityData.getLevel() >= 2) { damage = (float) (STATS_CONFIG.waterCannonDamage * 1.5 * bender.getDamageMult(Waterbending.ID)); - size = 0.75f; + size = 0.55f; ticks = 100; } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { damage = (float) (STATS_CONFIG.waterCannonDamage * 2.5 * bender.getDamageMult(Waterbending.ID)); - size = 1f; - ticks = 150; + ticks = 125; } damage *= bender.getDamageMult(Waterbending.ID); @@ -101,8 +101,7 @@ public boolean tick(BendingContext ctx) { entity.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(MOVEMENT_MODIFIER_ID); - world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.ENTITY_GENERIC_SPLASH, - SoundCategory.PLAYERS, 1, 2); + world.playSound(null, entity.posX, entity.posY, entity.posZ, SoundEvents.ENTITY_GENERIC_SPLASH, SoundCategory.PLAYERS, 1, 2); return true; } @@ -111,8 +110,7 @@ public boolean tick(BendingContext ctx) { } - private void fireCannon(World world, EntityLivingBase entity, float damage, double speed, - float size, float ticks) { + private void fireCannon(World world, EntityLivingBase entity, float damage, double speed, float size, float ticks) { EntityWaterCannon cannon = new EntityWaterCannon(world); @@ -121,6 +119,7 @@ private void fireCannon(World world, EntityLivingBase entity, float damage, doub cannon.setSizeMultiplier(size); cannon.setPosition(Vector.getEyePos(entity)); cannon.setLifeTime(ticks); + cannon.setAbility(new AbilityWaterCannon()); Vector velocity = Vector.getLookRectangular(entity); velocity = velocity.normalize().times(speed); @@ -131,13 +130,11 @@ private void fireCannon(World world, EntityLivingBase entity, float damage, doub private void applyMovementModifier(EntityLivingBase entity, float multiplier) { - IAttributeInstance moveSpeed = entity.getEntityAttribute(SharedMonsterAttributes - .MOVEMENT_SPEED); + IAttributeInstance moveSpeed = entity.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); moveSpeed.removeModifier(MOVEMENT_MODIFIER_ID); - moveSpeed.applyModifier(new AttributeModifier(MOVEMENT_MODIFIER_ID, - "Water charge modifier", multiplier - 1, 1)); + moveSpeed.applyModifier(new AttributeModifier(MOVEMENT_MODIFIER_ID, "Water charge modifier", multiplier - 1, 1)); } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterParticleSpawner.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterParticleSpawner.java index 39090ac954..61ae48dc1e 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterParticleSpawner.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterParticleSpawner.java @@ -16,8 +16,14 @@ import java.util.List; +import static com.crowsofwar.avatar.common.data.TickHandlerController.WATER_CHARGE; + public class WaterParticleSpawner extends TickHandler { + public WaterParticleSpawner(int id) { + super(id); + } + @Override public boolean tick(BendingContext ctx) { EntityLivingBase entity = ctx.getBenderEntity(); @@ -29,40 +35,35 @@ public boolean tick(BendingContext ctx) { maxDuration = 60; } int duration = data.getTickHandlerDuration(this); - double radius = (maxDuration - duration) / 10; - - + double radius = ((float) maxDuration - duration) / 10; if (data.hasTickHandler(WATER_CHARGE) && !world.isRemote) { WorldServer World = (WorldServer) world; for (int i = 0; i < 180; i++) { - Vector lookpos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + - i * 2), 0).times(radius).withY(entity.getEyeHeight() / 2); + Vector lookpos = Vector.toRectangular(Math.toRadians(entity.rotationYaw + i * 2), 0).times(radius).withY(entity.getEyeHeight() / 2); World.spawnParticle(EnumParticleTypes.WATER_SPLASH, lookpos.x() + entity.posX, lookpos.y() + entity.getEntityBoundingBox().minY, lookpos.z() + entity.posZ, 1, 0, 0, 0, 0.05); } - AxisAlignedBB box = new AxisAlignedBB(entity.posX + (1 * radius) , entity.posY + 2, entity.posZ + (1 * radius), - entity.posX - (1 * radius), entity.posY - 2, entity.posZ - (1 * radius)); + AxisAlignedBB box = new AxisAlignedBB(entity.posX + radius, entity.posY + entity.getEyeHeight() / 2 + radius / 4, entity.posZ + radius, + entity.posX - radius, entity.posY + entity.getEyeHeight() / 2 - radius / 4, entity.posZ - radius); List projectiles = world.getEntitiesWithinAABB(EntityThrowable.class, box); if (!projectiles.isEmpty()) { for (Entity e : projectiles) { - e.applyEntityCollision(e); - e.setDead(); + Vector vel = Vector.getVelocity(e).times(-1); + e.addVelocity(vel.x(), 0, vel.z()); } } if (abilityData.getLevel() >= 2) { List arrows = world.getEntitiesWithinAABB(EntityArrow.class, box); if (!arrows.isEmpty()) { for (Entity e : arrows) { - e.applyEntityCollision(e); - e.setDead(); + Vector vel = Vector.getVelocity(e).times(-1); + e.addVelocity(vel.x(), 0, vel.z()); } } } return false; - - } - else return true; + } else return true; } } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterPassives.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterPassives.java index d11e318cea..dcef1ccaff 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterPassives.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterPassives.java @@ -3,24 +3,16 @@ import com.crowsofwar.avatar.AvatarInfo; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.Chi; import com.crowsofwar.avatar.common.entity.mob.EntityBender; -import net.minecraft.block.Block; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Blocks; import net.minecraft.init.MobEffects; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.event.entity.living.LivingEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import static com.crowsofwar.avatar.common.config.ConfigChi.CHI_CONFIG; -import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; - @Mod.EventBusSubscriber(modid = AvatarInfo.MOD_ID) public class WaterPassives { @@ -39,10 +31,10 @@ public static void waterPassives(LivingEvent.LivingUpdateEvent event) { entity.addPotionEffect(new PotionEffect(MobEffects.HASTE, 10, 1)); //entity.addPotionEffect(new PotionEffect(MobEffects.REGENERATION, 10, 0)); //OP right now; will be implemented later with the skill tree - } } } - } + } } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterSkateHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterSkateHandler.java index da65f2bd05..27dbabaa20 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterSkateHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterSkateHandler.java @@ -55,7 +55,8 @@ public class WaterSkateHandler extends TickHandler { private final ParticleSpawner particles; - public WaterSkateHandler() { + public WaterSkateHandler(int id) { + super(id); particles = new NetworkParticleSpawner(); } @@ -124,7 +125,17 @@ private boolean skate(BendingData data, EntityLivingBase player, Bender bender) } } - player.setPosition(player.posX, yPos + .2, player.posZ); + /*Block belowBlock = player.world.getBlockState(new BlockPos(player.getPosition()).down()).getBlock(); + Block playerBlock = player.world.getBlockState(new BlockPos(player.getPosition())).getBlock(); + + if (belowBlock != Blocks.WATER && belowBlock != Blocks.FLOWING_WATER) { + if (playerBlock == Blocks.AIR) { + world.setBlockState(new BlockPos(player.getPosition()), Blocks.FLOWING_WATER.getBlockLayer()getDefaultState()); + } + + }**/ + + player.setPosition(player.posX, yPos, player.posZ); Vector currentVelocity = new Vector(player.motionX, player.motionY, player.motionZ); Vector targetVelocity = toRectangular(toRadians(player.rotationYaw), 0).times(targetSpeed); @@ -163,8 +174,8 @@ private boolean skate(BendingData data, EntityLivingBase player, Bender bender) world.playSound(null, player.getPosition(), SoundEvents.ENTITY_PLAYER_SPLASH, SoundCategory.PLAYERS, 0.4f, 2f); } - particles.spawnParticles(world, EnumParticleTypes.WATER_SPLASH, 50, 60, - Vector.getEntityPos(player).plus(0, .1, 0), new Vector(.2, 0.2, .2)); + particles.spawnParticles(world, EnumParticleTypes.WATER_SPLASH, 50, 60, + Vector.getEntityPos(player).plus(0, .1, 0), new Vector(.2, 0.2, .2)); if (player.ticksExisted % 10 == 0) { @@ -188,21 +199,23 @@ private boolean skate(BendingData data, EntityLivingBase player, Bender bender) */ private boolean shouldSkate(EntityLivingBase player, AbilityData data) { IBlockState below = player.world.getBlockState(new BlockPos(player.getPosition()).down()); + IBlockState playerPos = player.world.getBlockState(new BlockPos(player.getPosition())); int surface = getSurfacePos(player); boolean allowWaterfallSkating = data.getLevel() >= 2; boolean allowGroundSkating = data.isMasterPath(AbilityTreePath.FIRST); + boolean onGround = (below.getBlock() != Blocks.AIR) && below.getBlock() != Blocks.LAVA && below.getBlock() != Blocks.FLOWING_LAVA; + boolean onWaterBendableBlock = STATS_CONFIG.waterBendableBlocks.contains(below.getBlock()); + boolean onSnowLayer = playerPos.getBlock() == Blocks.SNOW_LAYER; boolean inWaterBlock = ((below.getBlock() == Blocks.WATER) - && (below.getValue(BlockLiquid.LEVEL) == 0 || allowWaterfallSkating)) || player.world.isRainingAt(player.getPosition()) || below.getBlock() == Blocks.SNOW || below.getBlock() == Blocks.ICE - || below.getBlock() == Blocks.PACKED_ICE || below.getBlock() == Blocks.FROSTED_ICE || below.getBlock() == Blocks.SNOW_LAYER; - boolean onGround = (below.getBlock() != Blocks.AIR); + && (below.getValue(BlockLiquid.LEVEL) == 0 || allowWaterfallSkating)) || (player.world.isRainingAt(player.getPosition()) && onGround) || onWaterBendableBlock || onSnowLayer; + if (allowGroundSkating && onGround) { return (!player.isSneaking() && surface != -1 && surface - player.posY <= 3); } else return !player.isSneaking() && (player.isInWater() || inWaterBlock) && surface != -1 - && surface - player.posY <= 3 && onGround; - + && surface - player.posY <= 3; } @@ -231,7 +244,7 @@ private int getSurfacePos(EntityLivingBase player) { private void pushEntitiesAway(EntityLivingBase target, EntityLivingBase entity) { Vector velocity = Vector.getEntityPos(target).minus(Vector.getEntityPos(entity)); - velocity = velocity.withY(0.1).times(2 / 20); + velocity = velocity.withY(0.1).times(2F / 20); target.addVelocity(velocity.x(), velocity.y(), velocity.z()); } diff --git a/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterSmashHandler.java b/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterSmashHandler.java index 48087da259..c4367f14ab 100644 --- a/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterSmashHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/bending/water/WaterSmashHandler.java @@ -1,21 +1,19 @@ package com.crowsofwar.avatar.common.bending.water; +import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.air.SmashGroundHandler; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.SoundEvents; import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; public class WaterSmashHandler extends SmashGroundHandler { - @Override - protected void smashEntity(EntityLivingBase target, EntityLivingBase entity) { - super.smashEntity(target, entity); + public WaterSmashHandler(int id) { + super(id); } @Override - protected int getNumberOfParticles() { + protected int getParticleAmount() { return 10; } @@ -30,22 +28,27 @@ protected EnumParticleTypes getParticle() { } @Override - protected float getParticleSpeed() { - return 0.2F; + protected double getParticleSpeed() { + return 3; } @Override protected float getDamage() { - return 4; + return 3.75F; } @Override protected float getKnockbackHeight() { - return 0.5F; + return 0.1F; } @Override protected double getSpeed() { return 6; } + + @Override + protected Ability getAbility() { + return new AbilityWaterSkate(); + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/command/NodeBendingAdd.java b/src/main/java/com/crowsofwar/avatar/common/command/NodeBendingAdd.java index cbb1ff372c..041e088b10 100644 --- a/src/main/java/com/crowsofwar/avatar/common/command/NodeBendingAdd.java +++ b/src/main/java/com/crowsofwar/avatar/common/command/NodeBendingAdd.java @@ -56,16 +56,18 @@ protected ICommandNode doFunction(CommandCall call, List options) { for (BendingStyle controller : controllers) { BendingData data = BendingData.get(world, playerName); - if (data == null) { - MSG_PLAYER_DATA_NO_DATA.send(sender, playerName); - } else { - if (data.hasBendingId(controller.getId())) { - MSG_BENDING_ADD_ALREADY_HAS.send(sender, playerName, controller.getName()); + if (controller.canEntityUse()) { + if (data == null) { + MSG_PLAYER_DATA_NO_DATA.send(sender, playerName); } else { - data.addBending(controller); - MSG_BENDING_ADD_SUCCESS.send(sender, playerName, controller.getName()); - } + if (data.hasBendingId(controller.getId())) { + MSG_BENDING_ADD_ALREADY_HAS.send(sender, playerName, controller.getName()); + } else { + data.addBending(controller); + MSG_BENDING_ADD_SUCCESS.send(sender, playerName, controller.getName()); + } + } } } diff --git a/src/main/java/com/crowsofwar/avatar/common/command/NodeBendingRemove.java b/src/main/java/com/crowsofwar/avatar/common/command/NodeBendingRemove.java index 20c669fd44..532ffb1c8c 100644 --- a/src/main/java/com/crowsofwar/avatar/common/command/NodeBendingRemove.java +++ b/src/main/java/com/crowsofwar/avatar/common/command/NodeBendingRemove.java @@ -57,15 +57,17 @@ protected ICommandNode doFunction(CommandCall call, List options) { for (BendingStyle controller : controllers) { BendingData data = BendingData.get(world, playerName); - if (data == null) { - MSG_PLAYER_DATA_NO_DATA.send(sender, playerName); - } else { - - if (data.hasBending(controller)) { - data.removeBending(controller); - MSG_BENDING_REMOVE_SUCCESS.send(sender, playerName, controller.getName()); + if (controller.canEntityUse()) { + if (data == null) { + MSG_PLAYER_DATA_NO_DATA.send(sender, playerName); } else { - MSG_BENDING_REMOVE_DOESNT_HAVE.send(sender, playerName, controller.getName()); + + if (data.hasBending(controller)) { + data.removeBending(controller); + MSG_BENDING_REMOVE_SUCCESS.send(sender, playerName, controller.getName()); + } else { + MSG_BENDING_REMOVE_DOESNT_HAVE.send(sender, playerName, controller.getName()); + } } } } diff --git a/src/main/java/com/crowsofwar/avatar/common/config/ConfigClient.java b/src/main/java/com/crowsofwar/avatar/common/config/ConfigClient.java index c9e49fce75..30e215aacc 100644 --- a/src/main/java/com/crowsofwar/avatar/common/config/ConfigClient.java +++ b/src/main/java/com/crowsofwar/avatar/common/config/ConfigClient.java @@ -39,7 +39,14 @@ public class ConfigClient { public float chiBarAlpha = 0.5f; @Load - public float bendingCycleAlpha = 0.5f; + public float bendingCycleAlpha = 1f; + + @Load + public final boolean displayGetBendingMessage = true; + //For some reason if it's not final it won't work + //Controls whether or not to show the get bending message + //when you press the use bending key + @Load public boolean useCustomParticles = true; @@ -50,6 +57,15 @@ public class ConfigClient { @Load private Map nameConflicts = new HashMap<>(); +// @Load +// public ShaderSettings shaderSettings = new ShaderSettings(); + + @Load + public ActiveBendingSettings activeBendingSettings = new ActiveBendingSettings(); + + @Load + public ChiBarSettings chiBarSettings = new ChiBarSettings(); + public static void load() { ConfigLoader.load(CLIENT_CONFIG, "avatar/cosmetic.yml"); @@ -100,4 +116,57 @@ public static void save() { ConfigLoader.save(CLIENT_CONFIG, "avatar/cosmetic.yml"); } + /*public static class ShaderSettings { + + @Load + public boolean useSlipstreamShaders = false; + + @Load + public boolean useCleanseShaders = true; + + @Load + public boolean useRestoreShaders = true; + + @Load + public boolean usePurifyShaders = true; + }**/ + + public static class ActiveBendingSettings { + + @Load + public final boolean shouldBendingMenuRender = true; + //For some reason if it's not final it won't work + //Determines if element menu should render at all + + /* @Load + public final boolean shouldBendingMenuDisappear = true; + //For some reason if it's not final it won't work + //Makes the menu disappear after the duration- affects chi as well. + //Currently unused + + @Load + public final int bendingMenuDuration = 200; + //If the menu should disappear, how long it should take before disappearing + //currently unused +**/ + + } + + public static class ChiBarSettings { + @Load + public final boolean shouldChibarRender = true; + + @Load + public final boolean shouldChiNumbersRender = true; +/* + @Load + public final boolean shouldChibarDisappear = true; + //Currently unused + + @Load + public final int chibarDuration = 200; + //Currently unused + **/ + } + } diff --git a/src/main/java/com/crowsofwar/avatar/common/config/ConfigMobs.java b/src/main/java/com/crowsofwar/avatar/common/config/ConfigMobs.java index 1630e5ce04..4ac5e08946 100644 --- a/src/main/java/com/crowsofwar/avatar/common/config/ConfigMobs.java +++ b/src/main/java/com/crowsofwar/avatar/common/config/ConfigMobs.java @@ -23,9 +23,12 @@ import com.crowsofwar.gorecore.config.Load; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; +import net.minecraft.init.Items; import net.minecraft.item.Item; +import scala.actors.threadpool.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -34,11 +37,28 @@ public class ConfigMobs { private static final Map DEFAULT_FOODS = new HashMap<>(); + private static final Map DEFAULT_TRADE_ITEMS = new HashMap<>(); + private static final Map AIRBENDING_TRADE_ITEMS = new HashMap<>(); + private static final Map FIREBENDING_TRADE_ITEMS = new HashMap<>(); + private static final Map DEFAULT_SCROLL_DROP = new HashMap<>(); private static final Map DEFAULT_SCROLL_TYPE = new HashMap<>(); public static ConfigMobs MOBS_CONFIG = new ConfigMobs(); static { + //Default items that are tradable for scrolls- the number is just random for now. + //TODO: Make the number correspond to the amount of the item the player has to hold + DEFAULT_TRADE_ITEMS.put("minecraft:diamond", 1); + DEFAULT_TRADE_ITEMS.put("minecraft:gold_ingot", 1); + DEFAULT_TRADE_ITEMS.put("minecraft:emerald", 1); + //Required items for trading for a airbending scroll + AIRBENDING_TRADE_ITEMS.put("minecraft:elytra", 1); + AIRBENDING_TRADE_ITEMS.put("minecraft:dragon_breath", 1); + AIRBENDING_TRADE_ITEMS.put("minecraft:totem_of_undying", 1); + //Required items for trading for a firebending scroll + FIREBENDING_TRADE_ITEMS.put("minecraft:magma_cream", 1); + FIREBENDING_TRADE_ITEMS.put("minecraft:blaze_rod", 1); + // Wheat DEFAULT_FOODS.put("minecraft:bread", 5); DEFAULT_FOODS.put("minecraft:hay_block", 75); @@ -57,7 +77,7 @@ public class ConfigMobs { DEFAULT_FOODS.put("minecraft:cake", 45); DEFAULT_FOODS.put("minecraft:sugar", 2); - DEFAULT_SCROLL_DROP.put("polar_bear", 15.0); + DEFAULT_SCROLL_DROP.put("polar_bear", 5.0); DEFAULT_SCROLL_TYPE.put("polar_bear", "water"); DEFAULT_SCROLL_DROP.put("squid", 2.0); DEFAULT_SCROLL_TYPE.put("squid", "water"); @@ -77,21 +97,21 @@ public class ConfigMobs { DEFAULT_SCROLL_DROP.put("blaze", 30.0); DEFAULT_SCROLL_TYPE.put("blaze", "fire"); - DEFAULT_SCROLL_DROP.put("bat", 15.0); + DEFAULT_SCROLL_DROP.put("bat", 7.5); DEFAULT_SCROLL_TYPE.put("bat", "air"); - DEFAULT_SCROLL_DROP.put("parrot", 10.0); + DEFAULT_SCROLL_DROP.put("parrot", 5.0); DEFAULT_SCROLL_TYPE.put("parrot", "air"); - DEFAULT_SCROLL_DROP.put("chicken", 5.0); + DEFAULT_SCROLL_DROP.put("chicken", 1.0); DEFAULT_SCROLL_TYPE.put("chicken", "air"); - DEFAULT_SCROLL_DROP.put("sheep", 1.0); + DEFAULT_SCROLL_DROP.put("sheep", 0.25); DEFAULT_SCROLL_TYPE.put("sheep", "air"); - DEFAULT_SCROLL_DROP.put("mooshroom", 5.0); + DEFAULT_SCROLL_DROP.put("mooshroom", 1.0); DEFAULT_SCROLL_TYPE.put("mooshroom", "earth"); - DEFAULT_SCROLL_DROP.put("cave_spider", 5.0); + DEFAULT_SCROLL_DROP.put("cave_spider", 2.5); DEFAULT_SCROLL_TYPE.put("cave_spider", "earth"); - DEFAULT_SCROLL_DROP.put("silverfish", 10.0); + DEFAULT_SCROLL_DROP.put("silverfish", 5.0); DEFAULT_SCROLL_TYPE.put("silverfish", "earth"); DEFAULT_SCROLL_DROP.put("spider", 2.0); DEFAULT_SCROLL_TYPE.put("spider", "earth"); @@ -141,15 +161,34 @@ public class ConfigMobs { @Load private Map scrollType; + @Load + public int maxNumberOfBenders = 3; + //The largest of amount of benders that can spawn in a village + + @Load + private Map scrollTradeItems; + private Map tradeItems; + private Map airScrollTradeItems; + private Map airTradeItems; + private Map fireScrollTradeItems; + private Map fireTradeItems; + + + + public static void load() { + MOBS_CONFIG.scrollTradeItems = DEFAULT_TRADE_ITEMS; + MOBS_CONFIG.airScrollTradeItems = AIRBENDING_TRADE_ITEMS; + MOBS_CONFIG.fireScrollTradeItems = FIREBENDING_TRADE_ITEMS; MOBS_CONFIG.bisonFoods = DEFAULT_FOODS; MOBS_CONFIG.scrollDropChance = DEFAULT_SCROLL_DROP; MOBS_CONFIG.scrollType = DEFAULT_SCROLL_TYPE; ConfigLoader.load(MOBS_CONFIG, "avatar/mobs.yml"); MOBS_CONFIG.loadLists(); + } - private void loadLists() { + public void loadLists() { bisonFoodList = new HashMap<>(); for (Map.Entry entry : bisonFoods.entrySet()) { String name = entry.getKey(); @@ -160,12 +199,62 @@ private void loadLists() { AvatarLog.warn(WarningType.CONFIGURATION, "Invalid bison food; item " + name + " not found"); } } + tradeItems = new HashMap<>(); + for (Map.Entry entry : scrollTradeItems.entrySet()) { + String name = entry.getKey(); + Item item = Item.getByNameOrId(name); + if (item != null) { + tradeItems.put(item, entry.getValue()); + } else { + AvatarLog.warn(WarningType.CONFIGURATION, "Invalid trade item; item " + name + " not found"); + } + } + airTradeItems = new HashMap<>(); + for (Map.Entry entry : airScrollTradeItems.entrySet()) { + String name = entry.getKey(); + Item item = Item.getByNameOrId(name); + if (item != null) { + airTradeItems.put(item, entry.getValue()); + } else { + AvatarLog.warn(WarningType.CONFIGURATION, "Invalid trade item; item " + name + " not found"); + } + } + fireTradeItems = new HashMap<>(); + for (Map.Entry entry : fireScrollTradeItems.entrySet()) { + String name = entry.getKey(); + Item item = Item.getByNameOrId(name); + if (item != null) { + fireTradeItems.put(item, entry.getValue()); + } else { + AvatarLog.warn(WarningType.CONFIGURATION, "Invalid trade item; item " + name + " not found"); + } + } } public int getDomesticationValue(Item item) { return bisonFoodList.containsKey(item) ? bisonFoodList.get(item) : 0; } + public boolean isTradeItem(Item item) { + return tradeItems.containsKey(item); + } + + public int getTradeItemAmount(Item item) { + return tradeItems.getOrDefault(item, 0); + } + + public boolean isAirTradeItem(Item item) { + return airTradeItems.containsKey(item); + } + + public int getAirTradeItemAmount(Item item) { + return airTradeItems.containsKey(item) ? airTradeItems.get(item) : 0; + } + + public boolean isFireTradeItem(Item item) { + return fireTradeItems.containsKey(item); + } + public boolean isBisonFood(Item item) { return bisonFoodList.containsKey(item); } diff --git a/src/main/java/com/crowsofwar/avatar/common/config/ConfigSkills.java b/src/main/java/com/crowsofwar/avatar/common/config/ConfigSkills.java index 307fb74ab7..b6617891ca 100644 --- a/src/main/java/com/crowsofwar/avatar/common/config/ConfigSkills.java +++ b/src/main/java/com/crowsofwar/avatar/common/config/ConfigSkills.java @@ -35,7 +35,7 @@ public class ConfigSkills { airGustHit = 3f, airBurstHit = 4F, buffUsed = 2f, - earthspikeHit = 3.5F, + earthspikeHit = 3.0F, ravineHit = 3f, waveHit = 4f, waterHit = 3f, diff --git a/src/main/java/com/crowsofwar/avatar/common/config/ConfigStats.java b/src/main/java/com/crowsofwar/avatar/common/config/ConfigStats.java index bb7586fe23..81e7254846 100644 --- a/src/main/java/com/crowsofwar/avatar/common/config/ConfigStats.java +++ b/src/main/java/com/crowsofwar/avatar/common/config/ConfigStats.java @@ -40,10 +40,11 @@ public class ConfigStats { ravineSettings = new AttackSettings(3.5F, 0.25), // waveSettings = new AttackSettings(0.25F, 4), // airbladeSettings = new AttackSettings(3, .03), // - fireArcSettings = new AttackSettings(2, 1), // + fireArcSettings = new AttackSettings(3, 1), // waterArcSettings = new AttackSettings(1.5F, 1), boulderSettings = new AttackSettings(0.1F, 0.1), - airBurstSettings = new AttackSettings (0.5F, 1); + airBurstSettings = new AttackSettings (1F, 1), + lightningSpearSettings = new AttackSettings(4F, 2); @Load public double wallWaitTime = 10, wallWaitTime2 = 60, wallMomentum = 10; @@ -52,7 +53,7 @@ public class ConfigStats { public int wallJumpDelay = 10; @Load - public float waterArcTicks = 40; + public float waterArcTicks = 120; //Has to be a float so I can times it by a fraction; there aren't any partial ticks, though. @Load @@ -112,6 +113,7 @@ public class ConfigStats { chiPrison = 5, chiSandPrison = 3, chiLightning = 6, + chiLightningSpear = 4, chiLightningRaze = 5, chiIceShieldCreate = 4, chiIceShieldProtect = 0.15f, @@ -139,6 +141,9 @@ public class ConfigStats { @Load public double waterArcSearchRadius = 4, waterArcAngles = 8; + @Load + public boolean useWaterCannonParticles = true; + @Load public double waterCannonSearchRadius = 3, waterCannonAngles = 8, waterCannonDamage = 1; @@ -148,6 +153,12 @@ public class ConfigStats { @Load public double cleanseSearchRadius = 5, cleanseAngles = 10; + @Load + public double fireSearchRadius = 4, fireAngles = 8; + + @Load + public boolean shiftActivateFireDevour = true; + @Load public boolean addDungeonLoot = true; @@ -175,6 +186,7 @@ public class ConfigStats { "minecraft:brick_block", "minecraft:mossy_cobblestone", "minecraft:stonebrick", + "minecraft:stone_slab", "minecraft:clay", "minecraft:hardened_clay", "minecraft:stained_hardened_clay", @@ -200,6 +212,15 @@ public class ConfigStats { "minecraft:flowing_water" ); + @Load + public List iceBendableBlockNames = Arrays.asList( + "minecraft:snow", + "minecraft:snow_layer", + "minecraft:ice", + "minecraft:packed_ice", + "minecraft:frosted_ice" + ); + @Load public List plantBendableBlockNames = Arrays.asList( "minecraft:tallgrass", @@ -207,7 +228,8 @@ public class ConfigStats { "minecraft:double_grass", "minecraft:waterlily", "minecraft:red_flower", - //For some reason, most of the plants in minecraft are tallgrass, double_grass, or red_flowers. Weird. + "minecraft:double_plant", + //For some reason, most of the plants in minecraft are tallgrass, double_grass, double_plant, or red_flowers. Weird. "minecraft:leaves", "minecraft:yellow_flower", "minecraft:red_mushroom", @@ -238,11 +260,34 @@ public class ConfigStats { ); + @Load + public List waterArcBreakableBlockNames = Arrays.asList( + "minecraft:stone", + "minecraft:sand", + "minecraft:sandstone", + "minecraft:cobblestone", + "minecraft:dirt", + "minecraft:gravel", + "minecraft:brick_block", + "minecraft:mossy_cobblestone", + "minecraft:stonebrick", + "minecraft:clay", + "minecraft:hardened_clay", + "minecraft:stained_hardened_clay", + "minecraft:coal_ore", + "minecraft:iron_ore", + "minecraft:red_sandstone", + "minecraft:grass", + "minecraft:grass_path" + ); + public List plantBendableBlocks; public List waterBendableBlocks; public List bendableBlocks; public List sandBlocks; public List airBladeBreakableBlocks; + public List iceBendableBlocks; + public List waterArcBreakableBlocks; private ConfigStats() { } @@ -257,6 +302,8 @@ public void loadBlocks() { sandBlocks = STATS_CONFIG.loadBlocksList(sandBlocksNames); waterBendableBlocks = STATS_CONFIG.loadBlocksList(waterBendableBlockNames); plantBendableBlocks = STATS_CONFIG.loadBlocksList(plantBendableBlockNames); + iceBendableBlocks = STATS_CONFIG.loadBlocksList(iceBendableBlockNames); + waterArcBreakableBlocks = STATS_CONFIG.loadBlocksList(waterArcBreakableBlockNames); } /** @@ -310,6 +357,10 @@ public static class AirBurstSettings { public float durationToFire = 40; //How long it takes to shoot the air burst, in ticks + @Load + public int performanceAmount = 15; + //How much performance is added to the player's performance score upon a hit + } public static class FireballSettings { @@ -334,7 +385,7 @@ public static class FireballSettings { public static class CloudburstSettings { @Load - public double damage = 1.5; + public double damage = 2; @Load public double push = 1.5; diff --git a/src/main/java/com/crowsofwar/avatar/common/controls/AvatarControl.java b/src/main/java/com/crowsofwar/avatar/common/controls/AvatarControl.java index 766aeba689..785bca6810 100644 --- a/src/main/java/com/crowsofwar/avatar/common/controls/AvatarControl.java +++ b/src/main/java/com/crowsofwar/avatar/common/controls/AvatarControl.java @@ -20,8 +20,7 @@ import com.crowsofwar.avatar.AvatarMod; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; +import java.util.*; /** * Represents all controls needed to access by AvatarMod. This includes: @@ -48,8 +47,6 @@ public class AvatarControl { CONTROL_LEFT_CLICK_DOWN, CONTROL_RIGHT_CLICK_DOWN, CONTROL_MIDDLE_CLICK_DOWN, - CONTROL_SPACE, - CONTROL_SPACE_DOWN, CONTROL_JUMP, CONTROL_LEFT_CLICK_UP, CONTROL_RIGHT_CLICK_UP, @@ -64,7 +61,7 @@ public class AvatarControl { */ private AvatarControl(String name, boolean keybinding) { this.name = name; - this.needsKeybinding = keybinding; + needsKeybinding = keybinding; ALL_CONTROLS.add(this); } @@ -81,8 +78,6 @@ public static void initControls() { CONTROL_LEFT_CLICK_DOWN = new AvatarControl("LeftClickDown", false); CONTROL_RIGHT_CLICK_DOWN = new AvatarControl("RightClickDown", false); CONTROL_MIDDLE_CLICK_DOWN = new AvatarControl("MiddleClickDown", false); - CONTROL_SPACE = new AvatarControl("Space", false); - CONTROL_SPACE_DOWN = new AvatarControl("SpaceDown", false); CONTROL_JUMP = new AvatarControl("key.jump", true); CONTROL_LEFT_CLICK_UP = new AvatarControl("LeftClickUp", false); CONTROL_RIGHT_CLICK_UP = new AvatarControl("RightClickUp", false); diff --git a/src/main/java/com/crowsofwar/avatar/common/controls/KeybindingWrapper.java b/src/main/java/com/crowsofwar/avatar/common/controls/KeybindingWrapper.java index 0e9498b2c3..13b5ad9ace 100644 --- a/src/main/java/com/crowsofwar/avatar/common/controls/KeybindingWrapper.java +++ b/src/main/java/com/crowsofwar/avatar/common/controls/KeybindingWrapper.java @@ -17,7 +17,7 @@ package com.crowsofwar.avatar.common.controls; /** - * Wrapper class so vanilla KeyBinding class can be used on both sides + * Wrapper class so vanilla KeyBindings don't crash on the server side * * @author CrowsOfWar */ diff --git a/src/main/java/com/crowsofwar/avatar/common/data/AvatarPlayerData.java b/src/main/java/com/crowsofwar/avatar/common/data/AvatarPlayerData.java index 5ff387ac6c..97add7a1e2 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/AvatarPlayerData.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/AvatarPlayerData.java @@ -25,6 +25,7 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.WorldServer; +import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.network.NetworkRegistry.TargetPoint; import java.util.*; @@ -120,8 +121,9 @@ private void sendPacket() { } double range = Math.sqrt(rangeSq) + 0.01;// +0.01 "just in case" - AvatarMod.network.sendToAllAround(packet, - new TargetPoint(player.dimension, player.posX, player.posY, player.posZ, range)); + TargetPoint targetPoint = new TargetPoint(player.dimension, player.posX, player.posY, player.posZ, range); + //FMLLog.info("Target Point: " + targetPoint); + AvatarMod.network.sendToAllAround(packet, targetPoint); changed.clear(); diff --git a/src/main/java/com/crowsofwar/avatar/common/data/AvatarWorldData.java b/src/main/java/com/crowsofwar/avatar/common/data/AvatarWorldData.java index eba32ef9e7..167d2fa370 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/AvatarWorldData.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/AvatarWorldData.java @@ -56,7 +56,7 @@ public static AvatarWorldData getDataFromWorld(World world) { } @Override - public Class playerDataClass() { + public Class playerDataClass() { return AvatarPlayerData.class; } diff --git a/src/main/java/com/crowsofwar/avatar/common/data/Bender.java b/src/main/java/com/crowsofwar/avatar/common/data/Bender.java index 95545512e0..820b71b2a6 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/Bender.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/Bender.java @@ -21,7 +21,6 @@ import com.crowsofwar.avatar.common.QueuedAbilityExecutionHandler; import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.air.Airbending; -import com.crowsofwar.avatar.common.bending.earth.Earthbending; import com.crowsofwar.avatar.common.bending.water.Waterbending; import com.crowsofwar.avatar.common.data.ctx.AbilityContext; import com.crowsofwar.avatar.common.data.ctx.BendingContext; @@ -269,10 +268,10 @@ public void onUpdate() { Chi chi = data.chi(); if (CHI_CONFIG.lowChiDebuffs) { - if (chi.getTotalChi() <= chi.getMaxChi()/15) { + if (chi.getTotalChi() <= chi.getMaxChi() / 15) { entity.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 5)); } - if (chi.getTotalChi() <= chi.getMaxChi()/10) { + if (chi.getTotalChi() <= chi.getMaxChi() / 10) { entity.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 5)); } @@ -284,11 +283,11 @@ public void onUpdate() { chi.changeTotalChi(CHI_CONFIG.regenPerSecond / 20f); } if (data.hasBendingId(Waterbending.ID) && entity.isInWater()) { - chi.changeTotalChi(CHI_CONFIG.regenInWater/20F); + chi.changeTotalChi(CHI_CONFIG.regenInWater / 20F); } if (data.hasBendingId(Airbending.ID)) { - chi.changeTotalChi(CHI_CONFIG.regenPerSecond/10); + chi.changeTotalChi(CHI_CONFIG.regenPerSecond / 10); } if (chi.getAvailableChi() < CHI_CONFIG.maxAvailableChi) { @@ -302,13 +301,15 @@ public void onUpdate() { List tickHandlers = data.getAllTickHandlers(); if (tickHandlers != null) { for (TickHandler handler : tickHandlers) { - if (handler.tick(ctx)) { - // Can use this since the list is a COPY of the - // underlying list - data.removeTickHandler(handler); - } else { - int newDuration = data.getTickHandlerDuration(handler) + 1; - data.setTickHandlerDuration(handler, newDuration); + if (handler != null) { + if (handler.tick(ctx)) { + // Can use this since the list is a COPY of the + // underlying list + data.removeTickHandler(handler); + } else { + int newDuration = data.getTickHandlerDuration(handler) + 1; + data.setTickHandlerDuration(handler, newDuration); + } } } } diff --git a/src/main/java/com/crowsofwar/avatar/common/data/BenderInfoPlayer.java b/src/main/java/com/crowsofwar/avatar/common/data/BenderInfoPlayer.java index a948bd577d..7f8c68ab55 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/BenderInfoPlayer.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/BenderInfoPlayer.java @@ -15,7 +15,7 @@ public class BenderInfoPlayer extends BenderInfo { private UUID playerId; public BenderInfoPlayer(@Nonnull String playerName) { - this(AccountUUIDs.getId(playerName).getUUID()); + this(AccountUUIDs.getId(playerName)); } public BenderInfoPlayer(@Nonnull UUID playerId) { diff --git a/src/main/java/com/crowsofwar/avatar/common/data/BendingData.java b/src/main/java/com/crowsofwar/avatar/common/data/BendingData.java index dfaa999705..16c44dd476 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/BendingData.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/BendingData.java @@ -53,6 +53,7 @@ public class BendingData { private MiscData miscData; private Map powerRatingManagers; private Vision vision; + /** * Create a new BendingData * @@ -499,7 +500,7 @@ public MiscData getMiscData() { } public void setMiscData(MiscData md) { - this.miscData = md; + miscData = md; } public void writeToNbt(NBTTagCompound writeTo) { @@ -532,7 +533,9 @@ public void writeToNbt(NBTTagCompound writeTo) { chi().writeToNBT(writeTo); AvatarUtils.writeList(tickHandlers, - (nbt, handler) -> nbt.setInteger("Id", handler.id()), + (nbt, handler) -> { + if (handler != null && nbt != null) nbt.setInteger("Id", handler.id()); + }, writeTo, "TickHandlers"); @@ -588,8 +591,9 @@ public void readFromNbt(NBTTagCompound readFrom) { chi().readFromNBT(readFrom); AvatarUtils.readList(tickHandlers, // - nbt -> TickHandler.fromId(nbt.getInteger("Id")), // - readFrom, "TickHandlers"); + nbt -> { + return TickHandlerController.fromId(nbt.getInteger("Id")); + }, readFrom, "TickHandlers"); for (TickHandler tickHandler : tickHandlers) { tickHandlerDuration.putIfAbsent(tickHandler, 0); @@ -613,4 +617,4 @@ public void saveAll() { saveAll.run(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/crowsofwar/avatar/common/data/CachedEntity.java b/src/main/java/com/crowsofwar/avatar/common/data/CachedEntity.java index 46c6078e17..b5955a83da 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/CachedEntity.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/CachedEntity.java @@ -44,8 +44,7 @@ public CachedEntity(@Nullable UUID id) { } private static UUID getId(Entity entity) { - return entity instanceof EntityPlayer ? AccountUUIDs.getId(entity.getName()).getUUID() - : entity.getUniqueID(); + return entity instanceof EntityPlayer ? AccountUUIDs.getId(entity.getName()) : entity.getUniqueID(); } public void readFromNbt(NBTTagCompound nbt) { diff --git a/src/main/java/com/crowsofwar/avatar/common/data/PowerRatingManager.java b/src/main/java/com/crowsofwar/avatar/common/data/PowerRatingManager.java index 71d917ee14..36a12384be 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/PowerRatingManager.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/PowerRatingManager.java @@ -39,7 +39,7 @@ public double getRating(BendingContext ctx) { for (PowerRatingModifier modifier : modifiers) { result += modifier.get(ctx); } - return MathHelper.clamp(result, -100, 100); + return MathHelper.clamp(result, -1000, 1000); } public void addModifier(PowerRatingModifier modifier, BendingContext ctx) { diff --git a/src/main/java/com/crowsofwar/avatar/common/data/TickHandler.java b/src/main/java/com/crowsofwar/avatar/common/data/TickHandler.java index bd431b4f94..25052a1fdb 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/TickHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/TickHandler.java @@ -1,80 +1,33 @@ -/* +/* This file is part of AvatarMod. - + AvatarMod is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + AvatarMod is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with AvatarMod. If not, see . */ package com.crowsofwar.avatar.common.data; -import com.crowsofwar.avatar.common.bending.air.*; -import com.crowsofwar.avatar.common.bending.earth.SpawnEarthspikesHandler; -import com.crowsofwar.avatar.common.bending.fire.*; -import com.crowsofwar.avatar.common.bending.lightning.LightningCreateHandler; -import com.crowsofwar.avatar.common.bending.lightning.LightningRedirectHandler; -import com.crowsofwar.avatar.common.bending.water.WaterChargeHandler; -import com.crowsofwar.avatar.common.bending.water.WaterParticleSpawner; -import com.crowsofwar.avatar.common.bending.water.WaterSkateHandler; -import com.crowsofwar.avatar.common.bending.water.WaterSmashHandler; import com.crowsofwar.avatar.common.data.ctx.BendingContext; -import com.crowsofwar.avatar.common.entity.mob.BisonSummonHandler; import io.netty.buffer.ByteBuf; -import java.util.HashMap; -import java.util.Map; - /** * @author CrowsOfWar */ public abstract class TickHandler { - - public static TickHandler AIR_PARTICLE_SPAWNER = new AirParticleSpawner(); - public static TickHandler FIRE_PARTICLE_SPAWNER = new FireParticleSpawner(); - public static TickHandler FLAMETHROWER = new FlamethrowerUpdateTick(); - public static TickHandler WATER_SKATE = new WaterSkateHandler(); - public static TickHandler BISON_SUMMONER = new BisonSummonHandler(); - public static TickHandler SMASH_GROUND = new SmashGroundHandler(); - public static TickHandler LIGHTNING_CHARGE = new LightningCreateHandler(); - public static TickHandler WATER_CHARGE = new WaterChargeHandler(); - public static TickHandler LIGHTNING_REDIRECT = new LightningRedirectHandler(); - public static TickHandler SMASH_GROUND_FIRE = new FireSmashGroundHandler(); - public static TickHandler SMASH_GROUND_FIRE_BIG = new FireSmashGroundHandlerBig(); - public static TickHandler SMASH_GROUND_WATER = new WaterSmashHandler(); - public static TickHandler WATER_PARTICLE_SPAWNER = new WaterParticleSpawner(); - public static TickHandler INFERNO_PARTICLE_SPAWNER = new InfernoPunchParticleSpawner(); - public static TickHandler SPAWN_EARTHSPIKES_HANDLER = new SpawnEarthspikesHandler(); - public static TickHandler AIRBURST_CHARGE_HANDLER = new AirBurstHandler(); - public static TickHandler AIR_STATCTRL_HANDLER = new AirStatusControlHandler(); - public static TickHandler FIRE_STATCTRL_HANDLER = new FireStatusControlHandler(); - public static TickHandler AIR_DODGE = new AirDodgeHandler(); - - private static int nextId = 1; - private static Map allHandlers; private final int id; - public TickHandler() { - if (allHandlers == null) allHandlers = new HashMap<>(); - - id = nextId++; - allHandlers.put(id, this); - - } - - public static TickHandler fromId(int id) { - return allHandlers.get(id); - } - - public static TickHandler fromBytes(ByteBuf buf) { - return fromId(buf.readInt()); + public TickHandler(int id) { + this.id = id; + TickHandlerController.allHandlers.put(id, this); } /** diff --git a/src/main/java/com/crowsofwar/avatar/common/data/TickHandlerController.java b/src/main/java/com/crowsofwar/avatar/common/data/TickHandlerController.java new file mode 100644 index 0000000000..d392a0bd8c --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/data/TickHandlerController.java @@ -0,0 +1,57 @@ +package com.crowsofwar.avatar.common.data; + +import com.crowsofwar.avatar.client.gui.RenderElementTickHandler; +import com.crowsofwar.avatar.common.bending.air.*; +import com.crowsofwar.avatar.common.bending.earth.*; +import com.crowsofwar.avatar.common.bending.fire.*; +import com.crowsofwar.avatar.common.bending.lightning.*; +import com.crowsofwar.avatar.common.bending.water.*; +import com.crowsofwar.avatar.common.entity.mob.BisonSummonHandler; +import io.netty.buffer.ByteBuf; + +import java.util.*; + +/** + * @author Mahtaran + */ +public class TickHandlerController { + // @formatter:off + static Map allHandlers = new HashMap<>(); + public static TickHandler AIR_PARTICLE_SPAWNER = new AirParticleSpawner(0); + public static TickHandler FIRE_PARTICLE_SPAWNER = new FireParticleSpawner(1); + public static TickHandler FLAMETHROWER = new FlamethrowerUpdateTick(2); + public static TickHandler WATER_SKATE = new WaterSkateHandler(3); + public static TickHandler BISON_SUMMONER = new BisonSummonHandler(4); + public static TickHandler SMASH_GROUND = new SmashGroundHandler(5); + public static TickHandler LIGHTNING_CHARGE = new LightningCreateHandler(6); + public static TickHandler WATER_CHARGE = new WaterChargeHandler(7); + public static TickHandler LIGHTNING_REDIRECT = new LightningRedirectHandler(8); + public static TickHandler SMASH_GROUND_FIRE = new FireSmashGroundHandler(9); + public static TickHandler SMASH_GROUND_FIRE_BIG = new FireSmashGroundHandlerBig(10); + public static TickHandler SMASH_GROUND_WATER = new WaterSmashHandler(11); + public static TickHandler WATER_PARTICLE_SPAWNER = new WaterParticleSpawner(12); + public static TickHandler INFERNO_PARTICLE_SPAWNER = new InfernoPunchParticleSpawner(13); + public static TickHandler SPAWN_EARTHSPIKES_HANDLER = new SpawnEarthspikesHandler(14); + public static TickHandler AIRBURST_CHARGE_HANDLER = new AirBurstHandler(15); + public static TickHandler AIR_STATCTRL_HANDLER = new AirStatusControlHandler(16); + public static TickHandler FIRE_STATCTRL_HANDLER = new FireStatusControlHandler(17); + //public static TickHandler AIR_DODGE = new AirDodgeHandler(18); + public static TickHandler RENDER_ELEMENT_HANDLER = new RenderElementTickHandler(19); + public static TickHandler STAFF_GUST_HANDLER = new StaffGustCooldown(20); + public static TickHandler SLIPSTREAM_COOLDOWN_HANDLER = new SlipstreamCooldownHandler(21); + public static TickHandler PURIFY_COOLDOWN_HANDLER = new PurifyCooldownHandler(22); + public static TickHandler PURIFY_PARTICLE_SPAWNER = new PurifyParticleHandler(23); + public static TickHandler FIRE_DEVOUR_HANDLER = new FireDevourTickHandler(24); + public static TickHandler CLEANSE_COOLDOWN_HANDLER = new CleanseCooldownHandler(25); + public static TickHandler RESTORE_COOLDOWN_HANDLER = new RestoreCooldownHandler(26); + public static TickHandler RESTORE_PARTICLE_SPAWNER = new RestoreParticleHandler(27); + // @formatter:on + + public static TickHandler fromId(int id) { + return allHandlers.get(id); + } + + public static TickHandler fromBytes(ByteBuf buf) { + return fromId(buf.readInt()); + } +} diff --git a/src/main/java/com/crowsofwar/avatar/common/data/WallJumpManager.java b/src/main/java/com/crowsofwar/avatar/common/data/WallJumpManager.java index 9c5be474ad..a7ecca6b30 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/WallJumpManager.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/WallJumpManager.java @@ -15,6 +15,7 @@ import javax.annotation.Nullable; +import static com.crowsofwar.avatar.common.data.TickHandlerController.FIRE_PARTICLE_SPAWNER; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; /** @@ -116,7 +117,7 @@ public EnumParticleTypes getWallJumpParticleType() { // Fire jumping? AbilityData fireJumpData = bender.getData().getAbilityData("fire_jump"); boolean learnedSkill = fireJumpData.isMasterPath(AbilityData.AbilityTreePath.SECOND); - boolean isFireJumping = bender.getData().hasTickHandler(TickHandler.FIRE_PARTICLE_SPAWNER); + boolean isFireJumping = bender.getData().hasTickHandler(FIRE_PARTICLE_SPAWNER); if (isFireJumping && learnedSkill) { return AvatarParticles.getParticleFlames(); } diff --git a/src/main/java/com/crowsofwar/avatar/common/data/ctx/BendingContext.java b/src/main/java/com/crowsofwar/avatar/common/data/ctx/BendingContext.java index 44d4a3c096..2666946271 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/ctx/BendingContext.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/ctx/BendingContext.java @@ -26,6 +26,7 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockCauldron; import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; @@ -180,7 +181,12 @@ public boolean consumeWater(int amount) { EntityLivingBase entity = bender.getEntity(); - if (entity.getHeldItemMainhand().getItem() == Items.WATER_BUCKET || entity.getHeldItemOffhand().getItem() == Items.WATER_BUCKET) { + if (entity.getHeldItemMainhand().getItem() == Items.WATER_BUCKET) { + entity.setHeldItem(EnumHand.MAIN_HAND, new ItemStack(Items.BUCKET, 1)); + return true; + } + if (entity.getHeldItemOffhand().getItem() == Items.WATER_BUCKET) { + entity.setHeldItem(EnumHand.OFF_HAND, new ItemStack(Items.BUCKET, 1)); return true; } diff --git a/src/main/java/com/crowsofwar/avatar/common/data/ctx/PlayerBender.java b/src/main/java/com/crowsofwar/avatar/common/data/ctx/PlayerBender.java index 5556555768..776e1d0fbc 100644 --- a/src/main/java/com/crowsofwar/avatar/common/data/ctx/PlayerBender.java +++ b/src/main/java/com/crowsofwar/avatar/common/data/ctx/PlayerBender.java @@ -16,27 +16,25 @@ */ package com.crowsofwar.avatar.common.data.ctx; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.*; +import net.minecraft.item.ItemStack; + import com.crowsofwar.avatar.AvatarMod; import com.crowsofwar.avatar.client.gui.AvatarUiRenderer; -import com.crowsofwar.avatar.common.analytics.AnalyticEvents; -import com.crowsofwar.avatar.common.analytics.AvatarAnalytics; +import com.crowsofwar.avatar.common.analytics.*; import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.lightning.Lightningbending; import com.crowsofwar.avatar.common.data.*; import com.crowsofwar.avatar.common.entity.EntityLightningArc; import com.crowsofwar.avatar.common.entity.mob.EntityBender; import com.crowsofwar.avatar.common.item.AvatarItems; -import com.crowsofwar.avatar.common.network.packets.PacketCErrorMessage; -import com.crowsofwar.avatar.common.network.packets.PacketSUseAbility; +import com.crowsofwar.avatar.common.network.packets.*; import com.crowsofwar.avatar.common.util.Raytrace; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.item.ItemStack; import static com.crowsofwar.avatar.common.AvatarChatMessages.MSG_LIGHTNING_REDIRECT_SUCCESS; import static com.crowsofwar.avatar.common.config.ConfigChi.CHI_CONFIG; +import static com.crowsofwar.avatar.common.data.TickHandlerController.LIGHTNING_REDIRECT; /** * @author CrowsOfWar @@ -162,24 +160,22 @@ public BenderInfo getInfo() { return new BenderInfoPlayer(player.getName()); } + @Override public boolean redirectLightning(EntityLightningArc lightningArc) { if (lightningArc.isCreatedByRedirection()) { return false; } - EntityLivingBase owner = lightningArc.getOwner(); BendingData data = getData(); AbilityData abilityData = data.getAbilityData("lightning_redirect"); if ((owner instanceof EntityPlayer && !((EntityPlayer) owner).isCreative()) && abilityData.getLevel() == -1) { return false; - } - else if ((abilityData.getLevel() == -1 && (owner instanceof EntityBender))) { + } else if ((abilityData.getLevel() == -1 && (owner instanceof EntityBender))) { return false; - } - else if (!data.hasBendingId(Lightningbending.ID)){ + } else if (!data.hasBendingId(Lightningbending.ID)) { return false; } @@ -192,12 +188,11 @@ else if (!data.hasBendingId(Lightningbending.ID)){ if (lightningArc.getOwner() != null) { data.getMiscData().setRedirectionSource(originalShooterInfo); - data.addTickHandler(TickHandler.LIGHTNING_REDIRECT); + data.addTickHandler(LIGHTNING_REDIRECT); } - String lightningArcOwner = lightningArc.getOwner() == null ? "lightningbender" : - lightningArc.getOwner().getName(); + String lightningArcOwner = lightningArc.getOwner() == null ? "lightningbender" : lightningArc.getOwner().getName(); MSG_LIGHTNING_REDIRECT_SUCCESS.send(player, lightningArcOwner); return true; diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/AvatarEntity.java b/src/main/java/com/crowsofwar/avatar/common/entity/AvatarEntity.java index 9b3f46454d..3ed71f6961 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/AvatarEntity.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/AvatarEntity.java @@ -17,8 +17,8 @@ package com.crowsofwar.avatar.common.entity; -import com.crowsofwar.avatar.common.AvatarDamageSource; import com.crowsofwar.avatar.common.bending.Ability; +import com.crowsofwar.avatar.common.bending.BendingStyle; import com.crowsofwar.avatar.common.data.AvatarWorldData; import com.crowsofwar.avatar.common.entity.data.SyncedEntity; import com.crowsofwar.avatar.common.particle.ClientParticleSpawner; @@ -49,9 +49,7 @@ import net.minecraft.world.World; import javax.annotation.Nullable; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.UUID; import java.util.function.Predicate; @@ -267,6 +265,16 @@ public void onUpdate() { } } } + for (int x = 0; x >= -1; x--) { + for (int z = 0; z >= -1; z--) { + BlockPos pos = new BlockPos(posX + x * width, posY, posZ + z * width); + if (world.getBlockState(pos).getBlock() == Blocks.FIRE) { + world.setBlockToAir(pos); + world.playSound(posX, posY, posZ, SoundEvents.BLOCK_FIRE_EXTINGUISH, + SoundCategory.PLAYERS, 1, 1, false); + } + } + } } @@ -349,7 +357,7 @@ public boolean canCollideWith(Entity entity) { if (entity == getOwner()) { return false; } - else return entity instanceof AvatarEntity; + else return entity instanceof AvatarEntity || entity instanceof EntityLivingBase; } @Override @@ -365,7 +373,7 @@ public void applyEntityCollision(Entity entity) { * confused with the vanilla {@link #applyEntityCollision(Entity)}, which is * where another entity is pushing this one. */ - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { } /** @@ -402,6 +410,12 @@ public boolean onFireContact() { return false; } + /** + * Called when a lightning bolt or source of lightning hits the enitty + */ + public boolean onLightningContact() { + return false; + } /** * Called when an airbending entity (such as an air gust) hits the entity. Returns whether * the entity was destroyed. @@ -423,7 +437,7 @@ public boolean canPush() { */ public boolean canDamageEntity(Entity entity) { - if (entity instanceof AvatarEntity && ((AvatarEntity) entity).getOwner() != entity) { + if (entity instanceof AvatarEntity && ((AvatarEntity) entity).getOwner() == entity) { return false; } if (entity instanceof EntityHanging || entity instanceof EntityXPOrb || entity instanceof EntityItem || @@ -540,4 +554,9 @@ public boolean shouldRenderInPass(int pass) { @Override protected void playStepSound(BlockPos pos, Block blockIn) { } + + //Used to determine what element the entity is + public BendingStyle getElement() { + return null; + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirBubble.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirBubble.java index 34c6bac712..3d12a53146 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirBubble.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirBubble.java @@ -16,7 +16,9 @@ */ package com.crowsofwar.avatar.common.entity; +import com.crowsofwar.avatar.common.bending.BendingStyle; import com.crowsofwar.avatar.common.bending.StatusControl; +import com.crowsofwar.avatar.common.bending.air.Airbending; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.util.AvatarUtils; @@ -30,8 +32,6 @@ import net.minecraft.entity.ai.attributes.IAttributeInstance; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityXPOrb; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.init.SoundEvents; @@ -88,6 +88,11 @@ protected void entityInit() { dataManager.register(SYNC_SIZE, 2.5f); } + @Override + public BendingStyle getElement() { + return new Airbending(); + } + @Override public EntityLivingBase getController() { return !isDissipating() ? getOwner() : null; @@ -109,9 +114,8 @@ public void setSize(float size) { dataManager.set(SYNC_SIZE, size); } - @Override - public void setVelocity(double x, double y, double z) { + public void setVelocity(Vector velocity) { super.setVelocity(0, 0, 0); } @@ -120,12 +124,6 @@ public void setPositionAndUpdate(double x, double y, double z) { if (getOwner() != null) { super.setPositionAndUpdate(getOwner().posX, getOwner().getEntityBoundingBox().minY, getOwner().posZ); - this.posX = getOwner().posX; - this.posY = getOwner().getEntityBoundingBox().minY; - this.posZ = getOwner().posZ; - - this.motionX = this.motionY = this.motionZ = 0; - } } @@ -134,6 +132,12 @@ public boolean canBeCollidedWith() { return true; } + + @Override + public boolean isPushedByWater() { + return false; + } + @Override public void onUpdate() { //super.onUpdate(); @@ -151,8 +155,12 @@ public void onUpdate() { return; } - - if (putsOutFires) { + if (owner.isDead) { + dissipateSmall(); + removeStatCtrl(); + return; + } + if (putsOutFires && ticksExisted % 2 == 0) { setFire(0); for (int x = 0; x <= 1; x++) { for (int z = 0; z <= 1; z++) { @@ -176,25 +184,26 @@ public void onUpdate() { } } - if (owner.isDead) { - dissipateSmall(); - removeStatCtrl(); - return; - } - for (int i = 0; i < 2; i++) { - setPosition(owner.posX, owner.getEntityBoundingBox().minY, owner.posZ); + Vector pos1 = this.position(); + Vector pos2 = this.position(); + setPosition(owner.posX, owner.getEntityBoundingBox().minY, owner.posZ); this.motionX = this.motionY = this.motionZ = 0; - if (!world.isRemote) { this.posX = owner.posX; this.posY = owner.getEntityBoundingBox().minY; this.posZ = owner.posZ; + this.motionX = this.motionY = this.motionZ = 0; + pos2 = this.position(); } - - this.motionX = this.motionY = this.motionZ = 0; + resetPositionToBB(); + if (pos1 != pos2) { + System.out.println(pos1); + System.out.println(pos2); + System.out.println(getEntityPos(getOwner())); } + if (getOwner() != null) { EntityAirBubble bubble = AvatarEntity.lookupControlledEntity(world, EntityAirBubble.class, getOwner()); BendingData bD = BendingData.get(getOwner()); @@ -204,6 +213,16 @@ public void onUpdate() { } } + AxisAlignedBB box = new AxisAlignedBB(getEntityBoundingBox().minX - (getSize()/10), getEntityBoundingBox().minY, getEntityBoundingBox().minZ - (getSize()/10), + getEntityBoundingBox().maxX + (getSize()/10), getEntityBoundingBox().maxY + (getSize()/4), getEntityBoundingBox().maxZ + (getSize()/4)); + List nearby = world.getEntitiesWithinAABB(Entity.class, box); + if (!nearby.isEmpty()) { + for (Entity collided : nearby) { + if (collided != this && collided != getOwner() && collided.canBePushed()) { + onCollideWithEntity(collided); + } + } + } if (!world.isRemote && owner.isInsideOfMaterial(Material.WATER)) { owner.setAir(Math.min(airLeft, 300)); @@ -211,40 +230,42 @@ public void onUpdate() { } Bender ownerBender = Bender.get(getOwner()); - if (!world.isRemote && !ownerBender.consumeChi(STATS_CONFIG.chiAirBubbleOneSecond / 20f)) { + if (ownerBender != null) { + if (!world.isRemote && !ownerBender.consumeChi(STATS_CONFIG.chiAirBubbleOneSecond / 20f)) { - dissipateSmall(); + dissipateSmall(); - } - - ItemStack chest = owner.getItemStackFromSlot(EntityEquipmentSlot.CHEST); - boolean elytraOk = (STATS_CONFIG.allowAirBubbleElytra || chest.getItem() != Items.ELYTRA); - if (!elytraOk) { - ownerBender.sendMessage("avatar.airBubbleElytra"); - dissipateSmall(); - } + } - if (!isDissipating()) { - IAttributeInstance attribute = owner.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); - if (attribute.getModifier(SLOW_ATTR_ID) == null) { - attribute.applyModifier(SLOW_ATTR); + ItemStack chest = owner.getItemStackFromSlot(EntityEquipmentSlot.CHEST); + boolean elytraOk = (STATS_CONFIG.allowAirBubbleElytra || chest.getItem() != Items.ELYTRA); + if (!elytraOk) { + ownerBender.sendMessage("avatar.airBubbleElytra"); + dissipateSmall(); } - if (!owner.isInWater() && !ownerBender.isFlying() && chest.getItem() != Items.ELYTRA) { + if (!isDissipating()) { + IAttributeInstance attribute = owner.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); + if (attribute.getModifier(SLOW_ATTR_ID) == null) { + attribute.applyModifier(SLOW_ATTR); + } - owner.motionY += 0.03; + if (!ownerBender.isFlying() && chest.getItem() != Items.ELYTRA) { - if (doesAllowHovering()) { + owner.motionY += 0.03; - if (doesAllowHovering() && !owner.isSneaking()) { - handleHovering(); - } else { - owner.motionY += 0.03; + if (doesAllowHovering()) { + + if (doesAllowHovering() && !owner.isSneaking()) { + handleHovering(); + } else { + owner.motionY += 0.03; + } } + } } - } float size = getSize(); @@ -269,6 +290,11 @@ public void onUpdate() { } + @Override + public boolean canBePushed() { + return false; + } + /** * Handles hovering logic to make the owner hover. Preconditions (not in water, owner * present, etc) are handled by the caller @@ -285,7 +311,7 @@ private void handleHovering() { // Min/max acceptable hovering distance // Hovering is allowed between these two values // Hover distance doesn't need to be EXACT - final double minFloatHeight = 1.5; + final double minFloatHeight = 1.2; final double maxFloatHeight = 3; EntityLivingBase owner = getOwner(); @@ -329,7 +355,7 @@ private void handleHovering() { owner.motionY += 0.11; } if (distanceFromGround >= minFloatHeight && distanceFromGround < maxFloatHeight) { - owner.motionY *= 0.7; + owner.motionY *= 0.8; } if (distanceFromGround >= maxFloatHeight) { owner.motionY += 0.07; @@ -361,27 +387,37 @@ public boolean canPush() { } @Override - protected void onCollideWithEntity(Entity entity) { - if (canCollideWith(entity) && entity != getOwner()) { + public void onCollideWithEntity(Entity entity) { + if (entity instanceof AvatarEntity) { + if (((AvatarEntity) entity).getOwner() != getOwner()) { + ((AvatarEntity) entity).onAirContact(); + } + } - double mult = -2; - if (isDissipatingLarge()) mult = -4; - Vector vel = position().minus(getEntityPos(entity)); - vel = vel.normalize().times(mult).plusY(0.3f); + if (canCollideWith(entity) && entity != getOwner() && getOwner() != null) { - entity.motionX = vel.x(); - entity.motionY = vel.y(); - entity.motionZ = vel.z(); + + Vector velocity = getEntityPos(entity).minus(getEntityPos(getOwner())); + //Vector that comes from the owner of the air bubble towards the entity being collided with + double dist = getOwner().getDistance(entity); + double sizeMult = isDissipatingLarge() ? 4 * (getSize() * 2/3) : 2 * (getSize() * 2/3); + double mult = (dist - getSize()) * sizeMult > 1 ? (dist - getSize()) * sizeMult : 1 * sizeMult; + velocity = velocity.normalize().times(mult).withY(getSize()/4); + + //The velocity is 20 times the motion of the entity, so you wanna divide by 20, unless you wanna make the entities + //that have been collided with fly super far way + entity.addVelocity(velocity.x()/2, velocity.y(), velocity.z()/2); if (entity instanceof AvatarEntity) { AvatarEntity avent = (AvatarEntity) entity; - avent.setVelocity(vel); + avent.setVelocity(velocity); } entity.isAirBorne = true; AvatarUtils.afterVelocityAdded(entity); } } + @Override public boolean canCollideWith(Entity entity) { if (entity instanceof AvatarEntity && ((AvatarEntity) entity).getOwner() == getOwner()) { diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirGust.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirGust.java index f2f5b05319..ba735956bf 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirGust.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirGust.java @@ -17,6 +17,8 @@ package com.crowsofwar.avatar.common.entity; +import com.crowsofwar.avatar.common.bending.BendingStyle; +import com.crowsofwar.avatar.common.bending.air.Airbending; import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; @@ -39,6 +41,7 @@ public EntityAirGust(World world) { super(world); setSize(1.5f, 1.5f); putsOutFires = true; + this.noClip = true; } @Override @@ -55,6 +58,11 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { nbt.setBoolean("DestroyProjectiles", destroyProjectiles); } + @Override + public BendingStyle getElement() { + return new Airbending(); + } + @Override public void onUpdate() { super.onUpdate(); @@ -67,9 +75,9 @@ public void onUpdate() { } @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { EntityLivingBase owner = getOwner(); - if (!entity.world.isRemote && entity != owner && canCollideWith(entity)) { + if (!entity.world.isRemote && entity != owner && canCollideWith(entity) && owner != null) { if (entity instanceof AvatarEntity) { AvatarEntity avatarEntity = (AvatarEntity) entity; diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirSlash.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirSlash.java new file mode 100644 index 0000000000..e2d9ae884c --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirSlash.java @@ -0,0 +1,224 @@ +/*package com.crowsofwar.avatar.common.entity; + +import com.crowsofwar.avatar.common.AvatarDamageSource; +import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; +import com.crowsofwar.avatar.common.bending.BendingStyle; +import com.crowsofwar.avatar.common.bending.air.Airbending; +import com.crowsofwar.avatar.common.data.Bender; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.util.AvatarUtils; +import com.crowsofwar.gorecore.util.Vector; +import com.google.common.base.Predicate; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.Blocks; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.DamageSource; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.List; + +import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; +import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; + +public class EntityAirSlash extends AvatarEntity { + + private float damage; + + /** + * Hardness threshold to chop blocks. For example, setting to 1.5 will allow + * the airblade to chop stone. + *

+ * Note: Threshold of 0 means that the airblade can chop grass and similar + * blocks. Set to > 0 to avoid chopping blocks at all. + */ + /*private float chopBlocksThreshold; + private boolean chainAttack; + private boolean pierceArmor; + + public EntityAirSlash(World world) { + super(world); + setSize(1.5f, .2f); + this.chopBlocksThreshold = -1; + } + + @Override + public BendingStyle getElement() { + return new Airbending(); + } + + @Override + public boolean canCollideWith(Entity entity) { + return super.canCollideWith(entity) && entity != getOwner(); + } + + @Override + public void onUpdate() { + + super.onUpdate(); + + this.motionX = this.motionX * 0.95; + this.motionY = this.motionY * 0.95; + this.motionZ = this.motionZ * 0.95; + + if (!world.isRemote && velocity().sqrMagnitude() <= .7) { + setDead(); + } + + if (this.ticksExisted > 200) { + this.setDead(); + } + if (!world.isRemote && inWater) { + setDead(); + } + + if (!world.isRemote && chopBlocksThreshold >= 0 && this.collidedHorizontally) { + breakCollidingBlocks(); + + } + + if (!isDead && !world.isRemote) { + List collidedList = world.getEntitiesWithinAABB(Entity.class, + getEntityBoundingBox()); + + if (!collidedList.isEmpty()) { + for (Entity collided : collidedList) { + if (collided instanceof AvatarEntity) { + ((AvatarEntity) collided).onAirContact(); + } else if (canCollideWith(collided)) { + handleCollision((EntityLivingBase) collided); + } + + } + } + } + + } + + private void handleCollision(EntityLivingBase collided) { + Vector motion = velocity(); + motion = motion.times(STATS_CONFIG.airbladeSettings.push).withY(0.08); + collided.addVelocity(motion.x(), motion.y(), motion.z()); + + if (canDamageEntity(collided)) { + + + DamageSource source = AvatarDamageSource.causeAirbladeDamage(collided, getOwner()); + if (pierceArmor) { + source.setDamageBypassesArmor(); + } + + boolean successfulHit = collided.attackEntityFrom(source, damage); + + if (getOwner() != null) { + BendingData data = getOwnerBender().getData(); + data.getAbilityData("airblade").addXp(SKILLS_CONFIG.airbladeHit); + } + + if (successfulHit) { + BattlePerformanceScore.addMediumScore(getOwner()); + } + + if (chainAttack) { + if (successfulHit) { + + AxisAlignedBB aabb = getEntityBoundingBox().grow(10); + Predicate notFriendly =// + entity -> entity != collided && entity != getOwner(); + + List nextTargets = world.getEntitiesWithinAABB + (EntityLivingBase.class, aabb, notFriendly); + + nextTargets.sort(AvatarUtils.getSortByDistanceComparator + (this::getDistance)); + + if (!nextTargets.isEmpty()) { + EntityLivingBase nextTarget = nextTargets.get(0); + Vector direction = Vector.getEntityPos(nextTarget).minus(this.position()); + setVelocity(direction.normalize().times(velocity().magnitude() * + 0.5)); + } + + } + } else if (!world.isRemote) { + setDead(); + } + + } + } + + /** + * When the airblade can break blocks, checks any blocks that the airblade + * collides with and tries to break them + */ + /* private void breakCollidingBlocks() { + // Hitbox expansion (in each direction) to destroy blocks before the + // airblade collides with them + double expansion = 0.1; + AxisAlignedBB hitbox = getEntityBoundingBox().grow(expansion, expansion, expansion); + + for (int ix = 0; ix <= 1; ix++) { + for (int iz = 0; iz <= 1; iz++) { + + double x = ix == 0 ? hitbox.minX : hitbox.maxX; + double y = hitbox.minY; + double z = iz == 0 ? hitbox.minZ : hitbox.maxZ; + BlockPos pos = new BlockPos(x, y, z); + + tryBreakBlock(world.getBlockState(pos), pos); + + } + } + } + + /** + * Assuming the airblade can break blocks, tries to break the block. + */ + /* private void tryBreakBlock(IBlockState state, BlockPos pos) { + if (state.getBlock() == Blocks.AIR || !STATS_CONFIG.airBladeBreakableBlocks.contains(state.getBlock())) { + return; + } + if (!this.collidedHorizontally) { + return; + } + + float hardness = state.getBlockHardness(world, pos); + if (hardness <= chopBlocksThreshold) { + breakBlock(pos); + setVelocity(velocity().times(0.5)); + } + } + + + public Bender getOwnerBender() { + return Bender.get(getOwner()); + } + + public void setDamage(float damage) { + this.damage = damage; + } + + + @Override + protected void readEntityFromNBT(NBTTagCompound nbt) { + super.readEntityFromNBT(nbt); + damage = nbt.getFloat("Damage"); + + } + + @Override + protected void writeEntityToNBT(NBTTagCompound nbt) { + super.writeEntityToNBT(nbt); + nbt.setFloat("Damage", damage); + } + + @Override + public boolean isProjectile() { + return true; + } + +} +**/ \ No newline at end of file diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirblade.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirblade.java index 097d944308..83fed31733 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirblade.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityAirblade.java @@ -18,6 +18,8 @@ import com.crowsofwar.avatar.common.AvatarDamageSource; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; +import com.crowsofwar.avatar.common.bending.BendingStyle; +import com.crowsofwar.avatar.common.bending.air.Airbending; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.util.AvatarUtils; @@ -62,6 +64,16 @@ public EntityAirblade(World world) { this.chopBlocksThreshold = -1; } + @Override + public BendingStyle getElement() { + return new Airbending(); + } + + @Override + public boolean canCollideWith(Entity entity) { + return super.canCollideWith(entity) && entity != getOwner(); + } + @Override public void onUpdate() { @@ -74,12 +86,16 @@ public void onUpdate() { if (!world.isRemote && velocity().sqrMagnitude() <= .9) { setDead(); } + + if (this.ticksExisted > 200) { + this.setDead(); + } if (!world.isRemote && inWater) { setDead(); } if (!world.isRemote && chopBlocksThreshold >= 0 && this.collidedHorizontally) { - breakCollidingBlocks(); + breakCollidingBlocks(); } @@ -102,51 +118,55 @@ public void onUpdate() { } private void handleCollision(EntityLivingBase collided) { - - DamageSource source = AvatarDamageSource.causeAirbladeDamage(collided, getOwner()); - if (pierceArmor) { - source.setDamageBypassesArmor(); - } - boolean successfulHit = collided.attackEntityFrom(source, damage); - Vector motion = velocity(); motion = motion.times(STATS_CONFIG.airbladeSettings.push).withY(0.08); collided.addVelocity(motion.x(), motion.y(), motion.z()); - if (getOwner() != null) { - BendingData data = getOwnerBender().getData(); - data.getAbilityData("airblade").addXp(SKILLS_CONFIG.airbladeHit); - } + if (canDamageEntity(collided)) { - if (successfulHit) { - BattlePerformanceScore.addMediumScore(getOwner()); - } - if (chainAttack) { + DamageSource source = AvatarDamageSource.causeAirbladeDamage(collided, getOwner()); + if (pierceArmor) { + source.setDamageBypassesArmor(); + } + + boolean successfulHit = collided.attackEntityFrom(source, damage); + + if (getOwner() != null) { + BendingData data = getOwnerBender().getData(); + data.getAbilityData("airblade").addXp(SKILLS_CONFIG.airbladeHit); + } + if (successfulHit) { + BattlePerformanceScore.addMediumScore(getOwner()); + } - AxisAlignedBB aabb = getEntityBoundingBox().grow(10); - Predicate notFriendly =// - entity -> entity != collided && entity != getOwner(); + if (chainAttack) { + if (successfulHit) { - List nextTargets = world.getEntitiesWithinAABB - (EntityLivingBase.class, aabb, notFriendly); + AxisAlignedBB aabb = getEntityBoundingBox().grow(10); + Predicate notFriendly =// + entity -> entity != collided && entity != getOwner(); - nextTargets.sort(AvatarUtils.getSortByDistanceComparator - (this::getDistance)); + List nextTargets = world.getEntitiesWithinAABB + (EntityLivingBase.class, aabb, notFriendly); - if (!nextTargets.isEmpty()) { - EntityLivingBase nextTarget = nextTargets.get(0); - Vector direction = Vector.getEntityPos(nextTarget).minus(this.position()); - setVelocity(direction.normalize().times(velocity().magnitude() * - 0.5)); - } + nextTargets.sort(AvatarUtils.getSortByDistanceComparator + (this::getDistance)); + + if (!nextTargets.isEmpty()) { + EntityLivingBase nextTarget = nextTargets.get(0); + Vector direction = Vector.getEntityPos(nextTarget).minus(this.position()); + setVelocity(direction.normalize().times(velocity().magnitude() * + 0.5)); + } + } + } else if (!world.isRemote) { + setDead(); } - } else if (!world.isRemote) { - setDead(); - } + } } /** @@ -191,10 +211,6 @@ private void tryBreakBlock(IBlockState state, BlockPos pos) { } } - @Override - public void setDead() { - super.setDead(); - } public Bender getOwnerBender() { return Bender.get(getOwner()); diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityArc.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityArc.java index 8e1627c50c..2213039a13 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityArc.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityArc.java @@ -32,11 +32,13 @@ public abstract class EntityArc extends AvatarEntity { private List points; private int brightness = 15728880; + public double velocityMultiplier; public EntityArc(World world) { super(world); float size = .2f; setSize(size, size); + this.velocityMultiplier = 4; this.points = new ArrayList<>(); for (int i = 0; i < getAmountOfControlPoints(); i++) { @@ -122,7 +124,7 @@ protected void updateCpBehavior() { } else if (sqrDist > getControlPointMaxDistanceSq()) { Vector diff = leader.position().minus(p.position()); - diff = diff.normalize().times(3); + diff = diff.normalize().times(velocityMultiplier); p.setVelocity(p.velocity().plus(diff)); } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityAvatarLightning.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityAvatarLightning.java index caf88bd8c7..3f1aae9133 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityAvatarLightning.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityAvatarLightning.java @@ -18,6 +18,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.common.Mod; + import java.util.List; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; @@ -125,7 +126,7 @@ public void onUpdate() { if (entity instanceof AvatarEntity) { ((AvatarEntity) entity).onFireContact(); } else if (entity instanceof EntityLivingBase) { - handleCollision((EntityLivingBase) entity); + handleCollision(entity); } } @@ -134,19 +135,36 @@ public void onUpdate() { } +/* @SubscribeEvent + public static void onLightningStrike(LivingHurtEvent event) { + Entity hurt = event.getEntity(); + Entity source = event.getSource().getTrueSource(); + DamageSource damage = event.getSource(); + if (damage == DamageSource.LIGHTNING_BOLT) { + + if (source instanceof EntityAvatarLightning) { + event.setAmount(0); + EntityAvatarLightning lightning = (EntityAvatarLightning) source; + lightning.handleCollision(hurt); + System.out.println(event.getAmount()); + } + } + }**/ - private void handleCollision(EntityLivingBase collided) { - damageEntity(collided); + private void handleCollision(Entity collided) { + if (spawner.canDamageEntity(collided)) { + damageEntity(collided); + } collided.setFire(collided.isImmuneToFire() ? 0 : 8); } - private void damageEntity(EntityLivingBase entity) { + private void damageEntity(Entity entity) { if (world.isRemote) { return; } - DamageSource damageSource = AvatarDamageSource.causeLightningDamage(entity, spawner.getOwner()); + DamageSource damageSource = AvatarDamageSource.LIGHTNING; float damage = STATS_CONFIG.lightningRazeSettings.damage; if (spawner.getAbility() instanceof AbilityLightningRaze) { diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityBoulder.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityBoulder.java index 33d4e2427e..f5dc8a87bc 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityBoulder.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityBoulder.java @@ -3,18 +3,14 @@ import com.crowsofwar.avatar.common.AvatarDamageSource; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; import com.crowsofwar.avatar.common.bending.StatusControl; -import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.entity.data.Behavior; import com.crowsofwar.avatar.common.entity.data.BoulderBehavior; -import com.crowsofwar.avatar.common.entity.mob.EntityBender; import com.crowsofwar.gorecore.util.Vector; - import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.datasync.DataParameter; @@ -22,7 +18,6 @@ import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; import net.minecraft.util.math.AxisAlignedBB; - import net.minecraft.world.World; @@ -133,6 +128,7 @@ public EntityBoulder (World world) { } + @Override public void entityInit() { super.entityInit(); @@ -157,7 +153,9 @@ public void onUpdate() { super.onUpdate(); - + if (getBehavior() == null) { + this.setDead(); + } setBehavior((BoulderBehavior) getBehavior().onUpdate(this)); if (Health <= 0) { @@ -222,7 +220,7 @@ public void setDead() { } @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { if (!world.isRemote) { pushEntity(entity); if (attackEntity(entity)) { diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityCloudBall.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityCloudBall.java index 26bf62c85c..c0dfdf8831 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityCloudBall.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityCloudBall.java @@ -26,32 +26,32 @@ import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.WorldServer; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; +import java.util.Objects; import java.util.UUID; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; -import static com.crowsofwar.gorecore.util.Vector.getEntityPos; +import static com.crowsofwar.avatar.common.data.TickHandlerController.AIR_STATCTRL_HANDLER; public class EntityCloudBall extends AvatarEntity { /** * @param world */ public static final DataParameter SYNC_BEHAVIOR = EntityDataManager - .createKey(EntityCloudBall.class, CloudburstBehavior.DATA_SERIALIZER); + .createKey(EntityCloudBall.class, CloudburstBehavior.DATA_SERIALIZER); - public static final DataParameter SYNC_SIZE = EntityDataManager.createKey(EntityCloudBall.class, - DataSerializers.VARINT); + public static final DataParameter SYNC_SIZE = EntityDataManager.createKey(EntityCloudBall.class, DataSerializers.VARINT); private AxisAlignedBB expandedHitbox; private float damage; private boolean absorbtion; private boolean chismash; - private BlockPos position; /** * @param world @@ -63,15 +63,11 @@ public EntityCloudBall(World world) { } public void canAbsorb(boolean canAbsorb) { - this.absorbtion = canAbsorb; + absorbtion = canAbsorb; } public void canchiSmash(boolean canchiSmash) { - this.chismash = canchiSmash; - } - - public void setStartingPosition(BlockPos position) { - this.position = position; + chismash = canchiSmash; } @Override @@ -81,22 +77,25 @@ public void entityInit() { dataManager.register(SYNC_SIZE, 30); } - @Override public void onUpdate() { super.onUpdate(); int ticks = 0; + if (getBehavior() == null) { + this.setBehavior(new CloudburstBehavior.PlayerControlled()); + } setBehavior((CloudburstBehavior) getBehavior().onUpdate(this)); - if (this.getBehavior() instanceof CloudburstBehavior.Thrown) { + if (getBehavior() instanceof CloudburstBehavior.Thrown) { ticks++; if (ticks >= 200) { cloudBurst(); - this.setDead(); + setDead(); } } if (ticksExisted % 2 == 0) { - world.playSound(null, posX, posY, posZ, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, (0.05F), (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F); + world.playSound(null, posX, posY, posZ, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, (0.05F), + (1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F); } // Add hook or something @@ -111,7 +110,8 @@ public void onUpdate() { if (ball == null && bD.hasStatusControl(StatusControl.THROW_CLOUDBURST)) { bD.removeStatusControl(StatusControl.THROW_CLOUDBURST); } - if (ball != null && ball.getBehavior() instanceof CloudburstBehavior.PlayerControlled && !(bD.hasStatusControl(StatusControl.THROW_CLOUDBURST))) { + if (ball != null && ball.getBehavior() instanceof CloudburstBehavior.PlayerControlled && !(bD + .hasStatusControl(StatusControl.THROW_CLOUDBURST))) { bD.addStatusControl(StatusControl.THROW_CLOUDBURST); } @@ -148,6 +148,15 @@ public void setSize(int size) { dataManager.set(SYNC_SIZE, size); } + @Override + public void setDead() { + super.setDead(); + if (getOwner() != null && !world.isRemote && isDead) { + BendingData data = BendingData.get(getOwner()); + data.addTickHandler(AIR_STATCTRL_HANDLER); + } + } + @Override public boolean onCollideWithSolid() { @@ -194,9 +203,8 @@ public boolean canCollideWith(Entity entity) { for (UUID uuid : data.getAllBendingIds()) { CloudburstPowerModifier cloudModifier = new CloudburstPowerModifier(); cloudModifier.setTicks(100); - data.getPowerRatingManager(uuid).addModifier(cloudModifier, new - BendingContext(data, (EntityLivingBase) entity, new - Raytrace.Result())); + Objects.requireNonNull(data.getPowerRatingManager(uuid)) + .addModifier(cloudModifier, new BendingContext(data, (EntityLivingBase) entity, new Raytrace.Result())); } } @@ -235,7 +243,7 @@ public void writeEntityToNBT(NBTTagCompound nbt) { } public AxisAlignedBB getExpandedHitbox() { - return this.expandedHitbox; + return expandedHitbox; } public void cloudBurst() { @@ -254,34 +262,44 @@ public void cloudBurst() { hitBox = 4; } - this.setInvisible(true); - WorldServer World = (WorldServer) this.world; + setInvisible(true); + WorldServer World = (WorldServer) world; World.spawnParticle(EnumParticleTypes.CLOUD, posX, posY, posZ, 50, 0, 0, 0, speed); - world.playSound(null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F); + world.playSound(null, posX, posY, posZ, SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, SoundCategory.BLOCKS, 4.0F, + (1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F); List collided = world.getEntitiesInAABBexcluding(this, getEntityBoundingBox().grow(hitBox, hitBox, hitBox), - entity -> entity != getOwner()); + entity -> entity != getOwner()); if (!collided.isEmpty()) { for (Entity entity : collided) { - - damageEntity(entity); - - double mult = abilityData.getLevel() >= 2 ? -3 : -1.5; - double distanceTravelled = entity.getDistance(this.position.getX(), this.position.getY(), this.position.getZ()); - - Vector vel = position().minus(getEntityPos(entity)); - vel = vel.normalize().times(mult).plusY(0.15f); - - entity.motionX = vel.x() + distanceTravelled / 50; - entity.motionY = vel.y() > 0 ? vel.y() + distanceTravelled / 100 : 0.3F + distanceTravelled / 100; - entity.motionZ = vel.z() + distanceTravelled / 50; - - if (entity instanceof AvatarEntity) { - AvatarEntity avent = (AvatarEntity) entity; - avent.setVelocity(vel); + if (entity != getOwner() && entity != null && getOwner() != null) { + + damageEntity(entity); + + //Divide the result of the position difference to make entities fly + //further the closer they are to the player. + double dist = (hitBox - entity.getDistance(entity)) > 1 ? (hitBox- entity.getDistance(entity)) : 1; + Vector velocity = Vector.getEntityPos(entity).minus(Vector.getEntityPos(this)); + velocity = velocity.dividedBy(40).times(dist).withY(hitBox/50); + + double x = (velocity.x()); + double y = (velocity.y()) > 0 ? velocity.y() : 0.3F; + double z = (velocity.z()); + + if (!entity.world.isRemote) { + entity.addVelocity(x, y, z); + + if (collided instanceof AvatarEntity) { + if (!(collided instanceof EntityWall) && !(collided instanceof EntityWallSegment) + && !(collided instanceof EntityIcePrison) && !(collided instanceof EntitySandPrison)) { + AvatarEntity avent = (AvatarEntity) collided; + avent.addVelocity(x, y, z); + } + entity.isAirBorne = true; + AvatarUtils.afterVelocityAdded(entity); + } + } } - entity.isAirBorne = true; - AvatarUtils.afterVelocityAdded(entity); } } @@ -293,20 +311,20 @@ public void damageEntity(Entity entity) { if (getOwner() != null) { BendingData data = BendingData.get(getOwner()); AbilityData abilityData = data.getAbilityData("cloudburst"); - DamageSource ds = AvatarDamageSource.causeCloudburstDamage(entity, getOwner()); + DamageSource ds = AvatarDamageSource.causeAirDamage(entity, getOwner()); int lvl = abilityData.getLevel(); - float damage = 0.5F; + float damage = getDamage() / 3; if (lvl == 1) { - damage = 1; + damage = getDamage() / 2; } if (lvl == 2) { - damage = 1.5F; + damage = getDamage() / 1.5F; } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { - damage = 2; + damage = getDamage(); } if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { - damage = 2.5F; + damage = getDamage(); } entity.attackEntityFrom(ds, damage); if (entity.attackEntityFrom(ds, damage)) { @@ -329,7 +347,6 @@ public boolean shouldRenderInPass(int pass) { } //Fixes a glitch where the entity turns invisible - private void removeStatCtrl() { if (getOwner() != null) { BendingData data = Bender.get(getOwner()).getData(); @@ -342,6 +359,11 @@ public boolean isProjectile() { return true; } + @SideOnly(Side.CLIENT) + @Override + public boolean isInRangeToRenderDist(double distance) { + return true; + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityEarthspike.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityEarthspike.java index fb3d5ed3ab..a4fe7dfdb6 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityEarthspike.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityEarthspike.java @@ -19,24 +19,19 @@ import com.crowsofwar.avatar.common.AvatarDamageSource; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; -import com.crowsofwar.avatar.common.config.ConfigStats; +import com.crowsofwar.avatar.common.bending.earth.AbilityEarthspikes; +import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.gorecore.util.Vector; import net.minecraft.block.Block; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityHanging; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityEnderCrystal; import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.item.EntityItemFrame; import net.minecraft.entity.item.EntityXPOrb; +import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.EntityDamageSource; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; @@ -57,16 +52,12 @@ public class EntityEarthspike extends AvatarEntity { private double damage; private float Size; - private int attacked; private double lifetime; public EntityEarthspike(World world) { super(world); this.Size = 1; setSize(Size, Size); - //DO NOT CALL THIS ONUPDATE; THE EARTHSPIKE WILL HAVE SIZE VARIATION DEPENDING ON HOW - // LONG THE SPAWNER HAS EXISTED. - this.attacked = 0; this.damage = STATS_CONFIG.earthspikeSettings.damage; this.noClip = true; this.lifetime = 30; @@ -106,8 +97,8 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { @Override public void onEntityUpdate() { + //Add width and height stuff - super.onEntityUpdate(); this.motionX = 0; this.motionY = 0; this.motionZ = 0; @@ -116,17 +107,27 @@ public void onEntityUpdate() { this.setDead(); } + setSize(getSize(), getSize()); + BlockPos below = getPosition().offset(EnumFacing.DOWN); Block belowBlock = world.getBlockState(below).getBlock(); - - if (!world.isRemote && !ConfigStats.STATS_CONFIG.bendableBlocks.contains(belowBlock)) { - setDead(); + damage = damage * belowBlock.getBlockHardness(world.getBlockState(below), world, below); + if (getAbility() instanceof AbilityEarthspikes) { + AbilityData aD = AbilityData.get(getOwner(), getAbility().getName()); + if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + if (!world.isRemote && (!STATS_CONFIG.bendableBlocks.contains(belowBlock) || belowBlock == Blocks.AIR)) { + setDead(); + } + } + } + else if (belowBlock == Blocks.AIR) { + setDead();; } // Push collided entities back if (!world.isRemote) { - AxisAlignedBB box = new AxisAlignedBB(posX - Size, posY - Size, posZ - Size, posX + Size, posY + Size, posZ + Size); + AxisAlignedBB box = new AxisAlignedBB(posX + getSize(), posY + getSize(), posZ + getSize(), posX - getSize(), posY, posZ - getSize()); List collided = world.getEntitiesWithinAABB(Entity.class, box); if (!collided.isEmpty()) { for (Entity entity : collided) { @@ -139,20 +140,19 @@ public void onEntityUpdate() { } @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { if (!world.isRemote && entity != getOwner() && !(entity instanceof EntityEarthspike) && !(entity instanceof EntityEarthspikeSpawner) && canCollideWith(entity)) { pushEntity(entity); if (attackEntity(entity)) { - attacked++; if (getOwner() != null) { - BattlePerformanceScore.addMediumScore(getOwner()); + BattlePerformanceScore.addScore(getOwner(), 15); } } if (getOwner() != null && getAbility() != null) { BendingData data = BendingData.get(getOwner()); if (data != null) { - data.getAbilityData(getAbility().getName()).addXp(SKILLS_CONFIG.earthspikeHit * attacked); + data.getAbilityData(getAbility().getName()).addXp(SKILLS_CONFIG.earthspikeHit); } } } @@ -160,7 +160,7 @@ protected void onCollideWithEntity(Entity entity) { } private boolean attackEntity(Entity entity) { - if (!(entity instanceof EntityItem) && !(entity instanceof EntityXPOrb) && canCollideWith(entity)) { + if (!(entity instanceof EntityItem) && !(entity instanceof EntityXPOrb) && canCollideWith(entity) && canDamageEntity(entity)) { DamageSource ds = AvatarDamageSource.causeEarthspikeDamage(entity, getOwner()); float damage = (float) this.damage; return entity.attackEntityFrom(ds, damage); @@ -169,8 +169,8 @@ private boolean attackEntity(Entity entity) { } private void pushEntity(Entity entity) { - entity.motionX = this.motionX / 4; - entity.motionY = STATS_CONFIG.earthspikeSettings.push/1.5 + damage/20; - entity.motionZ = this.motionZ / 4; + entity.motionX += this.motionX / 4; + entity.motionY += (STATS_CONFIG.earthspikeSettings.push / 6) + (damage / 100); + entity.motionZ += this.motionZ / 4; } } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityEarthspikeSpawner.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityEarthspikeSpawner.java index 9fb62a1d75..5ec447ce87 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityEarthspikeSpawner.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityEarthspikeSpawner.java @@ -1,34 +1,18 @@ package com.crowsofwar.avatar.common.entity; -import com.crowsofwar.avatar.common.AvatarDamageSource; -import com.crowsofwar.avatar.common.bending.Ability; -import com.crowsofwar.avatar.common.bending.earth.AbilityEarthspikes; +import com.crowsofwar.avatar.common.bending.BendingStyle; +import com.crowsofwar.avatar.common.bending.earth.Earthbending; import com.crowsofwar.avatar.common.config.ConfigStats; -import com.crowsofwar.avatar.common.data.AbilityData; -import com.crowsofwar.avatar.common.data.Bender; -import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.ctx.AbilityContext; -import com.crowsofwar.avatar.common.data.ctx.BendingContext; -import com.crowsofwar.avatar.common.util.AvatarUtils; -import com.crowsofwar.gorecore.util.Vector; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityItem; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.DamageSource; import net.minecraft.util.EnumFacing; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraft.world.WorldServer; - -import java.util.List; - -import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; -import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; public class EntityEarthspikeSpawner extends AvatarEntity { @@ -77,6 +61,12 @@ public boolean canBeCollidedWith() { return false; } + @Override + public boolean onCollideWithSolid() { + setDead(); + return false; + } + @Override public void onUpdate() { super.onUpdate(); @@ -85,6 +75,7 @@ public void onUpdate() { setDead(); } + BlockPos below = getPosition().offset(EnumFacing.DOWN); Block belowBlock = world.getBlockState(below).getBlock(); @@ -100,6 +91,10 @@ public void onUpdate() { setDead(); } + if (!world.isRemote && belowBlock == Blocks.AIR) { + setDead(); + } + // Destroy if in a block IBlockState inBlock = world.getBlockState(getPosition()); if (inBlock.isFullBlock()) { @@ -120,7 +115,6 @@ public void onUpdate() { } } - @Override public boolean canCollideWith(Entity entity) { return false; @@ -132,9 +126,7 @@ public boolean canBePushed() { } @Override - public boolean onCollideWithSolid() { - setDead(); - return false; + public BendingStyle getElement() { + return new Earthbending(); } - } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityExplosionSpawner.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityExplosionSpawner.java index 49bdbd7393..a351a9b832 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityExplosionSpawner.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityExplosionSpawner.java @@ -3,7 +3,6 @@ import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityFireArc.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityFireArc.java index 9540003768..d2ce995e31 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityFireArc.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityFireArc.java @@ -17,47 +17,122 @@ package com.crowsofwar.avatar.common.entity; +import com.crowsofwar.avatar.common.AvatarDamageSource; +import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; +import com.crowsofwar.avatar.common.bending.BendingStyle; import com.crowsofwar.avatar.common.bending.StatusControl; +import com.crowsofwar.avatar.common.bending.air.Airbending; +import com.crowsofwar.avatar.common.bending.fire.AbilityFireArc; +import com.crowsofwar.avatar.common.bending.fire.Firebending; +import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.entity.data.FireArcBehavior; +import com.crowsofwar.avatar.common.particle.ClientParticleSpawner; +import com.crowsofwar.avatar.common.particle.ParticleSpawner; +import com.crowsofwar.avatar.common.util.AvatarUtils; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.DamageSource; import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; -public class EntityFireArc extends EntityArc { +import java.util.List; +import java.util.Objects; + +import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; +import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; - private static final Vector GRAVITY = new Vector(0, -9.81 / 60, 0); +public class EntityFireArc extends EntityArc { private static final DataParameter SYNC_BEHAVIOR = EntityDataManager .createKey(EntityFireArc.class, FireArcBehavior.DATA_SERIALIZER); + private static final DataParameter SYNC_SIZE = EntityDataManager + .createKey(EntityFireArc.class, DataSerializers.FLOAT); + private final ParticleSpawner particles; private float damageMult; private boolean createBigFire; + private float Gravity; + private float Size; + private BlockPos position; + public EntityFireArc(World world) { super(world); + this.Size = 0.4F; this.damageMult = 1; + this.Gravity = 9.82F; + this.particles = new ClientParticleSpawner(); + } + + public float getGravity() { + return this.Gravity; + } + + public void setGravity(float gravity) { + this.Gravity = gravity; + } + + public void setStartingPosition(BlockPos position) { + this.position = position; + } + + public float getSize() { + return dataManager.get(SYNC_SIZE); + } + + public void setSize(float size) { + dataManager.set(SYNC_SIZE, size); + } + + @Override + protected void updateCpBehavior() { + super.updateCpBehavior(); + getControlPoint(0).setPosition(this.position()); + getLeader().setPosition(this.position().plusY(getSize() / 4)); } @Override protected void entityInit() { super.entityInit(); dataManager.register(SYNC_BEHAVIOR, new FireArcBehavior.Idle()); + dataManager.register(SYNC_SIZE, Size); + } + + @Override + public boolean onAirContact() { + spawnExtinguishIndicators(); + setDead(); + return super.onAirContact(); } @Override public void onUpdate() { super.onUpdate(); + if (getBehavior() == null) { + this.setBehavior(new FireArcBehavior.Thrown()); + } FireArcBehavior newBehavior = (FireArcBehavior) getBehavior().onUpdate(this); if (getBehavior() != newBehavior) setBehavior(newBehavior); + if (getBehavior() != null && getBehavior() instanceof FireArcBehavior.PlayerControlled) { + this.velocityMultiplier = 4; + this.position = this.getPosition(); + } else this.velocityMultiplier = 8; + if (getOwner() != null) { EntityFireArc arc = AvatarEntity.lookupControlledEntity(world, EntityFireArc.class, getOwner()); BendingData bD = BendingData.get(getOwner()); @@ -69,6 +144,7 @@ public void onUpdate() { } } + setSize(getSize() / 2, getSize() / 2); if (getOwner() == null) { this.setDead(); @@ -97,7 +173,7 @@ public boolean onMinorWaterContact() { return true; } - private void cleanup() { + public void cleanup() { if (getOwner() != null) { BendingData data = Bender.get(getOwner()).getData(); data.removeStatusControl(StatusControl.THROW_FIRE); @@ -105,10 +181,33 @@ private void cleanup() { } @Override - protected void onCollideWithEntity(Entity entity) { + public BendingStyle getElement() { + return new Firebending(); + } + + @Override + public void onCollideWithEntity(Entity entity) { if (entity instanceof AvatarEntity && this.getBehavior() instanceof FireArcBehavior.Thrown) { ((AvatarEntity) entity).onFireContact(); } + if (getBehavior() != null && getBehavior() instanceof FireArcBehavior.Thrown) { + if (entity instanceof AvatarEntity) { + if (!(((AvatarEntity) entity).getElement() instanceof Airbending)) { + Firesplosion(); + } + } else { + Firesplosion(); + } + if (getAbility() instanceof AbilityFireArc && !world.isRemote) { + AbilityData data = AbilityData.get(getOwner(), "fire_arc"); + if (!data.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + cleanup(); + this.setDead(); + } + } + + + } } @Override @@ -118,6 +217,8 @@ public boolean onCollideWithSolid() { return false; } + Firesplosion(); + if (!world.isRemote) { int x = (int) Math.floor(posX); int y = (int) Math.floor(posY); @@ -137,10 +238,93 @@ public boolean onCollideWithSolid() { cleanup(); setDead(); + } return true; } + //Creates a FIRESPLOSION where it lands + //Sorry for caps that was just fun to write :P + public void Firesplosion() { + if (!world.isRemote && world instanceof WorldServer) { + + + float speed = 0.05F; + float hitBox = 0.5F; + int numberOfParticles = 250; + + if (getAbility() instanceof AbilityFireArc) { + AbilityData abilityData = BendingData.get(Objects.requireNonNull(getOwner())).getAbilityData("fire_arc"); + int lvl = abilityData.getLevel(); + this.damageMult = lvl >= 2 ? 2 : 0.5F; + //If the player's water arc level is level III or greater the aoe will do 2+ damage. + hitBox = lvl <= 0 ? 0.5F : 0.5f * (lvl + 1); + speed = lvl <= 0 ? 0.05F : 0.075F; + numberOfParticles = lvl <= 0 ? 250 : 250 + 100 * lvl; + } else this.damageMult = 0.5f; + + + //if (CLIENT_CONFIG.useCustomParticles) { + /*particles.spawnParticles(world, AvatarParticles.getParticleFlames(), 100, 200, Vector.getEntityPos(this), + new Vector(speed * 50, speed * 50, speed * 10));**/ + //} + //else { + WorldServer World = (WorldServer) this.world; + World.spawnParticle(EnumParticleTypes.FLAME, posX, posY, posZ, numberOfParticles, 0.2, 0.1, 0.2, speed); + //} + world.playSound(null, this.posX, this.posY, this.posZ, SoundEvents.ITEM_FIRECHARGE_USE, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F); + + List collided = world.getEntitiesInAABBexcluding(this, getEntityBoundingBox().grow(1, 1, 1), + entity -> entity != getOwner()); + if (!collided.isEmpty()) { + for (Entity entity : collided) { + if (entity != getOwner() && entity != null && getOwner() != null && canCollideWith(entity)) { + double distanceTravelled = entity.getDistance(this.position.getX(), this.position.getY(), this.position.getZ()); + + Vector velocity = Vector.getEntityPos(entity).minus(Vector.getEntityPos(this)); + double distance = Vector.getEntityPos(entity).dist(Vector.getEntityPos(this)); + double direction = (hitBox - distance) * (speed * 5) / hitBox; + velocity = velocity.times(direction).times(-1 + (-1 * hitBox / 2)).withY(speed / 2); + + double x = (velocity.x()) + distanceTravelled / 50; + double y = (velocity.y()) > 0 ? velocity.y() + distanceTravelled / 100 : 0.3F + distanceTravelled / 100; + double z = (velocity.z()) + distanceTravelled / 50; + entity.addVelocity(x, y, z); + if (canDamageEntity(entity)) { + damageEntity(entity); + } + BattlePerformanceScore.addSmallScore(getOwner()); + + if (entity instanceof AvatarEntity) { + AvatarEntity avent = (AvatarEntity) entity; + avent.addVelocity(x, y, z); + } + entity.isAirBorne = true; + AvatarUtils.afterVelocityAdded(entity); + } + } + } + } + + } + + + public void damageEntity(Entity entity) { + if (canDamageEntity(entity)) { + DamageSource ds = AvatarDamageSource.causeFireDamage(entity, getOwner()); + float damage = STATS_CONFIG.fireArcSettings.damage * damageMult; + if (entity.attackEntityFrom(ds, damage)) { + if (getOwner() != null && !world.isRemote && getAbility() != null) { + BendingData data1 = BendingData.get(getOwner()); + AbilityData abilityData1 = data1.getAbilityData(getAbility().getName()); + abilityData1.addXp(SKILLS_CONFIG.fireHit); + BattlePerformanceScore.addMediumScore(getOwner()); + + } + } + } + } + @Override public FireControlPoint createControlPoint(float size, int index) { return new FireControlPoint(this, size, 0, 0, 0); @@ -175,6 +359,12 @@ public void setCreateBigFire(boolean createBigFire) { this.createBigFire = createBigFire; } + @SideOnly(Side.CLIENT) + @Override + public boolean isInRangeToRenderDist(double distance) { + return true; + } + public static class FireControlPoint extends ControlPoint { public FireControlPoint(EntityArc arc, float size, double x, double y, double z) { diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityFireball.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityFireball.java index e1a3e30b8c..cb758305cc 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityFireball.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityFireball.java @@ -18,8 +18,10 @@ import com.crowsofwar.avatar.common.AvatarDamageSource; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; +import com.crowsofwar.avatar.common.bending.BendingStyle; import com.crowsofwar.avatar.common.bending.StatusControl; import com.crowsofwar.avatar.common.bending.fire.AbilityFireball; +import com.crowsofwar.avatar.common.bending.fire.Firebending; import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.AbilityData.AbilityTreePath; import com.crowsofwar.avatar.common.data.Bender; @@ -27,7 +29,6 @@ import com.crowsofwar.avatar.common.entity.data.Behavior; import com.crowsofwar.avatar.common.entity.data.FireballBehavior; import com.crowsofwar.avatar.common.util.AvatarUtils; -import com.crowsofwar.avatar.common.world.AvatarFireExplosion; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -45,7 +46,8 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.WorldServer; -import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; @@ -58,23 +60,16 @@ */ public class EntityFireball extends AvatarEntity { - private static final DataParameter SYNC_BEHAVIOR = EntityDataManager - .createKey(EntityFireball.class, FireballBehavior.DATA_SERIALIZER); - public static final DataParameter SYNC_SIZE = EntityDataManager.createKey(EntityFireball.class, DataSerializers.VARINT); - + private static final DataParameter SYNC_BEHAVIOR = EntityDataManager + .createKey(EntityFireball.class, FireballBehavior.DATA_SERIALIZER); private AxisAlignedBB expandedHitbox; private float damage; private float explosionStrength; private BlockPos position; - public void setExplosionStrength(float strength) { - this.explosionStrength = strength; - } - - /** * @param world */ @@ -85,6 +80,15 @@ public EntityFireball(World world) { this.position = this.getPosition(); } + public void setExplosionStrength(float strength) { + this.explosionStrength = strength; + } + + @Override + public BendingStyle getElement() { + return new Firebending(); + } + @Override public void entityInit() { super.entityInit(); @@ -96,9 +100,11 @@ public void entityInit() { public void onUpdate() { super.onUpdate(); - setBehavior((FireballBehavior) getBehavior().onUpdate(this)); - + if (getBehavior() == null) { + this.setBehavior(new FireballBehavior.Thrown()); + } + setBehavior((FireballBehavior) getBehavior().onUpdate(this)); if (ticksExisted % 30 == 0) { world.playSound(null, posX, posY, posZ, SoundEvents.BLOCK_FIRE_AMBIENT, SoundCategory.BLOCKS, 6, 0.8F); } @@ -173,7 +179,7 @@ public void setSize(int size) { } @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { if (entity instanceof AvatarEntity) { ((AvatarEntity) entity).onFireContact(); } @@ -281,23 +287,23 @@ public boolean isProjectile() { public void Explode(float ExplosionSize) { if (world instanceof WorldServer) { float size = ExplosionSize; - float speed = size/20; + float speed = size / 20; float hitBox = size + 0.5F; if (getOwner() != null) { BendingData data = BendingData.get(getOwner()); - AbilityData abilityData = data.getAbilityData("cloudburst"); + AbilityData abilityData = data.getAbilityData("fireball"); if (abilityData.getLevel() == 1) { - speed = size/8; + speed = size / 8; hitBox = size + 1.5F; } if (abilityData.getLevel() >= 2) { - speed = size/4; + speed = size / 4; hitBox = size + 4; } this.setInvisible(true); WorldServer World = (WorldServer) this.world; - World.spawnParticle(EnumParticleTypes.FLAME, posX, posY, posZ, getSize() * 15, 0, 0, 0, getSize()/200F); + World.spawnParticle(EnumParticleTypes.FLAME, posX, posY, posZ, getSize() * 15, 0, 0, 0, getSize() / 200F); World.spawnParticle(EnumParticleTypes.LAVA, posX, posY, posZ, 50, 0, 0, 0, speed); world.playSound(null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_GHAST_SHOOT, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F); List collided = world.getEntitiesInAABBexcluding(this, getEntityBoundingBox().grow(hitBox, hitBox, hitBox), @@ -305,30 +311,31 @@ public void Explode(float ExplosionSize) { if (!collided.isEmpty()) { for (Entity entity : collided) { - if (canCollideWith(entity) && entity != getOwner()) { + if (entity != getOwner() && entity != null && getOwner() != null) { + if (canCollideWith(entity) && entity != getOwner()) { - damageEntity(entity); + damageEntity(entity); - double mult = abilityData.getLevel() >= 2 ? -2 : -1; - double distanceTravelled = entity.getDistance(this.position.getX(), this.position.getY(), this.position.getZ()); + double mult = abilityData.getLevel() >= 2 ? -2 : -1; + double distanceTravelled = entity.getDistance(this.position.getX(), this.position.getY(), this.position.getZ()); - Vector vel = position().minus(getEntityPos(entity)); - vel = vel.normalize().times(mult).plusY(0.15f); + Vector vel = position().minus(getEntityPos(entity)); + vel = vel.normalize().times(mult).plusY(0.15f); - entity.motionX = vel.x() + 0.1 / distanceTravelled; - entity.motionY = vel.y() > 0 ? vel.y() + 0.1 / distanceTravelled : 0.3F + 0.1 / distanceTravelled; - entity.motionZ = vel.z() + 0.1 / distanceTravelled; + entity.motionX = vel.x() + 0.1 / distanceTravelled; + entity.motionY = vel.y() > 0 ? vel.y() + 0.1 / distanceTravelled : 0.3F + 0.1 / distanceTravelled; + entity.motionZ = vel.z() + 0.1 / distanceTravelled; - if (entity instanceof AvatarEntity) { - AvatarEntity avent = (AvatarEntity) entity; - avent.setVelocity(vel); + if (entity instanceof AvatarEntity) { + AvatarEntity avent = (AvatarEntity) entity; + avent.setVelocity(vel); + } + entity.isAirBorne = true; + AvatarUtils.afterVelocityAdded(entity); } - entity.isAirBorne = true; - AvatarUtils.afterVelocityAdded(entity); } } } - } } } @@ -338,7 +345,7 @@ public void damageEntity(Entity entity) { AbilityData abilityData = null; if (!world.isRemote && getAbility() instanceof AbilityFireball) { abilityData = AbilityData.get(getOwner(), getAbility().getName()); - DamageSource ds = AvatarDamageSource.causeCloudburstDamage(entity, getOwner()); + DamageSource ds = AvatarDamageSource.causeFireballDamage(entity, getOwner()); int lvl = abilityData.getLevel(); float damage = 1.5F; if (lvl == 1) { @@ -353,7 +360,6 @@ public void damageEntity(Entity entity) { if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { damage = 3.5F; } - entity.attackEntityFrom(ds, damage); if (entity.attackEntityFrom(ds, damage)) { abilityData.addXp(SKILLS_CONFIG.fireballHit); BattlePerformanceScore.addMediumScore(getOwner()); @@ -363,4 +369,9 @@ public void damageEntity(Entity entity) { } } + @SideOnly(Side.CLIENT) + @Override + public boolean isInRangeToRenderDist(double distance) { + return true; + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityFlames.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityFlames.java index dceaca6ff7..d8f5a01975 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityFlames.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityFlames.java @@ -19,6 +19,8 @@ import com.crowsofwar.avatar.common.AvatarDamageSource; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; +import com.crowsofwar.avatar.common.bending.BendingStyle; +import com.crowsofwar.avatar.common.bending.fire.Firebending; import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; @@ -31,8 +33,11 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; +import java.util.Objects; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; @@ -57,6 +62,11 @@ public EntityFlames(World worldIn) { setSize(0.1f, 0.1f); } + @Override + public BendingStyle getElement() { + return new Firebending(); + } + public EntityFlames(World world, EntityLivingBase owner) { this(world); this.owner = owner; @@ -76,7 +86,7 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { } @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { if (entity instanceof AvatarEntity) { ((AvatarEntity) entity).onFireContact(); } @@ -96,7 +106,7 @@ public void onUpdate() { true); if (raytrace.hitSomething()) { EnumFacing sideHit = raytrace.getSide(); - setVelocity(velocity().reflect(new Vector(sideHit)).times(0.5)); + setVelocity(velocity().reflect(new Vector(Objects.requireNonNull(sideHit))).times(0.5)); // Try to light firest if (lightsFires && sideHit != EnumFacing.DOWN && !world.isRemote) { @@ -124,7 +134,7 @@ public void onUpdate() { for (Entity entity : collided) { - entity.setFire((int) (3 * 1 + abilityData.getTotalXp() / 100f)); + entity.setFire((int) (3F * 1 + abilityData.getTotalXp() / 100f)); // Add extra damage // Adding 0 since even though this doesn't affect health, will @@ -178,4 +188,10 @@ public void setDamageMult(double damageMult) { this.damageMult = damageMult; } + @SideOnly(Side.CLIENT) + @Override + public boolean isInRangeToRenderDist(double distance) { + return true; + } + } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityFloatingBlock.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityFloatingBlock.java index d287995c8d..b475aa1680 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityFloatingBlock.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityFloatingBlock.java @@ -48,7 +48,6 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import java.util.List; import java.util.Random; import static com.crowsofwar.gorecore.util.GoreCoreNBTUtil.nestedCompound; diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityIcePrison.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityIcePrison.java index 748f1a6646..575c0038c6 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityIcePrison.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityIcePrison.java @@ -22,7 +22,6 @@ import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.entity.data.SyncedEntity; -import com.crowsofwar.gorecore.util.Vector; import com.google.common.base.Optional; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningArc.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningArc.java index 8a6a1fc179..3dc56b51f7 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningArc.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningArc.java @@ -1,7 +1,9 @@ package com.crowsofwar.avatar.common.entity; import com.crowsofwar.avatar.common.AvatarDamageSource; +import com.crowsofwar.avatar.common.AvatarParticles; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; +import com.crowsofwar.avatar.common.bending.lightning.AbilityLightningArc; import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; @@ -97,6 +99,24 @@ public EntityLightningArc(World world) { damage = 8; } + private void LightningBurst(double x, double y, double z) { + EntityShockwave wave = new EntityShockwave(world); + wave.setAbility(new AbilityLightningArc()); + wave.setOwner(getOwner()); + wave.setParticleAmount(1); + wave.setParticleSpeed(1.25); + wave.setParticle(AvatarParticles.getParticleElectricity()); + wave.setSpeed(0.8); + wave.setPosition(x, y, z); + wave.setDamage(getDamage() / 2); + wave.setRange(getSizeMultiplier() * 2); + wave.setParticleController(20); + wave.setSphere(true); + wave.setPerformanceAmount(10); + wave.setKnockbackHeight(0.2); + world.spawnEntity(wave); + } + @Override protected void entityInit() { super.entityInit(); @@ -118,6 +138,7 @@ public void onUpdate() { onUpdateMainArc(); } + if (getOwner() != null) { Vector controllerPos = Vector.getEyePos(getOwner()); Vector endPosition = getEndPos(); @@ -140,8 +161,11 @@ public void onUpdate() { if (!wasSuccessfullyRedirected) { damageEntity(stuckTo, 0.333f); } + getControlPoint(5).setPosition(Vector.getLookRectangular(getOwner()).times(2).plus(Vector.getEntityPos(getOwner()))); + getControlPoint(0).setPosition(Vector.getEntityPos(stuckTo)); } + if (velocity().equals(Vector.ZERO)) { stuckTime++; if (stuckTime == 1) { @@ -154,7 +178,6 @@ public void onUpdate() { if (existTooLong || stuckIsDead) { setDead(); } - setSize(0.33f * getSizeMultiplier(), 0.33f * getSizeMultiplier()); } @@ -171,7 +194,6 @@ private void onUpdateMainArc() { world.setLastLightningBolt(2); } } - // Electrocute enemies in water if (inWater && !world.isRemote) { if (floodFill == null) { @@ -185,18 +207,30 @@ private void onUpdateMainArc() { @Override protected void updateCpBehavior() { - for (LightningControlPoint controlPoint : getControlPoints()) { + if (getOwner() != null) { + for (LightningControlPoint controlPoint : getControlPoints()) { - controlPoint.setPosition(controlPoint.getPosition - (ticksExisted)); + controlPoint.setPosition(controlPoint.getPosition + (ticksExisted)); + } } - } @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { + if (getAbility() instanceof AbilityLightningArc && !world.isRemote) { + AbilityData aD = AbilityData.get(getOwner(), "lightning_arc"); + if (aD.isMasterPath(AbilityData.AbilityTreePath.SECOND) && entity instanceof EntityLivingBase) { + world.playSound(null, getPosition(), SoundEvents.ENTITY_LIGHTNING_THUNDER, + SoundCategory.PLAYERS, 1, 1); + damageEntity(((EntityLivingBase) entity), 1); + LightningBurst(this.posX, this.posY, this.posZ); + //Don't use the position of the entity, as that makes them fall through the world + entity.noClip = false; + this.setDead(); + } + } if (stuckTo == null && entity instanceof EntityLivingBase) { - stuckTo = (EntityLivingBase) entity; } @@ -214,15 +248,17 @@ public boolean canCollideWith(Entity entity) { @Override protected void collideWithNearbyEntities() { - List collisions = Raytrace.entityRaytrace(world, position(), velocity(), velocity - ().magnitude() / 20, entity -> entity != getOwner() && entity != this); + if (getOwner() != null) { + List collisions = Raytrace.entityRaytrace(world, position(), getEntityPos(getOwner()).minus(this.position()), this.getDistance(getOwner()), + entity -> entity != getOwner() && entity != this); - for (Entity collided : collisions) { - if (canCollideWith(collided)) { - onCollideWithEntity(collided); + for (Entity collided : collisions) { + if (canCollideWith(collided)) { + onCollideWithEntity(collided); + } } - } + } } private void handleWaterElectrocution(EntityLivingBase entity) { @@ -245,7 +281,7 @@ private void damageEntity(EntityLivingBase entity, float damageModifier) { // Handle lightning redirection if (!wasRedirected && isMainArc() && entity == stuckTo && Bender.isBenderSupported (entity)) { - wasSuccessfullyRedirected = Bender.get(entity).redirectLightning(this); + wasSuccessfullyRedirected = Objects.requireNonNull(Bender.get(entity)).redirectLightning(this); wasRedirected = true; } @@ -292,6 +328,7 @@ public boolean onCollideWithSolid() { world.setBlockState(getPosition(), Blocks.FIRE.getDefaultState()); } } + LightningBurst(posX, posY, posZ); return false; // return true; } @@ -403,6 +440,7 @@ public Vector getInterpolatedPosition(float partialTicks) { return getPosition(arc.ticksExisted + partialTicks); } + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningSpawner.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningSpawner.java index 9a6412f3a8..1390a13d5b 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningSpawner.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningSpawner.java @@ -1,23 +1,14 @@ package com.crowsofwar.avatar.common.entity; -import com.crowsofwar.avatar.common.bending.lightning.AbilityLightningRaze; -import com.crowsofwar.avatar.common.data.AbilityData; -import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.datasync.DataParameter; -import net.minecraft.network.datasync.DataSerializers; -import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import java.util.Random; - public class EntityLightningSpawner extends AvatarEntity { private int maxTicksAlive; diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningSpear.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningSpear.java index 697ca5b9e7..2ee7ee2dac 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningSpear.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityLightningSpear.java @@ -17,13 +17,18 @@ package com.crowsofwar.avatar.common.entity; import com.crowsofwar.avatar.common.AvatarDamageSource; +import com.crowsofwar.avatar.common.AvatarParticles; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; -import com.crowsofwar.avatar.common.bending.StatusControl; +import com.crowsofwar.avatar.common.bending.lightning.AbilityLightningSpear; +import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.entity.data.Behavior; import com.crowsofwar.avatar.common.entity.data.LightningFloodFill; import com.crowsofwar.avatar.common.entity.data.LightningSpearBehavior; +import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; +import com.crowsofwar.avatar.common.particle.ParticleSpawner; +import com.crowsofwar.avatar.common.util.AvatarUtils; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -34,12 +39,15 @@ import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; import net.minecraft.util.SoundCategory; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.world.Explosion; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; -import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; +import java.util.List; + +import static com.crowsofwar.avatar.common.bending.lightning.StatCtrlThrowLightningSpear.THROW_LIGHTNINGSPEAR; +import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; /** * @author CrowsOfWar @@ -49,10 +57,12 @@ public class EntityLightningSpear extends AvatarEntity { private static final DataParameter SYNC_BEHAVIOR = EntityDataManager .createKey(EntityLightningSpear.class, LightningSpearBehavior.DATA_SERIALIZER); - private static final DataParameter SYNC_SIZE = EntityDataManager.createKey(EntityLightningSpear.class, - DataSerializers.VARINT); + private static final DataParameter SYNC_SIZE = EntityDataManager.createKey(EntityLightningSpear.class, + DataSerializers.FLOAT); + + private static final DataParameter SYNC_DEGREES_PER_SECOND = EntityDataManager.createKey(EntityLightningSpear.class, + DataSerializers.FLOAT); - private AxisAlignedBB expandedHitbox; private float damage; @@ -72,19 +82,35 @@ public class EntityLightningSpear extends AvatarEntity { */ private LightningFloodFill floodFill; + private BlockPos position; + + private float Size; + + private float degreesPerSecond; + + private ParticleSpawner particleSpawner; /** * @param world */ public EntityLightningSpear(World world) { super(world); - setSize(.8f, .8f); + this.Size = 0.8F; + this.degreesPerSecond = 400; + setSize(Size, Size); + this.damage = 3F; + this.piercing = false; + this.setInvisible(false); + this.position = this.position().toBlockPos(); + this.particleSpawner = new NetworkParticleSpawner(); + } @Override public void entityInit() { super.entityInit(); dataManager.register(SYNC_BEHAVIOR, new LightningSpearBehavior.Idle()); - dataManager.register(SYNC_SIZE, 30); + dataManager.register(SYNC_SIZE, Size); + dataManager.register(SYNC_DEGREES_PER_SECOND, degreesPerSecond); } @Override @@ -95,25 +121,28 @@ public void onUpdate() { // Add hook or something if (getOwner()!= null) { - if (this.getBehavior() == controlled) { + if (getBehavior() != null && getBehavior() instanceof LightningSpearBehavior.PlayerControlled) { this.rotationYaw = this.getOwner().rotationYaw; this.rotationPitch = this.getOwner().rotationPitch; } } - - if (getOwner() == null) { - setDead(); - removeStatCtrl(); + if (getBehavior() != null && getBehavior() == controlled) { + this.position = this.position().toBlockPos(); } + + this.setSize(getSize() / 2, getSize() / 2); + //Even though doing size/8 would be better, the entity gets too small, and doesn't render far away enough. Super annoying. + + if (getOwner() != null) { EntityLightningSpear spear = AvatarEntity.lookupControlledEntity(world, EntityLightningSpear.class, getOwner()); BendingData bD = BendingData.get(getOwner()); - if (spear == null && bD.hasStatusControl(StatusControl.THROW_LIGHTNINGSPEAR)) { - bD.removeStatusControl(StatusControl.THROW_LIGHTNINGSPEAR); + if (spear == null && bD.hasStatusControl(THROW_LIGHTNINGSPEAR)) { + bD.removeStatusControl(THROW_LIGHTNINGSPEAR); } - if (spear != null && spear.getBehavior() instanceof LightningSpearBehavior.PlayerControlled && !(bD.hasStatusControl(StatusControl.THROW_LIGHTNINGSPEAR))) { - bD.addStatusControl(StatusControl.THROW_LIGHTNINGSPEAR); + if (spear != null && spear.getBehavior() == controlled && !(bD.hasStatusControl(THROW_LIGHTNINGSPEAR))) { + bD.addStatusControl(THROW_LIGHTNINGSPEAR); } } @@ -129,6 +158,9 @@ public void onUpdate() { setVelocity(Vector.ZERO); } + else { + this.setInvisible(false); + } if (inWater && !world.isRemote) { if (floodFill == null) { floodFill = new LightningFloodFill(world, getPosition(), 12, @@ -142,6 +174,76 @@ public void onUpdate() { } + public void LightningBurst() { + if (getOwner() != null) { + particleSpawner.spawnParticles(world, AvatarParticles.getParticleElectricity(), (int) (getSize() * 25), (int) (getSize() * 30), posX, posY, posZ, getSize() * 1.25, getSize() * 1.25, getSize() * 1.25); + world.playSound(null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_LIGHTNING_IMPACT, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F); + world.playSound(null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_LIGHTNING_THUNDER, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F); + List collided = world.getEntitiesInAABBexcluding(this, getEntityBoundingBox().grow(getSize() * 2, getSize() * 2, getSize() * 2), + entity -> entity != getOwner()); + + if (!collided.isEmpty()) { + for (Entity entity : collided) { + if (entity != getOwner() && entity != null && getOwner() != null && entity != this && canCollideWith(entity)) { + + damageEntity(entity); + + //Divide the result of the position difference to make entities fly + //further the closer they are to the player. + double dist = (getSize() * 2 - entity.getDistance(entity)) > 1 ? (getSize() * 2 - entity.getDistance(entity)) : 1; + Vector velocity = Vector.getEntityPos(entity).minus(Vector.getEntityPos(this)); + velocity = velocity.dividedBy(40).times(dist).withY(getSize()/50); + + double x = (velocity.x()); + double y = (velocity.y()) > 0 ? velocity.y() : 0.2F; + double z = (velocity.z()); + + if (!entity.world.isRemote) { + entity.addVelocity(x, y, z); + + if (collided instanceof AvatarEntity) { + if (!(collided instanceof EntityWall) && !(collided instanceof EntityWallSegment) && !(collided instanceof EntityIcePrison) && !(collided instanceof EntitySandPrison)) { + AvatarEntity avent = (AvatarEntity) collided; + avent.addVelocity(x, y, z); + } + entity.isAirBorne = true; + AvatarUtils.afterVelocityAdded(entity); + } + } + } + } + } + + } + } + + public void damageEntity(Entity entity) { + if (getOwner() != null) { + BendingData data = BendingData.get(getOwner()); + AbilityData abilityData = data.getAbilityData("lightning_spear"); + int lvl = abilityData.getLevel(); + float damage = getDamage()/3; + if (lvl == 1) { + damage = getDamage()/2; + } + if (lvl == 2) { + damage = getDamage()/1.5F; + } + if (abilityData.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + damage = getDamage(); + } + if (abilityData.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + damage = getDamage(); + } + entity.attackEntityFrom(AvatarDamageSource.LIGHTNING, damage); + if (entity.attackEntityFrom(AvatarDamageSource.LIGHTNING, damage)) { + abilityData.addXp(SKILLS_CONFIG.cloudburstHit); + BattlePerformanceScore.addMediumScore(getOwner()); + + } + } + } + /** * When a lightning spear hits water, electricity spreads through the water and nearby * entities are electrocuted. This method is called when an entity gets electrocuted. @@ -170,6 +272,7 @@ public EntityLivingBase getController() { return getBehavior() instanceof LightningSpearBehavior.PlayerControlled ? getOwner() : null; } + public float getDamage() { return damage; } @@ -178,11 +281,11 @@ public void setDamage(float damage) { this.damage = damage; } - public int getSize() { + public float getSize() { return dataManager.get(SYNC_SIZE); } - public void setSize(int size) { + public void setSize(float size) { dataManager.set(SYNC_SIZE, size); } @@ -202,29 +305,33 @@ public void setGroupAttack(boolean groupAttack) { this.groupAttack = groupAttack; } + public void setDegreesPerSecond (float degrees) { + dataManager.set(SYNC_DEGREES_PER_SECOND, degrees); + } + + public float getDegreesPerSecond() { + return dataManager.get(SYNC_DEGREES_PER_SECOND); + } + @Override public boolean onCollideWithSolid() { if (!(getBehavior() instanceof LightningSpearBehavior.Thrown)) { return false; } - - float explosionSize = STATS_CONFIG.fireballSettings.explosionSize; - - - Explosion explosion = new Explosion(world, this, posX, posY, posZ, explosionSize, - !world.isRemote, STATS_CONFIG.fireballSettings.damageBlocks); - if (!ForgeEventFactory.onExplosionStart(world, explosion)) { - - explosion.doExplosionA(); - explosion.doExplosionB(true); - + setInvisible(false); + + LightningBurst(); + if (getAbility() != null && !world.isRemote) { + if (getAbility() instanceof AbilityLightningSpear) { + if (!(AbilityData.get(getOwner(), getAbility().getName()).isMasterPath(AbilityData.AbilityTreePath.FIRST))) { + setDead(); + } + } + } + else { + setDead(); } - - world.playSound(posX, posY, posZ, SoundEvents.ENTITY_LIGHTNING_THUNDER, SoundCategory - .PLAYERS, 1, 1, false); - - setDead(); return true; } @@ -243,26 +350,33 @@ public void writeEntityToNBT(NBTTagCompound nbt) { nbt.setInteger("Behavior", getBehavior().getId()); } - public AxisAlignedBB getExpandedHitbox() { - return this.expandedHitbox; - } - - @Override - public void setEntityBoundingBox(AxisAlignedBB bb) { - super.setEntityBoundingBox(bb); - expandedHitbox = bb.grow(0.35, 0.35, 0.35); - } - @Override - public boolean shouldRenderInPass(int pass) { - return pass == 1; + public void onCollideWithEntity(Entity entity) { + if (getBehavior() instanceof LightningSpearBehavior.Thrown && getBehavior() != null) { + if (this.canCollideWith(entity) && entity != getOwner()) { + if (getAbility() instanceof AbilityLightningSpear && !world.isRemote) { + AbilityData aD = AbilityData.get(getOwner(), getAbility().getName()); + if (!aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + LightningBurst(); + setDead(); + } + } else { + LightningBurst(); + } + } + } } - private void removeStatCtrl() { + public void removeStatCtrl() { if (getOwner() != null) { BendingData data = Bender.get(getOwner()).getData(); - data.removeStatusControl(StatusControl.THROW_LIGHTNINGSPEAR); + data.removeStatusControl(THROW_LIGHTNINGSPEAR); } } + @SideOnly(Side.CLIENT) + @Override + public boolean isInRangeToRenderDist(double distance) { + return true; + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntitySandPrison.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntitySandPrison.java index 9d1079c833..91652f709e 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntitySandPrison.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntitySandPrison.java @@ -16,9 +16,6 @@ */ package com.crowsofwar.avatar.common.entity; -import java.util.List; -import java.util.UUID; - import com.crowsofwar.avatar.common.AvatarDamageSource; import com.crowsofwar.avatar.common.bending.Ability; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; @@ -26,9 +23,7 @@ import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.entity.data.SyncedEntity; -import com.crowsofwar.gorecore.util.Vector; import com.google.common.base.Optional; - import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; @@ -44,6 +39,9 @@ import net.minecraft.util.SoundCategory; import net.minecraft.world.World; +import java.util.List; +import java.util.UUID; + /** * @author CrowsOfWar */ diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntitySandstorm.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntitySandstorm.java index 71ebbca3fc..b0e2756c0b 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntitySandstorm.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntitySandstorm.java @@ -11,7 +11,6 @@ import net.minecraft.block.BlockLiquid; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataSerializers; @@ -170,7 +169,7 @@ public boolean canPush() { } @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { // Number of blocks that the target "floats" above the ground final double floatingDistance = 2; diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityShield.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityShield.java index b9b67a28e3..9e8d23542a 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityShield.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityShield.java @@ -25,7 +25,6 @@ import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.World; import java.util.Arrays; diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityShockwave.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityShockwave.java new file mode 100644 index 0000000000..43fdb5737f --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityShockwave.java @@ -0,0 +1,251 @@ +package com.crowsofwar.avatar.common.entity; + +import com.crowsofwar.avatar.common.AvatarDamageSource; +import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; +import com.crowsofwar.avatar.common.bending.air.AbilityAirBurst; +import com.crowsofwar.avatar.common.data.AbilityData; +import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; +import com.crowsofwar.avatar.common.util.AvatarUtils; +import com.crowsofwar.gorecore.util.Vector; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.init.MobEffects; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.world.World; + +import java.util.List; + +import static com.crowsofwar.avatar.common.bending.BattlePerformanceScore.SCORE_MOD_MEDIUM; +import static com.crowsofwar.avatar.common.bending.BattlePerformanceScore.SCORE_MOD_SMALL; +import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; + +public class EntityShockwave extends AvatarEntity { + + public EnumParticleTypes particle; + //The range of the shockwave/how far it'll go before dissipating + public double speed; + //The amount entities will be knocked back + public float damage; + //Speed of the particles + //Particles to be spawned. + private int particleAmount; + //The amount of particles to be spawned + private double particleSpeed; + private int performanceAmount; + //The amount of battleperformance added per hit + private double range; + //The speed of the shockwave and how fast entities will be knocked back + private double knockbackHeight; + //The amount of damage the shockwave will do + private boolean isFire; + //Whether or not to set the target entities on fire + private int fireTime; + //How long to set the target entity on fire + private boolean isSphere; + //Whether or not to use a sphere of particles instead of a circular ring + private NetworkParticleSpawner particles; + + private double particleController; + //Used for spherical shockwaves + + public EntityShockwave(World world) { + super(world); + this.damage = 1; + this.particle = EnumParticleTypes.EXPLOSION_NORMAL; + this.particleSpeed = 0; + this.particleAmount = 10; + this.range = 4; + this.performanceAmount = 10; + this.knockbackHeight = 0.2; + this.speed = 0.8; + this.isFire = false; + this.fireTime = 0; + this.particleAmount = 0; + this.setSize(1, 1); + this.particles = new NetworkParticleSpawner(); + } + + public void setFire(boolean fire) { + this.isFire = fire; + } + + public void setFireTime(int time) { + this.fireTime = time; + } + + public void setPerformanceAmount(int amount) { + this.performanceAmount = amount; + } + + public void setParticleController(double amount) { + this.particleController = amount; + } + + public EnumParticleTypes getParticle() { + return particle; + } + + public void setParticle(EnumParticleTypes particle) { + this.particle = particle; + } + + public int getParticleAmount() { + return particleAmount; + } + + public void setParticleAmount(int amount) { + this.particleAmount = amount; + } + + public double getParticleSpeed() { + return particleSpeed; + } + + public void setParticleSpeed(double speed) { + this.particleSpeed = speed; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getKnockbackHeight() { + return knockbackHeight; + } + + public void setKnockbackHeight(double height) { + this.knockbackHeight = height; + } + + public double getDamage() { + return damage; + } + + public void setDamage(float damage) { + this.damage = damage; + } + + public boolean getSphere() { + return isSphere; + } + + public void setSphere(boolean sphere) { + this.isSphere = sphere; + } + + @Override + public boolean canBeCollidedWith() { + return false; + } + + @Override + public boolean canBePushed() { + return false; + } + + @Override + public void onUpdate() { + + this.setVelocity(Vector.ZERO); + this.motionX = this.motionY = this.motionZ = 0; + + if ((this.ticksExisted * speed) > range) { + this.setDead(); + } + if (ticksExisted > 140) { + setDead(); + } + + if (!world.isRemote) { + + for (double angle = 0; angle < 2 * Math.PI; angle += Math.PI / (getRange() * 10 * 1.5)) { + double x = posX + (ticksExisted * getSpeed()) * Math.sin(angle); + double y = posY + 0.5; + double z = posZ + (ticksExisted * getSpeed()) * Math.cos(angle); + particles.spawnParticles(world, getParticle(), getParticleAmount() / 2, getParticleAmount(), x, y, z, getParticleSpeed(), + getParticleSpeed(), getParticleSpeed()); + } + + if (isSphere) { + double x, y, z; + if (ticksExisted % 2 == 0) { + for (double theta = 0; theta <= 180; theta += 1) { + double dphi = particleController / Math.sin(Math.toRadians(theta)); + + for (double phi = 0; phi < 360; phi += dphi) { + double rphi = Math.toRadians(phi); + double rtheta = Math.toRadians(theta); + + x = ticksExisted * getSpeed() * Math.cos(rphi) * Math.sin(rtheta); + y = ticksExisted * getSpeed() * Math.sin(rphi) * Math.sin(rtheta); + z = ticksExisted * getSpeed() * Math.cos(rtheta); + + particles.spawnParticles(world, getParticle(), getParticleAmount() / 2, getParticleAmount(), x + posX, y + posY, + z + posZ, getParticleSpeed(), getParticleSpeed(), getParticleSpeed()); + + } + }//Creates a sphere. Courtesy of Project Korra's Air Burst! + } + } + } + + AxisAlignedBB box = new AxisAlignedBB(posX + (ticksExisted * speed), posY + 1.5, posZ + (ticksExisted * speed), + posX - (ticksExisted * speed), posY - 1.5, posZ - (ticksExisted * speed)); + + List targets = world.getEntitiesWithinAABB( + Entity.class, box); + + targets.remove(getOwner()); + + for (Entity target : targets) { + if (target != getOwner() && this.canCollideWith(target) && target != this && !(target instanceof EntityItem) && !world.isRemote) { + + if (this.canDamageEntity(target)) { + if (target.attackEntityFrom(AvatarDamageSource.causeShockwaveDamage(target, getOwner()), damage)) { + int amount = performanceAmount > SCORE_MOD_SMALL ? performanceAmount : (int) SCORE_MOD_SMALL; + amount = amount > SCORE_MOD_MEDIUM ? (int) SCORE_MOD_MEDIUM : performanceAmount; + BattlePerformanceScore.addScore(getOwner(), amount); + target.setFire(isFire ? fireTime : 0); + if (getAbility() != null && !world.isRemote && getAbility() instanceof AbilityAirBurst) { + AbilityData aD = AbilityData.get(getOwner(), getAbility().getName()); + aD.addXp(SKILLS_CONFIG.airBurstHit - aD.getLevel()); + if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST) && target instanceof EntityLivingBase) { + ((EntityLivingBase) target).addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 50)); + ((EntityLivingBase) target).addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 50)); + ((EntityLivingBase) target).addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 50)); + } + } + } + } + double xSpeed = isSphere ? Vector.getEntityPos(target).minus(Vector.getEntityPos(this)).normalize().x() * (ticksExisted * speed) : + Vector.getEntityPos(target).minus(Vector.getEntityPos(this)).normalize().x() * (ticksExisted / 5F * speed); + double ySpeed = isSphere ? Vector.getEntityPos(target).minus(Vector.getEntityPos(this)).normalize().y() * (ticksExisted / 2F * speed) : + knockbackHeight; // Throws target into the air. + double zSpeed = isSphere ? Vector.getEntityPos(target).minus(Vector.getEntityPos(this)).normalize().z() * (ticksExisted * speed) : + Vector.getEntityPos(target).minus(Vector.getEntityPos(this)).normalize().z() * (ticksExisted / 5F * speed); + ySpeed = ySpeed > knockbackHeight ? ySpeed : knockbackHeight; + target.motionX += xSpeed; + target.motionY += ySpeed * 2; + target.motionZ += zSpeed; + + AvatarUtils.afterVelocityAdded(target); + } + } + } +} + diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityWallSegment.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityWallSegment.java index e7dd65bef6..5b0b9073f8 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityWallSegment.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityWallSegment.java @@ -25,21 +25,19 @@ import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.entity.data.SyncedEntity; import com.crowsofwar.avatar.common.entity.data.WallBehavior; +import com.crowsofwar.avatar.common.util.AvatarUtils; import com.crowsofwar.gorecore.util.Vector; import com.google.common.base.Optional; import io.netty.buffer.ByteBuf; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; -import net.minecraft.network.play.server.SPacketEntityVelocity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; @@ -176,6 +174,11 @@ public void dropBlocks() { } } + @Override + public boolean canBePushed() { + return false; + } + @Override public void onUpdate() { super.onUpdate(); @@ -243,7 +246,7 @@ public boolean canPush() { @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { // Note... only called server-side double amt = 0.05; @@ -274,9 +277,7 @@ protected void onCollideWithEntity(Entity entity) { entity.motionY = 0.01; entity.isAirBorne = true; - if (entity instanceof EntityPlayerMP) { - ((EntityPlayerMP) entity).connection.sendPacket(new SPacketEntityVelocity(entity)); - } + AvatarUtils.afterVelocityAdded(entity); if (entity instanceof AvatarEntity) { Vector velocity = ((AvatarEntity) entity).velocity(); if (ns) { @@ -328,4 +329,6 @@ public boolean canCollideWith(Entity entity) { } + + } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterArc.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterArc.java index 5d925625f4..d711b9b00b 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterArc.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterArc.java @@ -50,7 +50,6 @@ import static com.crowsofwar.avatar.common.bending.StatusControl.THROW_WATER; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; -import static com.crowsofwar.gorecore.util.Vector.getEntityPos; public class EntityWaterArc extends EntityArc { @@ -77,12 +76,12 @@ public class EntityWaterArc extends EntityArc public EntityWaterArc(World world) { super(world); + this.Size = 0.4F; setSize(Size, Size); this.lastPlayedSplash = -1; this.damageMult = 1; this.putsOutFires = true; - this.Size = 0.4F; - this.Gravity = 9.81F; + this.Gravity = 9.82F; } @@ -99,7 +98,7 @@ public void isSpear(boolean isSpear) { } public void setSize(float size) { - dataManager.set(SYNC_SIZE, Size); + dataManager.set(SYNC_SIZE, size); } public float getSize() { @@ -114,9 +113,10 @@ public void setGravity(float gravity) { this.Gravity = gravity; } - public void setStartingPosition (BlockPos position) { + public void setStartingPosition(BlockPos position) { this.position = position; } + @Override protected void entityInit() { super.entityInit(); @@ -124,6 +124,12 @@ protected void entityInit() { dataManager.register(SYNC_SIZE, Size); } + @Override + protected void updateCpBehavior() { + super.updateCpBehavior(); + getControlPoint(0).setPosition(this.position()); + getLeader().setPosition(this.position().plusY(getSize()/8)); + } public void damageEntity(Entity entity) { if (canDamageEntity(entity)) { @@ -144,40 +150,54 @@ public void damageEntity(Entity entity) { public void Splash() { if (world instanceof WorldServer) { + + float speed = 0.025F; + float hitBox = 0.5F; + int numberOfParticles = 500; + + if (getAbility() instanceof AbilityWaterArc) { + AbilityData abilityData = BendingData.get(Objects.requireNonNull(getOwner())).getAbilityData("water_arc"); + int lvl = abilityData.getLevel(); + this.damageMult = lvl >= 2 ? 2 : 0.5F; + //If the player's water arc level is level III or greater the aoe will do 2+ damage. + hitBox = lvl <= 0 ? 0.5F : 0.5f * (lvl + 1); + speed = lvl <= 0 ? 0.025F : 0.025F * (lvl + 1); + numberOfParticles = lvl <= 0 ? 500 : 500 + 100 * lvl; + } else this.damageMult = 0.5f; + + WorldServer World = (WorldServer) this.world; - World.spawnParticle(EnumParticleTypes.WATER_WAKE, posX, posY, posZ, 500, 0.2, 0.1, 0.2, 0.03); + World.spawnParticle(EnumParticleTypes.WATER_WAKE, posX, posY, posZ, numberOfParticles, 0.2, 0.1, 0.2, speed); world.playSound(null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_GENERIC_SPLASH, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F); + List collided = world.getEntitiesInAABBexcluding(this, getEntityBoundingBox().grow(1, 1, 1), entity -> entity != getOwner()); if (!collided.isEmpty()) { for (Entity entity : collided) { - if (getAbility() instanceof AbilityWaterArc) { - AbilityData abilityData = BendingData.get(Objects.requireNonNull(getOwner())).getAbilityData("water_arc"); - int lvl = abilityData.getLevel(); - this.damageMult = lvl >= 2 ? 2 : 0.5F; - //If the player's water arc level is level III or greater the aoe will do 2+ damage. + if (entity != getOwner() && entity != null && getOwner() != null) { + + + Vector velocity = Vector.getEntityPos(entity).minus(Vector.getEntityPos(this)); + double distance = Vector.getEntityPos(entity).dist(Vector.getEntityPos(this)); + double direction = (hitBox - distance) * (speed * 5) / hitBox; + velocity = velocity.times(direction).times(-1 + (-1 * hitBox / 2)).withY(speed / 2); + + double x = (velocity.x()); + double y = (velocity.y()) > 0 ? velocity.y() : 0.25F; + double z = (velocity.z()); + entity.addVelocity(x, y, z); + if (canDamageEntity(entity)) { + damageEntity(entity); + } + BattlePerformanceScore.addSmallScore(getOwner()); + + if (entity instanceof AvatarEntity) { + AvatarEntity avent = (AvatarEntity) entity; + avent.addVelocity(x, y, z); + } + entity.isAirBorne = true; + AvatarUtils.afterVelocityAdded(entity); } - else this.damageMult = 0.5f; - - - double mult = -0.5; - double distanceTravelled = entity.getDistance(this.position.getX(), this.position.getY(), this.position.getZ()); - - Vector vel = position().minus(getEntityPos(entity)); - vel = vel.normalize().times(mult).plusY(0.15f); - - entity.motionX = vel.x() * (BendingData.get(getOwner()).getAbilityData("water_arc").getLevel() + 1) + 0.1/distanceTravelled; - entity.motionY = vel.y() * (BendingData.get(getOwner()).getAbilityData("water_arc").getLevel() + 1) > 0 ? vel.y() * (BendingData.get(getOwner()).getAbilityData("water_arc").getLevel() + 1) + 0.1/distanceTravelled : 0.15F + 0.1/distanceTravelled; - entity.motionZ = vel.z() * (BendingData.get(getOwner()).getAbilityData("water_arc").getLevel() + 1) + 0.1/distanceTravelled;; - damageEntity(entity); - BattlePerformanceScore.addMediumScore(getOwner()); - - if (entity instanceof AvatarEntity) { - AvatarEntity avent = (AvatarEntity) entity; - avent.setVelocity(vel); - } - entity.isAirBorne = true; - AvatarUtils.afterVelocityAdded(entity); } } @@ -187,7 +207,7 @@ public void Splash() { @Override public boolean onCollideWithSolid() { - if (isSpear) { + if (isSpear && getBehavior() != null && getBehavior() instanceof WaterArcBehavior.Thrown) { breakCollidingBlocks(); Splash(); setDead(); @@ -202,12 +222,11 @@ public boolean onCollideWithSolid() { cleanup(); - if (world.isRemote) { Random random = new Random(); - double xVel = 0, yVel = 0, zVel = 0; - double offX = 0, offY = 0, offZ = 0; + double xVel, yVel, zVel; + double offX, offY, offZ; if (collidedVertically) { @@ -251,15 +270,10 @@ public boolean onCollideWithSolid() { } @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { if (entity instanceof AvatarEntity && getBehavior() instanceof WaterArcBehavior.Thrown && ((AvatarEntity) entity).getOwner() != getOwner()) { ((AvatarEntity) entity).onMinorWaterContact(); } - if (!isSpear && getBehavior() instanceof WaterArcBehavior.Thrown) { - Splash(); - this.setDead(); - cleanup(); - } } @@ -288,6 +302,23 @@ public void onUpdate() { if (getOwner() == null) { this.setDead(); } + setSize(getSize()/2, getSize()/2); + + if (getBehavior() != null && getBehavior() instanceof WaterArcBehavior.PlayerControlled) { + this.velocityMultiplier = 4; + this.setStartingPosition(this.getPosition()); + } + + if (getAbility() instanceof AbilityWaterArc && !world.isRemote && getOwner() != null) { + if (getBehavior() != null && getBehavior() instanceof WaterArcBehavior.Thrown) { + AbilityData aD = AbilityData.get(getOwner(), "water_arc"); + int lvl = aD.getLevel(); + this.velocityMultiplier = lvl >= 1 ? 8 + (2 * lvl) : 8; + } + } else if (getBehavior() != null && getBehavior() instanceof WaterArcBehavior.Thrown) { + this.velocityMultiplier = 8; + } + if (getOwner() != null) { EntityWaterArc arc = AvatarEntity.lookupControlledEntity(world, EntityWaterArc.class, getOwner()); @@ -332,14 +363,16 @@ public EntityLivingBase getController() { public void cleanup() { if (getOwner() != null) { - BendingData data = Bender.get(getOwner()).getData(); - data.removeStatusControl(THROW_WATER); + BendingData data = Objects.requireNonNull(Bender.get(getOwner())).getData(); + if (data != null) { + data.removeStatusControl(THROW_WATER); + } } } public static class WaterControlPoint extends ControlPoint { - public WaterControlPoint(EntityArc arc, float size, double x, double y, double z) { + private WaterControlPoint(EntityArc arc, float size, double x, double y, double z) { super(arc, size, x, y, z); } @@ -369,7 +402,7 @@ private void breakCollidingBlocks() { * Assuming the waterarc can break blocks, tries to break the block. */ private void tryBreakBlock(IBlockState state, BlockPos pos) { - if (state.getBlock() == Blocks.AIR) { + if (state.getBlock() == Blocks.AIR || !STATS_CONFIG.waterArcBreakableBlocks.contains(state.getBlock())) { return; } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterBubble.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterBubble.java index 948a87824a..e742035a7a 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterBubble.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterBubble.java @@ -115,7 +115,7 @@ public void onUpdate() { } @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { if (entity instanceof AvatarEntity) { ((AvatarEntity) entity).onMajorWaterContact(); } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterCannon.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterCannon.java index ee6ab991b7..9b0be8486d 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterCannon.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityWaterCannon.java @@ -2,14 +2,15 @@ import com.crowsofwar.avatar.common.AvatarDamageSource; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; +import com.crowsofwar.avatar.common.bending.water.AbilityWaterCannon; import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.particle.NetworkParticleSpawner; +import com.crowsofwar.avatar.common.particle.ParticleSpawner; import com.crowsofwar.avatar.common.util.AvatarUtils; import com.crowsofwar.avatar.common.util.Raytrace; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityItem; import net.minecraft.init.SoundEvents; import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataSerializers; @@ -17,13 +18,15 @@ import net.minecraft.util.DamageSource; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.SoundCategory; -import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.WorldServer; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; +import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; public class EntityWaterCannon extends EntityArc { @@ -33,6 +36,17 @@ public class EntityWaterCannon extends EntityArc= 2) { + particleController = 17; + } + + if (data.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + particleController = 120; + } + } + for (double i = 0; i < 1; i += 1 / dist) { + Vector startPos = getControlPoint(1).position(); + Vector distance = this.position().minus(getControlPoint(1).position()); + distance = distance.times(i); + for (double angle = 0; angle < 360; angle += particleController) { + Vector position = AvatarUtils.getOrthogonalVector(this.position().minus(getControlPoint(1).position()), angle, getSizeMultiplier() * 1.4); + particles.spawnParticles(world, EnumParticleTypes.WATER_WAKE, 1, 1, + position.x() + startPos.x() + distance.x(), position.y() + startPos.y() + distance.y(), position.z() + startPos.z() + distance.z(), 0, 0, 0); + + } + particles.spawnParticles(world, EnumParticleTypes.WATER_WAKE, 1, 1, + startPos.x() + distance.x(), startPos.y() + distance.y(), startPos.z() + distance.z(), 0, 0, 0); + } + } } + if (getOwner() != null) { Vector direction = Vector.getLookRectangular(getOwner()); - this.setVelocity(direction.times(20)); - double x = getOwner().posX - posX; - double y = getOwner().posY - posY; - double z = getOwner().posZ - posZ; - this.rotationYaw = (float) (MathHelper.atan2(x, z) * (180 / Math.PI)); - this.rotationPitch = (float) (MathHelper.atan2(y, MathHelper.sqrt(x * x + z * z)) * (180 / Math.PI)); + this.setVelocity(direction.times(25)); } if (this.ticksExisted >= lifeTime && !world.isRemote) { setDead(); - + } + if (ticksExisted > 150) { + setDead(); } if (getOwner() == null) { @@ -130,12 +165,12 @@ protected void updateCpBehavior() { } @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { if (this.canCollideWith(entity) && getOwner() != entity) { if (!world.isRemote) { - int numberOfParticles = (int) (500 * getSizeMultiplier()); + int numberOfParticles = (int) (400 * getSizeMultiplier()); WorldServer World = (WorldServer) world; World.spawnParticle(EnumParticleTypes.WATER_WAKE, posX, posY, posZ, numberOfParticles, 0, 0, 0, 0.05 + getSizeMultiplier() / 10); //Change based on size @@ -162,22 +197,17 @@ protected void collideWithNearbyEntities() { if (getOwner() != null) { BendingData data = BendingData.get(getOwner()); - List collisions = Raytrace.entityRaytrace(world, getControlPoint(1).position(), velocity(), velocity - ().magnitude() / 20, entity -> entity != getOwner() && entity != this); - /*Original raytrace- but, it's pretty glitchy. Basically, look at an entity, and the water cannon will teleport. - That's why you have to use this complex vector maths to get the water cannon to face the player.**/ - /*double dist = this.getDistanceToEntity(getOwner()); - Vec3d direction = Vec3d.fromPitchYaw(rotationPitch, rotationYaw); - List collisions = Raytrace.entityRaytrace(world, getControlPoint(0).position(),Vector.getLookRectangular(this), dist, entity -> entity != getOwner()); - **/ + double dist = this.getDistance(getOwner()); + List collisions = Raytrace.entityRaytrace(world, getControlPoint(1).position(), this.position().minus(getControlPoint(1).position()), dist, entity -> entity != getOwner()); + if (!collisions.isEmpty()) { for (Entity collided : collisions) { if (canCollideWith(collided) && collided != getOwner()) { onCollideWithEntity(collided); //Needed because the water cannon will still glitch through the entity if (!(data.getAbilityData("water_cannon").isMasterPath(AbilityData.AbilityTreePath.SECOND))) { - this.setPosition(collided.posX, collided.posY + (collided.getEyeHeight() / 2), collided.posZ); + this.setPosition(collided.posX, this.posY, collided.posZ); } } } @@ -227,14 +257,25 @@ protected EntityWaterCannon.CannonControlPoint createControlPoint(float size, in } - public class CannonControlPoint extends ControlPoint { + class CannonControlPoint extends ControlPoint { - public CannonControlPoint(EntityArc arc, int index) { + private CannonControlPoint(EntityArc arc, int index) { // Make all control points the same size - super(arc, index == 1 ? 0.5f : 0.5f, 0, 0, 0); + super(arc, index == 1 ? 0.35f : 0.5f, 0, 0, 0); } } + + @Override + public boolean shouldRenderInPass(int pass) { + return true; + } + + @SideOnly(Side.CLIENT) + @Override + public boolean isInRangeToRenderDist(double distance) { + return true; + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/EntityWave.java b/src/main/java/com/crowsofwar/avatar/common/entity/EntityWave.java index e14634d783..a4d8407f2e 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/EntityWave.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/EntityWave.java @@ -20,11 +20,9 @@ import com.crowsofwar.avatar.common.AvatarDamageSource; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; import com.crowsofwar.avatar.common.data.AbilityData; -import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; @@ -154,7 +152,7 @@ public void onUpdate() { @Override - protected void onCollideWithEntity(Entity entity) { + public void onCollideWithEntity(Entity entity) { if (entity instanceof AvatarEntity) { ((AvatarEntity) entity).onMajorWaterContact(); } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/ai/EntityAiBenderAttackZombie.java b/src/main/java/com/crowsofwar/avatar/common/entity/ai/EntityAiBenderAttackZombie.java new file mode 100644 index 0000000000..6d67226777 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/entity/ai/EntityAiBenderAttackZombie.java @@ -0,0 +1,75 @@ +package com.crowsofwar.avatar.common.entity.ai; + +import com.crowsofwar.avatar.common.entity.mob.EntityHumanBender; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.util.math.AxisAlignedBB; + +import java.util.List; + +public class EntityAiBenderAttackZombie extends EntityAIBase { + + private final EntityHumanBender bender; + private double followRange; + + public EntityAiBenderAttackZombie(EntityHumanBender bender) { + this.bender = bender; + this.followRange = 15; + setMutexBits(1); + } + + @Override + public boolean shouldExecute() { + boolean nearbyZombie = false; + AxisAlignedBB box= new AxisAlignedBB(bender.posX + 15, bender.posY + 10, bender.posZ + 15, bender.posX - 15, bender.posY - 15, + bender.posZ - 15); + List zombie = bender.world.getEntitiesWithinAABB(EntityZombie.class, box); + if (!zombie.isEmpty()) { + nearbyZombie = true; + } + + return nearbyZombie; + } + + @Override + public boolean shouldContinueExecuting() { + + AxisAlignedBB box = new AxisAlignedBB(bender.posX + 15, bender.posY + 10, bender.posZ + 15, bender.posX - 15, bender.posY - 10, + bender.posZ - 15); + List zombie = bender.world.getEntitiesWithinAABB(EntityZombie.class, box); + if (!zombie.isEmpty()) { + EntityZombie z = zombie.get(0); + if (z == null || z.isDead) { + bender.setAttackTarget(null); + return false; + } + + if (bender.getAttackTarget() == null) { + bender.setAttackTarget(z); + } + + if (bender.getDistanceSq(z) > followRange * followRange) { + bender.setAttackTarget(null); + return false; + } + + followRange -= followRange > 5 ? 0.005 : 0; + + + bender.getMoveHelper().setMoveTo(z.posX, z.posY, z.posZ, 1); + bender.getLookHelper().setLookPositionWithEntity(z, 20, 20); + + + if (!bender.canEntityBeSeen(z)) { + bender.setAttackTarget(null); + return false; + } + + } + return !zombie.isEmpty(); + } + +} + diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/ai/EntityAiUseStaff.java b/src/main/java/com/crowsofwar/avatar/common/entity/ai/EntityAiUseStaff.java new file mode 100644 index 0000000000..adfb257a31 --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/entity/ai/EntityAiUseStaff.java @@ -0,0 +1,47 @@ +package com.crowsofwar.avatar.common.entity.ai; + +import com.crowsofwar.avatar.common.entity.mob.EntityHumanBender; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.util.math.AxisAlignedBB; + +import java.util.List; + +public class EntityAiUseStaff extends EntityAIBase { + + private final EntityHumanBender bender; + private int timeExecuting; + + + public EntityAiUseStaff(EntityHumanBender bender) { + this.bender = bender; + setMutexBits(1); + this.timeExecuting = 0; + } + + @Override + public boolean shouldExecute() { + return bender.getAttackTarget() != null; + } + + @Override + public boolean shouldContinueExecuting() { + + if (bender.getAttackTarget() != null) { + EntityLivingBase attacker = bender.getAttackTarget(); + bender.getMoveHelper().setMoveTo(attacker.posX, attacker.posY, attacker.posZ, 1); + bender.getLookHelper().setLookPositionWithEntity(attacker, 20, 20); + bender.getHeldItemMainhand().getItem().onEntitySwing(bender, bender.getHeldItemMainhand()); + return false; + } + return timeExecuting <= 20; + } + + @Override + public void updateTask() { + timeExecuting++; + } +} + + diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/data/AnimalCondition.java b/src/main/java/com/crowsofwar/avatar/common/entity/data/AnimalCondition.java index 8cde7f8e44..d3da930b82 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/data/AnimalCondition.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/data/AnimalCondition.java @@ -77,7 +77,7 @@ public void onUpdate() { distance = lastDistance; } float diff = distance - lastDistance; - addHunger(diff * 0.1f); + addHunger(diff * 0.05f); lastDistance = distance; @@ -211,7 +211,8 @@ public void setAgeDays(float days) { } public float getSizeMultiplier() { - return isAdult() ? 1 : 0.1f + getAgeDays() / getAdultAge() * 0.9f; + float adultSize = getAgeDays() < 5 ? getAgeDays() / getAdultAge() : 1.666777f; + return isAdult() ? adultSize : 0.1f + getAgeDays() / getAdultAge() * 0.9f; } public boolean isAdult() { diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/data/BoulderBehavior.java b/src/main/java/com/crowsofwar/avatar/common/entity/data/BoulderBehavior.java index 71bc2c2b27..e857a4626e 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/data/BoulderBehavior.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/data/BoulderBehavior.java @@ -1,14 +1,11 @@ package com.crowsofwar.avatar.common.entity.data; + import com.crowsofwar.avatar.common.AvatarDamageSource; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.entity.EntityBoulder; -import com.crowsofwar.avatar.common.entity.EntityCloudBall; -import com.crowsofwar.avatar.common.entity.EntityFloatingBlock; import com.crowsofwar.gorecore.util.Vector; -import net.minecraft.block.Block; -import net.minecraft.block.SoundType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; @@ -20,7 +17,6 @@ import java.util.List; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; -import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; public abstract class BoulderBehavior extends Behavior { @@ -99,7 +95,7 @@ public BoulderBehavior onUpdate(EntityBoulder entity) { private void collision(EntityLivingBase collided, EntityBoulder entity) { double speed = entity.velocity().magnitude(); - if (collided.attackEntityFrom(AvatarDamageSource.causeCloudburstDamage(collided, entity.getOwner()), + if (collided.attackEntityFrom(AvatarDamageSource.EARTH, entity.getDamage())) { BattlePerformanceScore.addMediumScore(entity.getOwner()); } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/data/CloudburstBehavior.java b/src/main/java/com/crowsofwar/avatar/common/entity/data/CloudburstBehavior.java index 99b7bd1e10..66ed3dd9ed 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/data/CloudburstBehavior.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/data/CloudburstBehavior.java @@ -17,6 +17,7 @@ import net.minecraft.world.World; import java.util.List; +import java.util.Objects; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; @@ -24,7 +25,7 @@ public abstract class CloudburstBehavior extends Behavior { public static final DataSerializer DATA_SERIALIZER = new Behavior.BehaviorSerializer<>(); - public static int ID_NOTHING, ID_FALL, ID_PICKUP, ID_PLAYER_CONTROL, ID_THROWN; + public static int ID_NOTHING, ID_PLAYER_CONTROL, ID_THROWN; public static void register() { DataSerializers.registerSerializer(DATA_SERIALIZER); @@ -72,7 +73,7 @@ public CloudburstBehavior onUpdate(EntityCloudBall entity) { entity.onCollideWithSolid(); } - entity.addVelocity(0, -1 / 120, 0); + entity.addVelocity(0, -1F / 120, 0); World world = entity.world; if (!entity.isDead) { @@ -80,12 +81,8 @@ public CloudburstBehavior onUpdate(EntityCloudBall entity) { entity.getExpandedHitbox()); if (!collidedList.isEmpty()) { for (Entity collided : collidedList) { - if (entity.canCollideWith(collided)) { - collision((EntityLivingBase) collided, entity); - Vector motion = new Vector(collided).minus(new Vector(entity)); - motion = motion.times(0.5).withY(0.10); - collided.addVelocity(motion.x(), motion.y(), motion.z()); - entity.cloudBurst(); + if (entity.canCollideWith(collided) && collided != entity.getOwner() && collided != entity) { + collision( collided, entity); } } @@ -97,30 +94,29 @@ public CloudburstBehavior onUpdate(EntityCloudBall entity) { } - private void collision(EntityLivingBase collided, EntityCloudBall entity) { + private void collision(Entity collided, EntityCloudBall entity) { - if (collided.attackEntityFrom(AvatarDamageSource.causeCloudburstDamage(collided, entity.getOwner()), - entity.getDamage())) { - BattlePerformanceScore.addMediumScore(entity.getOwner()); - } + if (collided.canBeCollidedWith() && entity.canCollideWith(collided) && !entity.world + .isRemote) { + if (collided.attackEntityFrom(AvatarDamageSource.causeAirDamage(collided, entity.getOwner()), + entity.getDamage())) { + BattlePerformanceScore.addMediumScore(entity.getOwner()); + } - Vector motion = entity.velocity().dividedBy(20); - motion = motion.times(STATS_CONFIG.cloudburstSettings.push).withY(0.11); - collided.addVelocity(motion.x(), motion.y(), motion.z()); + Vector motion = entity.velocity().dividedBy(80); + motion = motion.times(STATS_CONFIG.cloudburstSettings.push).withY(0.05); + collided.addVelocity(motion.x(), motion.y(), motion.z()); - BendingData data = Bender.get(entity.getOwner()).getData(); - if (!collided.world.isRemote && data != null) { - float xp = SKILLS_CONFIG.cloudburstHit; - data.getAbilityData(entity.getAbility().getName()).addXp(xp); - } + BendingData data = Objects.requireNonNull(Bender.get(entity.getOwner())).getData(); + if (!collided.world.isRemote && data != null) { + float xp = SKILLS_CONFIG.cloudburstHit; + data.getAbilityData(entity.getAbility().getName()).addXp(xp); + } - // Remove the cloudburst & spawn particles - if (!entity.world.isRemote) { entity.onCollideWithSolid(); entity.setDead(); } - } @Override @@ -152,16 +148,13 @@ public CloudburstBehavior onUpdate(EntityCloudBall entity) { if (owner == null) return this; - BendingData data = Bender.get(owner).getData(); + BendingData data = Objects.requireNonNull(Bender.get(owner)).getData(); - double yaw = Math.toRadians(owner.rotationYaw); - double pitch = Math.toRadians(owner.rotationPitch); - Vector forward = Vector.toRectangular(yaw, pitch); - Vector eye = Vector.getEyePos(owner); - Vector target = forward.times(2).plus(eye); + Vector forward = Vector.getLookRectangular(owner); + Vector eye = Vector.getEyePos(owner).minusY(0.5); + Vector target = forward.times(1.5).plus(eye); Vector motion = target.minus(Vector.getEntityPos(entity)).times(6); entity.setVelocity(motion); - entity.setStartingPosition(entity.getPosition()); if (entity.getAbility() instanceof AbilityCloudBurst && !entity.world.isRemote) { if (data.getAbilityData("cloudburst").isMasterPath(AbilityData.AbilityTreePath.SECOND)) { diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/data/FireArcBehavior.java b/src/main/java/com/crowsofwar/avatar/common/entity/data/FireArcBehavior.java index b69472a795..88405c5ec5 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/data/FireArcBehavior.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/data/FireArcBehavior.java @@ -30,13 +30,14 @@ import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.MoverType; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.network.datasync.DataSerializer; import net.minecraft.network.datasync.DataSerializers; import java.util.List; +import java.util.Objects; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; @@ -79,10 +80,11 @@ public FireArcBehavior onUpdate(EntityFireArc entity) { target = Vector.getEyePos(owner).plus(look.times(3)); } - Vector motion = target.minus(entity.position()); - motion = motion.times(0.5 * 20); - entity.setVelocity(motion); - + if (target != null) { + Vector motion = target.minus(entity.position()); + motion = motion.times(0.5 * 20); + entity.setVelocity(motion); + } // Ensure that owner always has stat ctrl active if (entity.ticksExisted % 10 == 0) { @@ -116,44 +118,43 @@ public static class Thrown extends FireArcBehavior { @Override public FireArcBehavior onUpdate(EntityFireArc entity) { - entity.addVelocity(Vector.DOWN.times(9.81 / 60)); + entity.addVelocity(Vector.DOWN.times(9.81 / 120)); List collidedList = entity.getEntityWorld().getEntitiesWithinAABB( - Entity.class, entity.getEntityBoundingBox().grow(0.9, 0.9, 0.9), + Entity.class, entity.getEntityBoundingBox().grow(0.5, 0.5, 0.5), collided -> collided != entity.getOwner()); for (Entity collided : collidedList) { + if (collided == entity.getOwner()) return this; if (entity.canCollideWith(collided)) { double push = STATS_CONFIG.fireArcSettings.push; collided.addVelocity(entity.motionX * push, 0.4 * push, entity.motionZ * push); collided.setFire(3); - if (collided.attackEntityFrom(AvatarDamageSource.causeFireDamage(collided, entity.getOwner()), - STATS_CONFIG.fireArcSettings.damage * entity.getDamageMult())) { - BattlePerformanceScore.addMediumScore(entity.getOwner()); + if (entity.canDamageEntity(collided) || collided instanceof EntityPlayer) { + if (collided.attackEntityFrom(AvatarDamageSource.causeFireDamage(collided, entity.getOwner()), + STATS_CONFIG.fireArcSettings.damage * entity.getDamageMult())) { + BattlePerformanceScore.addMediumScore(entity.getOwner()); + } } - + entity.onCollideWithEntity(entity); if (!entity.world.isRemote) { - BendingData data = Bender.get(entity.getOwner()).getData(); + BendingData data = Objects.requireNonNull(Bender.get(entity.getOwner())).getData(); if (data != null) { data.getAbilityData("fire_arc") .addXp(ConfigSkills.SKILLS_CONFIG.fireHit); + AbilityData abilityData = data.getAbilityData("fire_arc"); + if (abilityData.isMasterPath(AbilityTreePath.SECOND) && entity.getOwner() != null) { + data.addStatusControl(StatusControl.THROW_FIRE); + return new FireArcBehavior.PlayerControlled(); + } } } } } - if (!collidedList.isEmpty() && entity.getOwner() != null) { - BendingData data = BendingData.get(entity.getOwner()); - AbilityData abilityData = data.getAbilityData("fire_arc"); - if (abilityData.isMasterPath(AbilityTreePath.SECOND)) { - data.addStatusControl(StatusControl.THROW_FIRE); - return new FireArcBehavior.PlayerControlled(); - } - } - return this; } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/data/FireballBehavior.java b/src/main/java/com/crowsofwar/avatar/common/entity/data/FireballBehavior.java index a60b3221d4..4294d550a1 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/data/FireballBehavior.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/data/FireballBehavior.java @@ -95,7 +95,7 @@ public FireballBehavior onUpdate(EntityFireball entity) { entity.onCollideWithSolid(); } - entity.addVelocity(Vector.DOWN.times(1 / 40)); + entity.addVelocity(Vector.DOWN.times(1F / 40)); World world = entity.world; if (!entity.isDead) { @@ -104,13 +104,8 @@ public FireballBehavior onUpdate(EntityFireball entity) { if (!collidedList.isEmpty()) { Entity collided = collidedList.get(0); if (entity.canCollideWith(collided) && collided != entity.getOwner()) { - collision((EntityLivingBase) collided, entity); - } else if (collided != entity.getOwner()) { - Vector motion = new Vector(collided).minus(new Vector(entity)); - motion = motion.times(0.3).withY(0.08); - collided.addVelocity(motion.x(), motion.y(), motion.z()); + collision(collided, entity); } - } } @@ -118,35 +113,39 @@ public FireballBehavior onUpdate(EntityFireball entity) { } - private void collision(EntityLivingBase collided, EntityFireball entity) { + private void collision(Entity collided, EntityFireball entity) { double speed = entity.velocity().magnitude(); - collided.setFire(STATS_CONFIG.fireballSettings.fireTime); + if (entity.canDamageEntity(collided)) { + collided.setFire(STATS_CONFIG.fireballSettings.fireTime); - if (collided.attackEntityFrom(AvatarDamageSource.causeFireballDamage(collided, entity.getOwner()), - entity.getDamage())) { - BattlePerformanceScore.addMediumScore(entity.getOwner()); + if (collided.attackEntityFrom(AvatarDamageSource.causeFireballDamage(collided, entity.getOwner()), + entity.getDamage())) { + BattlePerformanceScore.addMediumScore(entity.getOwner()); + } } + if (entity.canCollideWith(collided) && collided.canBeCollidedWith()) { - Vector motion = entity.velocity().dividedBy(20); - motion = motion.times(STATS_CONFIG.fireballSettings.push).withY(0.08); - collided.addVelocity(motion.x(), motion.y(), motion.z()); + Vector motion = entity.velocity().dividedBy(20); + motion = motion.times(STATS_CONFIG.fireballSettings.push).withY(0.08); + collided.addVelocity(motion.x(), motion.y(), motion.z()); + + BendingData data = Bender.get(entity.getOwner()).getData(); + if (!collided.world.isRemote && data != null) { + float xp = SKILLS_CONFIG.fireballHit; + if (entity.getAbility() != null) { + data.getAbilityData(entity.getAbility().getName()).addXp(xp); + } - BendingData data = Bender.get(entity.getOwner()).getData(); - if (!collided.world.isRemote && data != null) { - float xp = SKILLS_CONFIG.fireballHit; - if (entity.getAbility() != null) { - data.getAbilityData(entity.getAbility().getName()).addXp(xp); } - } + // Remove the fireball & spawn particles + if (!entity.world.isRemote) { + entity.onCollideWithSolid(); + entity.setDead(); + } - // Remove the fireball & spawn particles - if (!entity.world.isRemote) { - entity.onCollideWithSolid(); - entity.setDead(); } - } @Override @@ -185,7 +184,7 @@ public FireballBehavior onUpdate(EntityFireball entity) { Vector forward = Vector.toRectangular(yaw, pitch); Vector eye = Vector.getEyePos(owner); Vector target = forward.times(2).plus(eye); - Vector motion = target.minus(Vector.getEntityPos(entity)).times(5); + Vector motion = target.minus(Vector.getEntityPos(entity)).times(7); entity.setVelocity(motion); if (entity.getAbility() instanceof AbilityFireball) { diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/data/FloatingBlockBehavior.java b/src/main/java/com/crowsofwar/avatar/common/entity/data/FloatingBlockBehavior.java index f0c9523890..f43a322a21 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/data/FloatingBlockBehavior.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/data/FloatingBlockBehavior.java @@ -199,7 +199,7 @@ private FloatingBlockBehavior collision(EntityLivingBase collided, EntityFloatin if (collided.attackEntityFrom( AvatarDamageSource.causeFloatingBlockDamage(collided, entity.getOwner()), - (float) (speed / 15 * STATS_CONFIG.floatingBlockSettings.damage * entity.getDamageMult()))) { + (float) (speed / 30 * STATS_CONFIG.floatingBlockSettings.damage * entity.getDamageMult()))) { BattlePerformanceScore.addMediumScore(entity.getOwner()); } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/data/LightningSpearBehavior.java b/src/main/java/com/crowsofwar/avatar/common/entity/data/LightningSpearBehavior.java index af74d41886..5109368940 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/data/LightningSpearBehavior.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/data/LightningSpearBehavior.java @@ -18,21 +18,31 @@ package com.crowsofwar.avatar.common.entity.data; import com.crowsofwar.avatar.common.AvatarDamageSource; +import com.crowsofwar.avatar.common.AvatarParticles; import com.crowsofwar.avatar.common.bending.BattlePerformanceScore; +import com.crowsofwar.avatar.common.bending.StatusControl; +import com.crowsofwar.avatar.common.bending.lightning.AbilityLightningSpear; +import com.crowsofwar.avatar.common.data.AbilityData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.entity.AvatarEntity; import com.crowsofwar.avatar.common.entity.EntityLightningSpear; +import com.crowsofwar.avatar.common.util.Raytrace; import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.network.datasync.DataSerializer; import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.util.SoundCategory; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; import java.util.List; +import java.util.Objects; import static com.crowsofwar.avatar.common.config.ConfigSkills.SKILLS_CONFIG; import static com.crowsofwar.avatar.common.config.ConfigStats.STATS_CONFIG; @@ -44,7 +54,7 @@ public abstract class LightningSpearBehavior extends Behavior DATA_SERIALIZER = new Behavior.BehaviorSerializer<>(); - public static int ID_NOTHING, ID_FALL, ID_PICKUP, ID_PLAYER_CONTROL, ID_THROWN; + public static int ID_NOTHING, ID_PLAYER_CONTROL, ID_THROWN; public static void register() { DataSerializers.registerSerializer(DATA_SERIALIZER); @@ -88,30 +98,24 @@ public LightningSpearBehavior onUpdate(EntityLightningSpear entity) { time++; if (entity.collided || (!entity.world.isRemote && time > 200)) { - entity.setDead(); entity.onCollideWithSolid(); - } - - entity.addVelocity(Vector.DOWN.times(1 / 12000)); - Vector direction = entity.velocity().toSpherical(); - entity.rotationYaw = (float) Math.toDegrees(direction.y()); - entity.rotationPitch = (float) Math.toDegrees(direction.x()); + } World world = entity.world; if (!entity.isDead) { - List collidedList = world.getEntitiesWithinAABBExcludingEntity(entity, - entity.getExpandedHitbox()); + AxisAlignedBB box = new AxisAlignedBB(entity.posX + entity.getSize(), entity.posY + entity.getSize(), entity.posZ + entity.getSize(), + entity.posX - entity.getSize(), entity.posY - entity.getSize(), entity.posZ - entity.getSize()); + List collidedList = world.getEntitiesWithinAABB(Entity.class, + box); if (!collidedList.isEmpty()) { - Entity collided = collidedList.get(0); - if (collided instanceof EntityLivingBase && collided != entity.getOwner()) { - collision((EntityLivingBase) collided, entity, entity.isGroupAttack()); - } else if (collided != entity.getOwner()) { - Vector motion = new Vector(collided).minus(new Vector(entity)); - motion = motion.times(0.7).withY(0.09); - collided.addVelocity(motion.x(), motion.y(), motion.z()); + for (Entity collided : collidedList) { + if (collided != entity.getOwner() && (entity.canCollideWith(collided) || (collided.canBeCollidedWith() && collided.canBePushed()))) { + if (collided != entity) { + collision(collided, entity, entity.isGroupAttack()); + } + } } - } } @@ -119,26 +123,41 @@ public LightningSpearBehavior onUpdate(EntityLightningSpear entity) { } - private void collision(EntityLivingBase collided, EntityLightningSpear entity, boolean triggerGroupAttack) { - double speed = entity.velocity().magnitude(); - if (collided.attackEntityFrom(AvatarDamageSource.causeFireballDamage(collided, entity.getOwner()), - entity.getDamage())) { - BattlePerformanceScore.addMediumScore(entity.getOwner()); - } - Vector motion = entity.velocity().dividedBy(5); - motion = motion.times(STATS_CONFIG.fireballSettings.push).withY(0.07); - collided.addVelocity(motion.x(), motion.y(), motion.z()); + private void collision(Entity collided, EntityLightningSpear entity, boolean triggerGroupAttack) { + if (collided.canBeCollidedWith() && collided.canBePushed() && collided != entity.getOwner() && collided != entity) { - BendingData data = Bender.get(entity.getOwner()).getData(); - if (!collided.world.isRemote && data != null) { - float xp = SKILLS_CONFIG.lightningspearHit; - data.getAbilityData("lightning_spear").addXp(xp); + if (collided.attackEntityFrom(AvatarDamageSource.causeLightningDamage(collided, entity.getOwner()), + entity.getDamage())) { + BattlePerformanceScore.addMediumScore(entity.getOwner()); + } + Vector motion = entity.velocity().dividedBy(40); + motion = motion.times(STATS_CONFIG.lightningSpearSettings.push).withY(0.04); + collided.addVelocity(motion.x(), motion.y(), motion.z()); + + BendingData data = Objects.requireNonNull(Bender.get(entity.getOwner())).getData(); + if (!entity.world.isRemote && data != null) { + float xp = SKILLS_CONFIG.lightningspearHit; + data.getAbilityData("lightning_spear").addXp(xp); + if (!data.getAbilityData("lightning_spear").isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + entity.LightningBurst(); + entity.world.playSound(null,collided.posX, entity.posY, collided.posZ, SoundEvents.ENTITY_LIGHTNING_IMPACT, SoundCategory.BLOCKS, 2.0F, + (1.0F + (entity.world.rand.nextFloat() - entity.world.rand.nextFloat()) * 0.2F)); + entity.removeStatCtrl(); + + } + else { + if (entity.world instanceof WorldServer) { + WorldServer World = (WorldServer) entity.world; + World.playSound(null,collided.posX, entity.posY, collided.posZ, SoundEvents.ENTITY_CREEPER_PRIMED, SoundCategory.BLOCKS, 2.0F, + (1.0F + (entity.world.rand.nextFloat() - entity.world.rand.nextFloat()) * 0.2F)); + World.spawnParticle(AvatarParticles.getParticleElectricity(), collided.posX, entity.posY, collided.posZ, 10, 0, 0, 0, 0.025); + } + } + } } - // Remove the fireball & spawn particles - if (!entity.world.isRemote && !entity.isPiercing()) entity.setDead(); if (triggerGroupAttack) { @@ -149,9 +168,9 @@ private void collision(EntityLivingBase collided, EntityLightningSpear entity, b entity.posX - radius, entity.posY - radius, entity.posZ - radius, entity.posX + radius, entity.posY + radius, entity.posZ + radius); - List targets = entity.world.getEntitiesWithinAABB( - EntityLivingBase.class, aabb); - for (EntityLivingBase target : targets) { + List targets = entity.world.getEntitiesWithinAABB( + Entity.class, aabb); + for (Entity target : targets) { if (target.getDistanceSq(entity) > radius * radius) { continue; } @@ -159,6 +178,7 @@ private void collision(EntityLivingBase collided, EntityLightningSpear entity, b } } + if (!entity.world.isRemote && !entity.isPiercing()) entity.setDead(); } @@ -185,30 +205,71 @@ public static class PlayerControlled extends LightningSpearBehavior { public PlayerControlled() { } + float maxSize = 1.6F; + float maxDamage = 4; @Override public LightningSpearBehavior onUpdate(EntityLightningSpear entity) { EntityLivingBase owner = entity.getOwner(); if (owner == null) return this; - BendingData data = Bender.get(owner).getData(); + BendingData data = BendingData.get(owner); + if (!data.hasStatusControl(StatusControl.THROW_LIGHTNINGSPEAR)) { + EntityLightningSpear spear = AvatarEntity.lookupControlledEntity(entity.world, EntityLightningSpear.class, entity.getOwner()); + if (spear != null) { + data.addStatusControl(StatusControl.THROW_LIGHTNINGSPEAR); + } + } + Raytrace.Result res = Raytrace.getTargetBlock(owner, 3, false); + + Vector target; + if (res.hitSomething()) { + target = res.getPosPrecise(); + } else { + Vector look = Vector.toRectangular(Math.toRadians(owner.rotationYaw), + Math.toRadians(owner.rotationPitch)); + target = Vector.getEyePos(owner).plus(look.times(3)); + } - double yaw = Math.toRadians(owner.rotationYaw); - double pitch = Math.toRadians(owner.rotationPitch); - Vector forward = Vector.toRectangular(yaw, pitch); - Vector eye = Vector.getEyePos(owner); - Vector target = forward.times(2).plus(eye); - Vector motion = target.minus(Vector.getEntityPos(entity)).times(5); + assert target != null; + Vector motion = target.minus(entity.position()); + motion = motion.times(0.5 * 20); entity.setVelocity(motion); Vector direction = entity.position().minus(Vector.getEyePos(owner)).toSpherical(); entity.rotationYaw = (float) Math.toDegrees(direction.y()); entity.rotationPitch = (float) Math.toDegrees(direction.x()); - int size = entity.getSize(); - if (size < 60 && entity.ticksExisted % 4 == 0) { - entity.setSize(size + 1); + + float size = entity.getSize(); + float damage = entity.getDamage(); + + if (entity.getAbility() instanceof AbilityLightningSpear && !entity.world.isRemote) { + AbilityData aD = AbilityData.get(entity.getOwner(), "lightning_spear"); + int lvl = aD.getLevel(); + if (lvl == 1) { + maxSize = 1.8F; + maxDamage = 5; + } + if (lvl == 2) { + maxSize = 2F; + maxDamage = 6; + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.SECOND)) { + maxSize = 2.6F; + maxDamage = 7; + } + if (aD.isMasterPath(AbilityData.AbilityTreePath.FIRST)) { + maxDamage = 8; + } } + if (size < maxSize && entity.ticksExisted % 4 == 0) { + entity.setSize(size + 0.005F); + } + if (damage < maxDamage && entity.ticksExisted % 4 == 0) { + entity.setDamage(damage + 0.005F); + } + return this; } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/data/WaterArcBehavior.java b/src/main/java/com/crowsofwar/avatar/common/entity/data/WaterArcBehavior.java index 6e92b7ef76..b8628f87f2 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/data/WaterArcBehavior.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/data/WaterArcBehavior.java @@ -117,7 +117,6 @@ public void save(NBTTagCompound nbt) { public static class Thrown extends WaterArcBehavior { float ticks = 0; - float startGravity; @Override public WaterArcBehavior onUpdate(EntityWaterArc entity) { @@ -140,36 +139,32 @@ public WaterArcBehavior onUpdate(EntityWaterArc entity) { } if (lvl <= 0) { //Level I or in Creative Mode - startGravity = STATS_CONFIG.waterArcTicks; if (ticks >= STATS_CONFIG.waterArcTicks) { - //Default is 40 + //Default is 120 entity.Splash(); entity.setDead(); } } if (lvl == 1) { //Level II. - startGravity = STATS_CONFIG.waterArcTicks * (5 / 4); if (ticks >= STATS_CONFIG.waterArcTicks * (5 / 4)) { - //50 + //150 entity.Splash(); entity.setDead(); } } if (lvl == 2) { //Level III - startGravity = STATS_CONFIG.waterArcTicks * (6 / 4); if (ticks >= STATS_CONFIG.waterArcTicks * (6 / 4)) { - //60 + //180 entity.Splash(); entity.setDead(); } } if (waterSpear) { //Level 4 Path Two - startGravity = STATS_CONFIG.waterArcTicks * (3); if (ticks >= STATS_CONFIG.waterArcTicks * (3)) { - //120 ticks + //360 ticks entity.Splash(); entity.setDead(); } @@ -178,9 +173,8 @@ public WaterArcBehavior onUpdate(EntityWaterArc entity) { if (abilityData != null) { if (abilityData.isMasterPath(AbilityTreePath.FIRST)) { //Level 4 Path One - startGravity = STATS_CONFIG.waterArcTicks * (5 / 4); if (ticks >= STATS_CONFIG.waterArcTicks * (5 / 4)) { - //50 + //150 entity.Splash(); entity.setDead(); } @@ -188,39 +182,37 @@ public WaterArcBehavior onUpdate(EntityWaterArc entity) { } } - if (startGravity / ticks <= 2) { - entity.addVelocity(Vector.DOWN.times(entity.getGravity() / 30)); - } + entity.addVelocity(Vector.DOWN.times(entity.getGravity() / 90)); List collidedList = entity.getEntityWorld().getEntitiesWithinAABB( - EntityLivingBase.class, entity.getEntityBoundingBox().grow(0.9, 0.9, 0.9), + EntityLivingBase.class, entity.getEntityBoundingBox().grow(0.5, 0.5, 0.5), collided -> collided != entity.getOwner()); for (EntityLivingBase collided : collidedList) { if (collided == entity.getOwner()) return this; - double x = entity.motionX / 2 * STATS_CONFIG.waterArcSettings.push; - double y = entity.motionY / 20 * STATS_CONFIG.waterArcSettings.push > 0.75 ? 0.75 : entity.motionY / 20 * STATS_CONFIG.waterArcSettings.push; - double z = entity.motionZ / 2 * STATS_CONFIG.waterArcSettings.push; - collided.addVelocity(x, y, z); - entity.damageEntity(collided); + if (entity.canCollideWith(collided)) { + double x = entity.motionX / 2 * STATS_CONFIG.waterArcSettings.push; + double y = entity.motionY / 20 * STATS_CONFIG.waterArcSettings.push > 0.75 ? 0.75 : entity.motionY / 20 * STATS_CONFIG.waterArcSettings.push; + double z = entity.motionZ / 2 * STATS_CONFIG.waterArcSettings.push; + collided.addVelocity(x, y, z); + if (entity.canDamageEntity(collided)) { + entity.damageEntity(collided); + } - if (!entity.world.isRemote && data != null) { + if (!entity.world.isRemote && data != null) { - abilityData.addXp(ConfigSkills.SKILLS_CONFIG.waterHit); + abilityData.addXp(ConfigSkills.SKILLS_CONFIG.waterHit); + + if (!waterSpear) { + entity.Splash(); + entity.setDead(); + entity.cleanup(); + } - if (abilityData.isMasterPath(AbilityTreePath.FIRST)) { - entity.setBehavior(new PlayerControlled()); - data.addStatusControl(StatusControl.THROW_WATER); - } - if (!waterSpear) { - entity.Splash(); - entity.setDead(); - entity.cleanup(); } } - } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/mob/BisonSummonHandler.java b/src/main/java/com/crowsofwar/avatar/common/entity/mob/BisonSummonHandler.java index 2ad27842d5..dbc011d819 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/mob/BisonSummonHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/mob/BisonSummonHandler.java @@ -16,61 +16,64 @@ */ package com.crowsofwar.avatar.common.entity.mob; -import com.crowsofwar.avatar.common.data.BendingData; +import net.minecraft.entity.EntityLivingBase; + import com.crowsofwar.avatar.common.data.TickHandler; import com.crowsofwar.avatar.common.data.ctx.BendingContext; -import net.minecraft.entity.EntityLivingBase; -import java.util.List; -import java.util.Random; +import java.util.*; /** * @author CrowsOfWar */ public class BisonSummonHandler extends TickHandler { + public BisonSummonHandler(int id) { + super(id); + } + @Override public boolean tick(BendingContext ctx) { if (ctx.getWorld().isRemote) return false; - BendingData data = ctx.getData(); + //BendingData data = ctx.getData(); - int cooldown = data.getMiscData().getPetSummonCooldown(); - if (cooldown <= 0) { + //int cooldown = data.getMiscData().getPetSummonCooldown(); + //if (cooldown <= 0) { - trySummonBison(ctx.getBenderEntity()); - return true; + trySummonBison(ctx.getBenderEntity()); + return true; - } else { + /*} else { data.getMiscData().setPetSummonCooldown(cooldown - 1); return false; - - } - +**/ } private boolean trySummonBison(EntityLivingBase player) { - List entities = player.world.getEntities(EntitySkyBison.class, - bison -> bison.getOwner() == player); + List entities = player.world.getEntities(EntitySkyBison.class, bison -> bison.getOwner() == player); if (!entities.isEmpty()) { - EntitySkyBison bison = entities.get(0); - Random random = new Random(); - // Find suitable location near player - for (int i = 0; i < 5; i++) { + for (EntitySkyBison bison : entities) { + Random random = new Random(); - double x = player.posX + (random.nextDouble() * 2 - 1) * 15; - double y = player.posY + (random.nextDouble() * 2 - 1) * 5; - double z = player.posZ + (random.nextDouble() * 2 - 1) * 15; + // Find suitable location near player + for (int i = 0; i < 5; i++) { - if (bison.attemptTeleport(x, y, z)) { - return true; - } + double x = player.posX + (random.nextDouble() * 2 - 1) * 15; + double y = player.posY + (random.nextDouble() * 2 - 1) * 5; + double z = player.posZ + (random.nextDouble() * 2 - 1) * 15; + bison.attemptTeleport(x, y, z); + if (bison.attemptTeleport(x, y, z)) { + return true; + } + + } } } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityAirbender.java b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityAirbender.java index 489982cefb..95cb928b0e 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityAirbender.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityAirbender.java @@ -17,12 +17,44 @@ package com.crowsofwar.avatar.common.entity.mob; import com.crowsofwar.avatar.common.bending.Abilities; +import com.crowsofwar.avatar.common.bending.air.Airbending; +import com.crowsofwar.avatar.common.data.Bender; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.entity.ai.EntityAiUseStaff; +import com.crowsofwar.avatar.common.item.AvatarItem; +import com.crowsofwar.avatar.common.item.AvatarItems; import com.crowsofwar.avatar.common.item.ItemScroll.ScrollType; +import com.crowsofwar.gorecore.format.FormattedMessage; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.EntityAIAttackMelee; +import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; +import net.minecraft.entity.ai.EntityAIZombieAttack; +import net.minecraft.entity.monster.EntityIronGolem; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.entity.passive.EntityWolf; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; import net.minecraft.world.storage.loot.LootTableList; +import org.lwjgl.Sys; + +import javax.annotation.Nullable; +import java.util.Objects; +import java.util.Random; + +import static com.crowsofwar.avatar.common.AvatarChatMessages.MSG_NEED_AIR_TRADE_ITEM; +import static com.crowsofwar.avatar.common.config.ConfigMobs.MOBS_CONFIG; /** * @author CrowsOfWar @@ -32,27 +64,51 @@ public class EntityAirbender extends EntityHumanBender { public static final ResourceLocation LOOT_TABLE = LootTableList .register(new ResourceLocation("avatarmod", "airbender")); + private int scrollsLeft; + private int level = 0; + /** * @param world */ public EntityAirbender(World world) { super(world); + getData().addBendingId(Airbending.ID); + } @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.35); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.25); + + } + + @Override + protected int getLevel() { + return level; + } + + @Override + protected void entityInit() { + super.entityInit(); + getData().addBendingId(Airbending.ID); + + } + + @Override + protected FormattedMessage getTradeFailMessage() { + return MSG_NEED_AIR_TRADE_ITEM; } @Override protected void addBendingTasks() { - this.tasks.addTask(2, Abilities.getAi("air_bubble", this, getBender())); - this.tasks.addTask(1, Abilities.getAi("air_gust", this, getBender())); - this.tasks.addTask(3, Abilities.getAi("airblade", this, getBender())); - this.tasks.addTask(4, new EntityAIAttackMelee(this, 1.7, true)); + this.tasks.addTask(4, Objects.requireNonNull(Abilities.getAi("air_bubble", this, Bender.get(this)))); + this.tasks.addTask(1, Objects.requireNonNull(Abilities.getAi("air_gust", this, Bender.get(this)))); + this.tasks.addTask(2, Objects.requireNonNull(Abilities.getAi("airblade", this, Bender.get(this)))); + this.tasks.addTask(4, new EntityAIAttackMelee(this, 1.4, true)); } + @Override protected ResourceLocation getLootTable() { return LOOT_TABLE; @@ -68,4 +124,96 @@ protected int getNumSkins() { return 7; } + @Override + protected int getScrollsLeft() { + return scrollsLeft > 0 ? scrollsLeft : 1; + } + + @Override + protected boolean isTradeItem(Item item) { + return super.isTradeItem(item) || MOBS_CONFIG.isAirTradeItem(item); + } + + @Override + protected int getTradeAmount(Item item) { + return super.getTradeAmount(item) + MOBS_CONFIG.getAirTradeItemAmount(item); + } + + @Override + public void onUpdate() { + super.onUpdate(); + + } + + + @Override + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata) { + getData().addBendingId(Airbending.ID); + if (level == 0 && !world.isRemote) { + Random rand = new Random(); + int level = rand.nextInt(3 + 1 - 1) + 1; + getData().addBendingId(Airbending.ID); + if (level < 2) { + this.level = 1; + } + if (level == 2) { + this.level = 2; + } + if (level > 2) { + this.level = 3; + + } + } + + if (level == 1) { + getData().getAbilityData("air_bubble").setLevel(-1); + getData().getAbilityData("air_gust").setLevel(0); + getData().getAbilityData("airblade").setLevel(0); + } + if (level == 2) { + getData().getAbilityData("air_bubble").setLevel(-1); + getData().getAbilityData("air_gust").setLevel(1); + getData().getAbilityData("airblade").setLevel(0); + } + if (level >= 3) { + getData().getAbilityData("air_bubble").setLevel(0); + getData().getAbilityData("air_gust").setLevel(2); + getData().getAbilityData("airblade").setLevel(1); + ItemStack staff = new ItemStack(AvatarItems.airbenderStaff, 1); + this.setHeldItem(EnumHand.MAIN_HAND, staff); + + } + scrollsLeft = this.level; + if (scrollsLeft == 0) { + scrollsLeft = 1; + } + return super.onInitialSpawn(difficulty, livingdata); + } + + @Override + public void setDead() { + //if (!world.isRemote && level >= 3) { + // this.entityDropItem(new ItemStack(AvatarItems.airbenderStaff, 1), 0); + //} + super.setDead(); + } + + + @Override + public ITextComponent getDisplayName() { + /*TextComponentString textcomponentstring = new TextComponentString("Level "+ level + " " + ScorePlayerTeam.formatPlayerName(this.getTeam(), this.getName())); + textcomponentstring.getStyle().setHoverEvent(this.getHoverEvent()); + textcomponentstring.getStyle().setInsertion(this.getCachedUniqueIdString()); + return textcomponentstring;**/ + return super.getDisplayName(); + } + + + @Override + public boolean processInteract(EntityPlayer player, EnumHand hand) { + /*if (!world.isRemote) { + System.out.println(level); + }**/ + return super.processInteract(player, hand); + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityFirebender.java b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityFirebender.java index e86815233b..4684224b05 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityFirebender.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityFirebender.java @@ -17,36 +17,60 @@ package com.crowsofwar.avatar.common.entity.mob; import com.crowsofwar.avatar.common.bending.Abilities; +import com.crowsofwar.avatar.common.bending.StatusControl; +import com.crowsofwar.avatar.common.bending.fire.Firebending; +import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.item.ItemScroll.ScrollType; +import com.crowsofwar.gorecore.format.FormattedMessage; +import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.EntityAIAttackMelee; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; import net.minecraft.world.storage.loot.LootTableList; +import javax.annotation.Nullable; +import java.util.Objects; import java.util.Random; +import static com.crowsofwar.avatar.common.AvatarChatMessages.MSG_NEED_FIRE_TRADE_ITEM; +import static com.crowsofwar.avatar.common.bending.fire.StatCtrlInfernoPunch.INFERNO_PUNCH; +import static com.crowsofwar.avatar.common.config.ConfigMobs.MOBS_CONFIG; + /** * @author CrowsOfWar */ public class EntityFirebender extends EntityHumanBender { - public static final ResourceLocation LOOT_TABLE = LootTableList + private static final ResourceLocation LOOT_TABLE = LootTableList .register(new ResourceLocation("avatarmod", "firebender")); - private Random rand = new Random(); - private int level = rand.nextInt(1) + 3; + private int scrollsLeft; + private int level = 0; /** * @param world */ public EntityFirebender(World world) { super(world); + getData().addBendingId(Firebending.ID); - getData().getAbilityData("fireball").setLevel(level); - getData().getAbilityData("flamethrower").setLevel(level); } + @Override + protected FormattedMessage getTradeFailMessage() { + return MSG_NEED_FIRE_TRADE_ITEM; + } + + @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); @@ -56,11 +80,14 @@ protected void applyEntityAttributes() { @Override protected void addBendingTasks() { - this.tasks.addTask(1, Abilities.getAi("flamethrower", this, getBender())); - this.tasks.addTask(1, Abilities.getAi("fireball", this, getBender())); - this.tasks.addTask(2, Abilities.getAi("fire_arc", this, getBender())); - //this.tasks.addTask(3, Abilities.getAi("inferno_punch", this, getBender())); - this.tasks.addTask(4, new EntityAIAttackMelee(this, 1.4, true)); + this.tasks.addTask(3, Objects.requireNonNull(Abilities.getAi("flamethrower", this, getBender()))); + this.tasks.addTask(2, Objects.requireNonNull(Abilities.getAi("fireball", this, getBender()))); + this.tasks.addTask(1, Objects.requireNonNull(Abilities.getAi("fire_arc", this, getBender()))); + //this.tasks.addTask(3, Objects.requireNonNull(Abilities.getAi("inferno_punch", this, getBender()))); + if (getData().hasStatusControl(INFERNO_PUNCH)) { + this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.35, true)); + } + this.tasks.addTask(4, new EntityAIAttackMelee(this, 1.3, true)); } @Override @@ -68,6 +95,40 @@ protected ResourceLocation getLootTable() { return LOOT_TABLE; } + @Override + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata) { + getData().addBendingId(Firebending.ID); + if (level == 0 && !world.isRemote) { + Random rand = new Random(); + int level = rand.nextInt(3) + 1; + if (level < 2) { + getData().getAbilityData("fireball").setLevel(-1); + getData().getAbilityData("flamethrower").setLevel(0); + getData().getAbilityData("fire_arc").setLevel(0); + getData().getAbilityData("inferno_punch").setLevel(-1); + this.level = 1; + scrollsLeft = 1; + } + if (level == 2) { + getData().getAbilityData("fireball").setLevel(0); + getData().getAbilityData("flamethrower").setLevel(0); + getData().getAbilityData("fire_arc").setLevel(1); + getData().getAbilityData("inferno_punch").setLevel(-1); + scrollsLeft = 2; + this.level = 2; + } + if (level > 2) { + getData().getAbilityData("fireball").setLevel(1); + getData().getAbilityData("flamethrower").setLevel(1); + getData().getAbilityData("fire_arc").setLevel(2); + getData().getAbilityData("inferno_punch").setLevel(0); + scrollsLeft = 3; + this.level = 3; + } + } + return super.onInitialSpawn(difficulty, livingdata); + } + @Override protected ScrollType getScrollType() { return ScrollType.FIRE; @@ -78,4 +139,19 @@ protected int getNumSkins() { return 1; } + @Override + protected int getScrollsLeft() { + return scrollsLeft; + } + + @Override + public boolean processInteract(EntityPlayer player, EnumHand hand) { + return super.processInteract(player, hand); + } + + @Override + protected boolean isTradeItem(Item item) { + return super.isTradeItem(item) || MOBS_CONFIG.isFireTradeItem(item); + } } + diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityHumanBender.java b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityHumanBender.java index bf8fb95f9f..dd3d18d271 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityHumanBender.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityHumanBender.java @@ -18,8 +18,10 @@ import com.crowsofwar.avatar.common.analytics.AnalyticEvents; import com.crowsofwar.avatar.common.analytics.AvatarAnalytics; +import com.crowsofwar.avatar.common.entity.ai.EntityAiBenderAttackZombie; import com.crowsofwar.avatar.common.entity.ai.EntityAiGiveScroll; import com.crowsofwar.avatar.common.item.ItemScroll.ScrollType; +import com.crowsofwar.gorecore.format.FormattedMessage; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -28,6 +30,7 @@ import net.minecraft.entity.ai.*; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; +import net.minecraft.item.Item; import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -43,7 +46,10 @@ import javax.annotation.Nullable; + import static com.crowsofwar.avatar.common.AvatarChatMessages.MSG_HUMANBENDER_NO_SCROLLS; +import static com.crowsofwar.avatar.common.AvatarChatMessages.MSG_NEED_TRADE_ITEM; +import static com.crowsofwar.avatar.common.config.ConfigMobs.MOBS_CONFIG; /** * @author CrowsOfWar @@ -55,13 +61,22 @@ public abstract class EntityHumanBender extends EntityBender { private EntityAiGiveScroll aiGiveScroll; private int scrollsLeft; + private boolean hasAttemptedTrade; /** * @param world */ public EntityHumanBender(World world) { super(world); - scrollsLeft = rand.nextInt(3) + 1; + scrollsLeft = getScrollsLeft(); + this.hasAttemptedTrade = false; + + + } + + @Override + public boolean getAlwaysRenderNameTagForRender() { + return true; } @Override @@ -83,20 +98,14 @@ protected void applyEntityAttributes() { protected void initEntityAI() { this.tasks.addTask(0, new EntityAISwimming(this)); - // this.targetTasks.addTask(2, - // new EntityAINearestAttackableTarget(this, EntityPlayer.class, true, - // false)); - this.targetTasks.addTask(2, new EntityAIHurtByTarget(this, false, EntityHumanBender.class)); - - addBendingTasks(); - + this.tasks.addTask(4, new EntityAiBenderAttackZombie(this)); + this.targetTasks.addTask(2, new EntityAIHurtByTarget(this, false)); this.tasks.addTask(4, aiGiveScroll = new EntityAiGiveScroll(this, getScrollType())); + addBendingTasks(); this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); this.tasks.addTask(8, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false, new Class[0])); - } @Override @@ -117,12 +126,32 @@ public void writeEntityToNBT(NBTTagCompound nbt) { protected abstract ScrollType getScrollType(); + protected boolean isTradeItem(Item item) { + return MOBS_CONFIG.isTradeItem(item); + } + + protected int getTradeAmount(Item item) { + return MOBS_CONFIG.getTradeItemAmount(item); + } + protected abstract int getNumSkins(); + protected int getLevel() { + return 1; + } + + protected int getScrollsLeft() { + return rand.nextInt(3) + 1; + } + public int getSkin() { return dataManager.get(SYNC_SKIN); } + protected FormattedMessage getTradeFailMessage() { + return MSG_NEED_TRADE_ITEM; + } + public void setSkin(int skin) { dataManager.set(SYNC_SKIN, skin); } @@ -203,18 +232,24 @@ public boolean attackEntityAsMob(Entity entityIn) { @Override public boolean processInteract(EntityPlayer player, EnumHand hand) { + hasAttemptedTrade = false; ItemStack stack = player.getHeldItem(hand); - if (stack.getItem() == Items.DIAMOND && !world.isRemote) { + /*int amount = stack.getCount(); + int tradeAmount = getTradeAmount(stack.getItem());**/ + + if (this.isTradeItem(stack.getItem()) && !world.isRemote/* && amount >= tradeAmount**/) { if (scrollsLeft > 0) { if (aiGiveScroll.giveScrollTo(player)) { - // Take diamond + // Take item scrollsLeft--; if (!player.capabilities.isCreativeMode) { stack.shrink(1); } + } + hasAttemptedTrade = true; } else { MSG_HUMANBENDER_NO_SCROLLS.send(player); AvatarAnalytics.INSTANCE.pushEvent(AnalyticEvents.onNpcNoScrolls()); @@ -223,9 +258,14 @@ public boolean processInteract(EntityPlayer player, EnumHand hand) { return true; } + else if (!(this.isTradeItem(stack.getItem())) && !world.isRemote && !hasAttemptedTrade){ + getTradeFailMessage().send(player); + hasAttemptedTrade = true; + return true; + } - return false; - } + return true; + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityOtterPenguin.java b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityOtterPenguin.java index 819619625b..f87d1af1fb 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityOtterPenguin.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityOtterPenguin.java @@ -35,6 +35,10 @@ import java.util.Set; +import static java.lang.Math.cos; +import static java.lang.Math.sin; +import static java.lang.Math.toRadians; + /** * @author CrowsOfWar */ @@ -56,20 +60,39 @@ protected void initEntityAI() { Set temptItems = Sets.newHashSet(Items.FISH); this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIPanic(this, 3D)); - this.tasks.addTask(3, new EntityAIMate(this, 1.0D)); - this.tasks.addTask(4, new EntityAITempt(this, 1.2D, false, temptItems)); - this.tasks.addTask(5, new EntityAIFollowParent(this, 1.1D)); - this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 3)); + this.tasks.addTask(1, new EntityAIPanic(this, 1.3D)); + this.tasks.addTask(3, new EntityAIMate(this, 1.25D)); + this.tasks.addTask(4, new EntityAITempt(this, 1.0D, false, temptItems)); + this.tasks.addTask(5, new EntityAIFollowParent(this, 1.25D)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); this.tasks.addTask(8, new EntityAILookIdle(this)); } + /** + * Checking speed + setting up this.isSprinting() to use for animation purposes + * @author Mnesikos + */ + @Override + public void updateAITasks() { + if (this.getMoveHelper().isUpdating()) { + double d0 = this.getMoveHelper().getSpeed(); + + if (d0 >= 1.25D) { + this.setSprinting(true); + } else { + this.setSprinting(false); + } + } else { + this.setSprinting(false); + } + } + @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10); - this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.3); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.2D); } @Override @@ -84,17 +107,12 @@ protected ResourceLocation getLootTable() { @Override public boolean processInteract(EntityPlayer player, EnumHand hand) { - if (!super.processInteract(player, hand) && !world.isRemote) { - - if (!isBreedingItem(player.getHeldItemMainhand()) - && !isBreedingItem(player.getHeldItemOffhand())) { - + if (!isBreedingItem(player.getHeldItemMainhand()) && !isBreedingItem(player.getHeldItemOffhand()) + && !player.isSneaking() && !this.isChild()) { player.startRiding(this); return true; - } - } return false; @@ -110,6 +128,19 @@ public Entity getControllingPassenger() { return getPassengers().isEmpty() ? null : getPassengers().get(0); } + /** + * Adjusts the rider's position, math borrowed from EntitySkyBison#updatePassenger + * @author Mnesikos + */ + @Override + public void updatePassenger(Entity passenger) { + if (this.isPassenger(passenger)) { + double offset = -0.5; + double angle = -toRadians(rotationYaw); + passenger.setPosition(this.posX + sin(angle) * offset, this.posY + passenger.getYOffset() + 0.2, this.posZ + cos(angle) * offset); + } + } + @Override public boolean canBeSteered() { return getControllingPassenger() instanceof EntityLivingBase; diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntitySkyBison.java b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntitySkyBison.java index 4a2e5bf3ec..2880317934 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntitySkyBison.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntitySkyBison.java @@ -22,9 +22,11 @@ import com.crowsofwar.avatar.common.analytics.AvatarAnalytics; import com.crowsofwar.avatar.common.bending.Abilities; import com.crowsofwar.avatar.common.bending.StatusControl; +import com.crowsofwar.avatar.common.bending.air.Airbending; import com.crowsofwar.avatar.common.data.AvatarWorldData; import com.crowsofwar.avatar.common.data.Bender; import com.crowsofwar.avatar.common.data.BenderEntityComponent; +import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.ctx.BendingContext; import com.crowsofwar.avatar.common.entity.ai.*; import com.crowsofwar.avatar.common.entity.data.AnimalCondition; @@ -76,9 +78,7 @@ import javax.annotation.Nullable; import java.lang.reflect.Field; -import java.util.List; -import java.util.Set; -import java.util.UUID; +import java.util.*; import static com.crowsofwar.avatar.common.AvatarChatMessages.*; import static com.crowsofwar.avatar.common.config.ConfigMobs.MOBS_CONFIG; @@ -131,7 +131,8 @@ public class EntitySkyBison extends EntityBender implements IEntityOwnable, IInv private final SyncedEntity ownerAttr; private final AnimalCondition condition; private Vector originalPos; - /** + private boolean madeSitByPlayer = false; + /** * Note: Is null clientside. */ private EntityAiBisonEatGrass aiEatGrass; @@ -142,17 +143,22 @@ public class EntitySkyBison extends EntityBender implements IEntityOwnable, IInv private boolean wasTouchingGround; + /** * @param world */ public EntitySkyBison(World world) { super(world); + moveHelper = new SkyBisonMoveHelper(this); ownerAttr = new SyncedEntity<>(this, SYNC_OWNER); condition = new AnimalCondition(this, 30, 20, SYNC_FOOD, SYNC_DOMESTICATION, SYNC_AGE); setSize(2.5f, 2); + this.noClip = false; + + initChest(); } @@ -217,9 +223,10 @@ protected void initEntityAI() { this.targetTasks.addTask(2, new EntityAiBisonDefendOwner(this)); this.targetTasks.addTask(3, new EntityAiBisonHelpOwnerTarget(this)); - this.tasks.addTask(1, Abilities.get("air_bubble").getAi(this, getBender())); - this.tasks.addTask(2, Abilities.get("air_gust").getAi(this, getBender())); - this.tasks.addTask(3, Abilities.get("airblade").getAi(this, getBender())); + this.tasks.addTask(4, Objects.requireNonNull(Abilities.get("air_bubble")).getAi(this, getBender())); + this.tasks.addTask(1, Objects.requireNonNull(Abilities.get("air_gust")).getAi(this, getBender())); + this.tasks.addTask(3, Objects.requireNonNull(Abilities.get("airblade")).getAi(this, getBender())); + this.tasks.addTask(2, new EntityAiBisonFollowAttacker(this)); this.tasks.addTask(3, new EntityAiBisonSit(this)); @@ -233,12 +240,15 @@ protected void initEntityAI() { } - // Note: Not called when using /summon with NBT tags (w/o nbt will call - // this) + // Note: Not called when using /summon with NBT tags (w/o nbt will call this) @Override @Nullable public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingData) { + getData().addBendingId(Airbending.ID); + getData().getAbilityData("air_gust").setLevel(0); + + boolean sterile = false; if (livingData instanceof BisonSpawnData) { @@ -471,14 +481,20 @@ public void updatePassenger(Entity passenger) { if (index > -1) { + float sizeOffset = condition.getAgeDays() < 5 ? condition.getAgeDays()/condition.getAdultAge() : 5; double offset = 0.75; double angle = (index + 0.5) * Math.PI - toRadians(rotationYaw); - double yOffset = passenger.getYOffset() + 1.75; + double yOffset = passenger.getYOffset() + (2.5 * (sizeOffset + 0.35)); - if (passenger == getControllingPassenger()) { + if (passenger == getControllingPassenger() && !this.isSitting()) { + angle = -toRadians(passenger.rotationYaw); + offset = 1; + yOffset = passenger.getYOffset() + (2.5 * (sizeOffset + 0.40)) - Math.sin(toRadians(rotationPitch)); + } + if (passenger == getControllingPassenger() && this.isSitting()) { angle = -toRadians(passenger.rotationYaw); offset = 1; - yOffset = passenger.getYOffset() + 2 - Math.sin(toRadians(rotationPitch)); + yOffset = passenger.getYOffset() + (2.5 * (sizeOffset + 0.35)) - Math.sin(toRadians(rotationPitch)); } passenger.setPosition(posX + sin(angle) * offset, posY + yOffset, posZ + cos(angle) * offset); @@ -564,7 +580,7 @@ public boolean processInteract(EntityPlayer player, EnumHand hand) { if (willBeOwned) { playTameEffect(true); - setOwnerId(AccountUUIDs.getId(player.getName()).getUUID()); + setOwnerId(AccountUUIDs.getId(player.getName())); if (!player.capabilities.isCreativeMode) { stack.shrink(1); } @@ -691,7 +707,11 @@ public boolean processInteract(EntityPlayer player, EnumHand hand) { } if (player.isSneaking() && getOwner() == player) { + if (!isSitting()) { + MSG_BISON_SITTING.send(player); + } setSitting(!isSitting()); + madeSitByPlayer = true; return true; } @@ -837,7 +857,7 @@ public boolean canPlayerViewInventory(EntityPlayer player) { public int getChestSlots() { if (condition.getDomestication() >= MOBS_CONFIG.bisonChestTameness && condition.isAdult()) { - int age = (int) (condition.getAgeDays() - condition.getAdultAge()); + int age = (int) (condition.getAgeDays() - 1); if (age >= 5) { return 27; @@ -886,6 +906,27 @@ public void onDeath(DamageSource cause) { public void onUpdate() { super.onUpdate(); + if (condition.getAgeDays() == 3) { + getData().getAbilityData("air_bubble").setLevel(0); + getData().getAbilityData("air_gust").setLevel(1); + getData().getAbilityData("airblade").setLevel(0); + } + if (condition.getAgeDays() == 4) { + getData().getAbilityData("air_bubble").setLevel(1); + getData().getAbilityData("air_gust").setLevel(1); + getData().getAbilityData("airblade").setLevel(1); + } + if (condition.getAgeDays() == 5) { + getData().getAbilityData("air_bubble").setLevel(2); + getData().getAbilityData("air_gust").setLevel(3); + getData().getAbilityData("airblade").setLevel(1); + } + + if(this.isSitting() && hasOwner() && (world.getBlockState(getEntityPos(this) + .toBlockPos()).getBlock() != Blocks.AIR)) { + this.motionX = this.motionY = this.motionZ = 0; + } + // Client-side chest sometimes doesn't have enough slots, since when the // # of slots changes, it doesn't necessarily re-init chest if (world.isRemote && chest.getSizeInventory() - 2 != getChestSlots()) { @@ -911,12 +952,23 @@ public void onUpdate() { } + // Adjusts bounding box based on entity's scaling size float sizeMult = condition.getSizeMultiplier(); - setSize(2.5f * sizeMult, 2 * sizeMult); + setSize(3.67F * sizeMult, 3.34F * sizeMult); condition.onUpdate(); + + if (!madeSitByPlayer && this.isSitting() && condition.getFoodPoints() > 0) { + this.setSitting(false); + } + if (condition.getFoodPoints() == 0 && getOwner() != null) { + MSG_BISON_SITTING.send(getOwner()); setSitting(true); + madeSitByPlayer = false; + if (ticksExisted % 40 == 0) { + MSG_BISON_NO_FOOD.send(getOwner()); + } } else if (!hasOwner()) { setSitting(false); } @@ -958,6 +1010,8 @@ public void onUpdate() { } + + // moveWithHeading @Override public void travel(float strafe, float jump, float forward) { diff --git a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityWaterbender.java b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityWaterbender.java index a09e662a3b..2008406733 100644 --- a/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityWaterbender.java +++ b/src/main/java/com/crowsofwar/avatar/common/entity/mob/EntityWaterbender.java @@ -21,6 +21,8 @@ import com.crowsofwar.avatar.common.data.BenderEntityComponent; import com.crowsofwar.avatar.common.item.ItemScroll.ScrollType; import net.minecraft.entity.ai.EntityAIAttackMelee; +import net.minecraft.init.Items; +import net.minecraft.item.Item; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraft.world.storage.loot.LootTableList; diff --git a/src/main/java/com/crowsofwar/avatar/common/event/AvatarEventHandler.java b/src/main/java/com/crowsofwar/avatar/common/event/AvatarEventHandler.java index 8258607529..34596fa64c 100644 --- a/src/main/java/com/crowsofwar/avatar/common/event/AvatarEventHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/event/AvatarEventHandler.java @@ -1,15 +1,22 @@ package com.crowsofwar.avatar.common.event; +import com.crowsofwar.avatar.AvatarInfo; +import com.crowsofwar.avatar.common.AvatarDamageSource; +import com.crowsofwar.avatar.common.entity.AvatarEntity; import com.crowsofwar.avatar.common.entity.EntityAvatarLightning; -import net.minecraftforge.event.entity.EntityStruckByLightningEvent; +import net.minecraft.util.DamageSource; +import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -public abstract class AvatarEventHandler implements Mod.EventHandler { - /*@SubscribeEvent - public void LightningEvent(EntityStruckByLightningEvent event) { - if (event.getLightning() instanceof EntityAvatarLightning){ - event.setCanceled(true); +@Mod.EventBusSubscriber(modid = AvatarInfo.MOD_ID) +public abstract class AvatarEventHandler { + @SubscribeEvent + public void onLivingHurtEvent(LivingHurtEvent event) { + if (event.getSource() == DamageSource.LIGHTNING_BOLT || event.getSource() == AvatarDamageSource.LIGHTNING) { + if (event.getEntity() instanceof AvatarEntity) { + ((AvatarEntity) event.getEntity()).onLightningContact(); + } } - }**/ + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/item/AvatarDungeonLoot.java b/src/main/java/com/crowsofwar/avatar/common/item/AvatarDungeonLoot.java index dcc42e4ad2..b8df566e3d 100644 --- a/src/main/java/com/crowsofwar/avatar/common/item/AvatarDungeonLoot.java +++ b/src/main/java/com/crowsofwar/avatar/common/item/AvatarDungeonLoot.java @@ -17,9 +17,12 @@ package com.crowsofwar.avatar.common.item; import com.crowsofwar.avatar.AvatarInfo; +import com.crowsofwar.avatar.common.entity.mob.EntityAirbender; +import net.minecraft.entity.projectile.EntityEgg; import net.minecraft.item.Item; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.datafix.fixes.SpawnEggNames; import net.minecraft.world.storage.loot.*; import net.minecraft.world.storage.loot.conditions.LootCondition; import net.minecraft.world.storage.loot.functions.LootFunction; @@ -59,7 +62,8 @@ public static void onLootLoad(LootTableLoadEvent e) { new LootItem(AvatarItems.itemScroll, 5).withMetadata(1), // new LootItem(AvatarItems.itemScroll, 5).withMetadata(2), // new LootItem(AvatarItems.itemScroll, 5).withMetadata(3), // - new LootItem(AvatarItems.itemScroll, 5).withMetadata(4)); + new LootItem(AvatarItems.itemScroll, 5).withMetadata(4), + new LootItem(AvatarItems.itemScroll, 10).withMetadata(5)); addLoot(e, 65, // new LootItem(AvatarItems.itemOstrichEquipment, 10).withMetadata(0), new LootItem(AvatarItems.itemOstrichEquipment, 10).withMetadata(1), diff --git a/src/main/java/com/crowsofwar/avatar/common/item/AvatarItems.java b/src/main/java/com/crowsofwar/avatar/common/item/AvatarItems.java index b8fe29af7f..572a89b0c2 100644 --- a/src/main/java/com/crowsofwar/avatar/common/item/AvatarItems.java +++ b/src/main/java/com/crowsofwar/avatar/common/item/AvatarItems.java @@ -41,6 +41,7 @@ public static ItemBisonArmor itemBisonArmor; public static ItemOstrichEquipment itemOstrichEquipment; private static ItemStack stackScroll; + public static ItemAirbenderStaff airbenderStaff; public static CreativeTabs tabItems = new CreativeTabs("avatar.items") { @Override public ItemStack getTabIconItem() { @@ -59,6 +60,7 @@ public static void init() { addItem(itemBisonArmor = new ItemBisonArmor()); addItem(itemBisonSaddle = new ItemBisonSaddle()); addItem(itemOstrichEquipment = new ItemOstrichEquipment()); + addItem(airbenderStaff = new ItemAirbenderStaff(Item.ToolMaterial.WOOD)); stackScroll = new ItemStack(itemScroll); MinecraftForge.EVENT_BUS.register(new AvatarItems()); diff --git a/src/main/java/com/crowsofwar/avatar/common/item/ItemAirbenderStaff.java b/src/main/java/com/crowsofwar/avatar/common/item/ItemAirbenderStaff.java new file mode 100644 index 0000000000..378309ccab --- /dev/null +++ b/src/main/java/com/crowsofwar/avatar/common/item/ItemAirbenderStaff.java @@ -0,0 +1,249 @@ +package com.crowsofwar.avatar.common.item; + +import com.crowsofwar.avatar.common.bending.air.AbilityAirGust; +import com.crowsofwar.avatar.common.bending.air.AbilityAirblade; +import com.crowsofwar.avatar.common.bending.air.Airbending; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.data.Chi; +import com.crowsofwar.avatar.common.entity.EntityAirGust; +import com.crowsofwar.avatar.common.entity.EntityAirblade; +import com.crowsofwar.gorecore.util.Vector; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.MobEffects; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemSword; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import java.util.Random; + +import static com.crowsofwar.avatar.common.AvatarChatMessages.MSG_AIR_STAFF_COOLDOWN; +import static com.crowsofwar.avatar.common.data.TickHandlerController.STAFF_GUST_HANDLER; + +public class ItemAirbenderStaff extends ItemSword implements AvatarItem { + + private boolean spawnGust; + + public ItemAirbenderStaff(Item.ToolMaterial material) { + super(material); + setUnlocalizedName("airbender_staff"); + setCreativeTab(AvatarItems.tabItems); + setMaxStackSize(1); + setMaxDamage(200); + + //Max damage is the durability of the item, or the max damage the item can take + + } + + + @Override + public float getAttackDamage() { + return 1F; + } + + @Override + public boolean hasEffect(ItemStack stack) { + return true; + } + + + @Override + public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) { + boolean isCreative = attacker instanceof EntityPlayer && ((EntityPlayer) attacker).isCreative(); + if (!isCreative) { + stack.damageItem(1, attacker); + } + Vector velocity = Vector.getLookRectangular(attacker).times(1.1); + target.motionX += velocity.x(); + target.motionY += velocity.y() > 0 ? velocity.y() + 0.2 : 0.3; + target.motionZ += velocity.z(); + return true; + + } + + + @Override + public EnumRarity getRarity(ItemStack stack) { + return EnumRarity.RARE; + } + + @Override + public Item item() { + return this; + } + + @Override + public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) { + if (handIn == EnumHand.OFF_HAND) { + boolean isCreative = playerIn.isCreative(); + BendingData data = BendingData.get(playerIn); + if (!data.hasTickHandler(STAFF_GUST_HANDLER) && !playerIn.world.isRemote) { + if (spawnGust) { + EntityAirGust gust = new EntityAirGust(playerIn.world); + gust.setPosition(Vector.getLookRectangular(playerIn).plus(Vector.getEntityPos(playerIn)).withY(playerIn.getEyeHeight() + + playerIn.getEntityBoundingBox().minY)); + gust.setAbility(new AbilityAirGust()); + gust.setOwner(playerIn); + gust.setVelocity(Vector.getLookRectangular(playerIn).times(30)); + playerIn.world.spawnEntity(gust); + if (!isCreative) { + data.addTickHandler(STAFF_GUST_HANDLER); + ItemStack stack = playerIn.getHeldItemOffhand(); + stack.damageItem(2, playerIn); + } + return new ActionResult(EnumActionResult.PASS, playerIn.getHeldItem(handIn)); + } else { + EntityAirblade blade = new EntityAirblade(playerIn.world); + blade.setPosition(Vector.getLookRectangular(playerIn).plus(Vector.getEntityPos(playerIn)).withY(playerIn.getEyeHeight() + playerIn.getEntityBoundingBox().minY)); + blade.setAbility(new AbilityAirblade()); + blade.setOwner(playerIn); + blade.setVelocity(Vector.getLookRectangular(playerIn).times(30)); + blade.setDamage(2); + playerIn.world.spawnEntity(blade); + if (!isCreative) { + data.addTickHandler(STAFF_GUST_HANDLER); + ItemStack stack = playerIn.getHeldItemOffhand(); + stack.damageItem(2, playerIn); + } + return new ActionResult(EnumActionResult.SUCCESS, playerIn.getHeldItem(handIn)); + } + } + if (data.hasTickHandler(STAFF_GUST_HANDLER) && !worldIn.isRemote) { + MSG_AIR_STAFF_COOLDOWN.send(playerIn); + } + return new ActionResult(EnumActionResult.SUCCESS, playerIn.getHeldItem(handIn)); + } + return new ActionResult(EnumActionResult.FAIL, playerIn.getHeldItem(handIn)); + } + + @Override + public boolean onEntitySwing(EntityLivingBase entityLiving, ItemStack stack) { + boolean isCreative = entityLiving instanceof EntityPlayer && ((EntityPlayer) entityLiving).isCreative(); + BendingData data = BendingData.get(entityLiving); + if (!data.hasTickHandler(STAFF_GUST_HANDLER) && !entityLiving.world.isRemote) { + if (spawnGust) { + EntityAirGust gust = new EntityAirGust(entityLiving.world); + gust.setPosition(Vector.getLookRectangular(entityLiving).plus(Vector.getEntityPos(entityLiving)).withY(entityLiving.getEyeHeight() + entityLiving.getEntityBoundingBox().minY)); + gust.setAbility(new AbilityAirGust()); + gust.setOwner(entityLiving); + gust.setVelocity(Vector.getLookRectangular(entityLiving).times(30)); + entityLiving.world.spawnEntity(gust); + if (!isCreative) { + data.addTickHandler(STAFF_GUST_HANDLER); + stack.damageItem(2, entityLiving); + } + return true; + } else { + EntityAirblade blade = new EntityAirblade(entityLiving.world); + blade.setPosition(Vector.getLookRectangular(entityLiving).plus(Vector.getEntityPos(entityLiving)).withY(entityLiving.getEyeHeight() + entityLiving.getEntityBoundingBox().minY)); + blade.setAbility(new AbilityAirblade()); + blade.setOwner(entityLiving); + blade.setVelocity(Vector.getLookRectangular(entityLiving).times(30)); + blade.setDamage(2); + entityLiving.world.spawnEntity(blade); + if (!isCreative) { + data.addTickHandler(STAFF_GUST_HANDLER); + stack.damageItem(2, entityLiving); + } + return true; + } + + } + if (data.hasTickHandler(STAFF_GUST_HANDLER) && entityLiving instanceof EntityPlayer && !entityLiving.world.isRemote) { + MSG_AIR_STAFF_COOLDOWN.send(entityLiving); + } + return false; + } + + @Override + public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int itemSlot, boolean isSelected) { + + if (isSelected && entityIn instanceof EntityLivingBase) { + spawnGust = !entityIn.isSneaking(); + if (!worldIn.isRemote && worldIn instanceof WorldServer) { + WorldServer world = (WorldServer) worldIn; + if (entityIn.ticksExisted % 40 == 0) { + world.spawnParticle(EnumParticleTypes.CLOUD, entityIn.posX, entityIn.posY + entityIn.getEyeHeight(), + entityIn.posZ, 1, 0, 0, 0, 0.04); + ((EntityLivingBase) entityIn).addPotionEffect(new PotionEffect(MobEffects.SPEED, 40)); + ((EntityLivingBase) entityIn).addPotionEffect(new PotionEffect(MobEffects.JUMP_BOOST, 40)); + if ((new Random().nextInt(2) + 1) >= 2) { + ((EntityLivingBase) entityIn).addPotionEffect(new PotionEffect(MobEffects.INVISIBILITY, 20)); + } + } + } + } + if (entityIn instanceof EntityLivingBase) { + if (((EntityLivingBase) entityIn).getHeldItemOffhand().getItem() == this) { + if (!worldIn.isRemote && worldIn instanceof WorldServer) { + WorldServer world = (WorldServer) worldIn; + if (entityIn.ticksExisted % 40 == 0) { + world.spawnParticle(EnumParticleTypes.CLOUD, entityIn.posX, entityIn.posY + entityIn.getEyeHeight(), + entityIn.posZ, 1, 0, 0, 0, 0.04); + ((EntityLivingBase) entityIn).addPotionEffect(new PotionEffect(MobEffects.SPEED, 40)); + ((EntityLivingBase) entityIn).addPotionEffect(new PotionEffect(MobEffects.JUMP_BOOST, 40)); + if ((new Random().nextInt(2) + 1) >= 2) { + ((EntityLivingBase) entityIn).addPotionEffect(new PotionEffect(MobEffects.INVISIBILITY, 20)); + } + } + } + } + } + if (entityIn instanceof EntityLivingBase) { + //Heals the item's durability if you have airbending + BendingData data = BendingData.get((EntityLivingBase) entityIn); + Chi chi = data.chi(); + if (entityIn.ticksExisted % 80 == 0 && chi != null && data.hasBendingId(Airbending.ID) && ((new Random().nextInt(2) + 1) >= 2)) { + if (stack.isItemDamaged()) { + float availableChi = chi.getAvailableChi(); + if (availableChi > 1) { + if (!(entityIn instanceof EntityPlayer && (((EntityPlayer) entityIn).isCreative()))) { + chi.setTotalChi(chi.getTotalChi() - 2); + } + stack.damageItem(-1, (EntityLivingBase) entityIn); + } + } + } + } + } + + + @Override + public Multimap getItemAttributeModifiers(EntityEquipmentSlot equipmentSlot) { + Multimap multimap = HashMultimap.create(); + + if (equipmentSlot == EntityEquipmentSlot.MAINHAND) { + spawnGust = new Random().nextBoolean(); + multimap.put(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(ATTACK_DAMAGE_MODIFIER, "Weapon modifier", getAttackDamage(), 0)); + multimap.put(SharedMonsterAttributes.ATTACK_SPEED.getName(), new AttributeModifier(ATTACK_SPEED_MODIFIER, "Weapon modifier", 0, 0)); + } + + return multimap; + } + + @Override + public boolean isDamageable() { + return true; + } + + @Override + public String getModelName(int meta) { + return "airbender_staff"; + } + + //Add power rating modifier +} diff --git a/src/main/java/com/crowsofwar/avatar/common/item/ItemBisonWhistle.java b/src/main/java/com/crowsofwar/avatar/common/item/ItemBisonWhistle.java index 137b37e80b..8607127f36 100644 --- a/src/main/java/com/crowsofwar/avatar/common/item/ItemBisonWhistle.java +++ b/src/main/java/com/crowsofwar/avatar/common/item/ItemBisonWhistle.java @@ -16,30 +16,27 @@ */ package com.crowsofwar.avatar.common.item; -import com.crowsofwar.avatar.common.TransferConfirmHandler; -import com.crowsofwar.avatar.common.data.BendingData; -import com.crowsofwar.avatar.common.data.TickHandler; -import com.crowsofwar.avatar.common.entity.mob.EntitySkyBison; -import com.crowsofwar.gorecore.util.AccountUUIDs; import net.minecraft.client.resources.I18n; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; +import net.minecraft.item.*; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumHand; +import net.minecraft.util.*; import net.minecraft.world.World; +import com.crowsofwar.avatar.common.TransferConfirmHandler; +import com.crowsofwar.avatar.common.data.BendingData; +import com.crowsofwar.avatar.common.entity.mob.EntitySkyBison; +import com.crowsofwar.gorecore.util.AccountUUIDs; + import javax.annotation.Nullable; -import java.util.List; -import java.util.UUID; +import java.util.*; import static com.crowsofwar.avatar.common.AvatarChatMessages.*; +import static com.crowsofwar.avatar.common.data.TickHandlerController.BISON_SUMMONER; import static com.crowsofwar.gorecore.util.GoreCoreNBTUtil.stackCompound; -import static net.minecraft.util.EnumActionResult.PASS; -import static net.minecraft.util.EnumActionResult.SUCCESS; +import static net.minecraft.util.EnumActionResult.*; /** * ItemBow @@ -143,7 +140,7 @@ public void onPlayerStoppedUsing(ItemStack stack, World world, EntityLivingBase BendingData data = BendingData.get(entity); data.getMiscData().setPetSummonCooldown((int) (seconds * 20)); - data.addTickHandler(TickHandler.BISON_SUMMONER); + data.addTickHandler(BISON_SUMMONER); MSG_BISON_WHISTLE_SUMMON.send(entity, (int) seconds); } else { diff --git a/src/main/java/com/crowsofwar/avatar/common/network/DataTransmitters.java b/src/main/java/com/crowsofwar/avatar/common/network/DataTransmitters.java index b8c693f288..6fb1616e8b 100644 --- a/src/main/java/com/crowsofwar/avatar/common/network/DataTransmitters.java +++ b/src/main/java/com/crowsofwar/avatar/common/network/DataTransmitters.java @@ -23,6 +23,7 @@ import com.crowsofwar.avatar.common.bending.StatusControl; import com.crowsofwar.avatar.common.data.*; import io.netty.buffer.ByteBuf; +import net.minecraftforge.fml.common.FMLLog; import java.util.*; @@ -147,18 +148,25 @@ public Chi read(ByteBuf buf, BendingData data) { public void write(ByteBuf buf, List list) { buf.writeInt(list.size()); for (TickHandler handler : list) { - buf.writeInt(handler.id()); + if (handler != null) { + buf.writeInt(handler.id()); + } } } @Override public List read(ByteBuf buf, BendingData data) { - List list = new ArrayList<>(); - int length = buf.readInt(); - for (int i = 0; i < length; i++) { - list.add(TickHandler.fromBytes(buf)); + int size = buf.readInt(); + List out = new ArrayList<>(); + for (int i = 0; i < size; i++) { + if (!buf.isReadable(4)) break; + TickHandler list = TickHandlerController.fromId(buf.readInt()); + if (list == null) + AvatarLog.warn(WarningType.WEIRD_PACKET, "Invalid tick handler id"); + else + out.add(list); } - return list; + return out; } }; diff --git a/src/main/java/com/crowsofwar/avatar/common/network/packets/PacketSRequestData.java b/src/main/java/com/crowsofwar/avatar/common/network/packets/PacketSRequestData.java index b456c1590c..ff76257088 100644 --- a/src/main/java/com/crowsofwar/avatar/common/network/packets/PacketSRequestData.java +++ b/src/main/java/com/crowsofwar/avatar/common/network/packets/PacketSRequestData.java @@ -19,7 +19,6 @@ import com.crowsofwar.avatar.common.network.PacketRedirector; import com.crowsofwar.gorecore.util.AccountUUIDs; -import com.crowsofwar.gorecore.util.AccountUUIDs.AccountId; import com.crowsofwar.gorecore.util.GoreCoreByteBufUtil; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; @@ -42,8 +41,7 @@ public PacketSRequestData(UUID asking) { } public PacketSRequestData(EntityPlayer player) { - AccountId result = AccountUUIDs.getId(player.getName()); - this.asking = result.getUUID(); + this.asking = AccountUUIDs.getId(player.getName()); } @Override diff --git a/src/main/java/com/crowsofwar/avatar/common/powerrating/PrModifierHandler.java b/src/main/java/com/crowsofwar/avatar/common/powerrating/PrModifierHandler.java index 491806ca90..162d731aeb 100644 --- a/src/main/java/com/crowsofwar/avatar/common/powerrating/PrModifierHandler.java +++ b/src/main/java/com/crowsofwar/avatar/common/powerrating/PrModifierHandler.java @@ -1,5 +1,7 @@ package com.crowsofwar.avatar.common.powerrating; +import com.crowsofwar.avatar.common.bending.air.Airbending; +import com.crowsofwar.avatar.common.bending.air.StaffPowerModifier; import com.crowsofwar.avatar.common.bending.earth.Earthbending; import com.crowsofwar.avatar.common.bending.earth.EarthbendingJingModifier; import com.crowsofwar.avatar.common.bending.fire.Firebending; @@ -8,7 +10,10 @@ import com.crowsofwar.avatar.common.data.BendingData; import com.crowsofwar.avatar.common.data.PowerRatingManager; import com.crowsofwar.avatar.common.data.ctx.BendingContext; +import com.crowsofwar.avatar.common.item.ItemAirbenderStaff; import com.crowsofwar.avatar.common.util.Raytrace; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import java.util.UUID; @@ -46,6 +51,20 @@ public static void addPowerRatingModifiers(Bender bender) { manager.addModifier(new EarthbendingJingModifier(), ctx); } } + if (bendingId.equals(Airbending.ID)) { + if (bender.getEntity().getHeldItemMainhand() != ItemStack.EMPTY) { + Item item = bender.getEntity().getHeldItemMainhand().getItem(); + if (item instanceof ItemAirbenderStaff) { + manager.addModifier(new StaffPowerModifier(), ctx); + } + } + if (bender.getEntity().getHeldItemOffhand() != ItemStack.EMPTY) { + Item item = bender.getEntity().getHeldItemOffhand().getItem(); + if (item instanceof ItemAirbenderStaff) { + manager.addModifier(new StaffPowerModifier(), ctx); + } + } + } } diff --git a/src/main/java/com/crowsofwar/avatar/common/util/AvatarUtils.java b/src/main/java/com/crowsofwar/avatar/common/util/AvatarUtils.java index 30b0ab454c..ad9b6ef3e8 100644 --- a/src/main/java/com/crowsofwar/avatar/common/util/AvatarUtils.java +++ b/src/main/java/com/crowsofwar/avatar/common/util/AvatarUtils.java @@ -18,7 +18,9 @@ package com.crowsofwar.avatar.common.util; import com.crowsofwar.avatar.AvatarLog; +import com.crowsofwar.gorecore.util.Vector; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; @@ -65,6 +67,66 @@ public static void afterVelocityAdded(Entity entity) { } } + /** + * Returns the location of the player's right side + * @param entity + * @param distance + * @return + */ + + public static Vector getRightSide(EntityLivingBase entity, double distance) { + final float angle = entity.rotationYaw / 60; + return Vector.getEntityPos(entity).minus(new Vector(Math.cos(angle), -entity.getEyeHeight(), Math.sin(angle)).normalize().times(distance)); + } + + /** + * Returns the location of the player's left side + * @param entity + * @param distance + * @return + */ + + public static Vector getLeftSide(EntityLivingBase entity, double distance) { + final float angle = entity.rotationYaw / 60; + return Vector.getEntityPos(entity).plus(new Vector(Math.cos(angle), -entity.getEyeHeight(), Math.sin(angle)).normalize().times(distance)); + } + + /** + * + * @param axis + * @param degrees + * @param length + * @return + */ + + public static Vector getOrthogonalVector(final Vector axis, final double degrees, final double length) { + Vector ortho = new Vector(axis.y(), -axis.x(), 0); + ortho = ortho.normalize(); + ortho = ortho.times(length); + + return rotateVectorAroundVector(axis, ortho, degrees); + } + + /** + * + * @param axis + * @param rotator + * @param degrees + * @return + */ + + public static Vector rotateVectorAroundVector(final Vector axis, final Vector rotator, final double degrees) { + final double angle = Math.toRadians(degrees); + Vector rotation = axis; + final Vector rotate = rotator; + rotation = rotation.normalize(); + + final Vector thirdaxis = rotation.cross(rotate).normalize().times(rotate.magnitude()); + + return rotate.times(Math.cos(angle)).plus(thirdaxis.times(Math.sin(angle))); + } + + /** * Ensures that the angle is in the range of 0-360. */ diff --git a/src/main/java/com/crowsofwar/gorecore/GoreCore.java b/src/main/java/com/crowsofwar/gorecore/GoreCore.java index 0fe25fcab7..31e21e47f4 100644 --- a/src/main/java/com/crowsofwar/gorecore/GoreCore.java +++ b/src/main/java/com/crowsofwar/gorecore/GoreCore.java @@ -36,6 +36,8 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; +import java.io.File; + @Mod(modid = GoreCore.MOD_ID, name = GoreCore.MOD_NAME, version = GoreCore.MOD_VERSION) public class GoreCore { @@ -57,15 +59,16 @@ public void preInit(FMLPreInitializationEvent event) { config = new GoreCoreModConfig(event); ConverterRegistry.addDefaultConverters(); - AccountUUIDs.readCache(); + File oldFile = GoreCore.proxy.getUUIDCacheFile(); + if (oldFile.exists()) { + // We don't need a cache anymore + oldFile.delete(); + } GoreCoreChatMessages.register(); proxy.sideSpecifics(); ChatSender.load(); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> AccountUUIDs.saveCache())); - } @EventHandler diff --git a/src/main/java/com/crowsofwar/gorecore/data/PlayerData.java b/src/main/java/com/crowsofwar/gorecore/data/PlayerData.java index bdc0f14676..5ed9d09d34 100644 --- a/src/main/java/com/crowsofwar/gorecore/data/PlayerData.java +++ b/src/main/java/com/crowsofwar/gorecore/data/PlayerData.java @@ -91,6 +91,11 @@ public PlayerData(DataSaver dataSaver, UUID playerID, EntityPlayer playerEntity) construct(dataSaver, playerID, playerEntity); } + @Override + public String toString() { + return "PlayerData(playerId = " + playerID + ", dataSaver = " + dataSaver + ")"; + } + /** * Called from constructor to initialize data. Override to change * constructor. diff --git a/src/main/java/com/crowsofwar/gorecore/data/PlayerDataFetcher.java b/src/main/java/com/crowsofwar/gorecore/data/PlayerDataFetcher.java index 69b035b9ae..6591537c4e 100644 --- a/src/main/java/com/crowsofwar/gorecore/data/PlayerDataFetcher.java +++ b/src/main/java/com/crowsofwar/gorecore/data/PlayerDataFetcher.java @@ -62,7 +62,7 @@ default T fetch(World world, String playerName) { if (world == null) throw new IllegalArgumentException("Cannot get player-data with null World"); if (playerName == null) throw new IllegalArgumentException("Cannot get player-data with null player name"); - return fetch(world, AccountUUIDs.getId(playerName).getUUID()); + return fetch(world, AccountUUIDs.getId(playerName)); } /** diff --git a/src/main/java/com/crowsofwar/gorecore/data/WorldData.java b/src/main/java/com/crowsofwar/gorecore/data/WorldData.java index f500930057..ac6c59adfb 100644 --- a/src/main/java/com/crowsofwar/gorecore/data/WorldData.java +++ b/src/main/java/com/crowsofwar/gorecore/data/WorldData.java @@ -22,6 +22,8 @@ import net.minecraft.world.storage.MapStorage; import net.minecraftforge.fml.common.FMLLog; +import java.util.Objects; + /** * A base class for WorldSavedData. * @@ -88,7 +90,7 @@ protected static T getDataForWorld(Class worldDataClass boolean separatePerDimension) { try { MapStorage ms = separatePerDimension ? world.getPerWorldStorage() : world.getMapStorage(); - T data = worldDataClass.cast(ms.getOrLoadData(worldDataClass, key)); + T data = worldDataClass.cast(Objects.requireNonNull(ms).getOrLoadData(worldDataClass, key)); if (data == null) { // TODO [1.10] Not sure if this is actually called anymore- need diff --git a/src/main/java/com/crowsofwar/gorecore/data/WorldDataPlayers.java b/src/main/java/com/crowsofwar/gorecore/data/WorldDataPlayers.java index 552b8d4eef..19959bc2e1 100644 --- a/src/main/java/com/crowsofwar/gorecore/data/WorldDataPlayers.java +++ b/src/main/java/com/crowsofwar/gorecore/data/WorldDataPlayers.java @@ -17,13 +17,10 @@ package com.crowsofwar.gorecore.data; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; import com.crowsofwar.gorecore.GoreCore; -import com.crowsofwar.gorecore.util.AccountUUIDs; -import com.crowsofwar.gorecore.util.GoreCoreNBTUtil; +import com.crowsofwar.gorecore.util.*; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; @@ -67,19 +64,18 @@ public NBTTagCompound writeToNBT(NBTTagCompound nbt) { * @return Player data for that player */ public T getPlayerData(UUID player) { - if (players.containsKey(player)) { - T data = getPlayerDataWithoutCreate(player); - if (getWorld() != null) - data.setPlayerEntity(AccountUUIDs.findEntityFromUUID(getWorld(), player)); - return data; - } else { - T data = createNewPlayerData(player); + Objects.requireNonNull(player, "Tried to create data for null player"); + Objects.requireNonNull(getWorld(), "Tried to create data for null world"); + T data = getPlayerDataWithoutCreate(player); + if (data == null) { + data = createNewPlayerData(player); players.put(player, data); - if (getWorld() != null) - data.setPlayerEntity(AccountUUIDs.findEntityFromUUID(getWorld(), player)); + data.setPlayerEntity(AccountUUIDs.findEntityFromUUID(getWorld(), player)); saveChanges(); - return data; } + Objects.requireNonNull(data, String.format("Couldn't create data for player \"%s\" and world \"%s\"!", player, getWorld().provider.getDimensionType().getName())); + return data; + } /** @@ -98,7 +94,7 @@ public T getPlayerDataWithoutCreate(UUID player) { return data; } - public abstract Class playerDataClass(); + public abstract Class playerDataClass(); private T createNewPlayerData(UUID player) { try { diff --git a/src/main/java/com/crowsofwar/gorecore/tree/test/GoreCoreCommand.java b/src/main/java/com/crowsofwar/gorecore/tree/test/GoreCoreCommand.java index 7b8aa962d4..d80244ada2 100644 --- a/src/main/java/com/crowsofwar/gorecore/tree/test/GoreCoreCommand.java +++ b/src/main/java/com/crowsofwar/gorecore/tree/test/GoreCoreCommand.java @@ -36,32 +36,7 @@ public String getName() { @Override protected ICommandNode[] addCommands() { - - NodeFunctional reloadId = new NodeBuilder("fixid")// - .addArgument(new ArgumentPlayerName("player"))// - .addArgumentDirect("confirm", ITypeConverter.CONVERTER_STRING, "")// - .build(popper -> { - - String username = popper.get(); - String confirm = popper.get(); - - if (!confirm.equals("destroy-data")) { - MSG_FIXID_CONFIRM.send(popper.from(), username); - MSG_FIXID_CONFIRM2.send(popper.from(), username); - return; - } - - FormattedMessage msg; - if (AccountUUIDs.getId(username).isTemporary()) { - msg = AccountUUIDs.tryFixId(username) ? MSG_FIXID_SUCCESS : MSG_FIXID_FAILURE; - } else { - msg = MSG_FIXID_ONLINE; - } - msg.send(popper.from(), username); - - }); - - return new ICommandNode[] { reloadId }; + return new ICommandNode[] {}; } } diff --git a/src/main/java/com/crowsofwar/gorecore/util/AccountUUIDs.java b/src/main/java/com/crowsofwar/gorecore/util/AccountUUIDs.java index 31a6880169..b9fc8566ea 100644 --- a/src/main/java/com/crowsofwar/gorecore/util/AccountUUIDs.java +++ b/src/main/java/com/crowsofwar/gorecore/util/AccountUUIDs.java @@ -17,27 +17,21 @@ package com.crowsofwar.gorecore.util; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; +import com.crowsofwar.gorecore.GoreCore; +import com.google.common.collect.Maps; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; +import net.minecraftforge.common.UsernameCache; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; -import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import java.util.Random; +import java.util.Objects; import java.util.UUID; - -import com.crowsofwar.gorecore.GoreCore; -import com.crowsofwar.gorecore.settings.GoreCoreModConfig; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.world.World; -import net.minecraftforge.fml.common.FMLLog; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** *

@@ -46,135 +40,20 @@ * Entity#getUniqueID(). *

* - *

- * UUID results are stored in a cache file, and are loaded from the cache as - * well. - *

- * * @author CrowsOfWar + * @author Mahtaran */ public final class AccountUUIDs { - - /** - * The cache of usernames -> account IDs, which is also saved to a cache - * file. Never exceeds {@link GoreCoreModConfig#MAX_UUID_CACHE_SIZE maximum - * cache size}. - */ - private static final Map idCache; - - static { - idCache = new HashMap<>(); - } - /** - * Clears the UUID cache, then reads the UUID cache from the cache file - * located in different places for client/server. This is so that the big - * cache list does not have to be re-created every time Minecraft restarts. - * - * @see #saveCache() + * Don't try to understand this. + * Ok, so actually it works like this: select first 8 characters, then 4, 4, 4 and finally 12. This is the UUID format. */ - public static void readCache() { - BufferedReader br = null; - try { - - long start = System.currentTimeMillis(); - GoreCore.LOGGER.info("Reading UUIDs from cache file"); - - idCache.clear(); - - File file = GoreCore.proxy.getUUIDCacheFile(); - if (!file.exists()) { - file.createNewFile(); - } - - br = new BufferedReader(new FileReader(file)); - - String line = null; - while ((line = br.readLine()) != null) { - if (line.startsWith("#")) continue; - if (!line.contains("=")) continue; - - String[] split = line.split("="); - if (split.length != 2) continue; - - boolean temp = false; - if (line.startsWith("%")) { - temp = true; - line = line.substring(1); - GoreCore.LOGGER.warn("UUID cache for player " + split[0] - + " is temporary, connect to online to fix this"); - } - - try { - idCache.put(split[0], new AccountId(UUID.fromString(split[1]), temp)); - } catch (IllegalArgumentException e) { - GoreCore.LOGGER.warn("UUID cache contains invalidly formatted UUID for player " + split[0] - + ", skipping"); - } - - } - - GoreCore.LOGGER.info("Finished reading " + idCache.entrySet().size() + " player UUID(s)"); - - } catch (Exception e) { - FMLLog.severe("Error reading GoreCore player UUID cache from text file:"); - e.printStackTrace(); - FMLLog.severe("Please contact CrowsOfWar for help."); - } finally { - if (br != null) try { - br.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } + private static final Pattern DASHLESS_PATTERN = Pattern.compile("^([A-Fa-f0-9]{8})([A-Fa-f0-9]{4})([A-Fa-f0-9]{4})([A-Fa-f0-9]{4})([A-Fa-f0-9]{12})$"); /** - * Saves the cache of UUIDs to a text file for reading later so that the - * UUID cache does not have to be re-built every time Minecraft restarts. - * - * @see #readCache() + * A cache of usernames not in Forge's UsernameCache */ - public static void saveCache() { - try { - - long start = System.currentTimeMillis(); - GoreCore.LOGGER.info("Saving UUIDs to cache file"); - - File file = GoreCore.proxy.getUUIDCacheFile(); - if (!file.exists()) file.createNewFile(); - - BufferedWriter bw = new BufferedWriter(new FileWriter(file)); - - Iterator> entries = idCache.entrySet().iterator(); - boolean next = entries.hasNext(); - - String ln = System.getProperty("line.separator"); - bw.write("# This holds a cache of all the players' UUIDs determined by GoreCore" + ln); - bw.write("# Please do not edit this file, or you may face strange problems like data deletion" - + ln); - bw.write("# This is re-written when Minecraft closes, so any of your comments will not be saved!" - + (next ? ln + ln : "")); - - while (next) { - Map.Entry current = entries.next(); - next = entries.hasNext(); - String username = current.getKey(); - AccountId account = current.getValue(); - bw.write((account.temporary ? "%" : "") + username + "=" + account.uuid + ln); - } - - bw.close(); - - GoreCore.LOGGER.info("GoreCore: Finished saving UUIDs. Time taken in seconds: %f.", - (System.currentTimeMillis() - start) / 1000.0); - - } catch (Exception e) { - GoreCore.LOGGER.error("Error saving GoreCore player UUID cache to text file", e); - GoreCore.LOGGER.error("Please contact CrowsOfWar to fix it."); - } - } - + private static final Map localCache = Maps.newHashMap(); /** *

* Finds the player in the world whose account has the given UUID. @@ -184,21 +63,21 @@ public static void saveCache() { * This is different from world.func_152378_a(playerID) in that * the world's method uses the player's entity ID, while this method uses * the player's account ID. + *

* * @param playerID * The UUID of the player to find * @param world * The world to look for the player in - * @return + * @return The player with that UUID */ public static EntityPlayer findEntityFromUUID(World world, UUID playerID) { for (int i = 0; i < world.playerEntities.size(); i++) { - UUID accountId = getId(world.playerEntities.get(i).getName()).getUUID(); - if (accountId.equals(playerID)) { + UUID accountId = getId(world.playerEntities.get(i).getName()); + if (accountId != null && accountId.equals(playerID)) { return world.playerEntities.get(i); } } - return null; } @@ -209,64 +88,22 @@ public static EntityPlayer findEntityFromUUID(World world, UUID playerID) { * will be made to obtain the UUID. *

* - *

- * The UUID found can be extracted from the UUID-result via - * {@link AccountId#getUUID()} as long as an error has not occurred. - *

- * * @param username * The username to get the UUID for * @return The UUID result of the getting */ - public static AccountUUIDs.AccountId getId(String username) { - if (idCache.containsKey(username)) { - return idCache.get(username); - } else { - UUID found = requestId(username); - return cacheResults(username, found == null ? new AccountId(username) : new AccountId(found)); + public static UUID getId(String username) { + Map cache = UsernameCache.getMap(); + if (!cache.containsValue(username)) { + if (localCache.containsKey(username)) return localCache.get(username); + return requestId(username); } - } - - /** - * Gets the AccountId of that player. If it is temporary, tries to send a - * request to Mojang's API and fix the UUID. - * - * @param username - * the name of that player - * @return true if the id was temporary AND it was successfully changed - */ - public static boolean tryFixId(String username) { - AccountId id = getId(username); - if (id.isTemporary()) { - UUID found = requestId(username); - if (found == null) { - return false; - } else { - // TODO Fix clients' saved UUIDs - cacheResults(username, new AccountId(found)); - return true; + for (Map.Entry entry : UsernameCache.getMap().entrySet()) { + if (entry.getValue().equalsIgnoreCase(username)) { + return entry.getKey(); } - } else { - return false; - } - } - - /** - * Caches the results for the given username, replacing any current data. - * However, the cache will not be added on to if the cache is too large (if - * the size of the cache exceeds the maximum UUID cache size). - * - * @param username - * The username to store in the cache (key) - * @param id - * The account ID to store in the cache (value) - * @return id parameter - */ - private static AccountId cacheResults(String username, AccountId id) { - if (idCache.size() < GoreCore.config.MAX_UUID_CACHE_SIZE) { - idCache.put(username, id); - } - return id; + } + return null; } /** @@ -284,20 +121,6 @@ private static UUID requestId(String username) { connection.setRequestProperty("User-Agent", "Mozilla/5.0"); int responseCode = connection.getResponseCode(); - BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); - - String line; - StringBuffer response = new StringBuffer(); - while ((line = br.readLine()) != null) - response.append(line); - br.close(); - - // For normal webpages, it would be like - // "...

HAI

" or - // something like that - // for this it's a JSON - String result = response.toString(); - if (responseCode == 204) { GoreCore.LOGGER.warn("Attempted to get a UUID for player " + username + ", but that account is not registered"); @@ -310,22 +133,16 @@ private static UUID requestId(String username) { return null; } - String resultOfExtraction = result.replace("{", ""); - resultOfExtraction = resultOfExtraction.replace("}", ""); - resultOfExtraction = resultOfExtraction.substring(0, resultOfExtraction.indexOf(',')); - resultOfExtraction = resultOfExtraction.substring(resultOfExtraction.indexOf(':'), - resultOfExtraction.length()); - resultOfExtraction = resultOfExtraction.replace("\"", ""); - resultOfExtraction = resultOfExtraction.replace(":", ""); - - String uuidCleaned = resultOfExtraction.replaceAll("[^a-zA-Z0-9]", ""); - uuidCleaned = (uuidCleaned.substring(0, 8) + "-" + uuidCleaned.substring(8, 12) + "-" - + uuidCleaned.substring(12, 16) + "-" + uuidCleaned.substring(16, 20) + "-" - + uuidCleaned.substring(20, 32)); - - UUID uuidResult = UUID.fromString(uuidCleaned); - return uuidResult; - + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + InputStream inputStream = connection.getInputStream(); + while ((length = inputStream.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + UUID uuid = UUID.fromString(addDashes(Objects.requireNonNull(JsonUtils.fromString(result.toString(), "id")).getAsString())); + localCache.put(username, uuid); + return uuid; } catch (Exception e) { GoreCore.LOGGER.error("Unexpected error getting UUID for " + username, e); return null; @@ -334,118 +151,74 @@ private static UUID requestId(String username) { /** * Lookup the username based on the account ID. Returns null on errors. - * Warning: is not cached + * Warning: is cached */ public static String getUsername(UUID id) { - try { - - String idString = id.toString().replaceAll("-", ""); - String url = "https://api.mojang.com/user/profiles/" + idString + "/names"; - - URL obj = new URL(url); - HttpURLConnection connection = (HttpURLConnection) obj.openConnection(); - - connection.setRequestMethod("GET"); - connection.setRequestProperty("User-Agent", "Mozilla/5.0"); - - int responseCode = connection.getResponseCode(); - BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); - - String line; - StringBuffer response = new StringBuffer(); - while ((line = br.readLine()) != null) - response.append(line); - br.close(); - - String result = response.toString(); - - if (responseCode == 204) { - GoreCore.LOGGER.warn("Attempted to get a username for player " + id - + ", but that account is not registered"); - return null; - } - - if (responseCode != 200) { - GoreCore.LOGGER.warn("Attempted to get a username for player " + id - + ", but the response code was unexpected (" + responseCode + ")"); + if (UsernameCache.containsUUID(id)) return UsernameCache.getLastKnownUsername(id); + else if (localCache.containsValue(id)) { + for (Map.Entry entry : localCache.entrySet()) { + if (entry.getValue().equals(id)) { + return entry.getKey(); + } + } + } else { + try { + String idString = id.toString().replaceAll("-", ""); + String url = "https://api.mojang.com/user/profiles/" + idString + "/names"; + + URL obj = new URL(url); + HttpURLConnection connection = (HttpURLConnection) obj.openConnection(); + + connection.setRequestMethod("GET"); + connection.setRequestProperty("User-Agent", "Mozilla/5.0"); + + int responseCode = connection.getResponseCode(); + if (responseCode == 204) { + GoreCore.LOGGER.warn("Attempted to get a username for player " + id + + ", but that account is not registered"); + return null; + } + + if (responseCode != 200) { + GoreCore.LOGGER.warn("Attempted to get a username for player " + id + + ", but the response code was unexpected (" + responseCode + ")"); + return null; + } + + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + InputStream inputStream = connection.getInputStream(); + while ((length = inputStream.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + String username = JsonUtils.fromString(result.toString(), "name").getAsString(); + localCache.put(username, id); + return username; + } catch (Exception e) { + GoreCore.LOGGER.error("Unexpected error getting username for " + id, e); return null; } - - String searchFor = "\"name\":\""; - int index1 = result.lastIndexOf(searchFor) + searchFor.length(); - int index2 = result.indexOf('"', index1); - - return result.substring(index1, index2); - - } catch (Exception e) { - GoreCore.LOGGER.error("Unexpected error getting username for " + id, e); - return null; } + return null; } /** - * GetUUIDResult shows the result of getting UUIDs from player names through - * {@link AccountUUIDs#getId(String)}. It has a UUID for the result and a - * {@link Outcome} that describes what happened. - * - * @author CrowsOfWar + * Add dashes to a UUID. Method from SquirrelID + * + *

If dashes already exist, the same UUID will be returned.

+ * + * @param uuid the UUID + * @return a UUID with dashes + * @throws IllegalArgumentException thrown if the given input is not actually an UUID + * @author sk89q */ - public static class AccountId { - private final UUID uuid; - private final boolean temporary; - - /** - * Creates a temporary ID using a generated UUID based on the username - */ - public AccountId(String username) { - Random random = new Random(username.hashCode()); - this.uuid = new UUID(random.nextLong(), random.nextLong()); - this.temporary = true; - } - - /** - * Creates an account ID from a successful result - * - * @param uuid - * UUID obtained from Mojang API - */ - public AccountId(UUID uuid) { - this.uuid = uuid; - this.temporary = false; - } - - /** - * Creates an account ID which might be temporary - */ - public AccountId(UUID uuid, boolean temporary) { - this.uuid = uuid; - this.temporary = temporary; - } - - /** - * Gets the UUID of this UUID result. If the result isn't successful, it - * is null. - */ - public UUID getUUID() { - return uuid; - } - - /** - * Returns whether this ID is temporary. If an error occurred when - * accessing Mojang's API, an unofficial UUID is generated and this will - * return true. - * - * @return - */ - public boolean isTemporary() { - return temporary; + public static String addDashes(String uuid) { + uuid = uuid.replace("-", ""); // Remove dashes + Matcher matcher = DASHLESS_PATTERN.matcher(uuid); + if (!matcher.matches()) { + throw new IllegalArgumentException("Invalid UUID format"); } - - @Override - public String toString() { - return "AccountId[uuid=" + uuid + ",temporary=" + temporary + "]"; - } - + return matcher.replaceAll("$1-$2-$3-$4-$5"); } - } diff --git a/src/main/java/com/crowsofwar/gorecore/util/JsonUtils.java b/src/main/java/com/crowsofwar/gorecore/util/JsonUtils.java new file mode 100644 index 0000000000..d053f71fed --- /dev/null +++ b/src/main/java/com/crowsofwar/gorecore/util/JsonUtils.java @@ -0,0 +1,61 @@ +/* + This file is part of AvatarMod. + + AvatarMod is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + AvatarMod is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with AvatarMod. If not, see . +*/ +package com.crowsofwar.gorecore.util; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import com.google.gson.GsonBuilder; + +/** + *

+ * Contains utility methods for parsing JSON, using Google's GSON API + *

+ * + * @author Mahtaran + */ +public final class JsonUtils { + /** + *

+ * Gets the JsonElement at a certain path. + *

+ * + * @param jsonString + * The JSON String + * @param path + * The path where to get the element from, with subsections divided by dots (.) + * @return The JsonElement at the path + */ + public static JsonElement fromString(String jsonString, String path) throws JsonSyntaxException { + JsonObject json = new GsonBuilder().create().fromJson(jsonString, JsonObject.class); + // Prefixed by two slashes because otherwise it's a special delimiter + String[] segments = path.split("\\."); + for (String segment : segments) { + if (json != null) { + JsonElement element = json.get(segment); + if (!element.isJsonObject()) { + return element; + } else { + json = element.getAsJsonObject(); + } + } else { + return null; + } + } + return json; + } +} diff --git a/src/main/java/com/crowsofwar/gorecore/util/Vector.java b/src/main/java/com/crowsofwar/gorecore/util/Vector.java index 0cdfb52be7..d7e51d2d39 100644 --- a/src/main/java/com/crowsofwar/gorecore/util/Vector.java +++ b/src/main/java/com/crowsofwar/gorecore/util/Vector.java @@ -97,7 +97,7 @@ public Vector(Vec3d vec) { * @param entity The entity to use */ public Vector(Entity entity) { - this(entity.posX, entity.posY, entity.posZ); + this(entity.posX, entity.getEntityBoundingBox().minY, entity.posZ); } /** diff --git a/src/main/resources/assets/avatarmod/advancements/airbending/air_scroll.json b/src/main/resources/assets/avatarmod/advancements/airbending/air_scroll.json new file mode 100644 index 0000000000..4a70e2ba16 --- /dev/null +++ b/src/main/resources/assets/avatarmod/advancements/airbending/air_scroll.json @@ -0,0 +1,31 @@ +{ + "display": { + "title": "Awakening in the Iceberg", + "description": "Gain an airbending scroll!", + "icon": { + "item": "avatarmod:scroll", + "data": 4 + }, + "background": "avatarmod:textures/advancements/background/air.png", + "frame": "goal" + }, + "rewards": { + "experience": 50, + "recipes": [ + "avatarmod:airbender_staff" + ] + }, + "criteria": { + "gained_air_scroll": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "avatarmod:scroll", + "data": 4 + } + ] + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/avatarmod/advancements/waterbending/water_scroll.json b/src/main/resources/assets/avatarmod/advancements/waterbending/water_scroll.json new file mode 100644 index 0000000000..4c80d7e5f4 --- /dev/null +++ b/src/main/resources/assets/avatarmod/advancements/waterbending/water_scroll.json @@ -0,0 +1,31 @@ +{ + "display": { + "title": "Cracking the Iceberg", + "description": "Gain a waterbending scroll!", + "icon": { + "item": "avatarmod:scroll", + "data": 3 + }, + "background": "avatarmod:textures/advancements/background/water.png", + "frame": "goal" + }, + "rewards": { + "experience": 250, + "recipes": [ + "avatarmod:water_pouch" + ] + }, + "criteria": { + "gained_water_scroll": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "avatarmod:scroll", + "data": 3 + } + ] + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/avatarmod/lang/en_US.lang b/src/main/resources/assets/avatarmod/lang/en_us.lang similarity index 87% rename from src/main/resources/assets/avatarmod/lang/en_US.lang rename to src/main/resources/assets/avatarmod/lang/en_us.lang index cf986f2c84..010a572ac0 100644 --- a/src/main/resources/assets/avatarmod/lang/en_US.lang +++ b/src/main/resources/assets/avatarmod/lang/en_us.lang @@ -74,7 +74,17 @@ avatar.nochi=Not enough chi! avatar.airBubbleElytra=Cannot use air bubble with elytra avatar.bisonStats=Bison is at ${food}%% food, ${health}%% health, and ${domestication} domestication. avatar.outOfScrolls=This bender's pack is empty. They probably wouldn't have any scrolls to give you. +avatar.needTradeItem=You need a diamond, gold, or emerald, to get a scroll! +avatar.needAirTradeItem=You need a diamond, gold, emerald, dragon's breath, totem of undying, or elytra to get a scroll! +avatar.needFireTradeItem=You need a diamond, gold ingot, emerald, magma cream, or blaze rod to get a scroll! +avatar.staffCooldown=The staff is on cooldown! You can't airbend with it! +avatar.slipstreamCooldown=Slipstream is on cooldown! You can't use it! +avatar.cleanseCooldown=Cleanse is on cooldown! You can't use it! +avatar.purifyCooldown=Purify is on cooldown! You can't use it! +avatar.restoreCooldown=Restore is on cooldown! You can't use it! avatar.abilityLocked=You need to unlock that ability before you can use it! +avatar.bisonNoFood=Your bison is too hungry to fly! You need to feed it apples and hay so it can fly. +avatar.bisonSitting=Your bison is now sitting! avatar.bisonChestSlots1=Your bison does not have any avatar.bisonChestSlots2=inventory yet, but will gain avatar.bisonChestSlots3=more slots as it grows older. @@ -110,7 +120,7 @@ avatar.bisonWhistle.transferAway.ignore=The transfer with ${newOwner} has been i avatar.bisonWhistle.transferTo.ignore=${oldOwner} has chosen not to respond to your transfer request. avatar.bisonWhistle.transferOffline=[error]This bison isn't yours. You can't transfer the bison since the owner ${owner} is offline.[/error] avatar.bisonWhistle.followOn=Your bison will now begin following you. -avatar.bisonWhistle.followOff=Your bison have stopped following you. +avatar.bisonWhistle.followOff=Your bison has stopped following you. avatar.bisonWhistle.nearby=[error]Your bison is already nearby![/error] avatar.specialtyScroll.success=You have now unlocked [translate=avatar.${specialtyBending}]! @@ -130,7 +140,7 @@ avatar.ability.ravine=§2§lRavine avatar.ability.ravine.desc=Create a powerful yet small fissure in the ground. Only works on level ground and earth, but can do plenty of damage. avatar.ability.ravine.lvl1=Slow, basic ravine avatar.ability.ravine.lvl2=Faster speed -avatar.ability.ravine.lvl3=Ravine travels farther unless there is an obstacle +avatar.ability.ravine.lvl3=Ravine travels farther unless there is an obstacle, more damage avatar.ability.ravine.lvl4_1=§2§l§oFissure ;; Destroys blocks under it, hit multiple enemies, but costs 1.5x chi avatar.ability.ravine.lvl4_2=§2§l§oShaking §2§l§oearth ;; Chance to knock armor and weapons off hit enemies @@ -166,20 +176,20 @@ avatar.ability.restore.lvl3= The amount of speed you lose is decreased, and your avatar.ability.restore.lvl4_1= §2§l§oGuardian §2§l§oof §2§l§oLife ;; Your strength and resistance are increased. avatar.ability.restore.lvl4_2= §2§l§oSustenance §2§l§oof §2§l§oLife ;; You receive instantaneous health, and your hunger disappears. -avatar.ability.light_fire=Light Fire +avatar.ability.light_fire=§c§lLight Fire avatar.ability.light_fire.desc=A small, utility type ability to light fires. It's less practical in combat than some other abilities. avatar.ability.light_fire.fail=You weren't able to light the fire. Maybe you should try again... avatar.ability.light_fire.lvl1=When you don't succeed, keep trying, otherwise mobs will start spawning... avatar.ability.light_fire.lvl2=Greater chance of creating fire avatar.ability.light_fire.lvl3=Greater chance of creating fire -avatar.ability.light_fire.lvl4_1=§c§l§oFlame §c§l§owall ;; Create a line of fire in the direction you're looking -avatar.ability.light_fire.lvl4_2=§c§l§oWide §c§l§orange ;; Light nearby blocks on fire as well +avatar.ability.light_fire.lvl4_1=§c§l§oFlame §c§l§odrive ;; Create a line of fire in the direction you're looking +avatar.ability.light_fire.lvl4_2=§c§l§oFlame §c§l§owall ;; Light nearby blocks on fire as well avatar.ability.fire_arc=§c§lFire Arc avatar.ability.fire_arc.desc=Make a flaming whip of fire and throw it at your enemies. avatar.ability.fire_arc.lvl1=Create a fire arc avatar.ability.fire_arc.lvl2=Moves faster -avatar.ability.fire_arc.lvl3=Tons more damage +avatar.ability.fire_arc.lvl3=Tons more damage, and you can redirect fire arcs that you look at in a 3 block radius! avatar.ability.fire_arc.lvl4_1=§c§l§oLarge §c§l§ofire ;; Can make even more fire upon landing avatar.ability.fire_arc.lvl4_2=§c§l§oBoomerang ;; Comes back upon a successful hit @@ -187,9 +197,9 @@ avatar.ability.flamethrower=§c§lFlamethrower avatar.ability.flamethrower.desc=Generate a stream of powerful, close-ranged flames. A trademark of Firebending. avatar.ability.flamethrower.lvl1=Attack within a short range avatar.ability.flamethrower.lvl2=Nearly twice as many flames; but more chi -avatar.ability.flamethrower.lvl3=Longer range, more precise -avatar.ability.flamethrower.lvl4_1=Flamestream ;; Extremely long-ranged, concentrated flames -avatar.ability.flamethrower.lvl4_2=The world will burn!! ;; Unfocused flames that create fires everywhere +avatar.ability.flamethrower.lvl3=Longer range, more precise, HUUUUGE damage increase +avatar.ability.flamethrower.lvl4_1=§c§l§oFlamestream ;; Extremely long-ranged, concentrated flames +avatar.ability.flamethrower.lvl4_2=§c§l§oThe world will burn!! ;; Unfocused flames that create fires everywhere avatar.ability.fireball=§c§lFireball avatar.ability.fireball.desc=Create a glowing orb of flame. It makes a firey explosion on impact. @@ -220,24 +230,24 @@ avatar.ability.inferno_punch.desc=Smash your enemies with a fist encased in raw avatar.ability.inferno_punch.lvl1=Incinerate your enemies with the force of a super-powered fist, knocking them back and setting them on fire! avatar.ability.inferno_punch.lvl2=Chi cost increases, damage, knockback, and firetime increases! avatar.ability.inferno_punch.lvl3=Even more damage! -avatar.ability.inferno_punch.lvl4_1=§c§l§oINCINERATE ;; Use a super-powerful inferno when you punch to create a massive fire explosion! Be warned, the explosion damages you too! +avatar.ability.inferno_punch.lvl4_1=§c§l§oINCINERATE ;; Use a super-powerful inferno when you punch to create a massive fire explosion! avatar.ability.inferno_punch.lvl4_2=§c§l§oFIRRRRRREBALLL ;; You can hit enemies from really far away, and enemies close to them are hit as well! avatar.ability.water_arc=§9§lWater §9§lArc avatar.ability.water_arc.desc=One of waterbending's most common attacks. Shoot a trailing arc of water at your enemy, but only when water is nearby. avatar.ability.water_arc.lvl1=Basic water arc -avatar.ability.water_arc.lvl2=Farther pick-up range -avatar.ability.water_arc.lvl3=Much faster +avatar.ability.water_arc.lvl2=Farther pick-up range, bigger water splash. +avatar.ability.water_arc.lvl3=Much faster, damage increase, and you can redirect water arcs that you look at in a 3 block radius! Bigger water splash. avatar.ability.water_arc.lvl4_1=§9§l§oWater Flurry ;; You can now instantly fire off water arcs; multiple arcs in quick succession make a combo. -avatar.ability.water_arc.lvl4_2=§9§l§oWater spear ;; Gravity disabled for 2s after thrown, slower +avatar.ability.water_arc.lvl4_2=§9§l§oWater spear ;; Super-duper-ultra fast, really high damage, breaks blocks! avatar.ability.wave=§9§lWave -avatar.ability.wave.desc=Summon a wave of water to destroy your enemies. Only works when they are in water. +avatar.ability.wave.desc=Summon a wave of water to destroy your enemies, travels a little on land. avatar.ability.wave.lvl1=Make your enemies wave goodbye avatar.ability.wave.lvl2=A lot more damage avatar.ability.wave.lvl3=Much larger -avatar.ability.wave.lvl4_1=§9§l§oWater §9§l§ospray ;; Creates minor explosion upon contact with enemy -avatar.ability.wave.lvl4_2=§9§l§oForce §9§l§owave ;; Very fast waves +avatar.ability.wave.lvl4_1=§9§l§oTsunami ;; Creates a massive wave +avatar.ability.wave.lvl4_2=§9§l§oForce §9§l§owave ;; Very fast waves, explosions avatar.ability.water_bubble=§9§lWater §9§lBubble avatar.ability.water_bubble.desc=Suspend and transport a bubble of water. Can be used like a long-range bucket. @@ -259,7 +269,7 @@ avatar.ability.water_cannon=§9§lWater §9§lCannon avatar.ability.water_cannon.desc=Make a continuous stream of water acts as crowd control. It takes a while to charge up, and takes 3 water charges out of water pouches. avatar.ability.water_cannon.lvl1=Basic water cannon avatar.ability.water_cannon.lvl2=Deals more damage, slightly larger -avatar.ability.water_cannon.lvl3=Deals even more damage; you can now just be near a source block to use water cannon, you don't have to look at one! +avatar.ability.water_cannon.lvl3=Deals even more damage; you can now just be near a waterbendable block to use water cannon, you don't have to look at one! avatar.ability.water_cannon.lvl4_1=§9§l§oTitanium §9§l§oTearer ;; Water is much larger and deals much more damage. Did you that water can punch holes through anything? Including humans!!!! avatar.ability.water_cannon.lvl4_2=§9§l§oRapidfire ;; Rapidly create many smaller streams of water that pierces through enemies! @@ -306,9 +316,9 @@ avatar.ability.air_bubble.lvl4_2=§f§l§oUndercurrent ;; Limited hovering, disa avatar.ability.cloudburst=§f§lCloudburst avatar.ability.cloudburst.desc=Create a whirling ball of air which can be thrown at enemies; creates a mini burst of air where it lands. -avatar.ability.cloudburst.lvl1= That was a big-ass burp -avatar.ability.cloudburst.lvl2=Faster speed when thrown -avatar.ability.cloudburst.lvl3=Much more damage +avatar.ability.cloudburst.lvl1=That was a big burp +avatar.ability.cloudburst.lvl2=Faster speed when thrown, larger explosion of air +avatar.ability.cloudburst.lvl3=Much more damage, bigger air explosion avatar.ability.cloudburst.lvl4_1=§f§l§oChi §f§l§oSmash ;; Temporarily applies severe debuffs to targets' bending power avatar.ability.cloudburst.lvl4_2=§f§l§oAbsorption ;; Cloudburst can absorb incoming projectiles, which increases its damage @@ -320,13 +330,21 @@ avatar.ability.slipstream.lvl3=Intermittently become invisible and increase the avatar.ability.slipstream.lvl4_1=§f§l§oDivine §f§l§oBreeze ;; Become stronger in melee and airbending combat avatar.ability.slipstream.lvl4_2=§f§l§oRun §f§l§olike §f§l§othe §f§l§owind ;; Become invisible more often and potion effects are stronger +avatar.ability.air_burst=§f§lAir Burst +avatar.ability.air_burst.desc=Slowly draw the surrounding air inwards, then release it in a massive blast that knocks back enemies! +avatar.ability.air_burst.lvl1="Nope!" nearby enemies, blasting them away with a shockwave of air. +avatar.ability.air_burst.lvl2=Charge timed reduced; damage, radius, and knockback increased. +avatar.ability.air_burst.lvl3=Everything is enhanced! +avatar.ability.air_burst.lvl4_1=§f§lPiercing Winds ;; Way higher damage, and release winds of such ferocity that they blind, weaken, and slow enemies! +avatar.ability.air_burst.lvl4_2=§f§lMaximum Pressure ;; Slowly draw enemies in before firing them away!! A massive radius! + avatar.ability.lightning_arc=§b§lLightning §b§lArc -avatar.ability.lightning_arc.desc=Create imposing arcs of electricity to electrocute your enemies! +avatar.ability.lightning_arc.desc=Create imposing arcs of electricity to electrocute your enemies! Explode on impact with the ground, but not mobs or players. avatar.ability.lightning_arc.lvl1=Intimidate potential boyfriends -avatar.ability.lightning_arc.lvl2=Lightning travels faster -avatar.ability.lightning_arc.lvl3=Lightning does more damage +avatar.ability.lightning_arc.lvl2=Lightning travels faster, bigger explosion on colliding with the ground. +avatar.ability.lightning_arc.lvl3=Lightning does more damage, bigger explosion on colliding with the ground. avatar.ability.lightning_arc.lvl4_1=§b§lFurious lightning ;; Does more damage, slightly smaller, another bolt -avatar.ability.lightning_arc.lvl4_2=§b§lLarge thunderbolts ;; Has a larger hitbox, making it easier to capture enemies +avatar.ability.lightning_arc.lvl4_2=§b§lLarge thunderbolts ;; Has a larger hitbox, and does all of its damage instantly, then explodes, instead of sticking. Additionally, its explosion is huge! avatar.ability.lightning_raze=§b§lLightning §b§lRaze avatar.ability.lightning_raze.desc=Rain down lightning bolts where you're looking! Pretty inaccurate. @@ -396,7 +414,7 @@ avatar.ability.explosion.lvl4_2=§8§l§oBOOOOOOOOOOOOOOOOOOM ;; HUGE explosion avatar.ability.explosive_pillar=§8§lExplosive Pillar avatar.ability.explosive_pillar.desc=Create a line of explosions that appear one after the other in the direction you're looking. -avatar.ability.explosive_pillar.lvl1=As the common person says, BOOM-BOOM-BOOM-BOOM BOOOOOOOOOM! +avatar.ability.explosive_pillar.lvl1=BOOM-BOOM-BOOM-BOOM BOOOOOOOOOM! avatar.ability.explosive_pillar.lvl2=Explosions are bigger, occur more frequently, and travel further. avatar.ability.explosive_pillar.lvl3=I'd say the same thing as above, but that'd be boring. SUPER-POWERED EXPLOSIONS BABY! avatar.ability.explosive_pillar.lvl4_1=§8§l§oEXPLOSION §8§l§oMACHINE §8§lGUN ;; Creates 3 explosive pillars that have small explosions and don't travel too far, but occur rapid-fire and are fun to use. @@ -437,8 +455,16 @@ avatar.key.editing2=ESC to unbind avatar.key.conflict1=%1$s avatar.key.conflict2=Conflict w/ %1$s -death.attack.avatar_earthbendBlock=%2$s §2§lsmashed %1$s with §2§learthbending! -death.attack.avatar_waterArc=%2$s used §9§lwaterbending to bring down %1$s ! +death.attack.avatar_Fire=%1$s was incinerated by §c§lfirebending! +death.attack.avatar_Water=%1$s drowned from §9§lwaterbending! +death.attack.avatar_Air=%1$s was blasted away with §f§lairbending! +death.attack.avatar_Earth=%1$s was crushed with §2§learthbending! +death.attack.avatar_Sand=%1$s suffocated from §6§lsandbending! +death.attack.avatar_Combustion=%1$s was blown to smithereens by §8§lcombustionbending! +death.attack.avatar_Lightning=%1$s was shocked with §b§llightningbending! +death.attack.avatar_Ice=%1$s was frozen by §3§licebending! +death.attack.avatar_earthbendBlock=%2$s §2§lsmashed %1$s with a §2§lblock! +death.attack.avatar_waterArc=%2$s's §9§lwater §9§larc drowned %1$s ! death.attack.avatar_ravine=%2$s §2§lcrushed %1$s in a §2§lravine! death.attack.avatar_wave=%1$s §9§lcan't §9§lsurf! death.attack.avatar_fireball=%2$s §c§lincinerated %1$s with a §c§lfireball! @@ -448,12 +474,13 @@ death.attack.avatar_fireArc=%1$s was §c§lFIRED by %2$s ! death.attack.avatar_groundSmash=%2$s §2§lsmashed %1$s to a pulp! death.attack.avatar_lightningBending=%2$s §b§lelectrocuted %1$s ! death.attack.avatar_lightningBendingRedirected=%2$s §b§lredirected lightning to §b§lelectrocute %1$s ! -death.attack.avatar_watercannon=%1$s couldn't handle the pressure of %2$s's §9§lWater §9§lCannon! -death.attack.avatar_cloudburst=%1$s was §f§lblown §f§lapart by %2$s's §f§lcloudburst! +death.attack.avatar_waterCannon=%1$s couldn't handle the pressure of %2$s's §9§lWater §9§lCannon! +death.attack.avatar_AirDamage=%1$s was §f§lblown §f§lapart by %2$s's §f§lair! death.attack.avatar_icePrison=The §3§lintense §3§lfrost of %2$s's §3§lice §3§lprison §3§lfroze %1$s ! death.attack.avatar_iceShard=%2$s was §3§lstabbed by %1$s's §3§lice §3§lshard! death.attack.avatar_sandPrison=%1$s was §6§lentombed by %1$s's §6§lsand §6§lprison! death.attack.avatar_sandstorm=%2$s was flung by %1$s's §6§lsandstorm! +death.attack.avatar_shockWave=%2$s was blasted away by %1$s's shockwave! entity.Airbender.name=§f§lAirbender entity.Firebender.name=§c§lFirebender @@ -491,5 +518,7 @@ item.avatarmod:ostrich_equip.woven.name=Woven Ostrich Armor item.avatarmod:ostrich_equip.chain.name=Chainmail Ostrich Armor item.avatarmod:ostrich_equip.plate.name=Golden Ostrich Armor +item.avatarmod:airbender_staff.name=Airbending Staff + avatar.tooltip.water_pouch=%d/5 Water avatar.tooltip.water_pouch.empty=Empty diff --git a/src/main/resources/assets/avatarmod/lang/es_AR.lang b/src/main/resources/assets/avatarmod/lang/es_ar.lang similarity index 100% rename from src/main/resources/assets/avatarmod/lang/es_AR.lang rename to src/main/resources/assets/avatarmod/lang/es_ar.lang diff --git a/src/main/resources/assets/avatarmod/lang/es_ES.lang b/src/main/resources/assets/avatarmod/lang/es_es.lang similarity index 100% rename from src/main/resources/assets/avatarmod/lang/es_ES.lang rename to src/main/resources/assets/avatarmod/lang/es_es.lang diff --git a/src/main/resources/assets/avatarmod/lang/es_MX.lang b/src/main/resources/assets/avatarmod/lang/es_mx.lang similarity index 100% rename from src/main/resources/assets/avatarmod/lang/es_MX.lang rename to src/main/resources/assets/avatarmod/lang/es_mx.lang diff --git a/src/main/resources/assets/avatarmod/lang/es_UY.lang b/src/main/resources/assets/avatarmod/lang/es_uy.lang similarity index 100% rename from src/main/resources/assets/avatarmod/lang/es_UY.lang rename to src/main/resources/assets/avatarmod/lang/es_uy.lang diff --git a/src/main/resources/assets/avatarmod/lang/es_VE.lang b/src/main/resources/assets/avatarmod/lang/es_ve.lang similarity index 100% rename from src/main/resources/assets/avatarmod/lang/es_VE.lang rename to src/main/resources/assets/avatarmod/lang/es_ve.lang diff --git a/src/main/resources/assets/avatarmod/lang/fr_FR.lang b/src/main/resources/assets/avatarmod/lang/fr_fr.lang similarity index 98% rename from src/main/resources/assets/avatarmod/lang/fr_FR.lang rename to src/main/resources/assets/avatarmod/lang/fr_fr.lang index 6f7a031484..d1e76c96fd 100644 --- a/src/main/resources/assets/avatarmod/lang/fr_FR.lang +++ b/src/main/resources/assets/avatarmod/lang/fr_fr.lang @@ -1,288 +1,288 @@ -avatar.category.main=Mod Avatar - -avatar.BendingList=Afficher la liste des Maîtrises -avatar.CheatEarthbending=Triche Maîtrise de la Terre -avatar.ThrowBlock=Lancer bloc -avatar.ToggleBending=Ramasser bloc - -avatar.RadialMenu=Maîtrise de la Terre -avatar.Bend=Utiliser la Maîtrise -avatar.BendingCycleLeft=Cycle de Maîtrises Gauche -avatar.BendingCycleRight=Cycle de Maîtrises Droite -avatar.Skills=Menu de Compétences -avatar.TransferBison=Confirmer le transfert de Bison - -avatar.earthbending=Maîtrise de la Terre -avatar.earthbending.demonym=Maître de la Terre -avatar.firebending=Maîtrise du Feu -avatar.firebending.demonym=Maître du Feu -avatar.waterbending=Maîtrise de l'Eau -avatar.waterbending.demonym=Maître de l'Eau -avatar.airbending=Maîtrise de l'Air -avatar.airbending.demonym=Maître de l'Air -avatar.all=Universel - -avatar.ui.openSkillsMenu=Cliquez pour ouvrir - -avatar.cmd.bending=Gérer les controleurs de la Maîtrise d'un joueur. -avatar.cmd.bending.list.noData=[error][error_value]${player}[/error_value] n'est pas un compte enregistré.[/error] -avatar.cmd.bending.list.nonbender=[italic][value]${player}[/value] n'est pas un Maître.[/italic] -avatar.cmd.bending.list.item=- [translate=avatar.${bending}] -avatar.cmd.bending.list.top=[bold]Lister [value]${amount}[/value] controleurs de Maîtrise de [value]${player}[/value][/bold]: - -avatar.cmd.bending.add.alreadyHas=[error][error_value]${player}[/error_value] est déjà un [error_value][translate=avatar.${bending}.demonym][/error_value][/error]. -avatar.cmd.bending.add.success=[bold][value]${player}[/value] est maintenant un [value][translate=avatar.${bending}.demonym][/value]![/bold] - -avatar.cmd.bending.remove.doesntHave=[error][error_value]${player}[/error_value] n'est pas un [error_value][translate=avatar.${bending}.demonym][/error_value][/error]. -avatar.cmd.bending.remove.success=[bold] [value][translate=avatar.${bending}][/value] retirée de [value]${player}[/value]![/bold] - -avatar.cmd.ability.set.range=[error]L'XP de compétence doit être de [error_value]0[/error_value] à [error_value]100[/error_value]. -avatar.cmd.ability.set.success=[bold]L'Experience de [value]${player}[/value] pour [value]${ability}[/value] a été mise avec succès à [value]${amount}[/value][/bold] - -avatar.cmd.ability.get=[bold]L'Experience de [value]${player}[/value] pour [value]${ability}[/value] est égal à [value]${amount}[/value][/bold] - -avatar.cmd.cfg.exception1=[error]Une erreur s'est produite lors de la recharge de la configuration[/error] -avatar.cmd.cfg.exception2=[error]Détails: [error_value]${details}[/error_value] voir les logs pour plus d'informations[/error] - -avatar.cmd.cfg.successful=[bold]Valeurs de configurations rechargées avec succès[/bold] - -avatar.cmd.pp.add=Points de progression de [value]${player}[/value] [value][translate=avatar.${bending}][/value] ont été augmentés à [value]${pps}[/value]. -avatar.cmd.pp.get=[value]${player}[/value] a actuellement [value]${pps}[/value] [value][translate=avatar.${bending}][/value] points de progression. -avatar.cmd.pp.set=Points de progression de [value]${player}[/value] [value][translate=avatar.${bending}][/value] ont été mit à [value]${pps}[/value]. -avatar.cmd.pp.set.range=[error]Les Points de progression doivent être supérieurs à 0.[/error] - -avatar.spec.locked=bloqué -avatar.spec.lvl1=niveau I -avatar.spec.lvl2=niveau II -avatar.spec.lvl3=niveau III -avatar.spec.lvl4_1=niveau IV, premier chemin -avatar.spec.lvl4_2=niveau IV, deuxieme chemin -avatar.cmd.xpset=Progrès de [value]${player}[/value] [value]${ability}[/value] a été mit à [value][translate=avatar.spec.${spec}][/value] -avatar.cmd.noAbility=Il n'y a pas de compétence nommée %s - -avatar.donthavebending=[error]Vous n'avez pas encore appris la ${bending}. Pour l'avoir, ecrivez: [error_value]/avatar bending add ${username} ${bending}[/error_value][/error] -avatar.nochi=Pas assez de chi! -avatar.airBubbleElytra=Vous ne pouvez pas utiliser la Bulle d'Air avec des elytres -avatar.bisonStats=Le Bison est à ${food}%% de nourriture, ${health}%% de santé, et ${domestication} de domestication. -avatar.outOfScrolls=Ce sac de Maître est vide. Il n'avait sûrement aucun manuscrit à vous donner. -avatar.abilityLocked=Vous avez besoin de débloquer cette compétence pour pouvoir l'utiliser! - -avatar.bisonWhistle.summon=Votre Bison à été appelé et il arrivera dans environ ${time} secondes! -avatar.bisonWhistle.assign=Ce sifflet de Bison à été lié à ${bison}. -avatar.bisonWhistle.notAssigned=[error]Ce sifflet de Bison n'a été lié à aucun Bison; accroupissez-vous et cliquez sur un Bison avec cet objet pour les lier.[/error] -avatar.bisonWhistle.notFound=[error]${bison} ne vit plus dans le monde physique.[/error] -avatar.bisonWhistle.notOwned=[error]Ce bison volant ne vous appartient pas.[/error] -avatar.bisonWhistle.untamed=[error]Ce bison volant est sauvage et vous devez d'abord l'apprivoiser.[/error] -avatar.bisonWhistle.tooltipBound=Lié à %s -avatar.bisonWhistle.tooltipUnbound=Pas lié -avatar.bisonWhistle.transferAway=Votre bison volant ${bison} à été transféré à ${newOwner}. -avatar.bisonWhistle.transferTo=Vous possedez à présent le bison volant de ${oldOwner} nommé ${bison}! -avatar.bisonWhistle.noTransfer=[error]Personne n'a reclamé un transfert de bison récemment.[/error] -avatar.bisonWhistle.transferAway.start=${newOwner} aimerait posséder votre bison ${bison}. Appuyez sur [keybinding=avatar.TransferBison] pour confirmer, ignorer pour décliner. -avatar.bisonWhistle.transferTo.start=Un message à été envoyé à ${oldOwner} pour confirmer le transfert de ${bison}. -avatar.bisonWhistle.transferAway.ignore=Le transfert avec ${newOwner} a été ignoré. -avatar.bisonWhistle.transferTo.ignore=${oldOwner} has chosen not to respond to your transfer request. -avatar.bisonWhistle.transferOffline=[error]Ce bison n'est pas le votre. Vous ne pouvez pas transferer ce bison puisque le propriétaire ${owner} n'est pas en ligne.[/error] -avatar.bisonChestSlots1=Votre bison n'a pas encore -avatar.bisonChestSlots2=d'inventaire, mais va obtenir -avatar.bisonChestSlots3=plus de places quand il grandira. - -avatar.ability.pickup_block=Ramasser un bloc -avatar.ability.pickup_block.desc=Utilisez la Maîtrise de la Terre pour déplacer des blocs maitrisables. Placez-les dans la position désirée, ou jetez les sur vos ennemis. -avatar.ability.pickup_block.lvl1=Deplacez et jetez des blocs maitrisables -avatar.ability.pickup_block.lvl2=Plus vite et plus loin quand il est jeté -avatar.ability.pickup_block.lvl3=Double de dégats -avatar.ability.pickup_block.lvl4_1=Boomerang de bloc ;; Le bloc revient après avoir touché un mob -avatar.ability.pickup_block.lvl4_2=Large impacte ;; 1/2 chance de créer une explosion à l'aterrisage. - -avatar.ability.ravine=Ravin -avatar.ability.ravine.desc=Créez une puissante mais petite fissure dans le sol. Fonctionne seulement sur le sol et la Terre, mais peut faire beaucoup de dégats. -avatar.ability.ravine.lvl1=Lent, ravin basic -avatar.ability.ravine.lvl2=Plus rapide -avatar.ability.ravine.lvl3=Le ravin parcourt plus loin, sauf s'il y a un obstacle -avatar.ability.ravine.lvl4_1=Fissure ;; Destruit les blocs en dessous, atteint plusieurs ennemies, mais coûte 1.5x de chi -avatar.ability.ravine.lvl4_2=Terre tremblante ;; Chance de renverse l'armure et les armes, et de frapper les ennemis - -avatar.ability.earth_wall=Mur -avatar.ability.earth_wall.desc=Elevez une barrière protective en face de vous. Il peut bloquer les projectiles et mobs. -avatar.ability.earth_wall.lvl1=Invoquez un petit mur -avatar.ability.earth_wall.lvl2=Créez un plus large mur -avatar.ability.earth_wall.lvl3=Créez un encore plus large mur -avatar.ability.earth_wall.lvl4_1=Tirez des projéctiles à travers le mur -avatar.ability.earth_wall.lvl4_2=Le mur reste elevé plus longtemps, mais utilise du chi - -avatar.ability.mine_blocks=Miner des Blocs -avatar.ability.mine_blocks.desc=Detruisez rapidement des blocs pour miner des tunnels -avatar.ability.mine_blocks.lvl1=Minez des blocs -avatar.ability.mine_blocks.lvl2=Minez encore plus de blocs -avatar.ability.mine_blocks.lvl3=Fortune niveau I quand vous minez -avatar.ability.mine_blocks.lvl4_1=Minez très profondement, fortune niveau III -avatar.ability.mine_blocks.lvl4_2=Minez des veines de minerai, fortune niveau IV - -avatar.ability.light_fire=Léger Feu -avatar.ability.light_fire.desc=Une petite capacité utile, pour allumer des feux. Moins pratique en combat que certaines capacités. -avatar.ability.light_fire.fail=Vous n'etiez pas capable d'allumer le feu. Vous devriez peut être réessayer... -avatar.ability.light_fire.lvl1=Essayez de créer un petit feu -avatar.ability.light_fire.lvl2=Plus de chance de créer du feu -avatar.ability.light_fire.lvl3=Encore plus de chance de créer du feu -avatar.ability.light_fire.lvl4_1=Mur de flammes ;; Créez une ligne de feu dans la direction où vous regardez -avatar.ability.light_fire.lvl4_2=Large portée ;; Enflammez aussi les proches blocs - -avatar.ability.fire_arc=Arc de feu -avatar.ability.fire_arc.desc=Faites un fouet enflammé et jetez le sur vos ennemis. -avatar.ability.fire_arc.lvl1=Créez un arc de feu -avatar.ability.fire_arc.lvl2=Se déplace plus rapidement -avatar.ability.fire_arc.lvl3=Beaucoup plus de dégats -avatar.ability.fire_arc.lvl4_1=Large feu ;; Peut faire encore plus de feu à l'atterissage -avatar.ability.fire_arc.lvl4_2=Boomerang ;; Revient suite à une frappe réussite - -avatar.ability.flamethrower=Lance-flammes -avatar.ability.flamethrower.desc=Genère un flux de puissantes, flames à distance. Un symbole de la Maîtrise du feu. -avatar.ability.flamethrower.lvl1=Attaque de courte rangée -avatar.ability.flamethrower.lvl2=Presque le double de flammes; mais plus de chi -avatar.ability.flamethrower.lvl3=Plus grande portée, plus de précision -avatar.ability.flamethrower.lvl4_1=Flux de flammes ;; Flammes concentrées, de très grand portée -avatar.ability.flamethrower.lvl4_2=Le Monde va bruler!! ;; Flammes non-concentrées, qui mettent le feu partout - -avatar.ability.fireball=Boule de Feu -avatar.ability.fireball.desc=Créez une orbe incandescante de flammes. Cela fait une explosion ardente à l'impact. -avatar.ability.fireball.lvl1=Créez une boule de feu basique. -avatar.ability.fireball.lvl2=Plus rapide au lancé. -avatar.ability.fireball.lvl3=Beaucoup plus de dégats lors d'un coup direct. -avatar.ability.fireball.lvl4_1=Explosion concentrée ;; Peut parfois détruire de l'obsidienne -avatar.ability.fireball.lvl4_2=Explosion chargée ;; Prend quelque secondes à charger, plus large explosion quand chargée - -avatar.ability.water_arc=Arc d'eau -avatar.ability.water_arc.desc=Une des attaques les plus communes de la Maîtrise de l'eau. Tirez un arc d'eau sur votre ennemi, mais seulement quand de l'eau est dans les parages. -avatar.ability.water_arc.lvl1=Arc d'eau basique -avatar.ability.water_arc.lvl2=Plus grande rangée de recupérage -avatar.ability.water_arc.lvl3=Beaucoup plus rapide -avatar.ability.water_arc.lvl4_1=Boomerang ;; Revient vers vous si vous touchez une cible -avatar.ability.water_arc.lvl4_2=Lance d'eau ;; Gravité desactivée pendant 2 secondes après etre lancé, plus lent - -avatar.ability.wave=Vague -avatar.ability.wave.desc=Invoquez une vague d'eau pour détruire vos ennemis. Marche seulement quand vous etes sous l'eau. -avatar.ability.wave.lvl1=Vague lente pour noyer vos ennemis. -avatar.ability.wave.lvl2=Beaucoup plus de dégats -avatar.ability.wave.lvl3=Beaucoup plus large -avatar.ability.wave.lvl4_1=Tsunami ;; Beaucoup plus large et affecte les créatures sur le sol -avatar.ability.wave.lvl4_2=Vague de force ;; Vague très rapide - -avatar.ability.water_bubble=Bulle d'eau -avatar.ability.water_bubble.desc=Suspendez et transportez une bulle d'eau. Peut etre utilisé comme un seau de longe rangée. -avatar.ability.water_bubble.lvl1=Bulle d'eau de petite rangée, l'eau sèche après l'impact -avatar.ability.water_bubble.lvl2=Lancez la bulle beaucoup plus loin -avatar.ability.water_bubble.lvl3=La bulle créée une sourve d'eau permanente à l'atterissage -avatar.ability.water_bubble.lvl4_1=Lancez la bulle d'eau très loin -avatar.ability.water_bubble.lvl4_2=N'utilise pas d'eau pour créer la bulle - eau infinie - -avatar.ability.water_skate=Patin d'eau -avatar.ability.water_skate.desc=Courez sur une surface d'eau. Pratique abilité evasive, ou juste pour se balader. -avatar.ability.water_skate.lvl1=Glissez à travers l'eau, ne pouvez pas utiliser d'abilités -avatar.ability.water_skate.lvl2=Peut utiliser des abilités en patinant -avatar.ability.water_skate.lvl3=Beaucoup plus rapide -avatar.ability.water_skate.lvl4_1=Patin equilibré ;; Peut patiner sur de l'eau coulante -avatar.ability.water_skate.lvl4_2=Impact aqueux ;; Fracassez le sol après avoir sauté - -avatar.ability.air_gust=Rafale d'air -avatar.ability.air_gust.desc=Generez une puissant rafale d'air pour repousser vos ennemis, vous permettant de vous concentrez sur un autre problème. -avatar.ability.air_gust.lvl1=Propulez vos ennemis au loin -avatar.ability.air_gust.lvl2=Moitié de temps de recharge -avatar.ability.air_gust.lvl3=Propulsion plus puissante -avatar.ability.air_gust.lvl4_1=Extincteur ;; Détruit des projectiles plus faibles -avatar.ability.air_gust.lvl4_2=Aspirateur ;; Aspire les ennemis VERS vous - -avatar.ability.air_jump=Saut d'air -avatar.ability.air_jump.desc=Manipulez l'air autour de vous pour vous propulser. Parfait pour rattraper un ennemi sans méfiance. -avatar.ability.air_jump.lvl1=Sautez dans les airs -avatar.ability.air_jump.lvl2=Pouvoir de saut légèrement amélioré -avatar.ability.air_jump.lvl3=Saut encore plus performant -avatar.ability.air_jump.lvl4_1=Double saut ;; Coûte le doule de chi -avatar.ability.air_jump.lvl4_2=Attaque au sol ;; Attaque les ennemis proches sur le sol - -avatar.ability.airblade=Lame d'air -avatar.ability.airblade.desc=Un puissant disque d'air en rotation suffisant pour couper de la chair. Peut etre fatale en succession rapide. -avatar.ability.airblade.lvl1=Abilité de base -avatar.ability.airblade.lvl2=Plus rapide et plus de dégats -avatar.ability.airblade.lvl3=Peut maintenant couper des blocs -avatar.ability.airblade.lvl4_1=Lame enchainée ;; Rebondit vers de multiples ennemis -avatar.ability.airblade.lvl4_2=Perceur d'armures ;; Coupe à travers des armures et de la pierre - -avatar.ability.air_bubble=Bulle d'air -avatar.ability.air_bubble.desc=Créez une bulle d'air autour de vous pour vous proteger des attaques. En revanche, cela utilise beaucoup de chi pour la maintenir. -avatar.ability.air_bubble.lvl1=Petite rangée et propulsion arrière -avatar.ability.air_bubble.lvl2=Bulle d'air d'une taille médium -avatar.ability.air_bubble.lvl3=Plus de propulsion vers l'arrière -avatar.ability.air_bubble.lvl4_1=Bulle préssurisé ;; Très large taille -avatar.ability.air_bubble.lvl4_2=Sous-courant ;; Survol limité, désactivé en s'accroupissant - -avatar.ability.undefined=??? - -avatar.ui.level0=Niveau I -avatar.ui.level1=Niveau II -avatar.ui.level2=Niveau III -avatar.ui.level3=-MAX- -avatar.ui.path_first=Premier Chemin -avatar.ui.path_second=Second Chemin -avatar.ui.unlock=Compétence bloquée -avatar.ui.unlockDesc=Utilisez un(e) [translate=avatar.${bending}] ou un Manuscrit Universel pour débloquer -avatar.ui.skillsMenu=[translate=avatar.${bending}] Expérience de compétence - -avatar.radial.undefined=A venir! -avatar.radial.xp=[translate=avatar.ui.level${level}], ${xp}%% -avatar.radial.max=Niveau IV, [translate=avatar.ui.path_${xp}] -avatar.radial.locked1=Compétence bloquée -avatar.radial.locked2=Appuyez sur ${level} pour débloquer -avatar.radial.lockedCreative1=Mode Créatif -avatar.radial.lockedCreative2=Bloqué mais en mode créatif - -avatar.getBending.title=Maîtrise bloquée -avatar.getBending.incompatible=Vous pouvez seulement utiliser des manuscrits du même type ou type universel -avatar.getBending.guide=Inserez 3 manuscrit du même type ou type universel pour débloquer la Maîtrise - -avatar.key.none1=Aucune touche -avatar.key.none2=Cliquez pour éditer -avatar.key.set1=%1$s -avatar.key.set2=Cliquez pour éditer -avatar.key.editing1=> %1$s < -avatar.key.editing2=ESC pour délier -avatar.key.conflict1=%1$s -avatar.key.conflict2=Conflit w/ %1$s - -death.attack.avatar_earthbendBlock=%2$s a brisé %1$s avec la Maîtrise de la Terre -death.attack.avatar_waterArc=%2$s a utilisé la Maîtrise de l'Eau pour abattre %1$s -death.attack.avatar_ravine=%2$s a brisé %1$s dans une ravine -death.attack.avatar_wave=%1$s ne peut pas surfer -death.attack.avatar_fireball=%2$s a foudroyé %1$s avec une boule de feu -death.attack.avatar_airblade=%1$s a été découpé par %2$s -death.attack.avatar_flamethrower=%1$s vient d'etre roti par %2$s!! -death.attack.avatar_groundSmash=%2$s a brisé %1$s en chair - -entity.Airbender.name=Maître de l'Air -entity.Firebender.name=Maître du Feu -entity.Waterbender.name=Maître e l'Eau -entity.SkyBison.name=Bison Volant -entity.OtterPenguin.name=Pingouin-Loutre - -itemGroup.avatar.items=Objects d'Avatar - -item.avatarmod:scroll.all.name=Manuscrit -item.avatarmod:scroll.air.name=Manuscrit de Maîtrise de l'Air -item.avatarmod:scroll.fire.name=Manuscrit de Maîtrise du Feu -item.avatarmod:scroll.earth.name=Manuscrit de Maîtrise de la Terre -item.avatarmod:scroll.water.name=Manuscrit de Maîtrise de l'Eau -item.avatarmod:water_pouch.name=Pochette d'Eau -item.avatarmod:bison_whistle.name=Sifflet de Bison - -item.avatarmod:bison_saddle.basic.name=Selle Basique de Bison -item.avatarmod:bison_saddle.sturdy.name=Selle Solide de Bison -item.avatarmod:bison_saddle.studded.name=Selle Clouté de Bison -item.avatarmod:bison_saddle.majestic.name=Majestueuse Selle de Bison - -item.avatarmod:bison_armor.woven.name=Armure tissée de Bison -item.avatarmod:bison_armor.chain.name=Armure de Bison en Chaîne -item.avatarmod:bison_armor.wrought.name=Armure Forgée de Bison -item.avatarmod:bison_armor.legendary.name=Armure Légendaire de Bison - -avatar.tooltip.water_pouch=%d/5 d'Eau +avatar.category.main=Mod Avatar + +avatar.BendingList=Afficher la liste des Maîtrises +avatar.CheatEarthbending=Triche Maîtrise de la Terre +avatar.ThrowBlock=Lancer bloc +avatar.ToggleBending=Ramasser bloc + +avatar.RadialMenu=Maîtrise de la Terre +avatar.Bend=Utiliser la Maîtrise +avatar.BendingCycleLeft=Cycle de Maîtrises Gauche +avatar.BendingCycleRight=Cycle de Maîtrises Droite +avatar.Skills=Menu de Compétences +avatar.TransferBison=Confirmer le transfert de Bison + +avatar.earthbending=Maîtrise de la Terre +avatar.earthbending.demonym=Maître de la Terre +avatar.firebending=Maîtrise du Feu +avatar.firebending.demonym=Maître du Feu +avatar.waterbending=Maîtrise de l'Eau +avatar.waterbending.demonym=Maître de l'Eau +avatar.airbending=Maîtrise de l'Air +avatar.airbending.demonym=Maître de l'Air +avatar.all=Universel + +avatar.ui.openSkillsMenu=Cliquez pour ouvrir + +avatar.cmd.bending=Gérer les controleurs de la Maîtrise d'un joueur. +avatar.cmd.bending.list.noData=[error][error_value]${player}[/error_value] n'est pas un compte enregistré.[/error] +avatar.cmd.bending.list.nonbender=[italic][value]${player}[/value] n'est pas un Maître.[/italic] +avatar.cmd.bending.list.item=- [translate=avatar.${bending}] +avatar.cmd.bending.list.top=[bold]Lister [value]${amount}[/value] controleurs de Maîtrise de [value]${player}[/value][/bold]: + +avatar.cmd.bending.add.alreadyHas=[error][error_value]${player}[/error_value] est déjà un [error_value][translate=avatar.${bending}.demonym][/error_value][/error]. +avatar.cmd.bending.add.success=[bold][value]${player}[/value] est maintenant un [value][translate=avatar.${bending}.demonym][/value]![/bold] + +avatar.cmd.bending.remove.doesntHave=[error][error_value]${player}[/error_value] n'est pas un [error_value][translate=avatar.${bending}.demonym][/error_value][/error]. +avatar.cmd.bending.remove.success=[bold] [value][translate=avatar.${bending}][/value] retirée de [value]${player}[/value]![/bold] + +avatar.cmd.ability.set.range=[error]L'XP de compétence doit être de [error_value]0[/error_value] à [error_value]100[/error_value]. +avatar.cmd.ability.set.success=[bold]L'Experience de [value]${player}[/value] pour [value]${ability}[/value] a été mise avec succès à [value]${amount}[/value][/bold] + +avatar.cmd.ability.get=[bold]L'Experience de [value]${player}[/value] pour [value]${ability}[/value] est égal à [value]${amount}[/value][/bold] + +avatar.cmd.cfg.exception1=[error]Une erreur s'est produite lors de la recharge de la configuration[/error] +avatar.cmd.cfg.exception2=[error]Détails: [error_value]${details}[/error_value] voir les logs pour plus d'informations[/error] + +avatar.cmd.cfg.successful=[bold]Valeurs de configurations rechargées avec succès[/bold] + +avatar.cmd.pp.add=Points de progression de [value]${player}[/value] [value][translate=avatar.${bending}][/value] ont été augmentés à [value]${pps}[/value]. +avatar.cmd.pp.get=[value]${player}[/value] a actuellement [value]${pps}[/value] [value][translate=avatar.${bending}][/value] points de progression. +avatar.cmd.pp.set=Points de progression de [value]${player}[/value] [value][translate=avatar.${bending}][/value] ont été mit à [value]${pps}[/value]. +avatar.cmd.pp.set.range=[error]Les Points de progression doivent être supérieurs à 0.[/error] + +avatar.spec.locked=bloqué +avatar.spec.lvl1=niveau I +avatar.spec.lvl2=niveau II +avatar.spec.lvl3=niveau III +avatar.spec.lvl4_1=niveau IV, premier chemin +avatar.spec.lvl4_2=niveau IV, deuxieme chemin +avatar.cmd.xpset=Progrès de [value]${player}[/value] [value]${ability}[/value] a été mit à [value][translate=avatar.spec.${spec}][/value] +avatar.cmd.noAbility=Il n'y a pas de compétence nommée %s + +avatar.donthavebending=[error]Vous n'avez pas encore appris la ${bending}. Pour l'avoir, ecrivez: [error_value]/avatar bending add ${username} ${bending}[/error_value][/error] +avatar.nochi=Pas assez de chi! +avatar.airBubbleElytra=Vous ne pouvez pas utiliser la Bulle d'Air avec des elytres +avatar.bisonStats=Le Bison est à ${food}%% de nourriture, ${health}%% de santé, et ${domestication} de domestication. +avatar.outOfScrolls=Ce sac de Maître est vide. Il n'avait sûrement aucun manuscrit à vous donner. +avatar.abilityLocked=Vous avez besoin de débloquer cette compétence pour pouvoir l'utiliser! + +avatar.bisonWhistle.summon=Votre Bison à été appelé et il arrivera dans environ ${time} secondes! +avatar.bisonWhistle.assign=Ce sifflet de Bison à été lié à ${bison}. +avatar.bisonWhistle.notAssigned=[error]Ce sifflet de Bison n'a été lié à aucun Bison; accroupissez-vous et cliquez sur un Bison avec cet objet pour les lier.[/error] +avatar.bisonWhistle.notFound=[error]${bison} ne vit plus dans le monde physique.[/error] +avatar.bisonWhistle.notOwned=[error]Ce bison volant ne vous appartient pas.[/error] +avatar.bisonWhistle.untamed=[error]Ce bison volant est sauvage et vous devez d'abord l'apprivoiser.[/error] +avatar.bisonWhistle.tooltipBound=Lié à %s +avatar.bisonWhistle.tooltipUnbound=Pas lié +avatar.bisonWhistle.transferAway=Votre bison volant ${bison} à été transféré à ${newOwner}. +avatar.bisonWhistle.transferTo=Vous possedez à présent le bison volant de ${oldOwner} nommé ${bison}! +avatar.bisonWhistle.noTransfer=[error]Personne n'a reclamé un transfert de bison récemment.[/error] +avatar.bisonWhistle.transferAway.start=${newOwner} aimerait posséder votre bison ${bison}. Appuyez sur [keybinding=avatar.TransferBison] pour confirmer, ignorer pour décliner. +avatar.bisonWhistle.transferTo.start=Un message à été envoyé à ${oldOwner} pour confirmer le transfert de ${bison}. +avatar.bisonWhistle.transferAway.ignore=Le transfert avec ${newOwner} a été ignoré. +avatar.bisonWhistle.transferTo.ignore=${oldOwner} has chosen not to respond to your transfer request. +avatar.bisonWhistle.transferOffline=[error]Ce bison n'est pas le votre. Vous ne pouvez pas transferer ce bison puisque le propriétaire ${owner} n'est pas en ligne.[/error] +avatar.bisonChestSlots1=Votre bison n'a pas encore +avatar.bisonChestSlots2=d'inventaire, mais va obtenir +avatar.bisonChestSlots3=plus de places quand il grandira. + +avatar.ability.pickup_block=Ramasser un bloc +avatar.ability.pickup_block.desc=Utilisez la Maîtrise de la Terre pour déplacer des blocs maitrisables. Placez-les dans la position désirée, ou jetez les sur vos ennemis. +avatar.ability.pickup_block.lvl1=Deplacez et jetez des blocs maitrisables +avatar.ability.pickup_block.lvl2=Plus vite et plus loin quand il est jeté +avatar.ability.pickup_block.lvl3=Double de dégats +avatar.ability.pickup_block.lvl4_1=Boomerang de bloc ;; Le bloc revient après avoir touché un mob +avatar.ability.pickup_block.lvl4_2=Large impacte ;; 1/2 chance de créer une explosion à l'aterrisage. + +avatar.ability.ravine=Ravin +avatar.ability.ravine.desc=Créez une puissante mais petite fissure dans le sol. Fonctionne seulement sur le sol et la Terre, mais peut faire beaucoup de dégats. +avatar.ability.ravine.lvl1=Lent, ravin basic +avatar.ability.ravine.lvl2=Plus rapide +avatar.ability.ravine.lvl3=Le ravin parcourt plus loin, sauf s'il y a un obstacle +avatar.ability.ravine.lvl4_1=Fissure ;; Destruit les blocs en dessous, atteint plusieurs ennemies, mais coûte 1.5x de chi +avatar.ability.ravine.lvl4_2=Terre tremblante ;; Chance de renverse l'armure et les armes, et de frapper les ennemis + +avatar.ability.earth_wall=Mur +avatar.ability.earth_wall.desc=Elevez une barrière protective en face de vous. Il peut bloquer les projectiles et mobs. +avatar.ability.earth_wall.lvl1=Invoquez un petit mur +avatar.ability.earth_wall.lvl2=Créez un plus large mur +avatar.ability.earth_wall.lvl3=Créez un encore plus large mur +avatar.ability.earth_wall.lvl4_1=Tirez des projéctiles à travers le mur +avatar.ability.earth_wall.lvl4_2=Le mur reste elevé plus longtemps, mais utilise du chi + +avatar.ability.mine_blocks=Miner des Blocs +avatar.ability.mine_blocks.desc=Detruisez rapidement des blocs pour miner des tunnels +avatar.ability.mine_blocks.lvl1=Minez des blocs +avatar.ability.mine_blocks.lvl2=Minez encore plus de blocs +avatar.ability.mine_blocks.lvl3=Fortune niveau I quand vous minez +avatar.ability.mine_blocks.lvl4_1=Minez très profondement, fortune niveau III +avatar.ability.mine_blocks.lvl4_2=Minez des veines de minerai, fortune niveau IV + +avatar.ability.light_fire=Léger Feu +avatar.ability.light_fire.desc=Une petite capacité utile, pour allumer des feux. Moins pratique en combat que certaines capacités. +avatar.ability.light_fire.fail=Vous n'etiez pas capable d'allumer le feu. Vous devriez peut être réessayer... +avatar.ability.light_fire.lvl1=Essayez de créer un petit feu +avatar.ability.light_fire.lvl2=Plus de chance de créer du feu +avatar.ability.light_fire.lvl3=Encore plus de chance de créer du feu +avatar.ability.light_fire.lvl4_1=Mur de flammes ;; Créez une ligne de feu dans la direction où vous regardez +avatar.ability.light_fire.lvl4_2=Large portée ;; Enflammez aussi les proches blocs + +avatar.ability.fire_arc=Arc de feu +avatar.ability.fire_arc.desc=Faites un fouet enflammé et jetez le sur vos ennemis. +avatar.ability.fire_arc.lvl1=Créez un arc de feu +avatar.ability.fire_arc.lvl2=Se déplace plus rapidement +avatar.ability.fire_arc.lvl3=Beaucoup plus de dégats +avatar.ability.fire_arc.lvl4_1=Large feu ;; Peut faire encore plus de feu à l'atterissage +avatar.ability.fire_arc.lvl4_2=Boomerang ;; Revient suite à une frappe réussite + +avatar.ability.flamethrower=Lance-flammes +avatar.ability.flamethrower.desc=Genère un flux de puissantes, flames à distance. Un symbole de la Maîtrise du feu. +avatar.ability.flamethrower.lvl1=Attaque de courte rangée +avatar.ability.flamethrower.lvl2=Presque le double de flammes; mais plus de chi +avatar.ability.flamethrower.lvl3=Plus grande portée, plus de précision +avatar.ability.flamethrower.lvl4_1=Flux de flammes ;; Flammes concentrées, de très grand portée +avatar.ability.flamethrower.lvl4_2=Le Monde va bruler!! ;; Flammes non-concentrées, qui mettent le feu partout + +avatar.ability.fireball=Boule de Feu +avatar.ability.fireball.desc=Créez une orbe incandescante de flammes. Cela fait une explosion ardente à l'impact. +avatar.ability.fireball.lvl1=Créez une boule de feu basique. +avatar.ability.fireball.lvl2=Plus rapide au lancé. +avatar.ability.fireball.lvl3=Beaucoup plus de dégats lors d'un coup direct. +avatar.ability.fireball.lvl4_1=Explosion concentrée ;; Peut parfois détruire de l'obsidienne +avatar.ability.fireball.lvl4_2=Explosion chargée ;; Prend quelque secondes à charger, plus large explosion quand chargée + +avatar.ability.water_arc=Arc d'eau +avatar.ability.water_arc.desc=Une des attaques les plus communes de la Maîtrise de l'eau. Tirez un arc d'eau sur votre ennemi, mais seulement quand de l'eau est dans les parages. +avatar.ability.water_arc.lvl1=Arc d'eau basique +avatar.ability.water_arc.lvl2=Plus grande rangée de recupérage +avatar.ability.water_arc.lvl3=Beaucoup plus rapide +avatar.ability.water_arc.lvl4_1=Boomerang ;; Revient vers vous si vous touchez une cible +avatar.ability.water_arc.lvl4_2=Lance d'eau ;; Gravité desactivée pendant 2 secondes après etre lancé, plus lent + +avatar.ability.wave=Vague +avatar.ability.wave.desc=Invoquez une vague d'eau pour détruire vos ennemis. Marche seulement quand vous etes sous l'eau. +avatar.ability.wave.lvl1=Vague lente pour noyer vos ennemis. +avatar.ability.wave.lvl2=Beaucoup plus de dégats +avatar.ability.wave.lvl3=Beaucoup plus large +avatar.ability.wave.lvl4_1=Tsunami ;; Beaucoup plus large et affecte les créatures sur le sol +avatar.ability.wave.lvl4_2=Vague de force ;; Vague très rapide + +avatar.ability.water_bubble=Bulle d'eau +avatar.ability.water_bubble.desc=Suspendez et transportez une bulle d'eau. Peut etre utilisé comme un seau de longe rangée. +avatar.ability.water_bubble.lvl1=Bulle d'eau de petite rangée, l'eau sèche après l'impact +avatar.ability.water_bubble.lvl2=Lancez la bulle beaucoup plus loin +avatar.ability.water_bubble.lvl3=La bulle créée une sourve d'eau permanente à l'atterissage +avatar.ability.water_bubble.lvl4_1=Lancez la bulle d'eau très loin +avatar.ability.water_bubble.lvl4_2=N'utilise pas d'eau pour créer la bulle - eau infinie + +avatar.ability.water_skate=Patin d'eau +avatar.ability.water_skate.desc=Courez sur une surface d'eau. Pratique abilité evasive, ou juste pour se balader. +avatar.ability.water_skate.lvl1=Glissez à travers l'eau, ne pouvez pas utiliser d'abilités +avatar.ability.water_skate.lvl2=Peut utiliser des abilités en patinant +avatar.ability.water_skate.lvl3=Beaucoup plus rapide +avatar.ability.water_skate.lvl4_1=Patin equilibré ;; Peut patiner sur de l'eau coulante +avatar.ability.water_skate.lvl4_2=Impact aqueux ;; Fracassez le sol après avoir sauté + +avatar.ability.air_gust=Rafale d'air +avatar.ability.air_gust.desc=Generez une puissant rafale d'air pour repousser vos ennemis, vous permettant de vous concentrez sur un autre problème. +avatar.ability.air_gust.lvl1=Propulez vos ennemis au loin +avatar.ability.air_gust.lvl2=Moitié de temps de recharge +avatar.ability.air_gust.lvl3=Propulsion plus puissante +avatar.ability.air_gust.lvl4_1=Extincteur ;; Détruit des projectiles plus faibles +avatar.ability.air_gust.lvl4_2=Aspirateur ;; Aspire les ennemis VERS vous + +avatar.ability.air_jump=Saut d'air +avatar.ability.air_jump.desc=Manipulez l'air autour de vous pour vous propulser. Parfait pour rattraper un ennemi sans méfiance. +avatar.ability.air_jump.lvl1=Sautez dans les airs +avatar.ability.air_jump.lvl2=Pouvoir de saut légèrement amélioré +avatar.ability.air_jump.lvl3=Saut encore plus performant +avatar.ability.air_jump.lvl4_1=Double saut ;; Coûte le doule de chi +avatar.ability.air_jump.lvl4_2=Attaque au sol ;; Attaque les ennemis proches sur le sol + +avatar.ability.airblade=Lame d'air +avatar.ability.airblade.desc=Un puissant disque d'air en rotation suffisant pour couper de la chair. Peut etre fatale en succession rapide. +avatar.ability.airblade.lvl1=Abilité de base +avatar.ability.airblade.lvl2=Plus rapide et plus de dégats +avatar.ability.airblade.lvl3=Peut maintenant couper des blocs +avatar.ability.airblade.lvl4_1=Lame enchainée ;; Rebondit vers de multiples ennemis +avatar.ability.airblade.lvl4_2=Perceur d'armures ;; Coupe à travers des armures et de la pierre + +avatar.ability.air_bubble=Bulle d'air +avatar.ability.air_bubble.desc=Créez une bulle d'air autour de vous pour vous proteger des attaques. En revanche, cela utilise beaucoup de chi pour la maintenir. +avatar.ability.air_bubble.lvl1=Petite rangée et propulsion arrière +avatar.ability.air_bubble.lvl2=Bulle d'air d'une taille médium +avatar.ability.air_bubble.lvl3=Plus de propulsion vers l'arrière +avatar.ability.air_bubble.lvl4_1=Bulle préssurisé ;; Très large taille +avatar.ability.air_bubble.lvl4_2=Sous-courant ;; Survol limité, désactivé en s'accroupissant + +avatar.ability.undefined=??? + +avatar.ui.level0=Niveau I +avatar.ui.level1=Niveau II +avatar.ui.level2=Niveau III +avatar.ui.level3=-MAX- +avatar.ui.path_first=Premier Chemin +avatar.ui.path_second=Second Chemin +avatar.ui.unlock=Compétence bloquée +avatar.ui.unlockDesc=Utilisez un(e) [translate=avatar.${bending}] ou un Manuscrit Universel pour débloquer +avatar.ui.skillsMenu=[translate=avatar.${bending}] Expérience de compétence + +avatar.radial.undefined=A venir! +avatar.radial.xp=[translate=avatar.ui.level${level}], ${xp}%% +avatar.radial.max=Niveau IV, [translate=avatar.ui.path_${xp}] +avatar.radial.locked1=Compétence bloquée +avatar.radial.locked2=Appuyez sur ${level} pour débloquer +avatar.radial.lockedCreative1=Mode Créatif +avatar.radial.lockedCreative2=Bloqué mais en mode créatif + +avatar.getBending.title=Maîtrise bloquée +avatar.getBending.incompatible=Vous pouvez seulement utiliser des manuscrits du même type ou type universel +avatar.getBending.guide=Inserez 3 manuscrit du même type ou type universel pour débloquer la Maîtrise + +avatar.key.none1=Aucune touche +avatar.key.none2=Cliquez pour éditer +avatar.key.set1=%1$s +avatar.key.set2=Cliquez pour éditer +avatar.key.editing1=> %1$s < +avatar.key.editing2=ESC pour délier +avatar.key.conflict1=%1$s +avatar.key.conflict2=Conflit w/ %1$s + +death.attack.avatar_earthbendBlock=%2$s a brisé %1$s avec la Maîtrise de la Terre +death.attack.avatar_waterArc=%2$s a utilisé la Maîtrise de l'Eau pour abattre %1$s +death.attack.avatar_ravine=%2$s a brisé %1$s dans une ravine +death.attack.avatar_wave=%1$s ne peut pas surfer +death.attack.avatar_fireball=%2$s a foudroyé %1$s avec une boule de feu +death.attack.avatar_airblade=%1$s a été découpé par %2$s +death.attack.avatar_flamethrower=%1$s vient d'etre roti par %2$s!! +death.attack.avatar_groundSmash=%2$s a brisé %1$s en chair + +entity.Airbender.name=Maître de l'Air +entity.Firebender.name=Maître du Feu +entity.Waterbender.name=Maître e l'Eau +entity.SkyBison.name=Bison Volant +entity.OtterPenguin.name=Pingouin-Loutre + +itemGroup.avatar.items=Objects d'Avatar + +item.avatarmod:scroll.all.name=Manuscrit +item.avatarmod:scroll.air.name=Manuscrit de Maîtrise de l'Air +item.avatarmod:scroll.fire.name=Manuscrit de Maîtrise du Feu +item.avatarmod:scroll.earth.name=Manuscrit de Maîtrise de la Terre +item.avatarmod:scroll.water.name=Manuscrit de Maîtrise de l'Eau +item.avatarmod:water_pouch.name=Pochette d'Eau +item.avatarmod:bison_whistle.name=Sifflet de Bison + +item.avatarmod:bison_saddle.basic.name=Selle Basique de Bison +item.avatarmod:bison_saddle.sturdy.name=Selle Solide de Bison +item.avatarmod:bison_saddle.studded.name=Selle Clouté de Bison +item.avatarmod:bison_saddle.majestic.name=Majestueuse Selle de Bison + +item.avatarmod:bison_armor.woven.name=Armure tissée de Bison +item.avatarmod:bison_armor.chain.name=Armure de Bison en Chaîne +item.avatarmod:bison_armor.wrought.name=Armure Forgée de Bison +item.avatarmod:bison_armor.legendary.name=Armure Légendaire de Bison + +avatar.tooltip.water_pouch=%d/5 d'Eau avatar.tooltip.water_pouch.empty=Vide \ No newline at end of file diff --git a/src/main/resources/assets/avatarmod/lang/pl_PL.lang b/src/main/resources/assets/avatarmod/lang/pl_pl.lang similarity index 98% rename from src/main/resources/assets/avatarmod/lang/pl_PL.lang rename to src/main/resources/assets/avatarmod/lang/pl_pl.lang index ffe9853024..a954c45def 100644 --- a/src/main/resources/assets/avatarmod/lang/pl_PL.lang +++ b/src/main/resources/assets/avatarmod/lang/pl_pl.lang @@ -1,292 +1,292 @@ -avatar.category.main=Avatar Mod - -avatar.BendingList=Wyświetl listę magii -avatar.CheatEarthbending=Cheat Earthbending -avatar.ThrowBlock=Rzuć blok -avatar.ToggleBending=Podnieś blok - -avatar.RadialMenu=Magia Ziemi -avatar.Bend=Użyj Magii -avatar.BendingCycleLeft=Zmień Magię w Lewo -avatar.BendingCycleRight=Zmień Magię w Prawo -avatar.Skills=Menu Umiejętności -avatar.TransferBison=Zatwierdź transfer Bizona - -avatar.earthbending=Magia Ziemi -avatar.earthbending.demonym=Mag Ziemi -avatar.firebending=Magia Ognia -avatar.firebending.demonym=Mag Ognia -avatar.waterbending=Magia Wody -avatar.waterbending.demonym=Mag Wody -avatar.airbending=Magia Powietrza -avatar.airbending.demonym=Mag Powietrza -avatar.all=Uniwersalny - -avatar.cmd.bending=Zarządzaj magią gracza. -avatar.cmd.bending.list.noData=[error][error_value]${player}[/error_value] nie jest zarejestrowanym kontem.[/error] -avatar.cmd.bending.list.nonbender=[italic][value]${player}[/value] nie jest magiem.[/italic] -avatar.cmd.bending.list.item=- [translate=avatar.${bending}] -avatar.cmd.bending.list.top=[bold]Wymieniam [value]${amount}[/value] magie które posiada [value]${player}[/value][/bold]: - -avatar.cmd.bending.add.alreadyHas=[error][error_value]${player}[/error_value] to już [error_value][translate=avatar.${bending}.demonym][/error_value][/error]. -avatar.cmd.bending.add.success=[bold][value]${player}[/value] to teraz [value][translate=avatar.${bending}.demonym][/value]![/bold] - -avatar.cmd.bending.remove.doesntHave=[error][error_value]${player}[/error_value] nie jest [error_value][translate=avatar.${bending}.demonym][/error_value][/error]. -avatar.cmd.bending.remove.success=[bold]Zabrano [value][translate=avatar.${bending}][/value] od [value]${player}[/value]![/bold] - -avatar.cmd.ability.set.range=[error]XP Umiejętności musi być od [error_value]0[/error_value] do [error_value]100[/error_value]. -avatar.cmd.ability.set.success=[bold]Pomyślnie ustawiono [value]${player}a[/value] doświadczenie dla [value]${ability}[/value] na [value]${amount}[/value][/bold] - -avatar.cmd.ability.get=[bold][value]${player}a[/value] doświadczenie dla [value]${ability}[/value] to [value]${amount}[/value][/bold] - -avatar.cmd.cfg.exception1=[error]Wystąpił błąd podczas próby przeładowania konfiguracji[/error] -avatar.cmd.cfg.exception2=[error]Detale: [error_value]${details}[/error_value] zobacz logi po więcej[/error] - -avatar.cmd.cfg.successful=[bold]Pomyślnie przeładowano wartości konfiguracji[/bold] - -avatar.cmd.pp.add=Zwiększono [value]${player}a[/value] [value][translate=avatar.${bending}][/value] punkty postępu do [value]${pps}[/value]. -avatar.cmd.pp.get=[value]${player}[/value] aktualnie posiada [value]${pps}[/value] [value][translate=avatar.${bending}][/value] punktów postępu. -avatar.cmd.pp.set=Ustaw [value]${player}[/value]a [value][translate=avatar.${bending}][/value] punkty postępu [value]${pps}[/value]. -avatar.cmd.pp.set.range=[error]Punkty postępu muszą być większe niż 0.[/error] - -avatar.spec.locked=zablokowane -avatar.spec.lvl1=poziom I -avatar.spec.lvl2=poziom II -avatar.spec.lvl3=poziom III -avatar.spec.lvl4_1=poziom IV, pierwsza droga -avatar.spec.lvl4_2=poziom IV, druga droga -avatar.cmd.xpset=Ustaw [value]${player}[/value]a [value]${ability}[/value] postęp na [value][translate=avatar.spec.${spec}][/value] -avatar.cmd.noAbility=Nie ma umiejętności zwanej %s - -avatar.donthavebending=[error]Nie nauczyłeś się ${bending} jeszcze. To get it, type in: [error_value]/avatar bending add ${username} ${bending}[/error_value][/error] -avatar.nochi=Niewystarczająco chi! -avatar.airBubbleElytra=Nie można użyć kuli powietrza z elytrą -avatar.bisonStats=Bizon ma ${food}%% głodu, ${health}%% życia, i ${domestication} udomowienia. -avatar.outOfScrolls=Tego maga inwentarz jest pusty. Prawdopodobnie nie będzie miał żadnych zwojów do dania. -avatar.abilityLocked=Musisz odblokować tą umiejętność zanim jej użyjesz! -avatar.bisonChestSlots1=Twój bizon nie ma jeszcze -avatar.bisonChestSlots2=żadnego inwentarzu, ale zdobędzie -avatar.bisonChestSlots3=więcej miejsc jak dorośnie. -avatar.skatingBendingDisabled=[error]Nie możesz użyć magii podczas surfowania aż nie zdobędziesz poziomu II.[/error] - -avatar.bisonWhistle.summon=Twój Bizon został zawołany i przybędzie tu za około ${time} sekund! -avatar.bisonWhistle.assign=Przywiązano Bizoni Gwizdek do ${bison}. -avatar.bisonWhistle.notAssigned=[error]Bizoni Gwizdek nie został przywiązany do bizona; kucnij i kliknij ppm na bizona by go przywiązać.[/error] -avatar.bisonWhistle.notFound=[error]${bison} już nie żyje w fizycznym świecie.[/error] -avatar.bisonWhistle.notOwned=[error]Nie posiadasz tego latającego bizona.[/error] -avatar.bisonWhistle.untamed=[error]Ten latający bizon jest dziki i musisz go najpierw oswoić.[/error] -avatar.bisonWhistle.tooltipBound=Przywiązano do %s -avatar.bisonWhistle.tooltipUnbound=Nie przywiązany -avatar.bisonWhistle.transferAway=Twój latający bizon ${bison} został przeniesiony do ${newOwner}. -avatar.bisonWhistle.transferTo=Posiadasz teraz latającego bizona ${bison} od ${oldOwner}! -avatar.bisonWhistle.noTransfer=[error]Nikt ostatnio nie zażądał transferu bizona.[/error] -avatar.bisonWhistle.transferAway.start=${newOwner} chciałby posiadać twojego bizona ${bison}. Kliknij [keybinding=avatar.TransferBison] by potwierdzić, zignoruj by odmówić. -avatar.bisonWhistle.transferTo.start=Wiadomość została wysłana do ${oldOwner} by potwierdzić transfer ${bison}. -avatar.bisonWhistle.transferAway.ignore=Transfer z ${newOwner} został zignorowany. -avatar.bisonWhistle.transferTo.ignore=${oldOwner} wybrał by nie odpowiedzieć na twoje żądanie. -avatar.bisonWhistle.transferOffline=[error]Ten bizon nie jest twój. Nie możesz ztransferować bizona gdyż właściciel ${owner} jest offline.[/error] -avatar.bisonWhistle.followOn=Twój bizon będzie teraz za tobą podążał. -avatar.bisonWhistle.followOff=Twój bizon przestał za tobą podążać. - -avatar.ability.pickup_block=Podnieś blok -avatar.ability.pickup_block.desc=Użyj magii ziemi by ruszyć możliwe bloki i położyć je w pożądanym miejscu lub rzucić nimi we wrogów. -avatar.ability.pickup_block.lvl1=Przemieść i rzuć możliwe bloki -avatar.ability.pickup_block.lvl2=Szybsze i dalsze rzucenie -avatar.ability.pickup_block.lvl3=Podwójne obrażenia -avatar.ability.pickup_block.lvl4_1=Klockowy boomerang ;; Blok wraca po pomyślnym zaatakowaniu moba -avatar.ability.pickup_block.lvl4_2=Wielkie uderzenie ;; 1/2 szansy by stworzyć eksplozję po wylądowaniu - -avatar.ability.ravine=Wąwóz -avatar.ability.ravine.desc=Stwórz małą ale potężną szczelinę w ziemi. Działa tylko na poziomie ziemi, ale może zadać wiele obrażeń. -avatar.ability.ravine.lvl1=Wolny, podstawowy wąwóz -avatar.ability.ravine.lvl2=Większa prędkość -avatar.ability.ravine.lvl3=Wąwóz podróżuje dalej chyba że jest przeszkoda -avatar.ability.ravine.lvl4_1=Szczelina ;; Niszczy bloki pod sobą, atakuje kilku wrogów, ale kosztuje 1.5x chi -avatar.ability.ravine.lvl4_2=Trzęsienie ziemi ;; Szansa wywalenia zbroi i broni z zaatakowanych wrogów - -avatar.ability.earth_wall=Ściana -avatar.ability.earth_wall.desc=Podnieś przed sobą barierę ochronną. Może zablokować nadciągające pociski i moby. -avatar.ability.earth_wall.lvl1=Przywołaj małą ścianę -avatar.ability.earth_wall.lvl2=Stwórz większą ścianę -avatar.ability.earth_wall.lvl3=Stwórz większą ścianę -avatar.ability.earth_wall.lvl4_1=Strzelaj pociskami przez ścianę -avatar.ability.earth_wall.lvl4_2=Ściana stoi dłużej, ale zużywa więcej chi - -avatar.ability.mine_blocks=Kopanie Bloków -avatar.ability.mine_blocks.desc=Szybko niszczysz bloki wykopując tunel -avatar.ability.mine_blocks.lvl1=Wykop kilka bloków -avatar.ability.mine_blocks.lvl2=Wykop jeszcze więcej bloków -avatar.ability.mine_blocks.lvl3=Fortuna poziomu I kiedy kopiesz -avatar.ability.mine_blocks.lvl4_1=Kop bardzo daleko, poziom III fortuny -avatar.ability.mine_blocks.lvl4_2=Wykop żyły rud, poziom IV fortuny - -avatar.ability.light_fire=Rozpal Ogień -avatar.ability.light_fire.desc=Umiejętność rozpalania ognia. Jest mniej praktyczna w walkach niż w kilku innych czynnościach -avatar.ability.light_fire.fail=Nie mogłeś rozpalić ognia. Może powinieneś spróbować ponownie... -avatar.ability.light_fire.lvl1=Spróbuj stworzyć mały ogień -avatar.ability.light_fire.lvl2=Większa szansa stworzenia ognia -avatar.ability.light_fire.lvl3=Większa szansa stworzenia ognia -avatar.ability.light_fire.lvl4_1=Ściana ognia ;; Tworzy linię ognia w kierunku na który patrzysz -avatar.ability.light_fire.lvl4_2=Szeroki zasięg ;; Podpal również pobliskie bloki - -avatar.ability.fire_arc=Łuk Ognia -avatar.ability.fire_arc.desc=Stwórz ognisty bat z ognia i rzucaj nim we wrogów. -avatar.ability.fire_arc.lvl1=Tworzy łuk ognia -avatar.ability.fire_arc.lvl2=Porusza się szybciej -avatar.ability.fire_arc.lvl3=O wiele więcej obrażeń -avatar.ability.fire_arc.lvl4_1=Duży ogień ;; Może zrobić więcej ognia po wylądowaniu -avatar.ability.fire_arc.lvl4_2=Boomerang ;; Powraca po pomyślnym uderzeniu - -avatar.ability.flamethrower=Miotacz Ognia -avatar.ability.flamethrower.desc=Generuje potężny strumień płomieni na krótki dystans. Znak rozpoznawczy Maga Ognia. -avatar.ability.flamethrower.lvl1=Atakuj krótkim zasięgiem -avatar.ability.flamethrower.lvl2=Prawie dwa razy tyle płomieni; ale więcej chi -avatar.ability.flamethrower.lvl3=Dalszy zasięg, bardziej precyzyjny -avatar.ability.flamethrower.lvl4_1=Ognisty strumień ;; Skoncentrowane płomienie na niezwykle daleki zasięg -avatar.ability.flamethrower.lvl4_2=Świat spłonie!! ;; Nieskupione płomienie które tworzą wszędzie ogień - -avatar.ability.fireball=Kula Ognia -avatar.ability.fireball.desc=Stwórz świecącą kulę płomieni. Tworzy ognistą eksplozję przy uderzeniu. -avatar.ability.fireball.lvl1=Stwórz podstawową kulę ognia -avatar.ability.fireball.lvl2=Szybsza gdy rzucona -avatar.ability.fireball.lvl3=O wiele więcej obrażeń po bezpośrednim uderzeniu -avatar.ability.fireball.lvl4_1=Skoncentrowana eksplozja ;; Czasami może zniszczyć obsydian -avatar.ability.fireball.lvl4_2=Naładowana eksplozja ;; Zabiera kilka sekund by się naładować, większa eksplozja po naładowaniu - -avatar.ability.water_arc=Łuk Wody -avatar.ability.water_arc.desc=Jeden z pospolitych ataków magów wody. Wystrzel łuk wody we wrogów, ale tylko gdy woda jest w pobliżu. -avatar.ability.water_arc.lvl1=Podstawowy łuk wody -avatar.ability.water_arc.lvl2=Dalszy zasięg pobierania wody -avatar.ability.water_arc.lvl3=O wiele szybszy -avatar.ability.water_arc.lvl4_1=Boomerang ;; Wraca do ciebie jak trafisz cel -avatar.ability.water_arc.lvl4_2=Wodna włócznia ;; Wyłączona grawitacja na 2s po rzuceniu, wolniejsze - -avatar.ability.wave=Fala -avatar.ability.wave.desc=Przywołaj falę wody by zniszczyła twoich wrogów. Działa tylko kiedy są w wodzie. -avatar.ability.wave.lvl1=Wolna fala by utopić wrogów -avatar.ability.wave.lvl2=O wiele więcej obrażeń -avatar.ability.wave.lvl3=O wiele większa -avatar.ability.wave.lvl4_1=Tsunami ;; O wiele większa i oddziałuje na stworzenia znajdujące się na lądzie -avatar.ability.wave.lvl4_2=Potężne fale ;; Bardzo szybkie fale - -avatar.ability.water_bubble=Wodna bańka -avatar.ability.water_bubble.desc=Zawieszenie i transportowanie bańki wody. Może być użyte jako wiadro dalekiego zasięgu. -avatar.ability.water_bubble.lvl1=Wodna bańka krótkiego zasięgu, woda wysycha po zderzeniu -avatar.ability.water_bubble.lvl2=Rzuć bańką dalej -avatar.ability.water_bubble.lvl3=Bańka tworzy stałe źródło wody po wylądowaniu -avatar.ability.water_bubble.lvl4_1=Rzucaj bańkę wody naprawdę daleko -avatar.ability.water_bubble.lvl4_2=Nie zużywa wody do tworzenia bańki - nieskończona woda - -avatar.ability.water_skate=Surfowanie -avatar.ability.water_skate.desc=Biegaj po tafli wody. Użyteczne w unikach, lub po prostu by pochodzić po wodzie. -avatar.ability.water_skate.lvl1=Ślizgaj się po wodzie, nie można używać umiejętności -avatar.ability.water_skate.lvl2=Możesz używać umiejętności podczas surfowania -avatar.ability.water_skate.lvl3=O wiele szybciej surfujesz -avatar.ability.water_skate.lvl4_1=Zbalansowane surfowanie ;; Możesz surfować nawet po płynącej wodzie -avatar.ability.water_skate.lvl4_2=Wodne uderzenie ;; Zmiażdż ziemię po skoku - -avatar.ability.air_gust=Poryw Wiatru -avatar.ability.air_gust.desc=Generuje silny poryw wiatru by odepchnąć wrogów, pozwalając ci skoncentrować się na innym problemie. -avatar.ability.air_gust.lvl1=Zdmuchuje wrogów -avatar.ability.air_gust.lvl2=Połowa odnawiania się umiejętności -avatar.ability.air_gust.lvl3=Mocniejsze odpychanie -avatar.ability.air_gust.lvl4_1=Gaszenie ;; Niszczy słabsze pociski -avatar.ability.air_gust.lvl4_2=Wsysanie ;; Przyciąga wrogów do ciebie - -avatar.ability.air_jump=Powietrzny Skok -avatar.ability.air_jump.desc=Manipulujesz powietrzem wokół siebie by się wystrzelić z ziemi. Perfekcyjne do łapania nic nie spodziewającego się wroga. -avatar.ability.air_jump.lvl1=Skacz przez wiatr -avatar.ability.air_jump.lvl2=Lekko zwiększona moc skoku -avatar.ability.air_jump.lvl3=Jeszcze lepsze skakanie -avatar.ability.air_jump.lvl4_1=Podwójny skok ;; Kosztuje dwa razy więcej chi -avatar.ability.air_jump.lvl4_2=Walnięcie w ziemię ;; Atakuje pobliskich wrogów na ziemi - -avatar.ability.airblade=Ostrze Powietrza -avatar.ability.airblade.desc=Kręcący się dysk powietrza, potężny na tyle by przeciąć ciało. Może być mordercze. -avatar.ability.airblade.lvl1=Podstawowa umiejętność -avatar.ability.airblade.lvl2=Większa szybkość i obrażenia -avatar.ability.airblade.lvl3=Może teraz przecinać bloki -avatar.ability.airblade.lvl4_1=Łańcuchowe ostrze ;; Skacze po wielu wrogach -avatar.ability.airblade.lvl4_2=Przebijacz zbroi ;; Przecina się przez zbroję i kamień - -avatar.ability.air_bubble=Kula Powietrza -avatar.ability.air_bubble.desc=Tworzysz kulę powietrza wokół siebie by obronić się przed nadciągającymi atakami. Jednakże, utrzymywanie jej zabiera dużą ilość chi. -avatar.ability.air_bubble.lvl1=Mały zasięg i odrzut -avatar.ability.air_bubble.lvl2=Średniej wielkośći kula powietrza -avatar.ability.air_bubble.lvl3=Więcej odrzutu -avatar.ability.air_bubble.lvl4_1=Kula pod presją ;; Bardzo duża wielkość -avatar.ability.air_bubble.lvl4_2=Podłoże ;; Lekko się unosisz, możesz to wyłączyć to przez kucanie - -avatar.ability.undefined=??? - -avatar.ui.level0=Poziom I -avatar.ui.level1=Poziom II -avatar.ui.level2=Poziom III -avatar.ui.level3=-MAX- -avatar.ui.path_first=Pierwsza Droga -avatar.ui.path_second=Druga Droga -avatar.ui.unlock=Umiejętność Zablokowana -avatar.ui.unlockDesc.airbending=Użyj Zwoju Magii Powietrza lub Uniwersalnego Zwoju by odblokować -avatar.ui.unlockDesc.firebending=Użyj Zwoju Magii Ognia lub Uniwersalnego Zwoju by odblokować -avatar.ui.unlockDesc.waterbending=Użyj Zwoju Magii Wody lub Uniwersalnego Zwoju by odblokować -avatar.ui.unlockDesc.earthbending=Użyj Zwoju Magii Ziemi lub Uniwersalnego Zwoju by odblokować -avatar.ui.skillsMenu=[translate=avatar.${bending}] - Ulepszanie Zdolności - -avatar.radial.undefined=Wkrótce! -avatar.radial.xp=[translate=avatar.ui.level${level}], ${xp}%% -avatar.radial.max=Poziom IV, [translate=avatar.ui.path_${xp}] -avatar.radial.locked1=Umiejętność Zablokowana -avatar.radial.locked2=Naciśnij ${level} by odblokować -avatar.radial.lockedCreative1=Tryb kreatywny -avatar.radial.lockedCreative2=Zablokowane ale na trybie kreatywnym - -avatar.getBending.title=Odblokuj Magię -avatar.getBending.incompatible=Możesz używać tylko zwojów swojej magii lub uniwersalne -avatar.getBending.guide=Wsadź 3 zwoje tej samej magii lub uniwersalne by odblokować Magię - -avatar.key.none1=Nie przypisano -avatar.key.none2=Kliknij by edytować -avatar.key.set1=%1$s -avatar.key.set2=Kliknij by edytować -avatar.key.editing1=> %1$s < -avatar.key.editing2=ESC by usunąć -avatar.key.conflict1=%1$s -avatar.key.conflict2=Konflikt z %1$s - -death.attack.avatar_earthbendBlock=%2$s roztrzaskał %1$s używając magii ziemi -death.attack.avatar_waterArc=%2$s użył magii wody by sprowadzić do ziemi %1$s -death.attack.avatar_ravine=%2$s zgniótł %1$s w wąwozie -death.attack.avatar_wave=%1$s nie umie surfować -death.attack.avatar_fireball=%2$s wysadził %1$s używając kuli ognia -death.attack.avatar_airblade=%1$s został pokrojony przez %2$s -death.attack.avatar_flamethrower=%1$s właśnie został upieczony przez %2$s!! -death.attack.avatar_groundSmash=%2$s roztrzaskał %1$s do masy celulozowej - -entity.Airbender.name=Mag Powietrza -entity.Firebender.name=Mag Ognia -entity.Waterbender.name=Mag Wody -entity.SkyBison.name=Latający Bizon -entity.OtterPenguin.name=Wydropingwin - -itemGroup.avatar.items=Przedmioty z Avatara - -item.avatarmod:scroll.all.name=Zwój -item.avatarmod:scroll.air.name=Zwój Magii Powietrza -item.avatarmod:scroll.fire.name=Zwój Magii Ognia -item.avatarmod:scroll.earth.name=Zwój Magii Ziemi -item.avatarmod:scroll.water.name=Zwój Magii Wody -item.avatarmod:water_pouch.name=Bukłak -item.avatarmod:bison_whistle.name=Bizoni Gwizdek - -item.avatarmod:bison_saddle.basic.name=Podstawowe Siodło Bizonie -item.avatarmod:bison_saddle.sturdy.name=Silne Siodło Bizonie -item.avatarmod:bison_saddle.studded.name=Wysadzane Siodło Bizonie -item.avatarmod:bison_saddle.majestic.name=Majestatyczne Siodło Bizonie - -item.avatarmod:bison_armor.woven.name=Tkana Zbroja dla Bizona -item.avatarmod:bison_armor.chain.name=Zbroja Kolczy dla Bizona -item.avatarmod:bison_armor.wrought.name=Fasonowana Zbroja dla Bizona -item.avatarmod:bison_armor.legendary.name=Legendarna Zbroja dla Bizona - -avatar.tooltip.water_pouch=%d/5 Wody +avatar.category.main=Avatar Mod + +avatar.BendingList=Wyświetl listę magii +avatar.CheatEarthbending=Cheat Earthbending +avatar.ThrowBlock=Rzuć blok +avatar.ToggleBending=Podnieś blok + +avatar.RadialMenu=Magia Ziemi +avatar.Bend=Użyj Magii +avatar.BendingCycleLeft=Zmień Magię w Lewo +avatar.BendingCycleRight=Zmień Magię w Prawo +avatar.Skills=Menu Umiejętności +avatar.TransferBison=Zatwierdź transfer Bizona + +avatar.earthbending=Magia Ziemi +avatar.earthbending.demonym=Mag Ziemi +avatar.firebending=Magia Ognia +avatar.firebending.demonym=Mag Ognia +avatar.waterbending=Magia Wody +avatar.waterbending.demonym=Mag Wody +avatar.airbending=Magia Powietrza +avatar.airbending.demonym=Mag Powietrza +avatar.all=Uniwersalny + +avatar.cmd.bending=Zarządzaj magią gracza. +avatar.cmd.bending.list.noData=[error][error_value]${player}[/error_value] nie jest zarejestrowanym kontem.[/error] +avatar.cmd.bending.list.nonbender=[italic][value]${player}[/value] nie jest magiem.[/italic] +avatar.cmd.bending.list.item=- [translate=avatar.${bending}] +avatar.cmd.bending.list.top=[bold]Wymieniam [value]${amount}[/value] magie które posiada [value]${player}[/value][/bold]: + +avatar.cmd.bending.add.alreadyHas=[error][error_value]${player}[/error_value] to już [error_value][translate=avatar.${bending}.demonym][/error_value][/error]. +avatar.cmd.bending.add.success=[bold][value]${player}[/value] to teraz [value][translate=avatar.${bending}.demonym][/value]![/bold] + +avatar.cmd.bending.remove.doesntHave=[error][error_value]${player}[/error_value] nie jest [error_value][translate=avatar.${bending}.demonym][/error_value][/error]. +avatar.cmd.bending.remove.success=[bold]Zabrano [value][translate=avatar.${bending}][/value] od [value]${player}[/value]![/bold] + +avatar.cmd.ability.set.range=[error]XP Umiejętności musi być od [error_value]0[/error_value] do [error_value]100[/error_value]. +avatar.cmd.ability.set.success=[bold]Pomyślnie ustawiono [value]${player}a[/value] doświadczenie dla [value]${ability}[/value] na [value]${amount}[/value][/bold] + +avatar.cmd.ability.get=[bold][value]${player}a[/value] doświadczenie dla [value]${ability}[/value] to [value]${amount}[/value][/bold] + +avatar.cmd.cfg.exception1=[error]Wystąpił błąd podczas próby przeładowania konfiguracji[/error] +avatar.cmd.cfg.exception2=[error]Detale: [error_value]${details}[/error_value] zobacz logi po więcej[/error] + +avatar.cmd.cfg.successful=[bold]Pomyślnie przeładowano wartości konfiguracji[/bold] + +avatar.cmd.pp.add=Zwiększono [value]${player}a[/value] [value][translate=avatar.${bending}][/value] punkty postępu do [value]${pps}[/value]. +avatar.cmd.pp.get=[value]${player}[/value] aktualnie posiada [value]${pps}[/value] [value][translate=avatar.${bending}][/value] punktów postępu. +avatar.cmd.pp.set=Ustaw [value]${player}[/value]a [value][translate=avatar.${bending}][/value] punkty postępu [value]${pps}[/value]. +avatar.cmd.pp.set.range=[error]Punkty postępu muszą być większe niż 0.[/error] + +avatar.spec.locked=zablokowane +avatar.spec.lvl1=poziom I +avatar.spec.lvl2=poziom II +avatar.spec.lvl3=poziom III +avatar.spec.lvl4_1=poziom IV, pierwsza droga +avatar.spec.lvl4_2=poziom IV, druga droga +avatar.cmd.xpset=Ustaw [value]${player}[/value]a [value]${ability}[/value] postęp na [value][translate=avatar.spec.${spec}][/value] +avatar.cmd.noAbility=Nie ma umiejętności zwanej %s + +avatar.donthavebending=[error]Nie nauczyłeś się ${bending} jeszcze. To get it, type in: [error_value]/avatar bending add ${username} ${bending}[/error_value][/error] +avatar.nochi=Niewystarczająco chi! +avatar.airBubbleElytra=Nie można użyć kuli powietrza z elytrą +avatar.bisonStats=Bizon ma ${food}%% głodu, ${health}%% życia, i ${domestication} udomowienia. +avatar.outOfScrolls=Tego maga inwentarz jest pusty. Prawdopodobnie nie będzie miał żadnych zwojów do dania. +avatar.abilityLocked=Musisz odblokować tą umiejętność zanim jej użyjesz! +avatar.bisonChestSlots1=Twój bizon nie ma jeszcze +avatar.bisonChestSlots2=żadnego inwentarzu, ale zdobędzie +avatar.bisonChestSlots3=więcej miejsc jak dorośnie. +avatar.skatingBendingDisabled=[error]Nie możesz użyć magii podczas surfowania aż nie zdobędziesz poziomu II.[/error] + +avatar.bisonWhistle.summon=Twój Bizon został zawołany i przybędzie tu za około ${time} sekund! +avatar.bisonWhistle.assign=Przywiązano Bizoni Gwizdek do ${bison}. +avatar.bisonWhistle.notAssigned=[error]Bizoni Gwizdek nie został przywiązany do bizona; kucnij i kliknij ppm na bizona by go przywiązać.[/error] +avatar.bisonWhistle.notFound=[error]${bison} już nie żyje w fizycznym świecie.[/error] +avatar.bisonWhistle.notOwned=[error]Nie posiadasz tego latającego bizona.[/error] +avatar.bisonWhistle.untamed=[error]Ten latający bizon jest dziki i musisz go najpierw oswoić.[/error] +avatar.bisonWhistle.tooltipBound=Przywiązano do %s +avatar.bisonWhistle.tooltipUnbound=Nie przywiązany +avatar.bisonWhistle.transferAway=Twój latający bizon ${bison} został przeniesiony do ${newOwner}. +avatar.bisonWhistle.transferTo=Posiadasz teraz latającego bizona ${bison} od ${oldOwner}! +avatar.bisonWhistle.noTransfer=[error]Nikt ostatnio nie zażądał transferu bizona.[/error] +avatar.bisonWhistle.transferAway.start=${newOwner} chciałby posiadać twojego bizona ${bison}. Kliknij [keybinding=avatar.TransferBison] by potwierdzić, zignoruj by odmówić. +avatar.bisonWhistle.transferTo.start=Wiadomość została wysłana do ${oldOwner} by potwierdzić transfer ${bison}. +avatar.bisonWhistle.transferAway.ignore=Transfer z ${newOwner} został zignorowany. +avatar.bisonWhistle.transferTo.ignore=${oldOwner} wybrał by nie odpowiedzieć na twoje żądanie. +avatar.bisonWhistle.transferOffline=[error]Ten bizon nie jest twój. Nie możesz ztransferować bizona gdyż właściciel ${owner} jest offline.[/error] +avatar.bisonWhistle.followOn=Twój bizon będzie teraz za tobą podążał. +avatar.bisonWhistle.followOff=Twój bizon przestał za tobą podążać. + +avatar.ability.pickup_block=Podnieś blok +avatar.ability.pickup_block.desc=Użyj magii ziemi by ruszyć możliwe bloki i położyć je w pożądanym miejscu lub rzucić nimi we wrogów. +avatar.ability.pickup_block.lvl1=Przemieść i rzuć możliwe bloki +avatar.ability.pickup_block.lvl2=Szybsze i dalsze rzucenie +avatar.ability.pickup_block.lvl3=Podwójne obrażenia +avatar.ability.pickup_block.lvl4_1=Klockowy boomerang ;; Blok wraca po pomyślnym zaatakowaniu moba +avatar.ability.pickup_block.lvl4_2=Wielkie uderzenie ;; 1/2 szansy by stworzyć eksplozję po wylądowaniu + +avatar.ability.ravine=Wąwóz +avatar.ability.ravine.desc=Stwórz małą ale potężną szczelinę w ziemi. Działa tylko na poziomie ziemi, ale może zadać wiele obrażeń. +avatar.ability.ravine.lvl1=Wolny, podstawowy wąwóz +avatar.ability.ravine.lvl2=Większa prędkość +avatar.ability.ravine.lvl3=Wąwóz podróżuje dalej chyba że jest przeszkoda +avatar.ability.ravine.lvl4_1=Szczelina ;; Niszczy bloki pod sobą, atakuje kilku wrogów, ale kosztuje 1.5x chi +avatar.ability.ravine.lvl4_2=Trzęsienie ziemi ;; Szansa wywalenia zbroi i broni z zaatakowanych wrogów + +avatar.ability.earth_wall=Ściana +avatar.ability.earth_wall.desc=Podnieś przed sobą barierę ochronną. Może zablokować nadciągające pociski i moby. +avatar.ability.earth_wall.lvl1=Przywołaj małą ścianę +avatar.ability.earth_wall.lvl2=Stwórz większą ścianę +avatar.ability.earth_wall.lvl3=Stwórz większą ścianę +avatar.ability.earth_wall.lvl4_1=Strzelaj pociskami przez ścianę +avatar.ability.earth_wall.lvl4_2=Ściana stoi dłużej, ale zużywa więcej chi + +avatar.ability.mine_blocks=Kopanie Bloków +avatar.ability.mine_blocks.desc=Szybko niszczysz bloki wykopując tunel +avatar.ability.mine_blocks.lvl1=Wykop kilka bloków +avatar.ability.mine_blocks.lvl2=Wykop jeszcze więcej bloków +avatar.ability.mine_blocks.lvl3=Fortuna poziomu I kiedy kopiesz +avatar.ability.mine_blocks.lvl4_1=Kop bardzo daleko, poziom III fortuny +avatar.ability.mine_blocks.lvl4_2=Wykop żyły rud, poziom IV fortuny + +avatar.ability.light_fire=Rozpal Ogień +avatar.ability.light_fire.desc=Umiejętność rozpalania ognia. Jest mniej praktyczna w walkach niż w kilku innych czynnościach +avatar.ability.light_fire.fail=Nie mogłeś rozpalić ognia. Może powinieneś spróbować ponownie... +avatar.ability.light_fire.lvl1=Spróbuj stworzyć mały ogień +avatar.ability.light_fire.lvl2=Większa szansa stworzenia ognia +avatar.ability.light_fire.lvl3=Większa szansa stworzenia ognia +avatar.ability.light_fire.lvl4_1=Ściana ognia ;; Tworzy linię ognia w kierunku na który patrzysz +avatar.ability.light_fire.lvl4_2=Szeroki zasięg ;; Podpal również pobliskie bloki + +avatar.ability.fire_arc=Łuk Ognia +avatar.ability.fire_arc.desc=Stwórz ognisty bat z ognia i rzucaj nim we wrogów. +avatar.ability.fire_arc.lvl1=Tworzy łuk ognia +avatar.ability.fire_arc.lvl2=Porusza się szybciej +avatar.ability.fire_arc.lvl3=O wiele więcej obrażeń +avatar.ability.fire_arc.lvl4_1=Duży ogień ;; Może zrobić więcej ognia po wylądowaniu +avatar.ability.fire_arc.lvl4_2=Boomerang ;; Powraca po pomyślnym uderzeniu + +avatar.ability.flamethrower=Miotacz Ognia +avatar.ability.flamethrower.desc=Generuje potężny strumień płomieni na krótki dystans. Znak rozpoznawczy Maga Ognia. +avatar.ability.flamethrower.lvl1=Atakuj krótkim zasięgiem +avatar.ability.flamethrower.lvl2=Prawie dwa razy tyle płomieni; ale więcej chi +avatar.ability.flamethrower.lvl3=Dalszy zasięg, bardziej precyzyjny +avatar.ability.flamethrower.lvl4_1=Ognisty strumień ;; Skoncentrowane płomienie na niezwykle daleki zasięg +avatar.ability.flamethrower.lvl4_2=Świat spłonie!! ;; Nieskupione płomienie które tworzą wszędzie ogień + +avatar.ability.fireball=Kula Ognia +avatar.ability.fireball.desc=Stwórz świecącą kulę płomieni. Tworzy ognistą eksplozję przy uderzeniu. +avatar.ability.fireball.lvl1=Stwórz podstawową kulę ognia +avatar.ability.fireball.lvl2=Szybsza gdy rzucona +avatar.ability.fireball.lvl3=O wiele więcej obrażeń po bezpośrednim uderzeniu +avatar.ability.fireball.lvl4_1=Skoncentrowana eksplozja ;; Czasami może zniszczyć obsydian +avatar.ability.fireball.lvl4_2=Naładowana eksplozja ;; Zabiera kilka sekund by się naładować, większa eksplozja po naładowaniu + +avatar.ability.water_arc=Łuk Wody +avatar.ability.water_arc.desc=Jeden z pospolitych ataków magów wody. Wystrzel łuk wody we wrogów, ale tylko gdy woda jest w pobliżu. +avatar.ability.water_arc.lvl1=Podstawowy łuk wody +avatar.ability.water_arc.lvl2=Dalszy zasięg pobierania wody +avatar.ability.water_arc.lvl3=O wiele szybszy +avatar.ability.water_arc.lvl4_1=Boomerang ;; Wraca do ciebie jak trafisz cel +avatar.ability.water_arc.lvl4_2=Wodna włócznia ;; Wyłączona grawitacja na 2s po rzuceniu, wolniejsze + +avatar.ability.wave=Fala +avatar.ability.wave.desc=Przywołaj falę wody by zniszczyła twoich wrogów. Działa tylko kiedy są w wodzie. +avatar.ability.wave.lvl1=Wolna fala by utopić wrogów +avatar.ability.wave.lvl2=O wiele więcej obrażeń +avatar.ability.wave.lvl3=O wiele większa +avatar.ability.wave.lvl4_1=Tsunami ;; O wiele większa i oddziałuje na stworzenia znajdujące się na lądzie +avatar.ability.wave.lvl4_2=Potężne fale ;; Bardzo szybkie fale + +avatar.ability.water_bubble=Wodna bańka +avatar.ability.water_bubble.desc=Zawieszenie i transportowanie bańki wody. Może być użyte jako wiadro dalekiego zasięgu. +avatar.ability.water_bubble.lvl1=Wodna bańka krótkiego zasięgu, woda wysycha po zderzeniu +avatar.ability.water_bubble.lvl2=Rzuć bańką dalej +avatar.ability.water_bubble.lvl3=Bańka tworzy stałe źródło wody po wylądowaniu +avatar.ability.water_bubble.lvl4_1=Rzucaj bańkę wody naprawdę daleko +avatar.ability.water_bubble.lvl4_2=Nie zużywa wody do tworzenia bańki - nieskończona woda + +avatar.ability.water_skate=Surfowanie +avatar.ability.water_skate.desc=Biegaj po tafli wody. Użyteczne w unikach, lub po prostu by pochodzić po wodzie. +avatar.ability.water_skate.lvl1=Ślizgaj się po wodzie, nie można używać umiejętności +avatar.ability.water_skate.lvl2=Możesz używać umiejętności podczas surfowania +avatar.ability.water_skate.lvl3=O wiele szybciej surfujesz +avatar.ability.water_skate.lvl4_1=Zbalansowane surfowanie ;; Możesz surfować nawet po płynącej wodzie +avatar.ability.water_skate.lvl4_2=Wodne uderzenie ;; Zmiażdż ziemię po skoku + +avatar.ability.air_gust=Poryw Wiatru +avatar.ability.air_gust.desc=Generuje silny poryw wiatru by odepchnąć wrogów, pozwalając ci skoncentrować się na innym problemie. +avatar.ability.air_gust.lvl1=Zdmuchuje wrogów +avatar.ability.air_gust.lvl2=Połowa odnawiania się umiejętności +avatar.ability.air_gust.lvl3=Mocniejsze odpychanie +avatar.ability.air_gust.lvl4_1=Gaszenie ;; Niszczy słabsze pociski +avatar.ability.air_gust.lvl4_2=Wsysanie ;; Przyciąga wrogów do ciebie + +avatar.ability.air_jump=Powietrzny Skok +avatar.ability.air_jump.desc=Manipulujesz powietrzem wokół siebie by się wystrzelić z ziemi. Perfekcyjne do łapania nic nie spodziewającego się wroga. +avatar.ability.air_jump.lvl1=Skacz przez wiatr +avatar.ability.air_jump.lvl2=Lekko zwiększona moc skoku +avatar.ability.air_jump.lvl3=Jeszcze lepsze skakanie +avatar.ability.air_jump.lvl4_1=Podwójny skok ;; Kosztuje dwa razy więcej chi +avatar.ability.air_jump.lvl4_2=Walnięcie w ziemię ;; Atakuje pobliskich wrogów na ziemi + +avatar.ability.airblade=Ostrze Powietrza +avatar.ability.airblade.desc=Kręcący się dysk powietrza, potężny na tyle by przeciąć ciało. Może być mordercze. +avatar.ability.airblade.lvl1=Podstawowa umiejętność +avatar.ability.airblade.lvl2=Większa szybkość i obrażenia +avatar.ability.airblade.lvl3=Może teraz przecinać bloki +avatar.ability.airblade.lvl4_1=Łańcuchowe ostrze ;; Skacze po wielu wrogach +avatar.ability.airblade.lvl4_2=Przebijacz zbroi ;; Przecina się przez zbroję i kamień + +avatar.ability.air_bubble=Kula Powietrza +avatar.ability.air_bubble.desc=Tworzysz kulę powietrza wokół siebie by obronić się przed nadciągającymi atakami. Jednakże, utrzymywanie jej zabiera dużą ilość chi. +avatar.ability.air_bubble.lvl1=Mały zasięg i odrzut +avatar.ability.air_bubble.lvl2=Średniej wielkośći kula powietrza +avatar.ability.air_bubble.lvl3=Więcej odrzutu +avatar.ability.air_bubble.lvl4_1=Kula pod presją ;; Bardzo duża wielkość +avatar.ability.air_bubble.lvl4_2=Podłoże ;; Lekko się unosisz, możesz to wyłączyć to przez kucanie + +avatar.ability.undefined=??? + +avatar.ui.level0=Poziom I +avatar.ui.level1=Poziom II +avatar.ui.level2=Poziom III +avatar.ui.level3=-MAX- +avatar.ui.path_first=Pierwsza Droga +avatar.ui.path_second=Druga Droga +avatar.ui.unlock=Umiejętność Zablokowana +avatar.ui.unlockDesc.airbending=Użyj Zwoju Magii Powietrza lub Uniwersalnego Zwoju by odblokować +avatar.ui.unlockDesc.firebending=Użyj Zwoju Magii Ognia lub Uniwersalnego Zwoju by odblokować +avatar.ui.unlockDesc.waterbending=Użyj Zwoju Magii Wody lub Uniwersalnego Zwoju by odblokować +avatar.ui.unlockDesc.earthbending=Użyj Zwoju Magii Ziemi lub Uniwersalnego Zwoju by odblokować +avatar.ui.skillsMenu=[translate=avatar.${bending}] - Ulepszanie Zdolności + +avatar.radial.undefined=Wkrótce! +avatar.radial.xp=[translate=avatar.ui.level${level}], ${xp}%% +avatar.radial.max=Poziom IV, [translate=avatar.ui.path_${xp}] +avatar.radial.locked1=Umiejętność Zablokowana +avatar.radial.locked2=Naciśnij ${level} by odblokować +avatar.radial.lockedCreative1=Tryb kreatywny +avatar.radial.lockedCreative2=Zablokowane ale na trybie kreatywnym + +avatar.getBending.title=Odblokuj Magię +avatar.getBending.incompatible=Możesz używać tylko zwojów swojej magii lub uniwersalne +avatar.getBending.guide=Wsadź 3 zwoje tej samej magii lub uniwersalne by odblokować Magię + +avatar.key.none1=Nie przypisano +avatar.key.none2=Kliknij by edytować +avatar.key.set1=%1$s +avatar.key.set2=Kliknij by edytować +avatar.key.editing1=> %1$s < +avatar.key.editing2=ESC by usunąć +avatar.key.conflict1=%1$s +avatar.key.conflict2=Konflikt z %1$s + +death.attack.avatar_earthbendBlock=%2$s roztrzaskał %1$s używając magii ziemi +death.attack.avatar_waterArc=%2$s użył magii wody by sprowadzić do ziemi %1$s +death.attack.avatar_ravine=%2$s zgniótł %1$s w wąwozie +death.attack.avatar_wave=%1$s nie umie surfować +death.attack.avatar_fireball=%2$s wysadził %1$s używając kuli ognia +death.attack.avatar_airblade=%1$s został pokrojony przez %2$s +death.attack.avatar_flamethrower=%1$s właśnie został upieczony przez %2$s!! +death.attack.avatar_groundSmash=%2$s roztrzaskał %1$s do masy celulozowej + +entity.Airbender.name=Mag Powietrza +entity.Firebender.name=Mag Ognia +entity.Waterbender.name=Mag Wody +entity.SkyBison.name=Latający Bizon +entity.OtterPenguin.name=Wydropingwin + +itemGroup.avatar.items=Przedmioty z Avatara + +item.avatarmod:scroll.all.name=Zwój +item.avatarmod:scroll.air.name=Zwój Magii Powietrza +item.avatarmod:scroll.fire.name=Zwój Magii Ognia +item.avatarmod:scroll.earth.name=Zwój Magii Ziemi +item.avatarmod:scroll.water.name=Zwój Magii Wody +item.avatarmod:water_pouch.name=Bukłak +item.avatarmod:bison_whistle.name=Bizoni Gwizdek + +item.avatarmod:bison_saddle.basic.name=Podstawowe Siodło Bizonie +item.avatarmod:bison_saddle.sturdy.name=Silne Siodło Bizonie +item.avatarmod:bison_saddle.studded.name=Wysadzane Siodło Bizonie +item.avatarmod:bison_saddle.majestic.name=Majestatyczne Siodło Bizonie + +item.avatarmod:bison_armor.woven.name=Tkana Zbroja dla Bizona +item.avatarmod:bison_armor.chain.name=Zbroja Kolczy dla Bizona +item.avatarmod:bison_armor.wrought.name=Fasonowana Zbroja dla Bizona +item.avatarmod:bison_armor.legendary.name=Legendarna Zbroja dla Bizona + +avatar.tooltip.water_pouch=%d/5 Wody avatar.tooltip.water_pouch.empty=Pusty \ No newline at end of file diff --git a/src/main/resources/assets/avatarmod/lang/pt_BR.lang b/src/main/resources/assets/avatarmod/lang/pt_br.lang similarity index 100% rename from src/main/resources/assets/avatarmod/lang/pt_BR.lang rename to src/main/resources/assets/avatarmod/lang/pt_br.lang diff --git a/src/main/resources/assets/avatarmod/lang/ru_RU.lang b/src/main/resources/assets/avatarmod/lang/ru_ru.lang similarity index 100% rename from src/main/resources/assets/avatarmod/lang/ru_RU.lang rename to src/main/resources/assets/avatarmod/lang/ru_ru.lang diff --git a/src/main/resources/assets/avatarmod/models/item/airbender_staff.json b/src/main/resources/assets/avatarmod/models/item/airbender_staff.json new file mode 100644 index 0000000000..13142a7071 --- /dev/null +++ b/src/main/resources/assets/avatarmod/models/item/airbender_staff.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "minecraft:items/stick" + } +} diff --git a/src/main/resources/assets/avatarmod/recipes/airbender_staff.json b/src/main/resources/assets/avatarmod/recipes/airbender_staff.json new file mode 100644 index 0000000000..79f9835c73 --- /dev/null +++ b/src/main/resources/assets/avatarmod/recipes/airbender_staff.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + " s ", + "sls", + " s " + ], + "key": { + "l": { + "item": "minecraft:stick" + }, + "s": { + "item": "avatarmod:scroll", + "data": 4 + } + }, + "result": { + "item": "avatarmod:airbender_staff" + } +} diff --git a/src/main/resources/assets/avatarmod/recipes/earthbending_scroll.json b/src/main/resources/assets/avatarmod/recipes/earthbending_scroll.json new file mode 100644 index 0000000000..24f5414aab --- /dev/null +++ b/src/main/resources/assets/avatarmod/recipes/earthbending_scroll.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ebe", + "bpb", + "ebe" + ], + "key": { + "b": { + "item": "minecraft:emerald" + }, + "p": { + "item": "minecraft:paper" + }, + "e": { + "item": "minecraft:experience_bottle" + } + }, + "result": { + "item": "avatarmod:scroll", + "data": 1 + } +} diff --git a/src/main/resources/assets/avatarmod/recipes/firebending_scroll.json b/src/main/resources/assets/avatarmod/recipes/firebending_scroll.json new file mode 100644 index 0000000000..521c26f1a8 --- /dev/null +++ b/src/main/resources/assets/avatarmod/recipes/firebending_scroll.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ebe", + "bpb", + "ebe" + ], + "key": { + "b": { + "item": "minecraft:blaze_rod" + }, + "p": { + "item": "minecraft:paper" + }, + "e": { + "item": "minecraft:experience_bottle" + } + }, + "result": { + "item": "avatarmod:scroll", + "data": 2 + } +} diff --git a/src/main/resources/assets/avatarmod/textures/advancements/background/air.png b/src/main/resources/assets/avatarmod/textures/advancements/background/air.png new file mode 100644 index 0000000000..cc340f3a76 Binary files /dev/null and b/src/main/resources/assets/avatarmod/textures/advancements/background/air.png differ diff --git a/src/main/resources/assets/avatarmod/textures/advancements/background/water.png b/src/main/resources/assets/avatarmod/textures/advancements/background/water.png new file mode 100644 index 0000000000..fa52631572 Binary files /dev/null and b/src/main/resources/assets/avatarmod/textures/advancements/background/water.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/air-bubble.png b/src/main/resources/assets/avatarmod/textures/entity/air-bubble.png index 926b8811c9..ac89f35646 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/air-bubble.png and b/src/main/resources/assets/avatarmod/textures/entity/air-bubble.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/air-gust.png b/src/main/resources/assets/avatarmod/textures/entity/air-gust.png index 2e9363efbf..67f63d0c00 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/air-gust.png and b/src/main/resources/assets/avatarmod/textures/entity/air-gust.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/air-ribbon.png b/src/main/resources/assets/avatarmod/textures/entity/air-ribbon.png index 53e30b49aa..97e3f0020e 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/air-ribbon.png and b/src/main/resources/assets/avatarmod/textures/entity/air-ribbon.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/air_bubble.png b/src/main/resources/assets/avatarmod/textures/entity/air_bubble.png index 2287c1be13..5c0315cb04 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/air_bubble.png and b/src/main/resources/assets/avatarmod/textures/entity/air_bubble.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/airblade.png b/src/main/resources/assets/avatarmod/textures/entity/airblade.png index 2e9363efbf..67f63d0c00 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/airblade.png and b/src/main/resources/assets/avatarmod/textures/entity/airblade.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/cloudburst.png b/src/main/resources/assets/avatarmod/textures/entity/cloudburst.png index 60831421b4..d90ba5a11f 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/cloudburst.png and b/src/main/resources/assets/avatarmod/textures/entity/cloudburst.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/earth_shield.png b/src/main/resources/assets/avatarmod/textures/entity/earth_shield.png index caeeda9158..65b1d34b06 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/earth_shield.png and b/src/main/resources/assets/avatarmod/textures/entity/earth_shield.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/earthspike.png b/src/main/resources/assets/avatarmod/textures/entity/earthspike.png index 40c36f6583..fe492f5bc3 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/earthspike.png and b/src/main/resources/assets/avatarmod/textures/entity/earthspike.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/earthspike_dirt.png b/src/main/resources/assets/avatarmod/textures/entity/earthspike_dirt.png new file mode 100644 index 0000000000..7c94be0c41 Binary files /dev/null and b/src/main/resources/assets/avatarmod/textures/entity/earthspike_dirt.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/earthspike_sand.png b/src/main/resources/assets/avatarmod/textures/entity/earthspike_sand.png new file mode 100644 index 0000000000..a1b18ab6be Binary files /dev/null and b/src/main/resources/assets/avatarmod/textures/entity/earthspike_sand.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/earthspike_sandstone.png b/src/main/resources/assets/avatarmod/textures/entity/earthspike_sandstone.png new file mode 100644 index 0000000000..64e9031eac Binary files /dev/null and b/src/main/resources/assets/avatarmod/textures/entity/earthspike_sandstone.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/earthspike_stone.png b/src/main/resources/assets/avatarmod/textures/entity/earthspike_stone.png new file mode 100644 index 0000000000..5f3646388b Binary files /dev/null and b/src/main/resources/assets/avatarmod/textures/entity/earthspike_stone.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/fire-ribbon.png b/src/main/resources/assets/avatarmod/textures/entity/fire-ribbon.png index 2a9492d2fd..599c4359de 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/fire-ribbon.png and b/src/main/resources/assets/avatarmod/textures/entity/fire-ribbon.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/fireball.png b/src/main/resources/assets/avatarmod/textures/entity/fireball.png index f139817f27..6cea494130 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/fireball.png and b/src/main/resources/assets/avatarmod/textures/entity/fireball.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/ice-prison.png b/src/main/resources/assets/avatarmod/textures/entity/ice-prison.png index f8b3991fec..bb88733359 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/ice-prison.png and b/src/main/resources/assets/avatarmod/textures/entity/ice-prison.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/ice-shard.png b/src/main/resources/assets/avatarmod/textures/entity/ice-shard.png index 8ed2fed1f5..3c08a8e983 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/ice-shard.png and b/src/main/resources/assets/avatarmod/textures/entity/ice-shard.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/ice-shield.png b/src/main/resources/assets/avatarmod/textures/entity/ice-shield.png index b18c0de53a..6794603b58 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/ice-shield.png and b/src/main/resources/assets/avatarmod/textures/entity/ice-shield.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/lightning-ribbon.png b/src/main/resources/assets/avatarmod/textures/entity/lightning-ribbon.png index 8558861ef6..6e056facbd 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/lightning-ribbon.png and b/src/main/resources/assets/avatarmod/textures/entity/lightning-ribbon.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/lightning_spear.png b/src/main/resources/assets/avatarmod/textures/entity/lightning_spear.png index e0bfffc1c9..97dd273a37 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/lightning_spear.png and b/src/main/resources/assets/avatarmod/textures/entity/lightning_spear.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/sand-prison.png b/src/main/resources/assets/avatarmod/textures/entity/sand-prison.png index 0a110370ce..36a03b8168 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/sand-prison.png and b/src/main/resources/assets/avatarmod/textures/entity/sand-prison.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/sandstorm.png b/src/main/resources/assets/avatarmod/textures/entity/sandstorm.png index d1e363f7d4..13e4c2b668 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/sandstorm.png and b/src/main/resources/assets/avatarmod/textures/entity/sandstorm.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/water-ribbon.png b/src/main/resources/assets/avatarmod/textures/entity/water-ribbon.png index 1ca565a464..58342b2c62 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/water-ribbon.png and b/src/main/resources/assets/avatarmod/textures/entity/water-ribbon.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/water_ribbon2.png b/src/main/resources/assets/avatarmod/textures/entity/water_ribbon2.png deleted file mode 100644 index ec9051c221..0000000000 Binary files a/src/main/resources/assets/avatarmod/textures/entity/water_ribbon2.png and /dev/null differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/water_still.png b/src/main/resources/assets/avatarmod/textures/entity/water_still.png index 53bd9f9b9b..8bc7be1564 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/water_still.png and b/src/main/resources/assets/avatarmod/textures/entity/water_still.png differ diff --git a/src/main/resources/assets/avatarmod/textures/entity/wave.png b/src/main/resources/assets/avatarmod/textures/entity/wave.png index bc19fd2833..159f168d9a 100644 Binary files a/src/main/resources/assets/avatarmod/textures/entity/wave.png and b/src/main/resources/assets/avatarmod/textures/entity/wave.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/ability_icons.png b/src/main/resources/assets/avatarmod/textures/gui/ability_icons.png index 0ff10a639b..33f61ddf71 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/ability_icons.png and b/src/main/resources/assets/avatarmod/textures/gui/ability_icons.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/bison_inventory.png b/src/main/resources/assets/avatarmod/textures/gui/bison_inventory.png index 61bf275d3e..d707f6f0d0 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/bison_inventory.png and b/src/main/resources/assets/avatarmod/textures/gui/bison_inventory.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/blurred_icons.png b/src/main/resources/assets/avatarmod/textures/gui/blurred_icons.png index b0785a1370..7b5eeef098 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/blurred_icons.png and b/src/main/resources/assets/avatarmod/textures/gui/blurred_icons.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/box.png b/src/main/resources/assets/avatarmod/textures/gui/box.png index 2ec70e813b..2ee21089d0 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/box.png and b/src/main/resources/assets/avatarmod/textures/gui/box.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/chi.png b/src/main/resources/assets/avatarmod/textures/gui/chi.png index 058030fa86..25d49f09d4 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/chi.png and b/src/main/resources/assets/avatarmod/textures/gui/chi.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/getbending.png b/src/main/resources/assets/avatarmod/textures/gui/getbending.png index 60dbc3f0e9..85e88e2d41 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/getbending.png and b/src/main/resources/assets/avatarmod/textures/gui/getbending.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/shield_health.png b/src/main/resources/assets/avatarmod/textures/gui/shield_health.png index 01f27db8d1..1a605ac3dd 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/shield_health.png and b/src/main/resources/assets/avatarmod/textures/gui/shield_health.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/skillmenu.png b/src/main/resources/assets/avatarmod/textures/gui/skillmenu.png index 4f7903bd9d..95e6711d2d 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/skillmenu.png and b/src/main/resources/assets/avatarmod/textures/gui/skillmenu.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/status_controls.png b/src/main/resources/assets/avatarmod/textures/gui/status_controls.png index 03504208d7..e8b63b1733 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/status_controls.png and b/src/main/resources/assets/avatarmod/textures/gui/status_controls.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/tab/airbending.png b/src/main/resources/assets/avatarmod/textures/gui/tab/airbending.png index 6e203fe5c1..7cc6030035 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/tab/airbending.png and b/src/main/resources/assets/avatarmod/textures/gui/tab/airbending.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/tab/combustionbending.png b/src/main/resources/assets/avatarmod/textures/gui/tab/combustionbending.png index 33ada46da3..8998151531 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/tab/combustionbending.png and b/src/main/resources/assets/avatarmod/textures/gui/tab/combustionbending.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/tab/earthbending.png b/src/main/resources/assets/avatarmod/textures/gui/tab/earthbending.png index eb7e4e8417..36a436aa3b 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/tab/earthbending.png and b/src/main/resources/assets/avatarmod/textures/gui/tab/earthbending.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/tab/firebending.png b/src/main/resources/assets/avatarmod/textures/gui/tab/firebending.png index 66a34d99bb..a22a3af106 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/tab/firebending.png and b/src/main/resources/assets/avatarmod/textures/gui/tab/firebending.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/tab/icebending.png b/src/main/resources/assets/avatarmod/textures/gui/tab/icebending.png index 6e7a23de43..268d64643a 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/tab/icebending.png and b/src/main/resources/assets/avatarmod/textures/gui/tab/icebending.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/tab/lightningbending.png b/src/main/resources/assets/avatarmod/textures/gui/tab/lightningbending.png index 4d37fdd579..355470b9e2 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/tab/lightningbending.png and b/src/main/resources/assets/avatarmod/textures/gui/tab/lightningbending.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/tab/sandbending.png b/src/main/resources/assets/avatarmod/textures/gui/tab/sandbending.png index 58e85ac07c..530a91b5aa 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/tab/sandbending.png and b/src/main/resources/assets/avatarmod/textures/gui/tab/sandbending.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/tab/waterbending.png b/src/main/resources/assets/avatarmod/textures/gui/tab/waterbending.png index 7901f6ebd0..62b0b61b2e 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/tab/waterbending.png and b/src/main/resources/assets/avatarmod/textures/gui/tab/waterbending.png differ diff --git a/src/main/resources/assets/avatarmod/textures/gui/white.png b/src/main/resources/assets/avatarmod/textures/gui/white.png index 2394e1c30b..03d49b398e 100644 Binary files a/src/main/resources/assets/avatarmod/textures/gui/white.png and b/src/main/resources/assets/avatarmod/textures/gui/white.png differ diff --git a/src/main/resources/assets/avatarmod/textures/misc/logo.png b/src/main/resources/assets/avatarmod/textures/misc/logo.png new file mode 100644 index 0000000000..b0d0a42f19 Binary files /dev/null and b/src/main/resources/assets/avatarmod/textures/misc/logo.png differ diff --git a/src/main/resources/assets/avatarmod/textures/misc/logo_956px.png b/src/main/resources/assets/avatarmod/textures/misc/logo_956px.png index a9a6576079..d9b8b74167 100644 Binary files a/src/main/resources/assets/avatarmod/textures/misc/logo_956px.png and b/src/main/resources/assets/avatarmod/textures/misc/logo_956px.png differ diff --git a/src/main/resources/assets/avatarmod/textures/mob/flyingbison.png b/src/main/resources/assets/avatarmod/textures/mob/flyingbison.png index 59da88c7c8..d0789d2e0e 100644 Binary files a/src/main/resources/assets/avatarmod/textures/mob/flyingbison.png and b/src/main/resources/assets/avatarmod/textures/mob/flyingbison.png differ diff --git a/src/main/resources/assets/avatarmod/textures/mob/flyingbison_saddle.png b/src/main/resources/assets/avatarmod/textures/mob/flyingbison_saddle.png index 2173354ddb..21e85e9ab7 100644 Binary files a/src/main/resources/assets/avatarmod/textures/mob/flyingbison_saddle.png and b/src/main/resources/assets/avatarmod/textures/mob/flyingbison_saddle.png differ diff --git a/src/main/resources/assets/avatarmod/textures/mob/otterpenguin.png b/src/main/resources/assets/avatarmod/textures/mob/otterpenguin.png index b3ead3d811..78b9548cd7 100644 Binary files a/src/main/resources/assets/avatarmod/textures/mob/otterpenguin.png and b/src/main/resources/assets/avatarmod/textures/mob/otterpenguin.png differ diff --git a/src/main/resources/assets/avatarmod/textures/particles/electricity.png b/src/main/resources/assets/avatarmod/textures/particles/electricity.png new file mode 100644 index 0000000000..362ed12427 Binary files /dev/null and b/src/main/resources/assets/avatarmod/textures/particles/electricity.png differ diff --git a/src/main/resources/assets/avatarmod/textures/particles/restore.png b/src/main/resources/assets/avatarmod/textures/particles/restore.png new file mode 100644 index 0000000000..cb12ec3146 Binary files /dev/null and b/src/main/resources/assets/avatarmod/textures/particles/restore.png differ diff --git a/src/main/resources/assets/avatarmod/textures/radial/icon_air_burst.png b/src/main/resources/assets/avatarmod/textures/radial/icon_air_burst.png new file mode 100644 index 0000000000..df398fe46b Binary files /dev/null and b/src/main/resources/assets/avatarmod/textures/radial/icon_air_burst.png differ diff --git a/src/main/resources/assets/avatarmod/textures/radial/lightningbending_segment.png b/src/main/resources/assets/avatarmod/textures/radial/lightningbending_segment.png index d141922cc7..6b3bb827cf 100644 Binary files a/src/main/resources/assets/avatarmod/textures/radial/lightningbending_segment.png and b/src/main/resources/assets/avatarmod/textures/radial/lightningbending_segment.png differ diff --git a/src/main/resources/assets/gorecore/lang/en_US.lang b/src/main/resources/assets/gorecore/lang/en_us.lang similarity index 100% rename from src/main/resources/assets/gorecore/lang/en_US.lang rename to src/main/resources/assets/gorecore/lang/en_us.lang diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 832f0bb6c2..c39e2a309d 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -1,15 +1,17 @@ -{ - "modListVersion": 2, - "modList": [{ +[ + { "modid": "avatarmod", "name": "Avatar Mod: Out of the Iceberg", "description": "A large, work-in-progress expansion to Minecraft which will add bending and much more in Minecraft, inspired by the TV show Avatar: The Last Airbender.", - "version": "${version}", - "mcversion": "${mcversion}", - "url": "http://avatarmod2.wikia.com", - "updateUrl": "http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/wip-mods/2726598", - "authorList": [ "CrowsOfWar", "EduMC", "MadWrist", "Captn_Dubz", "talhnation", "Sean_Amor", "Ferrujado" ], - "credits": "\nCode by CrowsOfWar\nArt by EduMC\nSky bison saddle/armor textures by CrowsOfWar\nChi bar by Sean_Amor\nTranslations by MadWrist\nSky bison & saddle model by Captn_Dubz\nOtterpenguin model by talhanation\nSkill menu tabs from FavouriteDragon, adjusted for ui by CrowsOfWar\nModels animated by CrowsOfWar\nTranslations from Ferrujado\n\nIdeas from the community", - "logoFile": "assets/avatarmod/textures/misc/logo_956px.png" - }] -} + "version": "a5.8", + "mcversion": "1.12.2", + "url": "http://avatar.amuzil.com", + "authorList": [ + "CrowsOfWar", + "Mahtaran", + "FavouriteDragon" + ], + "credits": "See credits.txt (On the Github)", + "logoFile": "assets/avatarmod/textures/misc/logo.png" + } +] diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta new file mode 100644 index 0000000000..2d3e00b05a --- /dev/null +++ b/src/main/resources/pack.mcmeta @@ -0,0 +1,7 @@ +{ + "pack": { + "description": "Avatar Mod Resources", + "pack_format": 3, + "_comment": "A pack_format of 3 should be used starting with Minecraft 1.11. All resources, including language files, should be lowercase (eg: en_us.lang). A pack_format of 2 will load your mod resources with LegacyV2Adapter, which requires language files to have uppercase letters (eg: en_US.lang)." + } +}