Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.Direction;
Expand All @@ -36,11 +35,6 @@ public class BlockSleepingBag extends BlockDirectional {

private static final int[][] footBlockToHeadBlockMap = new int[][] { { 0, 1 }, { -1, 0 }, { 0, -1 }, { 1, 0 } };

private static final String TAG_STORED_SPAWN = "storedSpawn";
private static final String TAG_SPAWN_POS_X = "posX";
private static final String TAG_SPAWN_POS_Y = "posY";
private static final String TAG_SPAWN_POS_Z = "posZ";

@SideOnly(Side.CLIENT)
private IIcon[] endIcons;

Expand Down Expand Up @@ -79,6 +73,15 @@ private static boolean isBlockHeadOfBed(int meta) {
return (meta & 8) != 0;
}

private static ChunkCoordinates getHeadCoordinates(int x, int y, int z, int meta) {
if (!isBlockHeadOfBed(meta)) {
int dir = getDirection(meta);
x += footBlockToHeadBlockMap[dir][0];
z += footBlockToHeadBlockMap[dir][1];
}
return new ChunkCoordinates(x, y, z);
}

public static boolean isSleepingInPortableBag(EntityPlayer player) {
return Wearing.isWearingBackpack(player)
&& Wearing.getWearingBackpackInv(player).getExtendedProperties().hasKey(Constants.TAG_SLEEPING_IN_BAG);
Expand All @@ -92,37 +95,27 @@ public static void packPortableSleepingBag(EntityPlayer player) {
}
}

public static void storeOriginalSpawn(EntityPlayer player, NBTTagCompound tag) {
ChunkCoordinates spawn = player.getBedLocation(player.worldObj.provider.dimensionId);
if (spawn != null) {
NBTTagCompound storedSpawn = new NBTTagCompound();
storedSpawn.setInteger(TAG_SPAWN_POS_X, spawn.posX);
storedSpawn.setInteger(TAG_SPAWN_POS_Y, spawn.posY);
storedSpawn.setInteger(TAG_SPAWN_POS_Z, spawn.posZ);
tag.setTag(TAG_STORED_SPAWN, storedSpawn);
LogHelper.info(
"Stored spawn data for " + player
.getDisplayName() + ": " + spawn + " dimID: " + player.worldObj.provider.dimensionId);
} else {
LogHelper.warn("Cannot store spawn data for " + player.getDisplayName());
public static void restoreOriginalSpawn(EntityPlayer player) {
final BackpackProperty props = BackpackProperty.get(player);

if (props != null) {
final ChunkCoordinates oldSpawn = props.getStoredSpawn();
if (oldSpawn != null) {
player.setSpawnChunk(oldSpawn, false, props.getStoredSpawnDimension());
}
}
}

public static void restoreOriginalSpawn(EntityPlayer player, NBTTagCompound tag) {
if (tag.hasKey(TAG_STORED_SPAWN)) {
NBTTagCompound storedSpawn = tag.getCompoundTag(TAG_STORED_SPAWN);
ChunkCoordinates coords = new ChunkCoordinates(
storedSpawn.getInteger(TAG_SPAWN_POS_X),
storedSpawn.getInteger(TAG_SPAWN_POS_Y),
storedSpawn.getInteger(TAG_SPAWN_POS_Z));
player.setSpawnChunk(coords, false, player.worldObj.provider.dimensionId);
tag.removeTag(TAG_STORED_SPAWN);
LogHelper.info(
"Restored spawn data for " + player
.getDisplayName() + ": " + coords + " dimID: " + player.worldObj.provider.dimensionId);
} else {
LogHelper.warn("No spawn data to restore for " + player.getDisplayName());
}
public static boolean shouldRestoreStoredSpawnOnDeath(EntityPlayer player) {
BackpackProperty prop = BackpackProperty.get(player);
if (prop == null) return false;

ChunkCoordinates sleepingBagSpawn = prop.getSleepingBagSpawn();
if (sleepingBagSpawn == null) return false;
if (prop.getSleepingBagSpawnDimension() != player.dimension) return false;

return player.worldObj.getBlock(sleepingBagSpawn.posX, sleepingBagSpawn.posY, sleepingBagSpawn.posZ)
!= ModBlocks.blockSleepingBag;
}

public void onPortableBlockActivated(World world, EntityPlayer player, int cX, int cY, int cZ) {
Expand Down Expand Up @@ -177,26 +170,36 @@ public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer p
setBedOccupied(world, x, y, z, false);
}

BackpackProperty props = BackpackProperty.get(player);
ChunkCoordinates previousSpawn = player.getBedLocation(player.dimension);
int previousSpawnDimension = player.dimension;
EntityPlayer.EnumStatus enumstatus = player.sleepInBedAt(x, y, z);

if (enumstatus == EntityPlayer.EnumStatus.OK) {
setBedOccupied(world, x, y, z, true);
ChunkCoordinates sleepingBagSpawn = new ChunkCoordinates(x, y, z);
if (props != null) {
props.setSleepingBagSpawn(sleepingBagSpawn, player.dimension);
if (previousSpawn != null) {
props.setStoredSpawn(previousSpawn, previousSpawnDimension);
}
}
// This is so the wake-up event can detect it. It fires before the player wakes up.
// and the bed location isn't set until then, normally.

if (isSleepingInPortableBag(player)) {
storeOriginalSpawn(player, Wearing.getWearingBackpackInv(player).getExtendedProperties());
player.setSpawnChunk(new ChunkCoordinates(x, y, z), true, player.dimension);
} else {
player.setSpawnChunk(new ChunkCoordinates(x, y, z), true, player.dimension);
if (!isSleepingInPortableBag(player)) {
LogHelper.info("Looking for a campfire nearby...");
ChunkCoordinates campfire = CoordsUtils
.findBlock3D(world, x, y, z, ModBlocks.blockCampFire, 8, 2);
if (campfire != null) {
LogHelper.info("Campfire Found, saving coordinates. " + campfire);
BackpackProperty.get(player).setCampFire(campfire);
} else {
LogHelper.info("No campfire found. Keeping spawnpoint at previous location");
BackpackProperty.get(player).setCampFire(null);
}
}
player.setSpawnChunk(sleepingBagSpawn, true, player.dimension);
return true;
} else {
if (enumstatus == EntityPlayer.EnumStatus.NOT_POSSIBLE_NOW) {
Expand Down Expand Up @@ -299,33 +302,36 @@ public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explos

@Override
public void onBlockDestroyedByPlayer(World world, int x, int y, int z, int meta) {
// TODO make it work if player destroyed head block of sleeping bag (so backpack 1 more tile away)
// LogHelper.info("onBlockDestroyedByPlayer() : BlockSleepingBag");
ChunkCoordinates head = getHeadCoordinates(x, y, z, meta);
int direction = getDirection(meta);
int tileZ = z;
int tileX = x;
switch (meta) {
case 0:
tileZ--;
break;
case 1:
tileX++;
break;
case 2:
tileZ++;
break;
case 3:
tileX--;
break;
if (isBlockHeadOfBed(meta)) {
tileX -= footBlockToHeadBlockMap[direction][0];
tileZ -= footBlockToHeadBlockMap[direction][1];
} else {
tileX += footBlockToHeadBlockMap[direction][0];
tileZ += footBlockToHeadBlockMap[direction][1];
}
// LogHelper.info("onBlockDestroyedByPlayer() Looking for tile entity in x=" +tileX+" y="+y+" z="+tileZ+" while
// breaking the block in x= "+x+" y="+y+" z="+z);
if (world.getTileEntity(tileX, y, tileZ) != null
&& world.getTileEntity(tileX, y, tileZ) instanceof TileAdventureBackpack) {
// LogHelper.info("onBlockDestroyedByPlayer() Found the tile entity in x=" +tileX+" y="+y+" z="+z+" while
// breaking the block in x= "+x+" y="+y+" z="+z+" ...removing.");
((TileAdventureBackpack) world.getTileEntity(tileX, y, tileZ)).setSleepingBagDeployed(false);
}

if (!world.isRemote) {
for (Object object : world.playerEntities) {
EntityPlayer player = (EntityPlayer) object;
BackpackProperty props = BackpackProperty.get(player);
if (props != null && props.getSleepingBagSpawn() != null
&& props.getSleepingBagSpawnDimension() == world.provider.dimensionId
&& props.getSleepingBagSpawn().posX == head.posX
&& props.getSleepingBagSpawn().posY == head.posY
&& props.getSleepingBagSpawn().posZ == head.posZ) {
restoreOriginalSpawn(player);
props.clearSleepingBagSpawn();
}
}
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.darkona.adventurebackpack.handlers;

import java.util.HashSet;
import java.util.Objects;

import net.minecraft.entity.EntityCreature;
import net.minecraft.entity.SharedMonsterAttributes;
Expand Down Expand Up @@ -165,18 +166,23 @@ public void playerDies(LivingDeathEvent event) {
// point if there's no campfire.
}

if (BlockSleepingBag.shouldRestoreStoredSpawnOnDeath(player)) {
BlockSleepingBag.restoreOriginalSpawn(player);
props.clearSleepingBagSpawn();
}

if (Wearing.isWearingWearable(player)) {
if (Wearing.isWearingTheRightBackpack(player, BackpackTypes.CREEPER)) {
player.worldObj.createExplosion(player, player.posX, player.posY, player.posZ, 4.0F, false);
}

if (player.getEntityWorld().getGameRules().getGameRuleBooleanValue("keepInventory")
|| PotionAndEnchantUtils.hasStickyItems(player)) {
((IBackWearableItem) props.getWearable().getItem())
((IBackWearableItem) Objects.requireNonNull(props.getWearable().getItem()))
.onPlayerDeath(player.worldObj, player, props.getWearable());
ServerProxy.storePlayerProps(player);
}
}
ServerProxy.storePlayerProps(player);
}
}
event.setResult(Event.Result.ALLOW);
Expand Down Expand Up @@ -275,36 +281,46 @@ public void playerWokeUp(PlayerWakeUpEvent event) {
ChunkCoordinates bedLocation = player.getBedLocation(player.dimension);
if (bedLocation != null && player.worldObj.getBlock(bedLocation.posX, bedLocation.posY, bedLocation.posZ)
== ModBlocks.blockSleepingBag) {
// If the player wakes up in one of those super confortable SleepingBags (tm) (Patent Pending)
// If the player wakes up in one of those super comfortable SleepingBags (tm) (Patent Pending)
if (BlockSleepingBag.isSleepingInPortableBag(player)) {
BlockSleepingBag.packPortableSleepingBag(player);
BackpackProperty.get(player).setWakingUpInPortableBag(true);
LogHelper.info("Player just woke up in a portable sleeping bag.");
} else {
BackpackProperty.get(player).setForceCampFire(true);
LogHelper.info(
"Player just woke up in a sleeping bag, forcing respawn in the last lighted campfire, if there's any");
BackpackProperty props = BackpackProperty.get(player);
if (props != null) {
if (props.getCampFire() != null) {
props.setForceCampFire(true);
LogHelper.info(
"Player just woke up in a deployed sleeping bag, forcing respawn near the last lit campfire");
} else {
LogHelper.info("Player just woke up in a deployed sleeping bag away from any campfire");
}
}
}
} else {
// If it's a regular bed or whatever
BackpackProperty.get(player).setForceCampFire(false);
BackpackProperty props = BackpackProperty.get(player);
props.setForceCampFire(false);
props.clearSleepingBagSpawn();
}
}

@SubscribeEvent
public void tickPlayer(TickEvent.PlayerTickEvent event) {
EntityPlayer player = event.player;
if (player != null && !player.isDead && Wearing.isWearingWearable(player)) {
if (event.phase == TickEvent.Phase.START) {
BackpackProperty.get(player).executeWearableUpdateProtocol();
}
if (event.phase == TickEvent.Phase.END) {
if (!player.worldObj.isRemote) {
if (BackpackProperty.get(player).isWakingUpInPortableBag() && Wearing.isWearingBackpack(player)) {
BlockSleepingBag.restoreOriginalSpawn(
player,
Wearing.getWearingBackpackInv(player).getExtendedProperties());
BackpackProperty.get(player).setWakingUpInPortableBag(false);
if (player != null && !player.isDead) {
if (Wearing.isWearingWearable(player)) {
if (event.phase == TickEvent.Phase.START) {
BackpackProperty.get(player).executeWearableUpdateProtocol();
}
if (event.phase == TickEvent.Phase.END) {
if (!player.worldObj.isRemote) {
if (BackpackProperty.get(player).isWakingUpInPortableBag()
&& Wearing.isWearingBackpack(player)) {
BlockSleepingBag.restoreOriginalSpawn(player);
BackpackProperty.get(player).setWakingUpInPortableBag(false);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@
public class BackpackProperty implements IExtendedEntityProperties {

private static final String PROPERTY_NAME = "abp.property";
private static final String TAG_STORED_SPAWN = "storedSpawn";
private static final String TAG_SLEEPING_BAG_SPAWN = "sleepingBagSpawn";

private EntityPlayer player;
private ItemStack wearable = null;
private ChunkCoordinates storedSpawn = null;
private int storedSpawnDimension = 0;
private ChunkCoordinates sleepingBagSpawn = null;
private int sleepingBagSpawnDimension = 0;
private ChunkCoordinates campFire = null;
private boolean forceCampFire = false;
private int dimension = 0;
Expand Down Expand Up @@ -72,6 +78,22 @@ public static BackpackProperty get(EntityPlayer player) {
@Override
public void saveNBTData(NBTTagCompound compound) {
if (wearable != null) compound.setTag("wearable", wearable.writeToNBT(new NBTTagCompound()));
if (storedSpawn != null) {
NBTTagCompound spawn = new NBTTagCompound();
spawn.setInteger("posX", storedSpawn.posX);
spawn.setInteger("posY", storedSpawn.posY);
spawn.setInteger("posZ", storedSpawn.posZ);
spawn.setInteger("dim", storedSpawnDimension);
compound.setTag(TAG_STORED_SPAWN, spawn);
}
if (sleepingBagSpawn != null) {
NBTTagCompound spawn = new NBTTagCompound();
spawn.setInteger("posX", sleepingBagSpawn.posX);
spawn.setInteger("posY", sleepingBagSpawn.posY);
spawn.setInteger("posZ", sleepingBagSpawn.posZ);
spawn.setInteger("dim", sleepingBagSpawnDimension);
compound.setTag(TAG_SLEEPING_BAG_SPAWN, spawn);
}
if (campFire != null) {
compound.setInteger("campFireX", campFire.posX);
compound.setInteger("campFireY", campFire.posY);
Expand All @@ -87,6 +109,24 @@ public void loadNBTData(NBTTagCompound compound) {
setWearable(
compound.hasKey("wearable") ? ItemStack.loadItemStackFromNBT(compound.getCompoundTag("wearable"))
: null);
if (compound.hasKey(TAG_STORED_SPAWN)) {
NBTTagCompound spawn = compound.getCompoundTag(TAG_STORED_SPAWN);
setStoredSpawn(
new ChunkCoordinates(
spawn.getInteger("posX"),
spawn.getInteger("posY"),
spawn.getInteger("posZ")),
spawn.getInteger("dim"));
}
if (compound.hasKey(TAG_SLEEPING_BAG_SPAWN)) {
NBTTagCompound spawn = compound.getCompoundTag(TAG_SLEEPING_BAG_SPAWN);
setSleepingBagSpawn(
new ChunkCoordinates(
spawn.getInteger("posX"),
spawn.getInteger("posY"),
spawn.getInteger("posZ")),
spawn.getInteger("dim"));
}
setCampFire(
new ChunkCoordinates(
compound.getInteger("campFireX"),
Expand All @@ -110,6 +150,41 @@ public ItemStack getWearable() {
return wearable;
}

public void setStoredSpawn(ChunkCoordinates coords) {
setStoredSpawn(coords, player.worldObj.provider.dimensionId);
}

public void setStoredSpawn(ChunkCoordinates coords, int dim) {
storedSpawn = coords;
storedSpawnDimension = dim;
}

public ChunkCoordinates getStoredSpawn() {
return storedSpawn;
}

public int getStoredSpawnDimension() {
return storedSpawnDimension;
}

public void setSleepingBagSpawn(ChunkCoordinates coords, int dim) {
sleepingBagSpawn = coords;
sleepingBagSpawnDimension = dim;
}

public ChunkCoordinates getSleepingBagSpawn() {
return sleepingBagSpawn;
}

public int getSleepingBagSpawnDimension() {
return sleepingBagSpawnDimension;
}

public void clearSleepingBagSpawn() {
sleepingBagSpawn = null;
sleepingBagSpawnDimension = 0;
}

public void setCampFire(ChunkCoordinates cf) {
campFire = cf;
}
Expand Down