mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Gems slowly lose their power over time; added a gem to transfer power over long distances
This commit is contained in:
parent
736e9a3f11
commit
55b050a992
13 changed files with 352 additions and 53 deletions
|
@ -7,7 +7,6 @@ import com.minelittlepony.unicopia.UItems;
|
|||
import com.minelittlepony.unicopia.item.ICastable;
|
||||
import com.minelittlepony.unicopia.network.EffectSync;
|
||||
import com.minelittlepony.unicopia.spell.ICaster;
|
||||
import com.minelittlepony.unicopia.spell.ILevelled;
|
||||
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
||||
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||
|
||||
|
@ -31,7 +30,7 @@ import net.minecraft.util.SoundCategory;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntitySpell extends EntityLiving implements IMagicals, ICaster<EntityLivingBase>, ILevelled {
|
||||
public class EntitySpell extends EntityLiving implements IMagicals, ICaster<EntityLivingBase> {
|
||||
|
||||
private EntityLivingBase owner = null;
|
||||
|
||||
|
@ -57,14 +56,20 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
|||
enablePersistence();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInRangeToRenderDist(double distance) {
|
||||
if (getCurrentLevel() > 0) {
|
||||
distance /= getCurrentLevel();
|
||||
}
|
||||
return super.isInRangeToRenderDist(distance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEffect(IMagicEffect effect) {
|
||||
effectDelegate.set(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMagicEffect getEffect() {
|
||||
return effectDelegate.get();
|
||||
}
|
||||
|
@ -162,6 +167,19 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
|||
super.onUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
if (getCurrentLevel() > 0 && !world.isRemote && world.rand.nextInt(200) == 0) {
|
||||
addLevels(-1);
|
||||
if (getCurrentLevel() <= 0) {
|
||||
setDead();
|
||||
}
|
||||
}
|
||||
|
||||
if (overLevelCap()) {
|
||||
if (world.rand.nextInt(10) == 0) {
|
||||
spawnExplosionParticle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -175,6 +193,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
|||
//super.updateFallState(y, onGround = this.onGround = true, state, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attackEntityFrom(DamageSource source, float amount) {
|
||||
if (!world.isRemote) {
|
||||
setDead();
|
||||
|
@ -200,6 +219,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDead() {
|
||||
if (hasEffect()) {
|
||||
getEffect().setDead();
|
||||
|
@ -207,6 +227,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
|||
super.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumActionResult applyPlayerInteraction(EntityPlayer player, Vec3d vec, EnumHand hand) {
|
||||
if (Predicates.MAGI.test(player)) {
|
||||
ItemStack currentItem = player.getHeldItem(EnumHand.MAIN_HAND);
|
||||
|
@ -240,7 +261,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
|||
addLevels(1);
|
||||
|
||||
if (!world.isRemote) {
|
||||
if ((rand.nextFloat() * getCurrentLevel()) > 10 || overLevelCap()) {
|
||||
if (overLevelCap() || (rand.nextFloat() * getCurrentLevel()) > 10) {
|
||||
world.createExplosion(this, posX, posY, posZ, getCurrentLevel()/2, true);
|
||||
setDead();
|
||||
return false;
|
||||
|
@ -257,7 +278,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
|||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return getEffect().getMaxLevel();
|
||||
return hasEffect() ? getEffect().getMaxLevel() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -267,7 +288,13 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
|||
|
||||
@Override
|
||||
public void setCurrentLevel(int level) {
|
||||
dataManager.set(LEVEL, Math.min(level, 0));
|
||||
level = Math.max(level, 0);
|
||||
if (hasEffect()) {
|
||||
getEffect().setCurrentLevel(level);
|
||||
level = getEffect().getCurrentLevel();
|
||||
}
|
||||
|
||||
dataManager.set(LEVEL, level);
|
||||
}
|
||||
|
||||
public boolean overLevelCap() {
|
||||
|
|
|
@ -87,6 +87,14 @@ public class ModelGem extends ModelBase {
|
|||
floatOffset += spell.hoverStart;
|
||||
floatOffset *= 180 / (float)Math.PI;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
if (spell.overLevelCap()) {
|
||||
GlStateManager.translate(Math.sin(stutter) / 5, 0, Math.cos(stutter) / 5);
|
||||
|
||||
GlStateManager.rotate((float)Math.sin(stutter), 0, 1, 0);
|
||||
}
|
||||
|
||||
GlStateManager.rotate(floatOffset, 0, 1, 0);
|
||||
|
||||
body.render(scale);
|
||||
|
@ -99,10 +107,35 @@ public class ModelGem extends ModelBase {
|
|||
|
||||
Color.glColor(SpellRegistry.instance().getSpellTint(spell.getEffect().getName()), 1);
|
||||
|
||||
GlStateManager.scale(1.2F, 1.2F, 1.2F);
|
||||
GlStateManager.translate(0, -0.2F, 0);
|
||||
|
||||
body.render(scale);
|
||||
int tiers = Math.min(spell.getCurrentLevel(), 5);
|
||||
|
||||
for (int i = 0; i <= tiers; i++) {
|
||||
float grow = (1 + i) * 0.2F;
|
||||
|
||||
GlStateManager.scale(1 + grow, 1 + grow, 1 + grow);
|
||||
GlStateManager.translate(0, -grow, 0);
|
||||
renderOverlay(grow, scale);
|
||||
|
||||
if (i == 5) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.rotate(-floatOffset * 0.9F, 0, 1, 0);
|
||||
GlStateManager.translate(0.6F, 0.8F, 0);
|
||||
GlStateManager.scale(0.4F, 0.4F, 0.4F);
|
||||
renderOverlay(grow, scale);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
for (int i = spell.getCurrentLevel(); i > 0; i--) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.rotate(floatOffset / i, 0, 1, 0);
|
||||
GlStateManager.translate(0.6F, 0, 0);
|
||||
renderOverlay(0.6F, scale);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
setLightingConditionsBrightness(entity.getBrightnessForRender());
|
||||
|
||||
|
@ -112,6 +145,13 @@ public class ModelGem extends ModelBase {
|
|||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
protected void renderOverlay(float grow, float scale) {
|
||||
|
||||
|
||||
body.render(scale);
|
||||
|
||||
}
|
||||
|
||||
private void setLightingConditionsBrightness(int brightness) {
|
||||
int texX = brightness % 0x10000;
|
||||
int texY = brightness / 0x10000;
|
||||
|
|
|
@ -33,7 +33,7 @@ public class EffectSync<T extends EntityLivingBase> {
|
|||
String id = comp.getString("effect_id");
|
||||
if (effect == null || id != effect.getName()) {
|
||||
effect = SpellRegistry.instance().createEffectFromNBT(comp);
|
||||
} else {
|
||||
} else if (owned.getEntity().world.isRemote) {
|
||||
effect.readFromNBT(comp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,10 +144,10 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
setEffect(null);
|
||||
} else {
|
||||
if (entity.getEntityWorld().isRemote) { // && entity.getEntityWorld().getWorldTime() % 10 == 0
|
||||
getEffect().render(this);
|
||||
getEffect().renderOnPerson(this);
|
||||
}
|
||||
|
||||
if (!getEffect().update(this)) {
|
||||
if (!getEffect().updateOnPerson(this)) {
|
||||
setEffect(null);
|
||||
}
|
||||
}
|
||||
|
@ -249,4 +249,13 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
|||
public EntityPlayer getOwner() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentLevel() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentLevel(int level) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,16 @@ package com.minelittlepony.unicopia.power;
|
|||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.player.IPlayer;
|
||||
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
|
||||
import com.minelittlepony.unicopia.power.data.Hit;
|
||||
import com.minelittlepony.unicopia.spell.SpellShield;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class PowerMagic implements IPower<PowerMagic.Magic> {
|
||||
public class PowerMagic implements IPower<Hit> {
|
||||
|
||||
@Override
|
||||
public String getKeyName() {
|
||||
|
@ -39,23 +39,23 @@ public class PowerMagic implements IPower<PowerMagic.Magic> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Magic tryActivate(EntityPlayer player, World w) {
|
||||
return new Magic(0);
|
||||
public Hit tryActivate(EntityPlayer player, World w) {
|
||||
return new Hit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Magic> getPackageType() {
|
||||
return Magic.class;
|
||||
public Class<Hit> getPackageType() {
|
||||
return Hit.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(EntityPlayer player, Magic data) {
|
||||
public void apply(EntityPlayer player, Hit data) {
|
||||
IPlayer prop = PlayerSpeciesList.instance().getPlayer(player);
|
||||
|
||||
if (prop.getEffect() instanceof SpellShield) {
|
||||
prop.setEffect(null);
|
||||
} else {
|
||||
prop.setEffect(new SpellShield(data.type));
|
||||
prop.setEffect(new SpellShield());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,14 +68,4 @@ public class PowerMagic implements IPower<PowerMagic.Magic> {
|
|||
public void postApply(IPlayer player) {
|
||||
|
||||
}
|
||||
|
||||
class Magic implements IData {
|
||||
|
||||
@Expose
|
||||
public int type;
|
||||
|
||||
public Magic(int strength) {
|
||||
type = strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.render;
|
|||
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||
import com.minelittlepony.unicopia.model.ModelGem;
|
||||
|
||||
import net.minecraft.client.renderer.culling.ICamera;
|
||||
import net.minecraft.client.renderer.entity.RenderLiving;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
@ -15,14 +16,22 @@ public class RenderGem extends RenderLiving<EntitySpell> {
|
|||
super(rendermanagerIn, new ModelGem(), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getEntityTexture(EntitySpell entity) {
|
||||
return gem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(EntitySpell livingEntity, ICamera camera, double camX, double camY, double camZ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getDeathMaxRotation(EntitySpell entity) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canRenderName(EntitySpell targetEntity) {
|
||||
return super.canRenderName(targetEntity) && (targetEntity.getAlwaysRenderNameTagForRender()
|
||||
|| targetEntity.hasCustomName() && targetEntity == renderManager.pointedEntity);
|
||||
|
|
|
@ -7,7 +7,7 @@ import net.minecraft.entity.EntityLivingBase;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface ICaster<E extends EntityLivingBase> extends IOwned<E> {
|
||||
public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelled {
|
||||
void setEffect(IMagicEffect effect);
|
||||
|
||||
IMagicEffect getEffect();
|
||||
|
|
|
@ -25,7 +25,9 @@ public interface IMagicEffect extends InbtSerialisable, ILevelled {
|
|||
* @param source The entity we are currently attached to.
|
||||
* @return true to keep alive
|
||||
*/
|
||||
boolean update(ICaster<?> caster);
|
||||
default boolean updateOnPerson(ICaster<?> caster) {
|
||||
return update(caster, getCurrentLevel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every tick when attached to a gem.
|
||||
|
@ -41,8 +43,8 @@ public interface IMagicEffect extends InbtSerialisable, ILevelled {
|
|||
*
|
||||
* @param source The entity we are currently attached to.
|
||||
*/
|
||||
default void render(ICaster<?> source) {
|
||||
|
||||
default void renderOnPerson(ICaster<?> source) {
|
||||
render(source, getCurrentLevel());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,9 +54,7 @@ public interface IMagicEffect extends InbtSerialisable, ILevelled {
|
|||
* @param source The entity we are attached to.
|
||||
* @param level Current spell level
|
||||
*/
|
||||
default void render(ICaster<?> source, int level) {
|
||||
|
||||
}
|
||||
void render(ICaster<?> source, int level);
|
||||
|
||||
/**
|
||||
* Return true to allow the gem update and move.
|
||||
|
|
141
src/main/java/com/minelittlepony/unicopia/spell/SpellCharge.java
Normal file
141
src/main/java/com/minelittlepony/unicopia/spell/SpellCharge.java
Normal file
|
@ -0,0 +1,141 @@
|
|||
package com.minelittlepony.unicopia.spell;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.client.particle.Particles;
|
||||
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||
import com.minelittlepony.util.shape.IShape;
|
||||
import com.minelittlepony.util.shape.Line;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class SpellCharge extends AbstractSpell {
|
||||
|
||||
private int desiredLevel = 0;
|
||||
|
||||
boolean searching = true;
|
||||
|
||||
private UUID targettedEntityId;
|
||||
private EntitySpell targettedEntity;
|
||||
|
||||
private static final AxisAlignedBB searchArea = new AxisAlignedBB(-15, -15, -15, 15, 15, 15);
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "charge";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ICaster<?> source, int level) {
|
||||
if (source.getWorld().rand.nextInt(4 + level * 4) == 0) {
|
||||
EntitySpell target = getTarget(source);
|
||||
|
||||
if (target != null) {
|
||||
Vec3d start = source.getEntity().getPositionVector();
|
||||
Vec3d end = target.getPositionVector();
|
||||
|
||||
IShape line = new Line(start, end);
|
||||
|
||||
Random rand = source.getWorld().rand;
|
||||
|
||||
for (int i = 0; i < line.getVolumeOfSpawnableSpace(); i++) {
|
||||
Vec3d pos = line.computePoint(rand);
|
||||
Particles.instance().spawnParticle(Unicopia.MAGIC_PARTICLE, false,
|
||||
pos.x + start.x, pos.y + start.y, pos.z + start.z,
|
||||
0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canTargetEntity(Entity e) {
|
||||
return e instanceof EntitySpell && ((EntitySpell)e).hasEffect();
|
||||
}
|
||||
|
||||
protected void setTarget(EntitySpell e) {
|
||||
searching = false;
|
||||
targettedEntity = e;
|
||||
targettedEntityId = e.getUniqueID();
|
||||
}
|
||||
|
||||
protected EntitySpell getTarget(ICaster<?> source) {
|
||||
if (targettedEntity == null && targettedEntityId != null) {
|
||||
source.getWorld().getEntities(EntitySpell.class, e -> e.getUniqueID().equals(targettedEntityId)).stream().findFirst().ifPresent(this::setTarget);
|
||||
}
|
||||
|
||||
if (targettedEntity != null && targettedEntity.isDead) {
|
||||
targettedEntity = null;
|
||||
targettedEntityId = null;
|
||||
searching = true;
|
||||
}
|
||||
|
||||
return targettedEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(ICaster<?> source, int level) {
|
||||
|
||||
if (searching) {
|
||||
BlockPos origin = source.getOrigin();
|
||||
|
||||
List<Entity> list = source.getWorld().getEntitiesInAABBexcluding(source.getEntity(),
|
||||
searchArea.offset(origin), this::canTargetEntity).stream().sorted((a, b) -> {
|
||||
return (int)(a.getDistanceSq(origin) - b.getDistanceSq(origin));
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
if (list.size() > 0) {
|
||||
setTarget((EntitySpell)list.get(0));
|
||||
}
|
||||
} else {
|
||||
EntitySpell target = getTarget(source);
|
||||
|
||||
if (target != null && !target.overLevelCap() && level > 0) {
|
||||
source.addLevels(-1);
|
||||
target.addLevels(1);
|
||||
}
|
||||
}
|
||||
|
||||
return !isDead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentLevel() {
|
||||
return desiredLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentLevel(int level) {
|
||||
desiredLevel = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound compound) {
|
||||
if (targettedEntityId != null) {
|
||||
compound.setUniqueId("target", targettedEntityId);
|
||||
}
|
||||
compound.setInteger("level", desiredLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound compound) {
|
||||
if (compound.hasKey("target")) {
|
||||
targettedEntityId = compound.getUniqueId("target");
|
||||
}
|
||||
|
||||
desiredLevel = compound.getInteger("level");
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ public class SpellRegistry {
|
|||
|
||||
private SpellRegistry() {
|
||||
registerSpell("shield", 0xffff00, SpellShield::new);
|
||||
registerSpell("charge", 0x0000ff, SpellCharge::new);
|
||||
}
|
||||
|
||||
public IMagicEffect getSpellFromName(String name) {
|
||||
|
|
|
@ -25,13 +25,6 @@ public class SpellShield extends AbstractSpell {
|
|||
|
||||
private int strength = 0;
|
||||
|
||||
public SpellShield() {
|
||||
}
|
||||
|
||||
public SpellShield(int type) {
|
||||
setCurrentLevel(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentLevel() {
|
||||
return strength;
|
||||
|
@ -49,20 +42,13 @@ public class SpellShield extends AbstractSpell {
|
|||
|
||||
@Override
|
||||
public int getMaxLevel() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ICaster<?> source) {
|
||||
spawnParticles(source, 4 + (strength * 2));
|
||||
return 17;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ICaster<?> source, int level) {
|
||||
if (source.getWorld().rand.nextInt(4 + level * 4) == 0) {
|
||||
spawnParticles(source, 4 + (level * 2));
|
||||
}
|
||||
}
|
||||
|
||||
protected void spawnParticles(ICaster<?> source, int strength) {
|
||||
IShape sphere = new Sphere(true, strength);
|
||||
|
@ -82,7 +68,7 @@ public class SpellShield extends AbstractSpell {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean update(ICaster<?> source) {
|
||||
public boolean updateOnPerson(ICaster<?> source) {
|
||||
update(source, strength);
|
||||
|
||||
if (source.getEntity().getEntityWorld().getWorldTime() % 50 == 0) {
|
||||
|
|
94
src/main/java/com/minelittlepony/util/shape/Line.java
Normal file
94
src/main/java/com/minelittlepony/util/shape/Line.java
Normal file
|
@ -0,0 +1,94 @@
|
|||
package com.minelittlepony.util.shape;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
/**
|
||||
* A lonely Line. The simplest form of shape.
|
||||
*
|
||||
*/
|
||||
public class Line implements IShape {
|
||||
|
||||
double len;
|
||||
|
||||
double dX;
|
||||
double dY;
|
||||
double dZ;
|
||||
|
||||
double sX;
|
||||
double sY;
|
||||
double sZ;
|
||||
|
||||
private float yaw = 0;
|
||||
private float pitch = 0;
|
||||
|
||||
/**
|
||||
* Creates a line with a given length, starting point, and gradient represented
|
||||
* by another point.
|
||||
*
|
||||
* @param length Length of this line
|
||||
* @param startX Offset X from origin
|
||||
* @param startY Offset Y from origin
|
||||
* @param startZ Offset Z from origin
|
||||
* @param deltaX Change in X
|
||||
* @param deltaY Change in Y
|
||||
* @param deltaZ Change in Z
|
||||
*/
|
||||
public Line(double length, double startX, double startY, double startZ, double deltaX, double deltaY, double deltaZ) {
|
||||
len = length;
|
||||
dX = deltaX;
|
||||
dY = deltaY;
|
||||
dZ = deltaZ;
|
||||
sX = startX;
|
||||
sY = startY;
|
||||
sZ = startZ;
|
||||
}
|
||||
|
||||
public Line(Vec3d start, Vec3d end) {
|
||||
Vec3d lenV = end.subtract(start);
|
||||
|
||||
len = lenV.length();
|
||||
|
||||
sX = start.x;
|
||||
sY = start.y;
|
||||
sZ = start.z;
|
||||
|
||||
dX = lenV.x / len;
|
||||
dY = lenV.y / len;
|
||||
dZ = lenV.z / len;
|
||||
}
|
||||
|
||||
public double getVolumeOfSpawnableSpace() {
|
||||
return len;
|
||||
}
|
||||
|
||||
public double getXOffset() {
|
||||
return sX;
|
||||
}
|
||||
|
||||
public double getYOffset() {
|
||||
return sY;
|
||||
}
|
||||
|
||||
public double getZOffset() {
|
||||
return sZ;
|
||||
}
|
||||
|
||||
public Vec3d computePoint(Random rand) {
|
||||
double distance = MathHelper.nextDouble(rand, 0, len);
|
||||
return (new Vec3d(distance * dX, distance * dY, distance * dZ)).rotateYaw(yaw).rotatePitch(pitch);
|
||||
}
|
||||
|
||||
public Line setRotation(float u, float v) {
|
||||
yaw = u;
|
||||
pitch = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isPointInside(Vec3d point) {
|
||||
point = point.rotateYaw(-yaw).rotatePitch(-pitch);
|
||||
return point.x/dX == point.y/dY && point.x/dX == point.z/dZ;
|
||||
}
|
||||
}
|
|
@ -21,6 +21,8 @@ item.gem.name=Gem
|
|||
item.corrupted_gem.name=Fractured Gem
|
||||
item.gem.shield.name=Gem of Repulsion
|
||||
item.corrupted_gem.shield.name=Corrupt Gem of Repulsion
|
||||
item.gem.charge.name=Channeling Gem
|
||||
item.corrupted_gem.charge.name=Gem of Draining
|
||||
item.gem.fire.name=Gem of Flame
|
||||
item.corrupted_gem.fire.name=Corrupt Gem of Burning
|
||||
item.gem.inferno.name=Gem of Inferno
|
||||
|
|
Loading…
Reference in a new issue