Jet shooting
This commit is contained in:
parent
5874cac33b
commit
1dcb3df6a8
@ -93,12 +93,11 @@
|
|||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone",
|
"bone": "Bone",
|
||||||
"radius": 0.04
|
"radius": 0.6
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tokens" : [
|
"tokens" : [
|
||||||
"BLENDER_TRANSFORM",
|
"SHOOTER",
|
||||||
"ATTACKER",
|
|
||||||
"GRAVITY",
|
"GRAVITY",
|
||||||
"TARGETABLE",
|
"TARGETABLE",
|
||||||
"OUTLINE",
|
"OUTLINE",
|
||||||
@ -117,17 +116,6 @@
|
|||||||
],
|
],
|
||||||
"rotatorSystem" : {
|
"rotatorSystem" : {
|
||||||
"rotatorItems" : [
|
"rotatorItems" : [
|
||||||
{
|
|
||||||
"boneName" : "Bone",
|
|
||||||
"constraints" : [
|
|
||||||
{
|
|
||||||
"followsView" : true,
|
|
||||||
"followsBone" : false,
|
|
||||||
"parentBone" : "",
|
|
||||||
"allowedMarginPitch" : 0.2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"equipPoints" : [
|
"equipPoints" : [
|
||||||
@ -142,6 +130,23 @@
|
|||||||
"offsetZ" : 0
|
"offsetZ" : 0
|
||||||
},
|
},
|
||||||
"attackMoves" : [
|
"attackMoves" : [
|
||||||
|
{
|
||||||
|
"attackMoveId" : "ProjectileFire",
|
||||||
|
"type" : "PROJECTILE",
|
||||||
|
"windupAnimationName" : "Idle1",
|
||||||
|
"holdAnimationName" : "Idle1",
|
||||||
|
"attackAnimationName" : "Idle1",
|
||||||
|
"damageStartFrame" : 1,
|
||||||
|
"damageEndFrame" : 2,
|
||||||
|
"firesProjectile" : true,
|
||||||
|
"nextMoveId" : "",
|
||||||
|
"nextAttackMoveWindowStart" : 0,
|
||||||
|
"nextAttackMoveWindowEnd" : 1,
|
||||||
|
"movementStart" : 0,
|
||||||
|
"movementEnd" : 0,
|
||||||
|
"movementGoal" : 0,
|
||||||
|
"initialMove" : false
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"healthSystem" : {
|
"healthSystem" : {
|
||||||
"maxHealth" : 100,
|
"maxHealth" : 100,
|
||||||
|
|||||||
@ -11,6 +11,16 @@
|
|||||||
"collidable": null,
|
"collidable": null,
|
||||||
"graphicsTemplate": null
|
"graphicsTemplate": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"objectId" : "skyscraper1",
|
||||||
|
"modelPath" : "Models/skyscraper1.fbx",
|
||||||
|
"tokens" : [
|
||||||
|
"DISABLE_COLLISION_REACTION",
|
||||||
|
"GENERATE_COLLISION_TERRAIN"
|
||||||
|
],
|
||||||
|
"collidable": null,
|
||||||
|
"graphicsTemplate": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"objectId" : "smoke1",
|
"objectId" : "smoke1",
|
||||||
"modelPath" : "Models/unitcube.fbx",
|
"modelPath" : "Models/unitcube.fbx",
|
||||||
|
|||||||
12
assets/Data/projectile.json
Normal file
12
assets/Data/projectile.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"projectiles" : [
|
||||||
|
{
|
||||||
|
"id" : "missile1",
|
||||||
|
"modelPath" : "Models/unitsphere.fbx",
|
||||||
|
"maxLife" : 10000,
|
||||||
|
"velocity" : 0.1,
|
||||||
|
"damage" : 1,
|
||||||
|
"hitboxRadius" : 0.4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -18,7 +18,7 @@
|
|||||||
"meshName" : "Cube.001",
|
"meshName" : "Cube.001",
|
||||||
"rotation" : [0.0, 0.0, -0.7071068, 0.7071068],
|
"rotation" : [0.0, 0.0, -0.7071068, 0.7071068],
|
||||||
"offset" : [0.0, 0.0, 0.0],
|
"offset" : [0.0, 0.0, 0.0],
|
||||||
"scale" : [0.3, 0.3, 0.3]
|
"scale" : [0.0015, 0.0015, 0.0015]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
assets/Models/skyscraper1.fbx
Normal file
BIN
assets/Models/skyscraper1.fbx
Normal file
Binary file not shown.
@ -10,6 +10,28 @@
|
|||||||
"rotY": 0,
|
"rotY": 0,
|
||||||
"rotZ": 0,
|
"rotZ": 0,
|
||||||
"rotW": 0.7071068
|
"rotW": 0.7071068
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"subtype": "skyscraper1",
|
||||||
|
"posX": 2,
|
||||||
|
"posY": 1,
|
||||||
|
"posZ": 2,
|
||||||
|
"rotX": -0.7071068,
|
||||||
|
"rotY": 0,
|
||||||
|
"rotZ": 0,
|
||||||
|
"rotW": 0.7071068
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "creature",
|
||||||
|
"subtype": "fighter",
|
||||||
|
"posX": 2,
|
||||||
|
"posY": 1,
|
||||||
|
"posZ": 2,
|
||||||
|
"rotX": -0.7071068,
|
||||||
|
"rotY": 0,
|
||||||
|
"rotZ": 0,
|
||||||
|
"rotW": 0.7071068
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"scriptPaths": [
|
"scriptPaths": [
|
||||||
|
|||||||
1
assets/Scenes/testscene2/someScript.js
Normal file
1
assets/Scenes/testscene2/someScript.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
console.log("Loaded testscene1");
|
||||||
30
assets/Scenes/testscene2/testscene2.json
Normal file
30
assets/Scenes/testscene2/testscene2.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"subtype": "terrain1",
|
||||||
|
"posX": 2,
|
||||||
|
"posY": 1,
|
||||||
|
"posZ": 2,
|
||||||
|
"rotX": -0.7071068,
|
||||||
|
"rotY": 0,
|
||||||
|
"rotZ": 0,
|
||||||
|
"rotW": 0.7071068
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "creature",
|
||||||
|
"subtype": "fighter",
|
||||||
|
"posX": 2,
|
||||||
|
"posY": 1,
|
||||||
|
"posZ": 2,
|
||||||
|
"rotX": -0.7071068,
|
||||||
|
"rotY": 0,
|
||||||
|
"rotZ": 0,
|
||||||
|
"rotW": 0.7071068
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scriptPaths": [
|
||||||
|
"Scenes/testscene1/someScript.js"
|
||||||
|
],
|
||||||
|
"initScriptPath": "Scenes/testscene1/someScript.js"
|
||||||
|
}
|
||||||
@ -425,6 +425,12 @@
|
|||||||
"/Textures/f15.png",
|
"/Textures/f15.png",
|
||||||
"/Textures/f15.png"
|
"/Textures/f15.png"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"Models/skyscraper1.fbx" : {
|
||||||
|
"Cube.001" : [
|
||||||
|
"Textures/skyscraper1.png",
|
||||||
|
"Textures/skyscraper1.png"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BIN
assets/Textures/skyscraper1.png
Normal file
BIN
assets/Textures/skyscraper1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 380 KiB |
@ -77,6 +77,7 @@ import electrosphere.controls.Control.ControlType;
|
|||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.state.BehaviorTree;
|
import electrosphere.entity.state.BehaviorTree;
|
||||||
import electrosphere.entity.state.attack.AttackTree;
|
import electrosphere.entity.state.attack.AttackTree;
|
||||||
|
import electrosphere.entity.state.attack.ShooterTree;
|
||||||
import electrosphere.entity.state.equip.EquipState;
|
import electrosphere.entity.state.equip.EquipState;
|
||||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||||
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
|
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
|
||||||
@ -808,6 +809,18 @@ public class ControlHandler {
|
|||||||
// CreatureUtils.setFacingVector(Globals.playerCharacter, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize());
|
// CreatureUtils.setFacingVector(Globals.playerCharacter, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize());
|
||||||
attackTree.start();
|
attackTree.start();
|
||||||
}
|
}
|
||||||
|
ShooterTree shooterTree = ShooterTree.getShooterTree(Globals.playerEntity);
|
||||||
|
if(shooterTree != null){
|
||||||
|
shooterTree.fire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnRepeat(new ControlMethod(){public void execute(){
|
||||||
|
if(Globals.playerEntity != null){
|
||||||
|
ShooterTree shooterTree = ShooterTree.getShooterTree(Globals.playerEntity);
|
||||||
|
if(shooterTree != null){
|
||||||
|
shooterTree.fire();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnRelease(new ControlMethod(){public void execute(){
|
controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnRelease(new ControlMethod(){public void execute(){
|
||||||
@ -820,6 +833,7 @@ public class ControlHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
|
controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setRepeatTimeout(0.5f * Main.targetFrameRate);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -175,6 +175,16 @@ public class EntityDataStrings {
|
|||||||
public static final String ATTACK_MOVE_TYPE_ACTIVE = "attackMoveTypeActive";
|
public static final String ATTACK_MOVE_TYPE_ACTIVE = "attackMoveTypeActive";
|
||||||
public static final String ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND = "MELEE_WEAPON_SWING_ONE_HAND";
|
public static final String ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND = "MELEE_WEAPON_SWING_ONE_HAND";
|
||||||
public static final String ATTACK_MOVE_TYPE_BOW_TWO_HAND = "RANGED_WEAPON_BOW_TWO_HAND";
|
public static final String ATTACK_MOVE_TYPE_BOW_TWO_HAND = "RANGED_WEAPON_BOW_TWO_HAND";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shooter tree
|
||||||
|
*/
|
||||||
|
public static final String SHOOTER_TREE = "shooterTree";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Projectile/Projectile tree
|
||||||
|
*/
|
||||||
|
public static final String PROJECTILE_TREE = "projectileTree";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Health System
|
Health System
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
package electrosphere.entity.state.attack;
|
package electrosphere.entity.state.attack;
|
||||||
|
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityDataStrings;
|
||||||
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.state.BehaviorTree;
|
import electrosphere.entity.state.BehaviorTree;
|
||||||
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
|
import electrosphere.entity.types.projectile.ProjectileUtils;
|
||||||
|
|
||||||
public class ShooterTree implements BehaviorTree {
|
public class ShooterTree implements BehaviorTree {
|
||||||
|
|
||||||
@ -15,11 +21,15 @@ public class ShooterTree implements BehaviorTree {
|
|||||||
|
|
||||||
Entity parent;
|
Entity parent;
|
||||||
|
|
||||||
int ammoAvailable;
|
int ammoAvailable = 1;
|
||||||
int ammoMax;
|
int ammoMax = 1;
|
||||||
|
|
||||||
|
int cooldownCurrent = 0;
|
||||||
|
int cooldownMax = 4;
|
||||||
|
|
||||||
public ShooterTree(Entity parent){
|
public ShooterTree(Entity parent){
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
this.state = ShooterTreeState.IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -28,9 +38,19 @@ public class ShooterTree implements BehaviorTree {
|
|||||||
switch(state){
|
switch(state){
|
||||||
case ATTACK: {
|
case ATTACK: {
|
||||||
//
|
//
|
||||||
|
Vector3d parentPosition = EntityUtils.getPosition(parent);
|
||||||
|
Vector3d movementDir = CreatureUtils.getFacingVector(parent);
|
||||||
|
ProjectileUtils.spawnProjectile("missile1", parentPosition, new Vector3d(movementDir),parent);
|
||||||
|
this.state = ShooterTreeState.COOLDOWN;
|
||||||
|
cooldownCurrent = cooldownMax;
|
||||||
} break;
|
} break;
|
||||||
case COOLDOWN: {
|
case COOLDOWN: {
|
||||||
//
|
//
|
||||||
|
if(cooldownCurrent > 0){
|
||||||
|
cooldownCurrent--;
|
||||||
|
} else {
|
||||||
|
state = ShooterTreeState.IDLE;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case IDLE: {
|
case IDLE: {
|
||||||
//
|
//
|
||||||
@ -48,8 +68,16 @@ public class ShooterTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
if(canFire){
|
if(canFire){
|
||||||
//fire
|
//fire
|
||||||
System.out.println("Fire!");
|
this.state = ShooterTreeState.ATTACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setShooterTree(Entity entity, ShooterTree shooterTree){
|
||||||
|
entity.putData(EntityDataStrings.SHOOTER_TREE, shooterTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ShooterTree getShooterTree(Entity entity){
|
||||||
|
return (ShooterTree)entity.getData(EntityDataStrings.SHOOTER_TREE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,6 +107,7 @@ public class LifeState implements BehaviorTree {
|
|||||||
public void damage(int damage){
|
public void damage(int damage){
|
||||||
if(!isInvincible){
|
if(!isInvincible){
|
||||||
lifeCurrent = lifeCurrent - damage;
|
lifeCurrent = lifeCurrent - damage;
|
||||||
|
System.out.println(lifeCurrent);
|
||||||
isInvincible = true;
|
isInvincible = true;
|
||||||
if(lifeCurrent < 0){
|
if(lifeCurrent < 0){
|
||||||
lifeCurrent = 0;
|
lifeCurrent = 0;
|
||||||
|
|||||||
@ -206,7 +206,8 @@ public class AirplaneMovementTree implements BehaviorTree {
|
|||||||
|
|
||||||
|
|
||||||
//rotate thrust vector
|
//rotate thrust vector
|
||||||
rotationVector.set(new Vector3f((float)rotationVector.x,(float)rotationVector.y,(float)rotationVector.z).mul(1.0f - this.maxRotationSpeed).add(new Vector3f(cameraEyeVector).mul(-this.maxRotationSpeed)));
|
rotationVector.set(rotation.transform(new Vector3f(0,0,1)));
|
||||||
|
// rotationVector.set(new Vector3f((float)rotationVector.x,(float)rotationVector.y,(float)rotationVector.z).mul(1.0f - this.maxRotationSpeed).add(new Vector3f(cameraEyeVector).mul(-this.maxRotationSpeed)));
|
||||||
|
|
||||||
|
|
||||||
rollVal = rollVal * 0.9f;
|
rollVal = rollVal * 0.9f;
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import org.joml.Vector3d;
|
|||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.state.BehaviorTree;
|
import electrosphere.entity.state.BehaviorTree;
|
||||||
import electrosphere.main.Globals;
|
import electrosphere.main.Globals;
|
||||||
@ -13,14 +14,31 @@ public class ProjectileTree implements BehaviorTree {
|
|||||||
Entity parent;
|
Entity parent;
|
||||||
int maxLife;
|
int maxLife;
|
||||||
int lifeCurrent = 0;
|
int lifeCurrent = 0;
|
||||||
Vector3f vector;
|
float damage = 0.0f;
|
||||||
|
Vector3d vector;
|
||||||
|
|
||||||
public ProjectileTree(Entity parent, int maxLife, Vector3f initialVector, float velocity){
|
public ProjectileTree(Entity parent, int maxLife, Vector3d initialVector, float velocity){
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.maxLife = maxLife;
|
this.maxLife = maxLife;
|
||||||
this.vector = initialVector.mul(velocity);
|
this.vector = initialVector.mul(velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used when spawning projectiles from projectiles.json file
|
||||||
|
* Separate constructor so can include damage value
|
||||||
|
* @param parent Parent entity of the projectile
|
||||||
|
* @param maxLife Max flight time of the projectile in frames
|
||||||
|
* @param initialVector The initial velocity vector of the projectile
|
||||||
|
* @param velocity The intiial velocity magnitude of the projectile
|
||||||
|
* @param damage The damage of the projectile
|
||||||
|
*/
|
||||||
|
public ProjectileTree(Entity parent, int maxLife, Vector3d initialVector, float velocity, float damage){
|
||||||
|
this.parent = parent;
|
||||||
|
this.maxLife = maxLife;
|
||||||
|
this.vector = initialVector.mul(velocity);
|
||||||
|
this.damage = damage;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simulate() {
|
public void simulate() {
|
||||||
|
|
||||||
@ -34,5 +52,31 @@ public class ProjectileTree implements BehaviorTree {
|
|||||||
positionCurrent.add(vector);
|
positionCurrent.add(vector);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only relevant when spawned from projectiles.json file
|
||||||
|
* @return The damage of the projectile as defined in projectiles.json
|
||||||
|
*/
|
||||||
|
public float getDamage(){
|
||||||
|
return damage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the projectile tree of a given entity
|
||||||
|
* @param entity The entity
|
||||||
|
* @param tree The projectile tree
|
||||||
|
*/
|
||||||
|
public static void setProjectileTree(Entity entity, ProjectileTree tree){
|
||||||
|
entity.putData(EntityDataStrings.PROJECTILE_TREE, tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the projectile tree of a given entity
|
||||||
|
* @param entity The entity
|
||||||
|
* @return The projectile tree
|
||||||
|
*/
|
||||||
|
public static ProjectileTree getProjectileTree(Entity entity){
|
||||||
|
return (ProjectileTree)entity.getData(EntityDataStrings.PROJECTILE_TREE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import electrosphere.game.data.creature.type.CreatureType;
|
|||||||
import electrosphere.entity.state.BehaviorTree;
|
import electrosphere.entity.state.BehaviorTree;
|
||||||
import electrosphere.entity.state.IdleTree;
|
import electrosphere.entity.state.IdleTree;
|
||||||
import electrosphere.entity.state.attack.AttackTree;
|
import electrosphere.entity.state.attack.AttackTree;
|
||||||
|
import electrosphere.entity.state.attack.ShooterTree;
|
||||||
import electrosphere.entity.state.collidable.CollidableTree;
|
import electrosphere.entity.state.collidable.CollidableTree;
|
||||||
import electrosphere.entity.state.equip.EquipState;
|
import electrosphere.entity.state.equip.EquipState;
|
||||||
import electrosphere.entity.state.gravity.GravityTree;
|
import electrosphere.entity.state.gravity.GravityTree;
|
||||||
@ -299,6 +300,11 @@ public class CreatureUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "SHOOTER": {
|
||||||
|
ShooterTree shooterTree = new ShooterTree(rVal);
|
||||||
|
ShooterTree.setShooterTree(rVal, shooterTree);
|
||||||
|
Globals.entityManager.registerBehaviorTree(shooterTree);
|
||||||
|
} break;
|
||||||
case "GRAVITY":
|
case "GRAVITY":
|
||||||
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
|
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
|
||||||
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
||||||
|
|||||||
@ -1,11 +1,19 @@
|
|||||||
package electrosphere.entity.types.hitbox;
|
package electrosphere.entity.types.hitbox;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.types.hitbox.HitboxUtils.HitboxPositionCallback;
|
||||||
|
|
||||||
public class HitboxData {
|
public class HitboxData {
|
||||||
String type;
|
String type;
|
||||||
String bone;
|
String bone;
|
||||||
float radius;
|
float radius;
|
||||||
boolean active = false;
|
boolean active = false;
|
||||||
|
//used for more advanced hitbox spawning to find hitbox position on frame update
|
||||||
|
HitboxPositionCallback positionCallback;
|
||||||
|
//used to filter this hitbox to hitting only certain parent entities
|
||||||
|
List<Entity> filter;
|
||||||
|
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return type;
|
return type;
|
||||||
@ -38,6 +46,38 @@ public class HitboxData {
|
|||||||
public void setRadius(float radius) {
|
public void setRadius(float radius) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the position callback
|
||||||
|
* @return The position callback
|
||||||
|
*/
|
||||||
|
public HitboxPositionCallback getPositionCallback(){
|
||||||
|
return positionCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position callback
|
||||||
|
* @param positionCallback The position callback
|
||||||
|
*/
|
||||||
|
public void setPositionCallback(HitboxPositionCallback positionCallback){
|
||||||
|
this.positionCallback = positionCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an entity filter on the hitbox
|
||||||
|
* @param filter The list of parent entities to exclude from collisions
|
||||||
|
*/
|
||||||
|
public void setEntityFilter(List<Entity> filter){
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entity filter
|
||||||
|
* @return The list of parent entities to exclude from collisions
|
||||||
|
*/
|
||||||
|
public List<Entity> getEntityFilter(){
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,9 +4,12 @@ import electrosphere.entity.Entity;
|
|||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
import electrosphere.entity.types.item.ItemUtils;
|
||||||
|
import electrosphere.entity.state.attack.ShooterTree;
|
||||||
import electrosphere.entity.state.life.LifeState;
|
import electrosphere.entity.state.life.LifeState;
|
||||||
import electrosphere.entity.state.life.LifeUtils;
|
import electrosphere.entity.state.life.LifeUtils;
|
||||||
|
import electrosphere.entity.state.movement.ProjectileTree;
|
||||||
import electrosphere.game.server.effects.ParticleEffects;
|
import electrosphere.game.server.effects.ParticleEffects;
|
||||||
import electrosphere.main.Globals;
|
import electrosphere.main.Globals;
|
||||||
|
|
||||||
@ -47,7 +50,35 @@ public class HitboxUtils {
|
|||||||
data.setBone(bone);
|
data.setBone(bone);
|
||||||
data.setRadius(size);
|
data.setRadius(size);
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
|
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
|
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
|
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
|
Globals.hitboxManager.registerHitbox(rVal);
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone
|
||||||
|
* @param parent The parent entity of the hitbox
|
||||||
|
* @param positionCallback The position callback for keeping hitbox entity position up to date
|
||||||
|
* @param size The size of the hitbox
|
||||||
|
* @param hurtbox If true, it will instead be a hurtbox
|
||||||
|
* @param filter an optional list of parent entities to not colide with
|
||||||
|
* @return The hitbox entity
|
||||||
|
*/
|
||||||
|
public static Entity spawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
|
||||||
|
Entity rVal = new Entity();
|
||||||
|
HitboxData data = new HitboxData();
|
||||||
|
data.setActive(true);
|
||||||
|
data.setPositionCallback(positionCallback);
|
||||||
|
data.setRadius(size);
|
||||||
|
data.setEntityFilter(filter);
|
||||||
|
if(hurtbox){
|
||||||
|
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
||||||
|
} else {
|
||||||
|
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
||||||
|
}
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
@ -60,22 +91,27 @@ public class HitboxUtils {
|
|||||||
Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT));
|
Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT));
|
||||||
HitboxData hitboxData = getHitboxData(hitbox);
|
HitboxData hitboxData = getHitboxData(hitbox);
|
||||||
String boneName = hitboxData.getBone();
|
String boneName = hitboxData.getBone();
|
||||||
Quaternionf parentRotation = ((Quaternionf)EntityUtils.getRotation(parent));
|
if(boneName != null){
|
||||||
Vector3f positionScale = ((Vector3f)EntityUtils.getScale(parent));
|
Quaternionf parentRotation = EntityUtils.getRotation(parent);
|
||||||
Vector3f worldPosition = new Vector3f();
|
Vector3f positionScale = EntityUtils.getScale(parent);
|
||||||
Vector3f bonePosition = EntityUtils.getActor(parent).getBonePosition(boneName);
|
Vector3f worldPosition = new Vector3f();
|
||||||
Vector3d parentPos = EntityUtils.getPosition(parent);
|
Vector3f bonePosition = EntityUtils.getActor(parent).getBonePosition(boneName);
|
||||||
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
|
Vector3d parentPos = EntityUtils.getPosition(parent);
|
||||||
Quaternionf rotation = new Quaternionf(parentRotation);
|
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
|
||||||
|
Quaternionf rotation = new Quaternionf(parentRotation);
|
||||||
worldPosition = worldPosition.mul(positionScale);
|
|
||||||
|
worldPosition = worldPosition.mul(positionScale);
|
||||||
|
|
||||||
worldPosition = worldPosition.rotate(rotation);
|
worldPosition = worldPosition.rotate(rotation);
|
||||||
|
|
||||||
|
|
||||||
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
|
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
|
||||||
|
|
||||||
((Vector3d)hitbox.getData(EntityDataStrings.DATA_STRING_POSITION)).set(worldPosition);
|
EntityUtils.getPosition(hitbox).set(worldPosition);
|
||||||
|
} else {
|
||||||
|
HitboxPositionCallback positionCallback = hitboxData.getPositionCallback();
|
||||||
|
EntityUtils.getPosition(hitbox).set(positionCallback.getPosition());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void collideEntities(Entity generatorHitbox){
|
public static void collideEntities(Entity generatorHitbox){
|
||||||
@ -90,6 +126,17 @@ public class HitboxUtils {
|
|||||||
|
|
||||||
HitboxData generatorData = getHitboxData(generatorHitbox);
|
HitboxData generatorData = getHitboxData(generatorHitbox);
|
||||||
HitboxData receiverData = getHitboxData(receiverHitbox);
|
HitboxData receiverData = getHitboxData(receiverHitbox);
|
||||||
|
|
||||||
|
//check projectile filters
|
||||||
|
List<Entity> generatorFilter = generatorData.getEntityFilter();
|
||||||
|
if(generatorFilter != null && generatorFilter.contains(receiverParent)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Entity> receiverFilter = receiverData.getEntityFilter();
|
||||||
|
if(receiverFilter != null && receiverFilter.contains(generatorParent)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//if there is a collision
|
//if there is a collision
|
||||||
//and the collision isn't against itself
|
//and the collision isn't against itself
|
||||||
@ -140,7 +187,16 @@ public class HitboxUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
int damage = 0;
|
||||||
|
//for entities using attacktree
|
||||||
|
if(CreatureUtils.getAttackTree(hitboxParent) != null){
|
||||||
|
damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
||||||
|
} else {
|
||||||
|
//for entities using shooter tree
|
||||||
|
if(ProjectileTree.getProjectileTree(hitboxParent) != null){
|
||||||
|
damage = (int)ProjectileTree.getProjectileTree(hitboxParent).getDamage();
|
||||||
|
}
|
||||||
|
}
|
||||||
LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
||||||
if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
||||||
EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
||||||
@ -161,5 +217,16 @@ public class HitboxUtils {
|
|||||||
public static List<Entity> getHurtboxAssociatedList(Entity e){
|
public static List<Entity> getHurtboxAssociatedList(Entity e){
|
||||||
return (List<Entity>)e.getData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST);
|
return (List<Entity>)e.getData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended to be implemented as an anonoymous class when needed
|
||||||
|
*/
|
||||||
|
public interface HitboxPositionCallback {
|
||||||
|
/**
|
||||||
|
* Gets the current position this hitbox should be at
|
||||||
|
* @return The position this hitbox should be at
|
||||||
|
*/
|
||||||
|
public Vector3d getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
package electrosphere.entity.types.projectile;
|
package electrosphere.entity.types.projectile;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Quaternionfc;
|
import org.joml.Quaternionfc;
|
||||||
@ -9,6 +12,9 @@ import org.joml.Vector3f;
|
|||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.state.movement.ProjectileTree;
|
import electrosphere.entity.state.movement.ProjectileTree;
|
||||||
|
import electrosphere.entity.types.hitbox.HitboxUtils;
|
||||||
|
import electrosphere.entity.types.hitbox.HitboxUtils.HitboxPositionCallback;
|
||||||
|
import electrosphere.game.data.projectile.ProjectileType;
|
||||||
import electrosphere.main.Globals;
|
import electrosphere.main.Globals;
|
||||||
|
|
||||||
public class ProjectileUtils {
|
public class ProjectileUtils {
|
||||||
@ -16,7 +22,7 @@ public class ProjectileUtils {
|
|||||||
public static Entity spawnBasicProjectile(String model, Vector3d initialPosition, Quaternionf rotation, int maxLife, Vector3f initialVector, float velocity){
|
public static Entity spawnBasicProjectile(String model, Vector3d initialPosition, Quaternionf rotation, int maxLife, Vector3f initialVector, float velocity){
|
||||||
Entity rVal = EntityUtils.spawnDrawableEntity(model);
|
Entity rVal = EntityUtils.spawnDrawableEntity(model);
|
||||||
Globals.assetManager.addModelPathToQueue(model);
|
Globals.assetManager.addModelPathToQueue(model);
|
||||||
ProjectileTree tree = new ProjectileTree(rVal,maxLife,initialVector,velocity);
|
ProjectileTree tree = new ProjectileTree(rVal,maxLife,new Vector3d(initialVector),velocity);
|
||||||
EntityUtils.getPosition(rVal).set(initialPosition);
|
EntityUtils.getPosition(rVal).set(initialPosition);
|
||||||
// EntityUtils.getRotation(currentEntity).rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize();
|
// EntityUtils.getRotation(currentEntity).rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize();
|
||||||
EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize();
|
EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize();
|
||||||
@ -27,4 +33,35 @@ public class ProjectileUtils {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* More sophisticated function for spawning projectiles. Uses the projectiles.json file to store data about types to spawn.
|
||||||
|
* Also filters the parent from being hit by their own projectiles.
|
||||||
|
* @param projectileType The type in projectiles.json to spawn
|
||||||
|
* @param initialPosition The initial position of the projectile
|
||||||
|
* @param initialVector The initial velocity of the projectile
|
||||||
|
* @param parent The parent that fired said projectile
|
||||||
|
* @return The projectile entity
|
||||||
|
*/
|
||||||
|
public static Entity spawnProjectile(String projectileType, Vector3d initialPosition, Vector3d initialVector, Entity parent){
|
||||||
|
ProjectileType rawType = Globals.gameConfigCurrent.getProjectileMap().getType(projectileType);
|
||||||
|
Entity rVal = EntityUtils.spawnDrawableEntity(rawType.getModelPath());
|
||||||
|
//initial coordinates
|
||||||
|
EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize();
|
||||||
|
EntityUtils.getPosition(rVal).set(initialPosition);
|
||||||
|
//projectile behavior tree
|
||||||
|
ProjectileTree tree = new ProjectileTree(rVal,rawType.getMaxLife(),initialVector,rawType.getVelocity(), rawType.getDamage());
|
||||||
|
Globals.entityManager.registerBehaviorTree(tree);
|
||||||
|
ProjectileTree.setProjectileTree(rVal, tree);
|
||||||
|
//filter construction
|
||||||
|
List<Entity> filter = new LinkedList<Entity>();
|
||||||
|
filter.add(parent);
|
||||||
|
//collidable
|
||||||
|
HitboxUtils.spawnRegularHitbox(rVal, new HitboxPositionCallback() {
|
||||||
|
public Vector3d getPosition(){
|
||||||
|
return EntityUtils.getPosition(rVal);
|
||||||
|
}
|
||||||
|
}, rawType.getHitboxRadius(), false, filter);
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import electrosphere.game.data.item.type.model.ItemTypeMap;
|
|||||||
import electrosphere.game.data.object.type.ObjectData;
|
import electrosphere.game.data.object.type.ObjectData;
|
||||||
import electrosphere.game.data.object.type.model.ObjectTypeLoader;
|
import electrosphere.game.data.object.type.model.ObjectTypeLoader;
|
||||||
import electrosphere.game.data.object.type.model.ObjectTypeMap;
|
import electrosphere.game.data.object.type.model.ObjectTypeMap;
|
||||||
|
import electrosphere.game.data.projectile.ProjectileTypeHolder;
|
||||||
import electrosphere.game.data.structure.type.model.StructureTypeMap;
|
import electrosphere.game.data.structure.type.model.StructureTypeMap;
|
||||||
import electrosphere.game.server.race.model.RaceMap;
|
import electrosphere.game.server.race.model.RaceMap;
|
||||||
import electrosphere.game.server.symbolism.model.SymbolMap;
|
import electrosphere.game.server.symbolism.model.SymbolMap;
|
||||||
@ -30,6 +31,7 @@ public class Config {
|
|||||||
ObjectTypeLoader objectTypeLoader;
|
ObjectTypeLoader objectTypeLoader;
|
||||||
SymbolMap symbolMap;
|
SymbolMap symbolMap;
|
||||||
RaceMap raceMap;
|
RaceMap raceMap;
|
||||||
|
ProjectileTypeHolder projectileTypeHolder;
|
||||||
|
|
||||||
public static Config loadDefaultConfig(){
|
public static Config loadDefaultConfig(){
|
||||||
Config config = new Config();
|
Config config = new Config();
|
||||||
@ -40,6 +42,8 @@ public class Config {
|
|||||||
config.objectTypeLoader = loadObjectTypes("Data/objects.json");
|
config.objectTypeLoader = loadObjectTypes("Data/objects.json");
|
||||||
config.symbolMap = FileUtils.loadObjectFromAssetPath("Data/symbolism.json", SymbolMap.class);
|
config.symbolMap = FileUtils.loadObjectFromAssetPath("Data/symbolism.json", SymbolMap.class);
|
||||||
config.raceMap = FileUtils.loadObjectFromAssetPath("Data/races.json", RaceMap.class);
|
config.raceMap = FileUtils.loadObjectFromAssetPath("Data/races.json", RaceMap.class);
|
||||||
|
config.projectileTypeHolder = FileUtils.loadObjectFromAssetPath("Data/projectile.json", ProjectileTypeHolder.class);
|
||||||
|
config.projectileTypeHolder.init();
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,5 +135,9 @@ public class Config {
|
|||||||
public ObjectTypeLoader getObjectTypeLoader() {
|
public ObjectTypeLoader getObjectTypeLoader() {
|
||||||
return objectTypeLoader;
|
return objectTypeLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ProjectileTypeHolder getProjectileMap(){
|
||||||
|
return projectileTypeHolder;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,37 @@
|
|||||||
|
package electrosphere.game.data.projectile;
|
||||||
|
|
||||||
|
public class ProjectileType {
|
||||||
|
|
||||||
|
|
||||||
|
String id;
|
||||||
|
String modelPath;
|
||||||
|
int maxLife;
|
||||||
|
float velocity;
|
||||||
|
float damage;
|
||||||
|
float hitboxRadius;
|
||||||
|
|
||||||
|
public String getId(){
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModelPath(){
|
||||||
|
return modelPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxLife(){
|
||||||
|
return maxLife;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getVelocity(){
|
||||||
|
return velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getDamage(){
|
||||||
|
return damage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getHitboxRadius(){
|
||||||
|
return hitboxRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package electrosphere.game.data.projectile;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ProjectileTypeHolder {
|
||||||
|
|
||||||
|
List<ProjectileType> projectiles;
|
||||||
|
|
||||||
|
Map<String,ProjectileType> projectileTypeMap;
|
||||||
|
|
||||||
|
public void init(){
|
||||||
|
projectileTypeMap = new HashMap<String, ProjectileType>();
|
||||||
|
for(ProjectileType type : projectiles){
|
||||||
|
projectileTypeMap.put(type.getId(), type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectileType getType(String id){
|
||||||
|
return projectileTypeMap.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user