How to convert a block into its class -Canarymod - java

I have been programming a plugin to move someone up when they right click a sign with certain text on on it but to find the text I need to convert the Block class to the sign class and use the getTextOnLine(); function here is my Java code
public class CowShooter extends EZPlugin implements PluginListener {
#Override
public boolean enable() {
Canary.hooks().registerListener(this, this);
return super.enable(); // Call parent class's version too.
}
#HookHandler
public void SignChangeHook(BlockRightClickHook event) {
Player player = event.getPlayer();
Block block = event.getBlockClicked();
if (block.getType() == BlockType.SignPost || block.getType() == BlockType.WallSign) {
Bad code
Sign sign = event.getBlockClicked();
if (sign.getTextOnLine(1) == "TP") {
Location loc = player.getLocation();
int playerX = (int) loc.getX();
int playerY = (int) loc.getY();
int playerZ = (int) loc.getZ();
loc.setY(playerY+10);
player.teleportTo(loc);
}
}
}
}
Here is the folder that the source code is in Source code for canarymod

Get the co-ordinates of the block and set them in the sign class
Location loc = player.getLocation();
loc.setX(event.getBlockClicked().getX());
loc.setZ(event.getBlockClicked().getZ());
loc.setY(event.getBlockClicked().getY());
World world = loc.getWorld();
Sign sign = (Sign)world.getTileEntity(world.getBlockAt(loc));

Related

How to modify sharpness damage in minecraft 1.12.2

How can I change the damage of the enchant sharpness in minecraft 1.12.2? I have tried this method but I don't understand how to go on
private RubySharpnessFixer plugin;
public EnchantmentWeaponDamageCustom(RubySharpnessFixer plugin, Rarity rarity, int i, EnumItemSlot... enumItemSlots) {
super(rarity, i, enumItemSlots);
this.plugin = plugin;
}
public float a(int i, EnumMonsterType enummonstertype) {
return (this.a == 0) ? (float)(Math.max(1, i) * plugin.getConfig().getDouble("damage-per-level")) : ((this.a == 1 && enummonstertype == EnumMonsterType.UNDEAD) ? (i * 2.5F) : ((this.a == 2 && enummonstertype == EnumMonsterType.ARTHROPOD) ? (i * 2.5F) : 0.0F));
}
public boolean hook() {
EnchantmentWeaponDamageCustom enchantmentWeaponDamageCustom = new EnchantmentWeaponDamageCustom(plugin, Rarity.COMMON, 16, EnumItemSlot.MAINHAND);
}
} ```
There is multiple ways :
1. In-game: Command
attribute #s minecraft:generic.attack_damage modifier add 0-0-0-0-0 attribute_name .25 add
(replace the 0-0-0-0-0 by a valid UUID)
There is a reddit post that explain it.
But I think it's not what you are looking for.
2. Plugin: NMS & reflection
Firstly, you have to change the enchant currently registered. Such as it's not authorized by default, we have to use reflection.
// import
import java.lang.reflect.Field;
import org.bukkit.craftbukkit.v1_12_R1.enchantments.CraftEnchantment;
import org.bukkit.enchantments.Enchantment;
// now the code :
try {
Enchantment enchantToChange = Enchantment.DAMAGE_ALL; // the enchant that we want to change
// SharpnessModifier is a class that is showed after
SharpnessModifier sharpness = new SharpnessModifier(0);
net.minecraft.server.v1_12_R1.Enchantment.enchantments.a(16, new MinecraftKey("sharpness"), sharpness); // add enchants to NMS class
CraftEnchantment newEnchant = new CraftEnchantment(sharpness);
Field byNameField = Enchantment.class.getDeclaredField("byName"); // enchant by name
byNameField.setAccessible(true);
Map<String, Enchantment> byName = (Map<String, Enchantment>) byNameField.get(null);
byName.put(enchantToChange.getName(), newEnchant);
Field byIdField = Enchantment.class.getDeclaredField("byId"); // enchant by ID
byIdField.setAccessible(true);
Map<Integer, Enchantment> byId = (Map<Integer, Enchantment>) byIdField.get(null);
byId.put(enchantToChange.getId(), newEnchant);
} catch (Exception e) {
e.printStackTrace();
}
Then, you have to create a new class that will manage all rules that you want to define for this enchant.
import net.minecraft.server.v1_12_R1.EnchantmentWeaponDamage;
import net.minecraft.server.v1_12_R1.EnumMonsterType;
import net.minecraft.server.v1_12_R1.ItemStack;
public class SharpnessModifier extends EnchantmentWeaponDamage {
public SharpnessModifier(int i){
super(Rarity.COMMON, i);
}
#Override
public int getMaxLevel() {
return 200;
}
#Override
public float a(int i, EnumMonsterType enumMonsterType){
// it's here that you will have what you want. You can calculate the damage
// default calculation :
/*
if (a == 0)
return (float) i * 5.0F;
if (a == 1 && enumMonsterType == EnumMonsterType.UNDEAD)
return (float) i * 2.5F;
if (a == 2 && enumMonsterType == EnumMonsterType.ARTHROPOD)
return (float) i * 2.5F;
else
return 0.0F;
*/
return Float.MAX_VALUE; // max damage, just to try. I just OS a wither
}
#Override
public boolean canEnchant(ItemStack item) {
return true; // allow for all item
}
}
3. Plugin: Damage event
This can also be done with packet.
You have to intercept damage event, and change damage value if player have sharpness.
#EventHandler
public void a(EntityDamageByEntityEvent e) {
if(e.getDamager() instanceof Player) {
Player p = (Player) e.getDamager();
ItemStack item = p.getItemInHand();
if(item.containsEnchantment(Enchantment.DAMAGE_ALL)) {
// manage damage with "e.setDamage(damage);"
}
}
}
It's not a very good solution because other things can interact with damage: critical, time (1.9+ pvp) ...

Minecraft add new potion effects from custom potion effect

Currently trying to create a potion effect that once it runs out of time, applies other potion effects to the player. Seemed simple enough yet I found a few errors and bugs trying to accomplish this,
Directly trying to add the effect
#Override
public void performEffect(EntityLivingBase entity, int amplifier){
if (entity instanceof EntityPlayer)
{
EntityPlayer player = (EntityPlayer)entity;
if(player != null){
if(player.getActivePotionEffect(PotionRegistry.effectBuzz) != null){
int duraction = player.getActivePotionEffect(PotionRegistry.effectBuzz).getDuration();
if(duration <= 2){
player.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 1200));
}
}
}
}
}
Needless to say this produces this error
[16:10:04] [Server thread/ERROR]: Encountered an unexpected exception
net.minecraft.util.ReportedException: Ticking player
at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:212)
~[NetworkSystem.class:?]
at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:807)
~[MinecraftServer.class:?]
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:688)
~[MinecraftServer.class:?]
at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156)
~[IntegratedServer.class:?]
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:537)
[MinecraftServer.class:?]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_161]
Caused by: java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(Unknown Source) ~[?:1.8.0_161]
at java.util.HashMap$KeyIterator.next(Unknown Source) ~[?:1.8.0_161]
at net.minecraft.entity.EntityLivingBase.updatePotionEffects(EntityLivingBase.java:650)
~[EntityLivingBase.class:?]
at net.minecraft.entity.EntityLivingBase.onEntityUpdate(EntityLivingBase.java:383)
~[EntityLivingBase.class:?]
at net.minecraft.entity.Entity.onUpdate(Entity.java:436) ~[Entity.class:?]
at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:2144)
~[EntityLivingBase.class:?]
at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:260)
~[EntityPlayer.class:?]
at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:345)
~[EntityPlayerMP.class:?]
at net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:174)
~[NetHandlerPlayServer.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:216)
~[NetworkDispatcher$1.class:?]
at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:309)
~[NetworkManager.class:?]
at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:197)
~[NetworkSystem.class:?]
... 5 more
Where as if I run this in a tick event
In CommonProxy
MinecraftForge.EVENT_BUS.register(new EventManager());
And then For the EventManager itself
public class EventManager {
public static PotionEffect potion = new PotionEffect(MobEffects.WEAKNESS, 1200);
public static PotionEffect potion2 = new PotionEffect(MobEffects.HUNGER, 600);
public static PotionEffect potion3 = new PotionEffect(MobEffects.UNLUCK, 1200);
#SubscribeEvent
public void onTick(WorldTickEvent event){
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
World world = Minecraft.getMinecraft().theWorld;
if(player != null){
boolean hasEffect = player.isPotionActive(PotionRegistry.effectBuzz);
int applyIt = 0;
if(hasEffect){
applyIt = 1;
} else if(!player.isPotionActive(potion.getPotion()) && applyIt == 1){
applyIt = 2;
} else {
applyIt = 0;
}
if(player != null && applyIt == 2){
player.addPotionEffect(potion);
}
}
}
}
This works, yet the effects are infinite.
You're performing your action whilst the potion effects are being looped. This is akin to modifying an array whilst iterating it. Don't do that.
Also, don't perform actions like potion effects client side.
The ONLY thing to do client side is graphics and user input/output.
Things like potions must be handled on the server, otherwise the server will overwrite your actions on the next update packet.
Just set a flag in your ExtendPlayer entity, and then onTick or player update event check for that flag existance and then add the potions.
#Override
public void performEffect(EntityLivingBase entity, int amplifier){
if (entity instanceof EntityPlayer)
{
EntityPlayer player = (EntityPlayer)entity;
if(player != null){
if(player.getActivePotionEffect(PotionRegistry.effectBuzz) != null){
int duraction = player.getActivePotionEffect(PotionRegistry.effectBuzz).getDuration();
if(duration <= 2){
ExtendedPlayer ePlayer = ExtendedPlayer.get(player);
ePlayer.enableBuzz();
}
}
}
}
}
Something akin to your Extended player
public class ExtendedPlayer implements IExtendedEntityProperties {
... Extended player setup here
protected boolean startBuzz = false;
public void enableBuzz()
{
this.startBuzz = true;
}
public static final ExtendedPlayer get(EntityPlayer player) {
return (ExtendedPlayer) player.getExtendedProperties("MuddymansExtendedPlayer");
}
public EntityPlayer getPlayer() {
return this.player;
}
/**
* Updates anything that needs to be updated each tick
* NOT called automatically, so you must call it yourself from LivingUpdateEvent or a TickHandler
*/
public void onUpdate() {
if(!player.worldObj.isRemote) {
if(this.enableBuzz) {
Player player = this.getPlayer()
player.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 1200));
player.addPotionEffect(new PotionEffect(MobEffects.HUNGER, 600));
player.addPotionEffect(new PotionEffect(MobEffects.UNLUCK, 1200));
this.startBuzz = false;
}
}
}
}
Call the exteded player update event from an event handler
#SubscribeEvent
public void livingTick(final LivingUpdateEvent event) {
if (event.entity != null && event.entity instanceof EntityPlayer) {
if(!event.entity.isDead) {
ExtendedPlayer.get((EntityPlayer)event.entity).onUpdate();
}
}

Processing - How to handle SVG coloring when saving?

I am working on how to load and save SVG files. So far I've figured out how to load, but a couple issues come up when saving the sketch directly to a SVG file.
import processing.svg.*;
PShape fbLogo;
PShape legoMan;
PShape load;
PGraphics pgDrawing;
boolean recording;
int count = 1;
void setup() {
size(640,360);
fbLogo = loadShape("fb-art.svg");
legoMan = loadShape("legoMan.svg");
}
void draw() {
if (recording) {
beginRecord(SVG, "test.svg");
}
shape(fbLogo,110,90,100,100);
shape(legoMan,200,40);
if (recording) {
endRecord();
recording = false;
}
}
void keyPressed() {
if (key == 's') {
recording = true;
println ("Sketch saved to .svg");
}
}
1) I get an error which reads textMode(SHAPE) is not supported by this renderer. I'm guessing it's because of how begin- and endRecord() handle file extensions, but I could be wrong.
2) The coloring in the output file is off. For example, this is how it actually should look like:
But this is how it outputs to:

How to check if a player right-clicked another player

Looking for the right event to work with. I want to check if a player right-clicked another player.
This is what i have so far (doesn't work. Not getting into the if or the else statement:
public void onPlayerRightClicks(PlayerInteractEntityEvent e) {
Player p=e.getPlayer();
if(e.getRightClicked() instanceof Player) p.sendMessage("You have rightclicked a player.");
else p.sendMessage("You didn't hit anyone with your spell");
}
Found the answer to the question by combining my own code with codes from another answer on a similar question:
#SuppressWarnings("deprecation")
#EventHandler
public void onPlayerClick(PlayerInteractEvent e) {
Player p=e.getPlayer();
NBTItem item = new NBTItem(p.getItemInHand());
Entity en=getNearestEntityInSight(p,5);
if(e.getAction()==Action.RIGHT_CLICK_AIR && en instanceof Player) p.sendMessage("You have rightclicked a player.");
else p.sendMessage("You didn't hit anyone with your spell");
}
public static Entity getNearestEntityInSight(Player player, int range) {
ArrayList<Entity> entities = (ArrayList<Entity>) player.getNearbyEntities(range, range, range);
ArrayList<Block> sightBlock = (ArrayList<Block>) player.getLineOfSight(null, range);
ArrayList<Location> sight = new ArrayList<Location>();
for (int i = 0;i<sightBlock.size();i++)
sight.add(sightBlock.get(i).getLocation());
for (int i = 0;i<sight.size();i++) {
for (int k = 0;k<entities.size();k++) {
if (Math.abs(entities.get(k).getLocation().getX()-sight.get(i).getX())<1.3) {
if (Math.abs(entities.get(k).getLocation().getY()-sight.get(i).getY())<1.5) {
if (Math.abs(entities.get(k).getLocation().getZ()-sight.get(i).getZ())<1.3) {
return entities.get(k);
}
}
}
}
}
return null;
}
Even though it works, i don't think it's an optimal answer, as there should be an event that can check whether or not a player rightclicked or at least leftclicked another player. The getNearestEntitySight method finds the closest entity in the player's sight. I combined it with my code which runs when a player rightclicks, using the PlayerInteractEvent.
Try this:
#EventHandler
public void onPlayerInteractEntity(final PlayerInteractAtEntityEvent e) {
final Player p = e.getPlayer();
if (e.getRightClicked() instanceof Player) {
final Player clicked = (Player) e.getRightClicked();
// DO STUFF
}
}

libgdx lag when sound.play() while collecting apple

I'am doing simple libgdx game. I have lag (game stop for 0. 5 sec) when i use sound.play()
edit this bug apear on android 4.0 on 2.3 everything is running fine.
method. I play sound by this code:
if(CollisionDetector.detect(touchArea, hoodie.getTouchArea())){
GameScreen.totalScore++;
setPosition();
System.out.println("played");
Assets.eatSound.play();
}
And i use this method to load sound:
static long waitForLoadCompleted(Sound sound,float volume) {
long id;
while ((id = sound.play(volume)) == -1) {
long t = TimeUtils.nanoTime();
while (TimeUtils.nanoTime() - t < 100000000);
}
return id;
}
What am i doing wrong? Or what can i do to fix this lag ?
edit:
I have just tried to do thread with sound.play() but it also doesn't work:
new Thread(new Runnable() {
#Override
public void run() {
// do something important here, asynchronously to the rendering thread
// post a Runnable to the rendering thread that processes the result
Gdx.app.postRunnable(new Runnable() {
#Override
public void run() {
// process the result, e.g. add it to an Array<Result> field of the ApplicationListener.
eatSound2.play();
}
});
}
}).start();
My Sound asset class looks like this but i still have lag with sound.
package com.redHoodie;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.utils.Disposable;
public class SoundEffect implements Disposable {
private static final int WaitLimit = 1000;
private static final int ThrottleMs = 100;
Sound eatSound;
Sound endSound;
public SoundEffect(){
eatSound = Gdx.audio.newSound(Gdx.files.internal("eatSound.ogg"));
endSound = Gdx.audio.newSound(Gdx.files.internal("sadend.wav"));
checkedPlay(eatSound);
}
protected long checkedPlay (Sound sound) {
return checkedPlay(sound, 1);
}
protected long checkedLoop (Sound sound) {
return checkedLoop(sound, 1);
}
protected long checkedPlay (Sound sound, float volume) {
int waitCounter = 0;
long soundId = 0;
boolean ready = false;
while (!ready && waitCounter < WaitLimit) {
soundId = sound.play(volume);
ready = (soundId != 0);
waitCounter++;
try {
Thread.sleep(ThrottleMs);
} catch (InterruptedException e) {
}
}
return soundId;
}
protected long checkedLoop (Sound sound, float volume) {
int waitCounter = 0;
long soundId = 0;
boolean ready = false;
while (!ready && waitCounter < WaitLimit) {
soundId = sound.loop(volume);
ready = (soundId != 0);
waitCounter++;
try {
Thread.sleep(ThrottleMs);
} catch (InterruptedException e) {
}
}
return soundId;
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
}
I had the same problem. It was because my .mp3 file was too short. Mine was 0.167 seconds long. I added 1.2 seconds of silence with Audacity, and it fixed the problem.
Lately I run into the same issue (except I'm using wav instead mp3 files). My app was lagging when I play many (like 10 or 20) sounds at the same time (same render method). "Solved" this by playing only 1 sound at the time. Generally it's hard to distinct many sounds at the same time. Also on desktop it works fine, but problem appears on android (9 or 8).
If someone still facing this issue as me there is the alternative solution with one limitation: no option to use sound id.
You can change default LibGDX behavior and use AsynchronousAndroidAudio by overriding this method in your AndroidLauncher class:
#Override
public AndroidAudio createAudio(Context context, AndroidApplicationConfiguration config) {
return new AsynchronousAndroidAudio(context, config);
}
See the official documentation for more info and also the pull request
Also, if for any reasons you need sound id you can take this implementation as an example and find a workaround for your project.
Fix is available starting from LibGDX 1.9.12

Categories

Resources