terrain work
This commit is contained in:
parent
c9ac7496a5
commit
c9ce7264fa
@ -23,5 +23,6 @@
|
||||
|
||||
+ bug fixes
|
||||
- Window does not play nice with its minWidth/minHeight being set differently
|
||||
- When inventory utils is used to create an item with charges in the inventory, the ui does not reflect the corrent number of charges (maybe not setting the value correctly??)
|
||||
|
||||
+ unreproducible bugs
|
||||
|
||||
@ -1671,6 +1671,11 @@ ClientSynchronizationManager un-deleted entity IDs when client receives creation
|
||||
MoveTo tree doesn't overwrite published status
|
||||
Fix AIManager.shutdown call not null checking
|
||||
Small explore node height offset
|
||||
Terrain items
|
||||
Digging produces terrain item form
|
||||
Terrain items can be placed to place terrain
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -129,6 +129,7 @@ public class Config {
|
||||
//create procedural item types
|
||||
ItemDataMap.loadSpawnItems(config.itemMap, config.objectTypeLoader);
|
||||
ItemDataMap.generateBlockItems(config.itemMap, config.blockData);
|
||||
ItemDataMap.generateVoxelItems(config.itemMap, config.voxelData);
|
||||
|
||||
//construct the sourcing map
|
||||
config.itemSourcingMap = ItemSourcingMap.parse(config);
|
||||
|
||||
@ -16,6 +16,7 @@ import electrosphere.game.data.common.CommonEntityType;
|
||||
import electrosphere.game.data.common.item.SpawnItemDescription;
|
||||
import electrosphere.game.data.graphics.GraphicsTemplate;
|
||||
import electrosphere.game.data.graphics.NonproceduralModel;
|
||||
import electrosphere.game.data.voxel.VoxelType;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.RenderUtils;
|
||||
|
||||
@ -190,6 +191,73 @@ public class Item extends CommonEntityType {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of the item type for a given voxel type
|
||||
* @param voxelType The voxel type
|
||||
* @return The id of the corresponding item data
|
||||
*/
|
||||
public static String getVoxelTypeId(VoxelType voxelType){
|
||||
return "vox:" + voxelType.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates item data from a voxel type
|
||||
* @param description The voxel type
|
||||
* @return The item data
|
||||
*/
|
||||
public static Item createVoxelItem(VoxelType voxelType){
|
||||
Item rVal = new Item();
|
||||
rVal.setId(Item.getVoxelTypeId(voxelType));
|
||||
|
||||
|
||||
if(voxelType.getTexture() != null){
|
||||
rVal.iconPath = voxelType.getTexture();
|
||||
} else {
|
||||
rVal.iconPath = Item.DEFAULT_ITEM_ICON_PATH;
|
||||
}
|
||||
|
||||
|
||||
NonproceduralModel modelData = new NonproceduralModel();
|
||||
modelData.setPath(AssetDataStrings.MODEL_BLOCK_SINGLE);
|
||||
GraphicsTemplate blockItemGraphicsTemplate = new GraphicsTemplate();
|
||||
blockItemGraphicsTemplate.setModel(modelData);
|
||||
rVal.setGraphicsTemplate(blockItemGraphicsTemplate);
|
||||
|
||||
//set uniforms for the model
|
||||
//TODO: texture work for single voxel
|
||||
// Map<String,Map<String,Object>> meshUniformMap = new HashMap<String,Map<String,Object>>();
|
||||
// Map<String,Object> uniforms = new HashMap<String,Object>();
|
||||
// if(Globals.voxelTextureAtlas.getVoxelTypeOffset(voxelType.getId()) == BlockTextureAtlas.MISSING && voxelType.getId() != BlockChunkData.BLOCK_TYPE_EMPTY){
|
||||
// LoggerInterface.loggerEngine.WARNING("Block type " + voxelType.getId() + " missing in BlockTextureAtlas");
|
||||
// }
|
||||
// uniforms.put("blockAtlasIndex",Globals.voxelTextureAtlas.getVoxelTypeOffset(voxelType.getId()));
|
||||
// meshUniformMap.put(RenderUtils.MESH_NAME_BLOCK_SINGLE,uniforms);
|
||||
// modelData.setUniforms(meshUniformMap);
|
||||
|
||||
//set item class
|
||||
rVal.equipData = new EquipData();
|
||||
rVal.equipData.equipClass = "tool";
|
||||
|
||||
|
||||
//set usage
|
||||
ItemUsage usage = new ItemUsage();
|
||||
usage.setVoxelId(voxelType.getId());
|
||||
usage.setOnlyOnMouseDown(true);
|
||||
rVal.setSecondaryUsage(usage);
|
||||
rVal.setPrimaryUsage(usage);
|
||||
|
||||
//set stacking data
|
||||
rVal.setMaxStack(MAX_BLOCK_STACK);
|
||||
|
||||
|
||||
//attach common tokens
|
||||
List<String> tokens = new LinkedList<String>(Arrays.asList(DEFAULT_TOKENS));
|
||||
tokens.add(CursorState.CURSOR_TOKEN);
|
||||
rVal.setTokens(tokens);
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* the idle animation for the item
|
||||
* @return
|
||||
|
||||
@ -13,6 +13,8 @@ import electrosphere.game.data.block.BlockData;
|
||||
import electrosphere.game.data.block.BlockType;
|
||||
import electrosphere.game.data.common.CommonEntityMap;
|
||||
import electrosphere.game.data.common.CommonEntityType;
|
||||
import electrosphere.game.data.voxel.VoxelData;
|
||||
import electrosphere.game.data.voxel.VoxelType;
|
||||
import electrosphere.util.FileUtils;
|
||||
|
||||
/**
|
||||
@ -145,4 +147,17 @@ public class ItemDataMap {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all voxel types as items
|
||||
* @param itemDataMap The item data map
|
||||
* @param voxelData The data on all voxel types
|
||||
*/
|
||||
public static void generateVoxelItems(ItemDataMap itemDataMap, VoxelData voxelData){
|
||||
for(VoxelType voxelType : voxelData.getTypes()){
|
||||
Item spawnItem = Item.createVoxelItem(voxelType);
|
||||
//create spawn items
|
||||
itemDataMap.putType(spawnItem.getId(), spawnItem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -15,6 +15,11 @@ public class ItemUsage {
|
||||
*/
|
||||
Integer blockId;
|
||||
|
||||
/**
|
||||
* If defined, this item will place the voxel type on use
|
||||
*/
|
||||
Integer voxelId;
|
||||
|
||||
/**
|
||||
* The hook to fire on the client when this item is used
|
||||
*/
|
||||
@ -109,6 +114,22 @@ public class ItemUsage {
|
||||
public void setSuppressServerRequest(Boolean suppressServerRequest) {
|
||||
this.suppressServerRequest = suppressServerRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the voxel id
|
||||
* @return The voxel id
|
||||
*/
|
||||
public Integer getVoxelId() {
|
||||
return voxelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the voxel id
|
||||
* @param voxelId The voxel id
|
||||
*/
|
||||
public void setVoxelId(Integer voxelId) {
|
||||
this.voxelId = voxelId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -460,7 +460,7 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
|
||||
Player player = Globals.playerManager.getPlayerFromId(connectionHandler.getPlayerId());
|
||||
Realm realm = Globals.realmManager.getPlayerRealm(player);
|
||||
Vector3d location = new Vector3d(message.getrealLocationX(), message.getrealLocationY(), message.getrealLocationZ());
|
||||
TerrainEditing.destroyTerrain(realm, location, message.getvalue(), message.getterrainWeight());
|
||||
TerrainEditing.destroyTerrain(realm, player.getPlayerEntity(), location, message.getvalue(), message.getterrainWeight());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
package electrosphere.renderer.ui;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.joml.Vector2i;
|
||||
@ -32,7 +33,7 @@ import electrosphere.renderer.ui.events.DragEvent.DragEventType;
|
||||
import electrosphere.renderer.ui.events.NavigationEvent.NavigationEventType;
|
||||
|
||||
/**
|
||||
* The main interface for working with the ui system
|
||||
* The main interface for working with the ui systemd
|
||||
*/
|
||||
public class ElementService extends SignalServiceImpl {
|
||||
|
||||
@ -51,8 +52,8 @@ public class ElementService extends SignalServiceImpl {
|
||||
);
|
||||
}
|
||||
|
||||
Map<String,Element> elementMap = new HashMap<String,Element>();
|
||||
List<Element> elementList = new LinkedList<Element>();
|
||||
Map<String,Element> elementMap = new ConcurrentHashMap<String,Element>();
|
||||
List<Element> elementList = new CopyOnWriteArrayList<Element>();
|
||||
FocusableElement currentFocusedElement = null;
|
||||
DraggableElement currentDragElement = null;
|
||||
|
||||
|
||||
@ -365,11 +365,11 @@ public class ServerWorldData {
|
||||
* @param position The real coordinate
|
||||
* @return The world space coordinate
|
||||
*/
|
||||
public Vector3i convertRealToWorldSpace(Vector3d position){
|
||||
public static Vector3i convertRealToWorldSpace(Vector3d position){
|
||||
return new Vector3i(
|
||||
convertRealToChunkSpace(position.x),
|
||||
convertRealToChunkSpace(position.y),
|
||||
convertRealToChunkSpace(position.z)
|
||||
ServerWorldData.convertRealToChunkSpace(position.x),
|
||||
ServerWorldData.convertRealToChunkSpace(position.y),
|
||||
ServerWorldData.convertRealToChunkSpace(position.z)
|
||||
);
|
||||
}
|
||||
|
||||
@ -380,9 +380,9 @@ public class ServerWorldData {
|
||||
*/
|
||||
public static Vector3i convertRealToLocalBlockSpace(Vector3d position){
|
||||
return new Vector3i(
|
||||
convertRealToLocalBlockSpace(position.x),
|
||||
convertRealToLocalBlockSpace(position.y),
|
||||
convertRealToLocalBlockSpace(position.z)
|
||||
ServerWorldData.convertRealToLocalBlockSpace(position.x),
|
||||
ServerWorldData.convertRealToLocalBlockSpace(position.y),
|
||||
ServerWorldData.convertRealToLocalBlockSpace(position.z)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,19 @@
|
||||
package electrosphere.server.physics.terrain.editing;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||
import electrosphere.game.data.item.Item;
|
||||
import electrosphere.game.data.voxel.VoxelType;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.server.datacell.ServerWorldData;
|
||||
import electrosphere.server.datacell.interfaces.VoxelCellManager;
|
||||
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
@ -16,6 +26,16 @@ public class TerrainEditing {
|
||||
* the minimum value before hard setting to 0
|
||||
*/
|
||||
static final float MINIMUM_FULL_VALUE = 0.01f;
|
||||
|
||||
/**
|
||||
* The default magnitude
|
||||
*/
|
||||
public static final float DEFAULT_MAGNITUDE = 1.1f;
|
||||
|
||||
/**
|
||||
* The default weight
|
||||
*/
|
||||
public static final float DEFAULT_WEIGHT = 1.0f;
|
||||
|
||||
/**
|
||||
* Performs a terrain chunk edit. Basically has a sphere around the provided position that it attempts to add value to.
|
||||
@ -47,8 +67,8 @@ public class TerrainEditing {
|
||||
for(i = 0; i < numPlacesToCheck; i++){
|
||||
//calculate position of edit
|
||||
Vector3d offsetPos = new Vector3d(position).add(xOffsetSet[i],yOffsetSet[i],zOffsetSet[i]);
|
||||
Vector3i chunkPos = realm.getServerWorldData().convertRealToWorldSpace(offsetPos);
|
||||
Vector3i voxelPos = realm.getServerWorldData().convertRealToVoxelSpace(offsetPos);
|
||||
Vector3i chunkPos = ServerWorldData.convertRealToWorldSpace(offsetPos);
|
||||
Vector3i voxelPos = ServerWorldData.convertRealToVoxelSpace(offsetPos);
|
||||
//get distance from true center point of sphere to current voxel position in world space
|
||||
float distance = (float)new Vector3d(Math.floor(offsetPos.x),Math.floor(offsetPos.y),Math.floor(offsetPos.z)).distance(position);
|
||||
float currentPositionMagnitude = editMagnitude - distance;
|
||||
@ -61,6 +81,9 @@ public class TerrainEditing {
|
||||
voxelPos.x >= 0 &&
|
||||
voxelPos.y >= 0 &&
|
||||
voxelPos.z >= 0 &&
|
||||
chunkPos.x >= 0 &&
|
||||
chunkPos.y >= 0 &&
|
||||
chunkPos.z >= 0 &&
|
||||
currentPositionMagnitude > 0 &&
|
||||
(data = voxelCellManager.getChunkAtPosition(chunkPos)) != null
|
||||
){
|
||||
@ -78,11 +101,13 @@ public class TerrainEditing {
|
||||
|
||||
/**
|
||||
* Performs a terrain chunk edit. Basically has a sphere around the provided position that it attempts to remove value from.
|
||||
* @param realm The realm to destroy terrain within
|
||||
* @param sourceEntity The entity performing the destruction
|
||||
* @param position The position to perform the edit
|
||||
* @param editMagnitude The magnitude of the edit to perform
|
||||
* @param weight The weight of the sphere to apply the edit to
|
||||
*/
|
||||
public static void destroyTerrain(Realm realm, Vector3d position, float editMagnitude, float weight){
|
||||
public static void destroyTerrain(Realm realm, Entity sourceEntity, Vector3d position, float editMagnitude, float weight){
|
||||
if(position != null && realm != null && realm.getDataCellManager() instanceof VoxelCellManager){
|
||||
VoxelCellManager voxelCellManager = (VoxelCellManager) realm.getDataCellManager();
|
||||
//calculate kernel size
|
||||
@ -102,11 +127,12 @@ public class TerrainEditing {
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<Integer,Float> typeAmountMap = new HashMap<Integer,Float>();
|
||||
for(i = 0; i < numPlacesToCheck; i++){
|
||||
//calculate position of edit
|
||||
Vector3d offsetPos = new Vector3d(position).add(xOffsetSet[i],yOffsetSet[i],zOffsetSet[i]);
|
||||
Vector3i chunkPos = realm.getServerWorldData().convertRealToWorldSpace(offsetPos);
|
||||
Vector3i voxelPos = realm.getServerWorldData().convertRealToVoxelSpace(offsetPos);
|
||||
Vector3i chunkPos = ServerWorldData.convertRealToWorldSpace(offsetPos);
|
||||
Vector3i voxelPos = ServerWorldData.convertRealToVoxelSpace(offsetPos);
|
||||
//get distance from true center point of sphere to current voxel position in world space
|
||||
float distance = (float)new Vector3d(Math.floor(offsetPos.x),Math.floor(offsetPos.y),Math.floor(offsetPos.z)).distance(position);
|
||||
float currentPositionMagnitude = editMagnitude - distance;
|
||||
@ -122,17 +148,37 @@ public class TerrainEditing {
|
||||
currentPositionMagnitude > 0 &&
|
||||
(data = voxelCellManager.getChunkAtPosition(chunkPos)) != null
|
||||
){
|
||||
int typeAtPos = voxelCellManager.getVoxelTypeAtLocalPosition(chunkPos, voxelPos);
|
||||
int originalTypeAtPos = voxelCellManager.getVoxelTypeAtLocalPosition(chunkPos, voxelPos);
|
||||
float current = data.getWeights()[voxelPos.x][voxelPos.y][voxelPos.z];
|
||||
//hard clamp so it doesn't go over 1
|
||||
float finalValue = Math.max(Math.min(current + weight / distance,1),-1);
|
||||
int finalType = originalTypeAtPos;
|
||||
if(finalValue < MINIMUM_FULL_VALUE && current >= MINIMUM_FULL_VALUE){
|
||||
finalValue = -1;
|
||||
typeAtPos = ServerTerrainChunk.VOXEL_TYPE_AIR;
|
||||
finalType = ServerTerrainChunk.VOXEL_TYPE_AIR;
|
||||
}
|
||||
voxelCellManager.editChunk(chunkPos, voxelPos, finalValue, finalType);
|
||||
|
||||
//keep track of how much we're editing each chunk so we can add items to inventories
|
||||
if(typeAmountMap.containsKey(originalTypeAtPos)){
|
||||
typeAmountMap.put(originalTypeAtPos,typeAmountMap.get(originalTypeAtPos) + (finalValue - current));
|
||||
} else {
|
||||
typeAmountMap.put(originalTypeAtPos,(finalValue - current));
|
||||
}
|
||||
voxelCellManager.editChunk(chunkPos, voxelPos, finalValue, typeAtPos);
|
||||
}
|
||||
}
|
||||
|
||||
if(sourceEntity == null){
|
||||
throw new Error("Does not support destroying terrain without a source entity");
|
||||
}
|
||||
|
||||
for(Entry<Integer,Float> typeEntry : typeAmountMap.entrySet()){
|
||||
VoxelType voxelType = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(typeEntry.getKey());
|
||||
Item voxelItem = Globals.gameConfigCurrent.getItemMap().getItem(Item.getVoxelTypeId(voxelType));
|
||||
int count = -(int)(float)typeEntry.getValue();
|
||||
InventoryUtils.serverCreateInventoryItem(sourceEntity, voxelItem.getId(), count);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.state.block.ServerBlockTree;
|
||||
import electrosphere.entity.state.equip.ServerToolbarState;
|
||||
import electrosphere.entity.state.furniture.ServerDoorState;
|
||||
import electrosphere.entity.state.item.ServerChargeState;
|
||||
import electrosphere.entity.state.life.ServerLifeTree;
|
||||
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
@ -24,6 +25,7 @@ import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.server.datacell.ServerWorldData;
|
||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||
import electrosphere.server.physics.block.editing.ServerBlockEditing;
|
||||
import electrosphere.server.physics.terrain.editing.TerrainEditing;
|
||||
import electrosphere.server.utils.ServerScriptUtils;
|
||||
|
||||
/**
|
||||
@ -43,7 +45,9 @@ public class PlayerActions {
|
||||
int itemActionCodeState = message.getitemActionCodeState();
|
||||
ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(playerEntity);
|
||||
if(serverToolbarState != null && serverToolbarState.getRealWorldItem() != null){
|
||||
Item item = Globals.gameConfigCurrent.getItemMap().getItem(serverToolbarState.getRealWorldItem());
|
||||
Entity realWorldItemEnt = serverToolbarState.getRealWorldItem();
|
||||
Entity inventoryItemEnt = serverToolbarState.getInInventoryItem();
|
||||
Item item = Globals.gameConfigCurrent.getItemMap().getItem(realWorldItemEnt);
|
||||
CreatureData creatureData = Globals.gameConfigCurrent.getCreatureTypeLoader().getType(CreatureUtils.getType(playerEntity));
|
||||
ServerBlockTree serverBlockTree = ServerBlockTree.getServerBlockTree(playerEntity);
|
||||
|
||||
@ -66,7 +70,7 @@ public class PlayerActions {
|
||||
item.getSecondaryUsage().getOnlyOnMouseDown() == null ||
|
||||
(itemActionCodeState == ItemActions.ITEM_ACTION_CODE_STATE_ON && item.getSecondaryUsage().getOnlyOnMouseDown())
|
||||
){
|
||||
PlayerActions.secondaryUsage(playerEntity, item, message);
|
||||
PlayerActions.secondaryUsage(playerEntity, inventoryItemEnt, item, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,10 +94,11 @@ public class PlayerActions {
|
||||
/**
|
||||
* Performs various secondary usages
|
||||
* @param playerEntity The player's entity
|
||||
* @param itemEnt The item entity
|
||||
* @param item The item data
|
||||
* @param message The message
|
||||
*/
|
||||
private static void secondaryUsage(Entity playerEntity, Item item, InventoryMessage message){
|
||||
private static void secondaryUsage(Entity playerEntity, Entity itemEnt, Item item, InventoryMessage message){
|
||||
ItemUsage secondaryUsage = item.getSecondaryUsage();
|
||||
Realm playerRealm = Globals.realmManager.getEntityRealm(playerEntity);
|
||||
|
||||
@ -103,20 +108,27 @@ public class PlayerActions {
|
||||
CommonEntityUtils.serverSpawnBasicObject(playerRealm, spawnPos, secondaryUsage.getSpawnEntityId());
|
||||
}
|
||||
|
||||
//voxel block editing
|
||||
//block editing
|
||||
if(secondaryUsage.getBlockId() != null){
|
||||
ServerWorldData serverWorldData = playerRealm.getServerWorldData();
|
||||
|
||||
//clamp the placement pos to the block grid..
|
||||
Vector3d placementPos = new Vector3d(message.getviewTargetX(),message.getviewTargetY(),message.getviewTargetZ());
|
||||
Vector3i worldPos = serverWorldData.convertRealToWorldSpace(placementPos);
|
||||
Vector3i blockPos = serverWorldData.convertRealToLocalBlockSpace(placementPos);
|
||||
Vector3i worldPos = ServerWorldData.convertRealToWorldSpace(placementPos);
|
||||
Vector3i blockPos = ServerWorldData.convertRealToLocalBlockSpace(placementPos);
|
||||
|
||||
|
||||
//actually edit
|
||||
ServerBlockEditing.editBlockChunk(playerRealm, worldPos, blockPos, (short)(int)secondaryUsage.getBlockId(), (short)0);
|
||||
LoggerInterface.loggerEngine.DEBUG("Place block type " + secondaryUsage.getBlockId() + " at " + placementPos + " -> " + worldPos + " " + blockPos);
|
||||
}
|
||||
|
||||
//voxel editing
|
||||
if(secondaryUsage.getVoxelId() != null){
|
||||
Vector3d placementPos = new Vector3d(message.getviewTargetX(),message.getviewTargetY(),message.getviewTargetZ());
|
||||
//actually edit
|
||||
TerrainEditing.editTerrain(playerRealm, placementPos, TerrainEditing.DEFAULT_MAGNITUDE, secondaryUsage.getVoxelId(), TerrainEditing.DEFAULT_WEIGHT);
|
||||
ServerChargeState.getServerChargeState(itemEnt).attemptAddCharges(-1);
|
||||
LoggerInterface.loggerEngine.DEBUG("Place voxel type " + secondaryUsage.getVoxelId() + " at " + placementPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user