script engine bugfix, hitbox subtypes

This commit is contained in:
austin 2024-07-02 17:07:16 -04:00
parent e5a187ce19
commit 14d423d533
11 changed files with 139 additions and 16 deletions

View File

@ -95,7 +95,9 @@ const COMPILER_runFile = (fileName) => {
loggerScripts.INFO('RUN FILE ' + normalizedFilePath) loggerScripts.INFO('RUN FILE ' + normalizedFilePath)
eval(COMPILER_fileMap[normalizedFilePath].content) eval(COMPILER_fileMap[normalizedFilePath].content)
} else { } else {
loggerScripts.WARNING('FAILED TO RESOLVE FILE ' + normalizedFilePath) const message = 'FAILED TO RESOLVE FILE ' + normalizedFilePath
loggerScripts.WARNING(message)
throw new Error(message)
} }
} }
@ -108,6 +110,10 @@ const COMPILER_printSource = (fileName) => {
if(!!COMPILER_fileMap[normalizedFilePath]){ if(!!COMPILER_fileMap[normalizedFilePath]){
loggerScripts.INFO('FILE CONTENT ' + normalizedFilePath) loggerScripts.INFO('FILE CONTENT ' + normalizedFilePath)
} else { } else {
loggerScripts.WARNING('FAILED TO RESOLVE FILE ' + normalizedFilePath) const message = 'FAILED TO RESOLVE FILE ' + normalizedFilePath
loggerScripts.WARNING(message)
loggerScripts.WARNING('file map content:')
loggerScripts.WARNING(OBject.keys(COMPILER_fileMap) + "")
throw new Error(message)
} }
} }

View File

@ -2,8 +2,20 @@
/** /**
* The host context that contains the core engine functions * The host context that contains the core engine functions
*/ */
export let HOST = { let HOST_ACCESS = {
classes: { }, //the classes available to the script engine classes: { }, //the classes available to the script engine
singletons: { }, //the singletons available to the script engine singletons: { }, //the singletons available to the script engine
} }
//fake require
REQUIRE_CACHE["/compiler/host_access.js"] = {
exports: {
'HOST_ACCESS': HOST_ACCESS,
'loggerScripts': loggerScripts,
},
exportedValues: [
'HOST_ACCESS',
'loggerScripts'
],
}

View File

@ -16,8 +16,9 @@ let exports = { }
* @param {*} cwd The current working directory * @param {*} cwd The current working directory
*/ */
const require = (path) => { const require = (path) => {
loggerScripts.DEBUG('Require path ' + path)
let normalizedFilePath = FILE_RESOLUTION_getFilePath(path) let normalizedFilePath = FILE_RESOLUTION_getFilePath(path)
if(REQUIRE_CACHE[path]){ if(!!REQUIRE_CACHE[normalizedFilePath]){
return REQUIRE_CACHE[normalizedFilePath].exports return REQUIRE_CACHE[normalizedFilePath].exports
} else if(!!COMPILER_fileMap[normalizedFilePath]?.content) { } else if(!!COMPILER_fileMap[normalizedFilePath]?.content) {
const code = COMPILER_fileMap[normalizedFilePath].moduleContent const code = COMPILER_fileMap[normalizedFilePath].moduleContent
@ -31,6 +32,12 @@ const require = (path) => {
loggerScripts.INFO("[require] CREATE MODULE " + normalizedFilePath) loggerScripts.INFO("[require] CREATE MODULE " + normalizedFilePath)
return module.exports return module.exports
} else { } else {
loggerScripts.WARNING("FAILED TO REQUIRE FILE " + normalizedFilePath) const errorMsg = "FAILED TO REQUIRE FILE " + normalizedFilePath
loggerScripts.WARNING(errorMsg)
loggerScripts.WARNING('Module value:')
loggerScripts.WARNING(Object.keys(REQUIRE_CACHE?.[normalizedFilePath]) + '')
loggerScripts.WARNING('Require cache contents:')
loggerScripts.WARNING(Object.keys(REQUIRE_CACHE) + '')
throw new Error(errorMsg)
} }
} }

View File

@ -1,7 +1,11 @@
import { Host } from '/engine/engine-interface'
import { loggerScripts } from '/compiler/host_access'
let host: Host
/** /**
* Called when the script engine first initializes * Called when the script engine first initializes
*/ */
export const ENGINE_onInit = () => { export const ENGINE_onInit = () => {
console.log('Script Engine Init') loggerScripts.INFO('Script Engine Init')
} }

View File

@ -17,9 +17,10 @@ Audio FX for everything
= Coding = = Coding =
Sub menu on title screen that allows changing control mappings Sub menu on title screen that allows changing control mappings
- Automatically generate based on the controls arrays in controls handler - Automatically generate based on the controls arrays in controls handler
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around) Review combat code
- Introduce block hitbox (blockbox) type - Damage calculation
- Sour spot, sweet spot for damage hitboxes and hurtboxes - Particle generation
- Revive tree
Enemy AI Enemy AI
Ability for private realms to have time start/stop based on the player's feedback <-- sync this up to tutorial ui via script Ability for private realms to have time start/stop based on the player's feedback <-- sync this up to tutorial ui via script
Scene Message Service Scene Message Service

View File

@ -408,6 +408,9 @@ Audio
(06/02/2024) (06/02/2024)
better scaffolding for scripting engine with hooks for equipping items, spawning entities, pausing/resuming play, etc better scaffolding for scripting engine with hooks for equipping items, spawning entities, pausing/resuming play, etc
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
- Introduce block hitbox (blockbox) type
- Sour spot, sweet spot for damage hitboxes and hurtboxes
# TODO # TODO

View File

@ -41,6 +41,15 @@ public class HitboxCollectionState {
BLOCK, // blocks a hit from another entity BLOCK, // blocks a hit from another entity
} }
/**
* The subtype of hitbox
*/
public enum HitboxSubtype {
SWEET, //extra damage
REGULAR, //regular damage
SOUR, //less damage
}
//the parent entity of the hitbox state //the parent entity of the hitbox state
Entity parent; Entity parent;
@ -86,6 +95,9 @@ public class HitboxCollectionState {
DGeom geom = null; DGeom geom = null;
HitboxType type = HitboxType.HIT; HitboxType type = HitboxType.HIT;
HitboxShapeType shapeType = HitboxShapeType.SPHERE; HitboxShapeType shapeType = HitboxShapeType.SPHERE;
//
//Get the type as an enum
//
switch(hitboxDataRaw.getType()){ switch(hitboxDataRaw.getType()){
case HitboxData.HITBOX_TYPE_HIT: { case HitboxData.HITBOX_TYPE_HIT: {
type = HitboxType.HIT; type = HitboxType.HIT;
@ -113,11 +125,34 @@ public class HitboxCollectionState {
geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), hitboxDataRaw.getRadius(), hitboxDataRaw.getLength(), Collidable.TYPE_OBJECT_BIT); geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), hitboxDataRaw.getRadius(), hitboxDataRaw.getLength(), Collidable.TYPE_OBJECT_BIT);
} break; } break;
} }
//
//Get the subtype as an enum
//
HitboxSubtype subType;
String subTypeRaw = hitboxDataRaw.getSubType();
if(subTypeRaw == null){
subTypeRaw = HitboxData.HITBOX_SUBTYPE_REUGLAR;
}
switch(subTypeRaw){
case HitboxData.HITBOX_SUBTYPE_SWEET: {
subType = HitboxSubtype.SWEET;
} break;
case HitboxData.HITBOX_SUBTYPE_REUGLAR: {
subType = HitboxSubtype.REGULAR;
} break;
case HitboxData.HITBOX_SUBTYPE_SOUR: {
subType = HitboxSubtype.SOUR;
} break;
default: {
subType = HitboxSubtype.REGULAR;
} break;
}
if(hitboxDataRaw.getBone() != null){ if(hitboxDataRaw.getBone() != null){
rVal.hitboxGeomMap.put(hitboxDataRaw.getBone(),geom); rVal.hitboxGeomMap.put(hitboxDataRaw.getBone(),geom);
} }
rVal.geoms.add(geom); rVal.geoms.add(geom);
rVal.geomStateMap.put(geom,new HitboxState(hitboxDataRaw.getBone(), hitboxDataRaw, type, shapeType, true)); rVal.geomStateMap.put(geom,new HitboxState(hitboxDataRaw.getBone(), hitboxDataRaw, type, subType, shapeType, true));
} }
//create body with all the shapes //create body with all the shapes
@ -310,7 +345,7 @@ public class HitboxCollectionState {
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));
double length = shapeStatus.getHitboxData().getRadius(); double length = shapeStatus.getHitboxData().getRadius();
double radius = shapeStatus.getHitboxData().getRadius(); // double radius = shapeStatus.getHitboxData().getRadius();
if(previousWorldPos != null){ if(previousWorldPos != null){
//called all subsequent updates to hitbox position //called all subsequent updates to hitbox position
@ -461,6 +496,9 @@ public class HitboxCollectionState {
//the type of hitbox //the type of hitbox
HitboxType type; HitboxType type;
//the subtype
HitboxSubtype subType;
//the type of geometry //the type of geometry
HitboxShapeType shapeType; HitboxShapeType shapeType;
@ -481,13 +519,15 @@ public class HitboxCollectionState {
* @param boneName The name of the bone the hitbox is attached to, if any * @param boneName The name of the bone the hitbox is attached to, if any
* @param data the hitbox data object * @param data the hitbox data object
* @param type The type of hitbox * @param type The type of hitbox
* @param subType The subtype of hitbox
* @param shapeType The type of shape the hitbox is * @param shapeType The type of shape the hitbox is
* @param isActive if the hitbox is active or not * @param isActive if the hitbox is active or not
*/ */
public HitboxState(String boneName, HitboxData data, HitboxType type, HitboxShapeType shapeType, boolean isActive){ public HitboxState(String boneName, HitboxData data, HitboxType type, HitboxSubtype subType, HitboxShapeType shapeType, boolean isActive){
this.boneName = boneName; this.boneName = boneName;
this.data = data; this.data = data;
this.type = type; this.type = type;
this.subType = subType;
this.shapeType = shapeType; this.shapeType = shapeType;
this.isActive = isActive; this.isActive = isActive;
} }
@ -540,6 +580,22 @@ public class HitboxCollectionState {
this.type = type; this.type = type;
} }
/**
* Gets the subtype of the hitbox
* @return The subtype
*/
public HitboxSubtype getSubType(){
return subType;
}
/**
* Sets the subtype of the hitbox
* @param subType The subtype
*/
public void setSubType(HitboxSubtype subType){
this.subType = subType;
}
/** /**
* Gets whether the hitbox is active or not * Gets whether the hitbox is active or not
* @return true if active, false otherwise * @return true if active, false otherwise

View File

@ -21,12 +21,23 @@ public class HitboxData {
//a block sphere that is connected to its previous position by a capsule. The capsule is used for collision checks //a block sphere that is connected to its previous position by a capsule. The capsule is used for collision checks
public static final String HITBOX_TYPE_BLOCK_CONNECTED = "block_connected"; public static final String HITBOX_TYPE_BLOCK_CONNECTED = "block_connected";
//a hitbox with extra effect (ie more damage)
public static final String HITBOX_SUBTYPE_SWEET = "sweet";
//a hitbox with normal effect
public static final String HITBOX_SUBTYPE_REUGLAR = "regular";
//a hitbox with less effect (ie reduced damange)
public static final String HITBOX_SUBTYPE_SOUR = "sour";
//used for debugging -- to show whether a hitbox is colliding with it or not //used for debugging -- to show whether a hitbox is colliding with it or not
public static final String HITBOX_TYPE_STATIC_CAPSULE = "static_capsule"; public static final String HITBOX_TYPE_STATIC_CAPSULE = "static_capsule";
//the type of hitbox //the type of hitbox
String type; String type;
//the subtype of hitbox (ie, sweetspot, sour spot, critical spot, armor spot, etc)
String subType;
//the bone it is attached to //the bone it is attached to
String bone; String bone;
@ -53,6 +64,14 @@ public class HitboxData {
return type; return type;
} }
/**
* Gets the subtype of the hitbox
* @return the subtype of hitbox
*/
public String getSubType() {
return subType;
}
/** /**
* Gets the type of bone * Gets the type of bone
* @return the type of bone * @return the type of bone
@ -101,10 +120,26 @@ public class HitboxData {
this.bone = bone; this.bone = bone;
} }
/**
* Sets the type of the hitbox
* @param type the type
*/
public void setType(String type) { public void setType(String type) {
this.type = type; this.type = type;
} }
/**
* Sets the subtype of the hitbox
* @param subType the subtype
*/
public void setSubType(String subType) {
this.subType = subType;
}
/**
* Sets the radius of the hitbox
* @param radius The radius
*/
public void setRadius(float radius) { public void setRadius(float radius) {
this.radius = radius; this.radius = radius;
} }

View File

@ -46,6 +46,7 @@ public class Logger {
* This should be used for debugging messages that are executed on a given condition that won't necessarily be every loop (ie all network messages) * This should be used for debugging messages that are executed on a given condition that won't necessarily be every loop (ie all network messages)
* @param message The message to report * @param message The message to report
*/ */
@Export
public void DEBUG(String message){ public void DEBUG(String message){
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG){ if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG){
System.out.println(message); System.out.println(message);

View File

@ -36,7 +36,7 @@ public class LoggerInterface {
loggerDB = new Logger(LogLevel.WARNING); loggerDB = new Logger(LogLevel.WARNING);
loggerAudio = new Logger(LogLevel.WARNING); loggerAudio = new Logger(LogLevel.WARNING);
loggerUI = new Logger(LogLevel.WARNING); loggerUI = new Logger(LogLevel.WARNING);
loggerScripts = new Logger(LogLevel.WARNING); loggerScripts = new Logger(LogLevel.DEBUG);
loggerStartup.INFO("Initialized loggers"); loggerStartup.INFO("Initialized loggers");
} }
} }

View File

@ -101,7 +101,6 @@ public class ScriptEngine {
//call the engine initialization function //call the engine initialization function
// invokeFunction("ENGINE_onInit"); // invokeFunction("ENGINE_onInit");
System.exit(0);
//read scripts into source map //read scripts into source map
// readScriptsDirectory("/src/main/sql", FileUtils.getAssetFile("/src/main/sql")); // readScriptsDirectory("/src/main/sql", FileUtils.getAssetFile("/src/main/sql"));
@ -271,8 +270,7 @@ public class ScriptEngine {
* Defines host members within javascript context * Defines host members within javascript context
*/ */
private void defineHostMembers(){ private void defineHostMembers(){
//remove top level members required for bootstrapping the engine hostObject = topLevelValue.getMember("HOST_ACCESS");
removeTopLevelValue("loggerScripts");
//give guest access to static classes //give guest access to static classes
Value classes = hostObject.getMember("classes"); Value classes = hostObject.getMember("classes");
for(Object[] currentClass : staticClasses){ for(Object[] currentClass : staticClasses){