bugfixes
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-04-15 17:46:41 -04:00
parent 1730695e1b
commit f25e64fd1c
10 changed files with 226 additions and 6 deletions

View File

@ -1488,6 +1488,10 @@ Sound effect on swinging fists/weapons
Queue loading audio file on creating virtual spatial source
Scaffold grid alignment data for entities
Remove old title menu items
Fix first person tree animation not nullchecking
Fix yoga not applying on item drop window creation
Fix client not destroying item on remove from inventory
Tests for above bugs

View File

@ -82,6 +82,7 @@ public class ClientSceneWrapper {
*/
public int mapClientToServerId(int clientId){
if(clientToServerIdMap.get(clientId) == null){
LoggerInterface.loggerNetworking.ERROR(new Error("Failed to map client entity " + clientId + " to server entity!"));
return -1;
}
return clientToServerIdMap.get(clientId);

View File

@ -229,8 +229,13 @@ public class WindowUtils {
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
}
/**
* Creates the window to receive item drop events
*/
static void initItemDropWindow(){
Globals.elementService.registerWindow(WindowStrings.WINDDOW_ITEM_DROP, MenuGeneratorsInventory.worldItemDropCaptureWindow());
Element itemDropWindow = MenuGeneratorsInventory.worldItemDropCaptureWindow();
Globals.elementService.registerWindow(WindowStrings.WINDDOW_ITEM_DROP, itemDropWindow);
Globals.signalSystem.post(SignalType.YOGA_APPLY, itemDropWindow);
}
static void initItemDragContainerWindow(){

View File

@ -6,6 +6,7 @@ import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.item.Item;
@ -51,6 +52,7 @@ public class MenuGeneratorsInventory {
div.setPositionY(0);
div.setWidth(Globals.WINDOW_WIDTH);
div.setHeight(Globals.WINDOW_HEIGHT);
div.setFlexGrow(1);
rVal.addChild(div);
return rVal;
}

View File

@ -164,7 +164,7 @@ public class FirstPersonTree implements BehaviorTree {
* @param priority The priority of the animation
*/
public static void conditionallyPlayAnimation(Entity entity, String animationName, int priority, double offset){
if(entity != null && entity == Globals.playerEntity && FirstPersonTree.hasTree(Globals.firstPersonEntity)){
if(entity != null && entity == Globals.playerEntity && Globals.firstPersonEntity != null && FirstPersonTree.hasTree(Globals.firstPersonEntity)){
FirstPersonTree.getTree(Globals.firstPersonEntity).playAnimation(animationName, priority);
}
}
@ -185,7 +185,7 @@ public class FirstPersonTree implements BehaviorTree {
* @param animationName the name of the animation
*/
public static void conditionallyPlayAnimation(Entity entity, TreeDataAnimation animation){
if(entity != null && entity == Globals.playerEntity && FirstPersonTree.hasTree(Globals.firstPersonEntity)){
if(entity != null && entity == Globals.playerEntity && Globals.firstPersonEntity != null && FirstPersonTree.hasTree(Globals.firstPersonEntity)){
FirstPersonTree.getTree(Globals.firstPersonEntity).playAnimation(animation);
}
}

View File

@ -52,9 +52,14 @@ public class ClientInventoryState implements BehaviorTree {
WindowUtils.attemptRedrawInventoryWindows();
} break;
case REMOVEITEMFROMINVENTORY: {
InventoryUtils.removeItemFromInventories(parent, Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()));
//attempt re-render ui
WindowUtils.attemptRedrawInventoryWindows();
Entity item = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId());
if(item != null){
InventoryUtils.removeItemFromInventories(parent, item);
//attempt re-render ui
WindowUtils.attemptRedrawInventoryWindows();
//destroy the item
ClientEntityUtils.destroyEntity(item);
}
} break;
case SERVERCOMMANDMOVEITEMCONTAINER: {
//this is a command to switch an item from one inventory to another (ie equip->natural or vice-versa)

View File

@ -339,6 +339,12 @@ public class InventoryUtils {
* @param item The item to eject
*/
public static void serverAttemptEjectItemTransform(Entity creature, Entity item){
if(creature == null){
throw new Error("Provided null creature!");
}
if(item == null){
throw new Error("Provided null item!");
}
//verify creature is creature, item is item, inventory exists, and item is in inventory
boolean creatureIsCreature = CreatureUtils.isCreature(creature);
boolean itemIsItem = ItemUtils.isItem(item);
@ -403,6 +409,12 @@ public class InventoryUtils {
//need creature so we can figure out where to drop the item
public static void serverAttemptEjectItem(Entity creature, Entity item){
if(creature == null){
throw new Error("Provided null creature!");
}
if(item == null){
throw new Error("Provided null item!");
}
//if we're the server, immediately attempt the transform
InventoryUtils.serverAttemptEjectItemTransform(creature,item);
}
@ -434,6 +446,12 @@ public class InventoryUtils {
* @param item The item to remove
*/
public static void removeItemFromInventories(Entity creature, Entity item){
if(creature == null){
throw new Error("Creature is null!");
}
if(item == null){
throw new Error("Item is null!");
}
//verify creature is creature, item is item, inventory exists, and item is in inventory
boolean creatureIsCreature = CreatureUtils.isCreature(creature);
boolean itemIsItem = ItemUtils.isItem(item);

View File

@ -0,0 +1,32 @@
package electrosphere.client.ui.menu;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import electrosphere.engine.Globals;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.test.annotations.IntegrationTest;
import electrosphere.test.template.EntityTestTemplate;
import electrosphere.test.testutils.TestEngineUtils;
/**
* Integration tests for WindowUtils
*/
public class WindowUtilsIntegrationTests extends EntityTestTemplate {
/**
* Make sure item drop event capture window size accounts for whole screen
*/
@IntegrationTest
public void test_ItemDropWindow_size(){
//warm up engine
TestEngineUtils.simulateFrames(1);
Window window = (Window)Globals.elementService.getWindow(WindowStrings.WINDDOW_ITEM_DROP);
Div captureDiv = (Div)window.getChildren().get(0);
assertNotEquals(captureDiv.getWidth(),0);
assertNotEquals(captureDiv.getHeight(),0);
}
}

View File

@ -0,0 +1,139 @@
package electrosphere.entity.state.inventory;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Set;
import org.joml.Vector3d;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityTags;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.test.annotations.IntegrationTest;
import electrosphere.test.template.EntityTestTemplate;
import electrosphere.test.testutils.TestEngineUtils;
/**
* Tests for the inventory utils functions
*/
public class InventoryUtilsTests extends EntityTestTemplate {
/**
* Make sure clientAttemptStoreItem performs its intended function
*/
@IntegrationTest
public void test_clientAttemptStoreItem(){
//warm up engine
TestEngineUtils.simulateFrames(1);
//spawn entities
TestEngineUtils.spawnPlayerEntity();
Entity katana = ItemUtils.serverSpawnBasicItem(Globals.realmManager.first(), new Vector3d(0,0,0), "Katana2H");
//wait for entities to propagate to client
TestEngineUtils.simulateFrames(1);
//verify the client got the extra entities
Set<Entity> clientSideCreatures = Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.CREATURE);
assertEquals(1, clientSideCreatures.size());
Set<Entity> clientSideItems = Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM);
assertEquals(1, clientSideItems.size());
//grab player entity
Entity clientCreature = clientSideCreatures.iterator().next();
Entity clientKatana = TestEngineUtils.getClientEquivalent(katana);
Globals.playerEntity = clientCreature;
//attempt to store
InventoryUtils.clientAttemptStoreItem(clientCreature, clientKatana);
//propagate to client
TestEngineUtils.simulateFrames(2);
//verify we still have everything
clientSideCreatures = Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.CREATURE);
assertEquals(1, clientSideCreatures.size());
clientSideItems = Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM);
assertEquals(1, clientSideItems.size());
//grab the item in particular
Entity child = clientSideItems.iterator().next();
//
//verify was created properly
assertTrue(ItemUtils.isItem(child));
assertTrue(ItemUtils.isWeapon(child));
assertNotNull(ItemUtils.getContainingParent(child));
//
//verify the item is stored in the inventory properly
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(clientCreature);
assertEquals(naturalInventory.getItems().size(),1);
}
/**
* Make sure clientAttemptEjectItem performs its intended function
*/
@IntegrationTest
public void test_clientAttemptEjectItem(){
//warm up engine
TestEngineUtils.simulateFrames(1);
//spawn entities
TestEngineUtils.spawnPlayerEntity();
Entity katana = ItemUtils.serverSpawnBasicItem(Globals.realmManager.first(), new Vector3d(0,0,0), "Katana2H");
//wait for entities to propagate to client
TestEngineUtils.simulateFrames(1);
//verify the client got the extra entities
Set<Entity> clientSideCreatures = Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.CREATURE);
assertEquals(1, clientSideCreatures.size());
Set<Entity> clientSideItems = Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM);
assertEquals(1, clientSideItems.size());
//grab player entity
Entity clientCreature = clientSideCreatures.iterator().next();
Entity clientKatana = TestEngineUtils.getClientEquivalent(katana);
Globals.playerEntity = clientCreature;
//attempt to store
InventoryUtils.clientAttemptStoreItem(clientCreature, clientKatana);
//allow time for client->server->client communication
TestEngineUtils.simulateFrames(2);
//attempt to eject
clientSideItems = Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM);
clientKatana = clientSideItems.iterator().next();
InventoryUtils.clientAttemptEjectItem(clientCreature, clientKatana);
//allow time for client->server->client communication
TestEngineUtils.simulateFrames(2);
//verify we still have everything
clientSideCreatures = Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.CREATURE);
assertEquals(1, clientSideCreatures.size());
clientSideItems = Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM);
assertEquals(1, clientSideItems.size());
//grab the item in particular
Entity child = clientSideItems.iterator().next();
//
//verify was created properly
assertTrue(ItemUtils.isItem(child));
assertTrue(ItemUtils.isWeapon(child));
assertNull(ItemUtils.getContainingParent(child));
//
//verify the item is stored in the inventory properly
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(clientCreature);
assertEquals(naturalInventory.getItems().size(),0);
}
}

View File

@ -12,6 +12,9 @@ import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.entity.Entity;
import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.net.server.ServerConnectionHandler;
import electrosphere.server.character.PlayerCharacterCreation;
/**
* Utils for testing the engine
@ -131,4 +134,15 @@ public class TestEngineUtils {
}
}
/**
* Spawns an entity for the player
* @return The entity
*/
public static void spawnPlayerEntity(){
CreatureTemplate creatureTemplate = CreatureTemplate.createDefault("human");
ServerConnectionHandler serverConnection = Globals.server.getFirstConnection();
serverConnection.setCreatureTemplate(creatureTemplate);
PlayerCharacterCreation.spawnPlayerCharacter(serverConnection);
}
}