Jumppad Plugin

Hi there, I am a server owner and I need to make a jumppad plugin. SpongeApi uses Vector3d from Flow Math, and I find it extremely complex to learn, because there is no documentation on the Flow Math library. The code below is a snippet I took from the status of Sponge Two example plugin, which shoots fireballs out of a stick.


private static Vector3d getVelocity(Player player, double multiplier) {
        double yaw = ((player.getRotation().getX() + 90) % 360);
        double pitch = ((player.getRotation().getY()) * -1);
        double rotYCos = Math.cos(Math.toRadians(pitch));
        double rotYSin = Math.sin(Math.toRadians(pitch));
        double rotXCos = Math.cos(Math.toRadians(yaw));
        double rotXSin = Math.sin(Math.toRadians(yaw));
        return new Vector3d((multiplier * rotYCos) * rotXCos,
                multiplier * rotYSin, (multiplier * rotYCos) * rotXSin);
    }
 

I do not understand what this code does, and should I be using this code on my jumppad plugin? I would like to thank the Sponge community in advance for their helpfulness.

Preview of my code for my Hub plugin. Tell me if any code is badly coded or incorrect.


/*
SpongePowered Plugin (c)Blockenton Server 2015 
SpongePowered is a registered trademark of the non-profit
Sponge Foundation 

This Plugin may not be used it any form outside the Blockenton
City server and may not be distributed, commercially or
privately in any form or way.

Thanks to authors:
Jeff Chen 
*/
package com.blockenton.server.plugins.hub;

import com.blockenton.server.plugins.hub.event.HubJoinEvent;

import java.util.Map;
import java.util.WeakHashMap;

import org.slf4j.Logger;

import org.spongepowered.api.entity.player.Player;
import org.spongepowered.api.event.state.*;
import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.util.event.Subscribe;

import com.flowpowered.math.vector.Vector3d;

import com.google.common.base.Optional;
import com.google.inject.Inject;
import org.spongepowered.api.Game;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.EntityTypes;
import org.spongepowered.api.entity.projectile.Projectile;
import org.spongepowered.api.entity.projectile.Snowball;
import org.spongepowered.api.entity.projectile.explosive.fireball.Fireball;
import org.spongepowered.api.event.entity.living.player.PlayerInteractEvent;
import org.spongepowered.api.item.ItemType;
import org.spongepowered.api.item.ItemTypes;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.plugin.PluginContainer;
import org.spongepowered.api.text.format.TextColors;
import org.spongepowered.api.text.format.TextStyles;
import org.spongepowered.api.text.message.Messages;
import org.spongepowered.api.util.event.Order;
import org.spongepowered.api.world.World;

/**
 * The main plugin class.
 * @author Jeff Chen
 */
@Plugin(id= "com.blockenton.server.hub.hub", name= "BlockentonHub", version= "0.0.1-SNAPSHOT")
public class JavaPlugin {
    
    private final WeakHashMap funCannonMap = new WeakHashMap();
    
    private Player player;
    
    private Logger logger;
    
    public Logger getLogger() {
        return logger;
    }
    
    @Inject
    private PluginContainer container;
    
    @Inject
    private Game game;
       
    private static Vector3d getVelocity(Player player, double multiplier) {
        double yaw = ((player.getRotation().getX() + 90) % 360);
        double pitch = ((player.getRotation().getY()) * -1);
        double rotYCos = Math.cos(Math.toRadians(pitch));
        double rotYSin = Math.sin(Math.toRadians(pitch));
        double rotXCos = Math.cos(Math.toRadians(yaw));
        double rotXSin = Math.sin(Math.toRadians(yaw));
        return new Vector3d((multiplier * rotYCos) * rotXCos,
                multiplier * rotYSin, (multiplier * rotYCos) * rotXSin);
    }
    
    public void spawnFunCannon1(Player player) {
        World world = player.getWorld();
        Optional optional = world.createEntity(EntityTypes.SNOWBALL, player.getLocation().getPosition()
                .add(Math.cos((player.getRotation().getX() - 90) % 360) * 0.2, 1.8, 
                        Math.sin((player.getRotation().getX() - 90) % 360) * 0.2));
        if (optional.isPresent()) {
            Vector3d velocity = getVelocity(player, 1.5D);
            optional.get().setVelocity(velocity);
            Snowball fireball = (Snowball) optional.get();
            fireball.setShooter(player);
            fireball.setDamage(0);
            world.spawnEntity(fireball);
            fireball.setFireTicks(100);
        }
    }
    
    public void spawnFunCannon2(Player player) {
        World world = player.getWorld();
        Optional optional = world.createEntity(EntityTypes.FIREBALL, player.getLocation().getPosition()
                .add(Math.cos((player.getRotation().getX() - 90) % 360) * 0.2, 1.8, 
                        Math.sin((player.getRotation().getX() - 90) % 360) * 0.2));
        if (optional.isPresent()) {
            Vector3d velocity = getVelocity(player, 1.5D);
            optional.get().setVelocity(velocity);
            Fireball fireball = (Fireball) optional.get();
            fireball.setShooter(player);
            fireball.setDamage(0);
            world.spawnEntity(fireball);
            fireball.setFireTicks(100);
        }   
    }
    
    @Subscribe
    public void onServerStart(ServerStartedEvent event) {
        
    }
    
    @Subscribe(order = Order.POST)
    public void onInteract(PlayerInteractEvent event) {
        this.player = event.getPlayer();
        Optional option = player.getItemInHand();
        
        if (option.isPresent()) {
            ItemType itemType = option.get().getItem();
            if (itemType.equals(ItemTypes.COMPASS)) {
                
            }
            if (itemType.equals(ItemTypes.BLAZE_ROD)) {
                int random = (int) Math.random();
                if (random < 5) {
                    spawnFunCannon1(player);
                }
                else {
                    
                }
            }
        }
    }
   
    /* 
    PlayerJoinEvent.
    */
    @Subscribe
    public void onHubJoin(HubJoinEvent event) {
        
        this.player = event.getPlayer();
        
        /*
        This code will
        create the welcome message:
        
        __________
        Welcome,  to the Blockenton City Server!
        __________
        
        Type /rules for rules.
        Use your compass to join minigames.
        */
        player.sendMessage(Messages.of("__________").builder().style(TextStyles.BOLD).color(TextColors.DARK_BLUE).build());
        player.sendMessage(Messages.of("Welcome, ").builder().style(TextStyles.ITALIC).color(TextColors.GOLD)
                .append(Messages.builder(player.getName()).style(TextStyles.BOLD).color(TextColors.GREEN)
                        .append(Messages.builder(" to the Blockenton City Server!").style(TextStyles.ITALIC).color(TextColors.GOLD)
                                .build())
                        .build())
                .build());
        player.sendMessage(Messages.of("__________").builder().style(TextStyles.BOLD).color(TextColors.DARK_BLUE).build());
    }
    
}

/**

* Thread FunCannonUpdate<. * @author CHEN */ class FunCannonUpdate implements Runnable { @Override public void run() { } }

I couldn’t really say much about the code quality (as I haven’t gotten around to messing with the sponge API yet) however I can definitely say the code is fairly messy and you might wanna clean it up a bit.

There is way too much going on in that one class. Code modularity is important for many reasons, but in this case separating functionality into pieces that should work on their own into separate class files is a good way to help you understand your structure. Right now, that looks less like an object and more like a procedural script. So, try and focus on understanding your overall structure. Hope that helps.

2 Likes

Loggers are injectable into the main class.

@Inject
private Logger logger;

In spawnFunCannon1 && spawnFunCannon2 methods, you duplicated work:

player.getLocation().getPosition() .add(Math.cos((player.getRotation().getX() - 90) % 360) * 0.2, 1.8, Math.sin((player.getRotation().getX() - 90) % 360) * 0.2));

I would suggest creating a method to do the math for you, plus it will look more pleasing. That way, if you ever want to change it, you only have to change it in one spot. so it may look like (pseudo code):

double x = player.geRotation().getX(); player.getLocation().getPostion().add(addCos(x), addSin(x));

Doesn’t that look a LOT cleaner? But that’s just my opinion based off of:

3 Likes