crops loot behavior
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-13 12:58:15 -04:00
parent fe655fdd1f
commit 4847528e48
6 changed files with 81 additions and 22 deletions

View File

@ -2,7 +2,7 @@
"objects" : [
{
"id" : "wheat",
"id" : "wheat_plant",
"hitboxData" : [
{
"type": "static_capsule",
@ -11,7 +11,24 @@
}
],
"tokens": [
"HARVESTABLE"
],
"buttonInteraction" : {
"onInteract" : "harvest",
"interactionShape" : {
"type" : "CUBE",
"dimension1" : 0.3,
"dimension2" : 0.3,
"dimension3" : 0.3,
"rotX": 0,
"rotY": 0,
"rotZ": 0,
"rotW": 1,
"offsetX" : 0.0,
"offsetY" : 0.1,
"offsetZ" : 0.0
}
},
"graphicsTemplate": {
"model": {
"path" : "Models/foliage/flowers/Flower_3_Group.gltf"
@ -20,16 +37,25 @@
"growthData" : {
"growthMax" : 1000,
"scaleMax" : 3,
"earlyGrowthLoot" : {
"tickets" : [
]
},
"maxGrowthLoot" : {
"tickets" : [
]
}
},
"healthSystem" : {
"maxHealth" : 5,
"onDamageIFrames" : 0,
"lootPool" : {
"tickets" : [
{
"itemId" : "mat:Rock",
"rarity" : 1.0,
"minQuantity" : 1,
"maxQuantity" : 1
}
]
}
}
}

View File

@ -1739,6 +1739,8 @@ Scaffolding growing component
(05/13/2025)
Fix character bug with loading into level
Multiple loot pool support
Crops replace loot pool on completion of growth

View File

@ -22,11 +22,6 @@ public class GrowthData {
*/
LootPool maxGrowthLoot;
/**
* The loot pool for when the entity has not completed growing
*/
LootPool earlyGrowthLoot;
/**
* Gets the maximum value to grow to
* @return The maximum value to grow to
@ -43,14 +38,6 @@ public class GrowthData {
return maxGrowthLoot;
}
/**
* Gets the loot pool to drop when death/harvest before max growth
* @return The loot pool
*/
public LootPool getEarlyGrowthLoot() {
return earlyGrowthLoot;
}
/**
* Gets the scale for when the entity finishes growing
* @return The scale

View File

@ -367,6 +367,11 @@ public class EntityDataStrings {
*/
public static final String TREE_SERVERGROWTH = "treeServerGrowth";
public static final String TREE_CLIENTGROWTH = "treeClientGrowth";
/**
* Loot pool
*/
public static final String LOOT_POOL = "lootPool";
/*
Entity categories

View File

@ -14,6 +14,7 @@ import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.life.ServerLifeTree;
import electrosphere.net.synchronization.annotation.SyncedField;
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
@ -54,6 +55,9 @@ public class ServerGrowthComponent implements BehaviorTree {
if(status < data.getGrowthMax()){
this.setStatus(status + 1);
}
if(status == data.getGrowthMax()){
ServerLifeTree.setLootPool(parent, this.data.getMaxGrowthLoot());
}
float percentage = this.status / (float)data.getGrowthMax();
Vector3d targetScale = new Vector3d(data.getScaleMax() * percentage);
ServerEntityUtils.setScale(parent, targetScale);

View File

@ -22,6 +22,7 @@ import org.joml.Vector3d;
import electrosphere.data.collidable.HitboxData;
import electrosphere.data.common.life.HealthSystem;
import electrosphere.data.common.life.loot.LootPool;
import electrosphere.data.common.life.loot.LootTicket;
import electrosphere.engine.Globals;
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState;
@ -85,7 +86,7 @@ public class ServerLifeTree implements BehaviorTree {
this.stateTransitionUtil.simulate(LifeStateEnum.DYING);
} break;
case DEAD: {
if(this.healthSystem.getLootPool() != null){
if(ServerLifeTree.hasLootPool(parent)){
this.rollLootPool();
}
//delete the entity
@ -134,13 +135,17 @@ public class ServerLifeTree implements BehaviorTree {
* Roll the loot pool
*/
protected void rollLootPool(){
if(this.healthSystem.getLootPool() == null || this.healthSystem.getLootPool().getTickets() == null){
if(!ServerLifeTree.hasLootPool(parent)){
return;
}
LootPool lootPool = ServerLifeTree.getLootPool(parent);
if(lootPool == null || lootPool.getTickets() == null){
return;
}
Random random = new Random();
Vector3d position = new Vector3d(EntityUtils.getPosition(parent));
Realm realm = Globals.realmManager.getEntityRealm(parent);
for(LootTicket ticket : this.healthSystem.getLootPool().getTickets()){
for(LootTicket ticket : lootPool.getTickets()){
if(random.nextDouble() <= ticket.getRarity()){
int numToGen = random.nextInt(ticket.getMinQuantity(), ticket.getMaxQuantity()+1);
for(int i = 0; i < numToGen; i++){
@ -244,6 +249,33 @@ public class ServerLifeTree implements BehaviorTree {
this.collisionAccumulator.add(collisionEvent);
}
/**
* Sets the loot pool of the entity
* @param entity The entity
* @param lootPool The loot pool
*/
public static void setLootPool(Entity entity, LootPool lootPool){
entity.putData(EntityDataStrings.LOOT_POOL, lootPool);
}
/**
* Gets the loot pool on an entity
* @param entity The entity
* @return The loot pool if it exists, null otherwise
*/
public static LootPool getLootPool(Entity entity){
return (LootPool)entity.getData(EntityDataStrings.LOOT_POOL);
}
/**
* Checks if an entity has a loot pool
* @param entity The entity
* @return true if it has a loot pool, false otherwise
*/
public static boolean hasLootPool(Entity entity){
return entity.containsKey(EntityDataStrings.LOOT_POOL);
}
/**
* <p> Automatically generated </p>
* <p>
@ -324,6 +356,9 @@ public class ServerLifeTree implements BehaviorTree {
}
)
});
if(this.healthSystem.getLootPool() != null){
ServerLifeTree.setLootPool(parent, this.healthSystem.getLootPool());
}
}
/**