Skip to content

Commit

Permalink
Metadata component (#902)
Browse files Browse the repository at this point in the history
  • Loading branch information
turanszkij authored Jul 25, 2024
1 parent 37b1ebf commit 6ba8f79
Show file tree
Hide file tree
Showing 35 changed files with 162,411 additions and 540 deletions.
37 changes: 36 additions & 1 deletion Content/Documentation/ScriptingAPI-Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ This is a reference and explanation of Lua scripting features in Wicked Engine.
19. [ExpressionComponent](#expressioncomponent)
19. [HumanoidComponent](#humanoidcomponent)
19. [DecalComponent](#decalcomponent)
19. [MetadataComponent](#metadatacomponent)
10. [Canvas](#canvas)
11. [High Level Interface](#high-level-interface)
1. [Application](#application)
Expand Down Expand Up @@ -734,6 +735,7 @@ The scene holds components. Entity handles can be used to retrieve associated co
- Component_CreateSprite(Entity entity) : Sprite result -- attach a Sprite to an entity. The returned component is associated with the entity and can be manipulated
- Component_CreateFont(Entity entity) : SpriteFont result -- attach a SpriteFont to an entity. The returned component is associated with the entity and can be manipulated
- Component_CreateVoxelGrid(Entity entity) : VoxelGrid result -- attach a VoxelGrid to an entity. The returned component is associated with the entity and can be manipulated
- Component_CreateMetadata(Entity entity) : MetadataComponent result -- attach a MetadataComponent to an entity. The returned component is associated with the entity and can be manipulated

- Component_GetName(Entity entity) : NameComponent? result -- query the name component of the entity (if exists)
- Component_GetLayer(Entity entity) : LayerComponent? result -- query the layer component of the entity (if exists)
Expand All @@ -757,7 +759,8 @@ The scene holds components. Entity handles can be used to retrieve associated co
- Component_GetHumanoid(Entity entity) : HumanoidComponent? result -- query the HumanoidComponent of the entity (if exists)
- Component_GetDecal(Entity entity) : DecalComponent? result -- query the DecalComponent of the entity (if exists)
- Component_GetSprite(Entity entity) : Sprite? result -- query the Sprite of the entity (if exists)
- Component_GetVoxexlGrid(Entity entity) : VoxelGrid? result -- query the VoxelGrid of the entity (if exists)
- Component_GetVoxelGrid(Entity entity) : VoxelGrid? result -- query the VoxelGrid of the entity (if exists)
- Component_GetMetadata(Entity entity) : MetadataComponent? result -- query the MetadataComponent of the entity (if exists)

- Component_GetNameArray() : NameComponent[] result -- returns the array of all components of this type
- Component_GetLayerArray() : LayerComponent[] result -- returns the array of all components of this type
Expand All @@ -784,6 +787,7 @@ The scene holds components. Entity handles can be used to retrieve associated co
- Component_GetSpriteArray() : Sprite[] result -- returns the array of all components of this type
- Component_GetFontArray() : SpriteFont[] result -- returns the array of all components of this type
- Component_GetVoxelGridArray() : VoxelGrid[] result -- returns the array of all components of this type
- Component_GetMetadataArray() : MetadataComponent[] result -- returns the array of all components of this type

- Entity_GetNameArray() : Entity[] result -- returns the array of all entities that have this component type
- Entity_GetLayerArray() : Entity[] result -- returns the array of all entities that have this component type
Expand Down Expand Up @@ -811,6 +815,7 @@ The scene holds components. Entity handles can be used to retrieve associated co
- Entity_GetSpriteArray() : Entity[] result -- returns the array of all entities that have this component type
- Entity_GetFontArray() : Entity[] result -- returns the array of all entities that have this component type
- Entity_GetVoxelGridArray() : Entity[] result -- returns the array of all entities that have this component type
- Entity_GetMetadataArray() : Entity[] result -- returns the array of all entities that have this component type

- Component_RemoveName(Entity entity) -- remove the name component of the entity (if exists)
- Component_RemoveLayer(Entity entity) -- remove the layer component of the entity (if exists)
Expand All @@ -837,6 +842,7 @@ The scene holds components. Entity handles can be used to retrieve associated co
- Component_RemoveSprite(Entity entity) -- remove the Sprite of the entity (if exists)
- Component_RemoveFont(Entity entity) -- remove the SpriteFont of the entity (if exists)
- Component_RemoveVoxelGrid(Entity entity) -- remove the VoxelGrid of the entity (if exists)
- Component_RemoveMetadata(Entity entity) -- remove the MetadataComponent of the entity (if exists)

- Component_Attach(Entity entity,parent, opt bool child_already_in_local_space = false) -- attaches entity to parent (adds a hierarchy component to entity). From now on, entity will inherit certain properties from parent, such as transform (entity will move with parent) or layer (entity's layer will be a sublayer of parent's layer). If child_already_in_local_space is false, then child will be transformed into parent's local space, if true, it will be used as-is.
- Component_Detach(Entity entity) -- detaches entity from parent (if hierarchycomponent exists for it). Restores entity's original layer, and applies current transformation to entity
Expand Down Expand Up @@ -1461,6 +1467,35 @@ The decal component is a textured sticker that can be put down onto meshes. Most
- SetSlopeBlendPower(float value)
- GetSlopeBlendPower() : float

#### MetadataComponent
The metadata component can store and retrieve an arbitrary amount of named user values for an entity. It is possible to use the same name for multiple of different value types, but one value can not have multiple entries with the same name.

- HasBool(string name) : bool
- HasInt(string name) : bool
- HasFloat(string name) : bool
- HasString(string name) : bool

- GetPreset() : int
- GetBool(string name) : bool
- GetInt(string name) : int
- GetFloat(string name) : float
- GetString(string name) : string

- SetPreset(int preset)
- SetBool(string name, bool value)
- SetInt(string name, int value)
- SetFloat(string name, float value)
- SetString(string name, string value)

[outer] MetadataPreset = {
Custom = 0,
Waypoint = 1,
Player = 2,
Enemy = 3,
NPC = 4,
Pickup = 5,
}


## Canvas
This is used to describe a drawable area
Expand Down
Binary file modified Content/scripts/character_controller/assets/level.wiscene
Binary file not shown.
263 changes: 54 additions & 209 deletions Content/scripts/character_controller/character_controller.lua
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ local voxelgrid = VoxelGrid(128,32,128)
voxelgrid.SetVoxelSize(0.25)
voxelgrid.SetCenter(Vector(0,0.1,0))

local function Character(model_entity, start_position, face, controllable, anim_scene)
local function Character(model_scene, start_transform, controllable, anim_scene)
local self = {
model = INVALID_ENTITY,
target_rot_horizontal = 0,
Expand Down Expand Up @@ -349,17 +349,19 @@ local function Character(model_entity, start_position, face, controllable, anim_
dialogs = {},
next_dialog = 1,

Create = function(self, model_entity, start_position, face, controllable)
self.start_position = start_position
self.face = face
self.face_next = face
Create = function(self, model_scene, start_transform, controllable, anim_scene)
self.start_position = start_transform.GetPosition()
self.face = vector.Rotate(start_transform.GetForward(), vector.QuaternionFromRollPitchYaw(self.rotation))
self.face_next = self.face
self.controllable = controllable
if controllable then
self.layerMask = Layers.Player
self.target_rot_horizontal = vector.GetAngle(Vector(0,0,1), self.face, Vector(0,1,0)) -- only modify camera rot for player
else
self.layerMask = Layers.NPC
end
self.model = model_entity
self.model = scene.Instantiate(model_scene, true)

local layer = scene.Component_GetLayer(self.model)
layer.SetLayerMask(self.layerMask)

Expand Down Expand Up @@ -1015,7 +1017,7 @@ local function Character(model_entity, start_position, face, controllable, anim_

}

self:Create(model_entity, start_position, face, controllable)
self:Create(model_scene, start_transform, controllable, anim_scene)
return self
end

Expand Down Expand Up @@ -1237,14 +1239,9 @@ runProcess(function()
local anim_scene = Scene()
loadingscreen.AddLoadModelTask(anim_scene, script_dir() .. "assets/animations.wiscene")
local loading_scene = Scene()
local character_entities = {
loadingscreen.AddLoadModelTask(loading_scene, script_dir() .. "assets/character.wiscene"),
loadingscreen.AddLoadModelTask(loading_scene, script_dir() .. "assets/character.wiscene"),
loadingscreen.AddLoadModelTask(loading_scene, script_dir() .. "assets/character.wiscene"),
loadingscreen.AddLoadModelTask(loading_scene, script_dir() .. "assets/character.wiscene"),
loadingscreen.AddLoadModelTask(loading_scene, script_dir() .. "assets/character.wiscene"),
}
loadingscreen.AddLoadModelTask(loading_scene, script_dir() .. "assets/level.wiscene")
local character_scene = Scene()
loadingscreen.AddLoadModelTask(character_scene, script_dir() .. "assets/character.wiscene")
loadingscreen.AddRenderPathActivationTask(path, application, 0.5)
application.SetActivePath(loadingscreen, 0.5) -- activate and switch to loading screen

Expand All @@ -1270,19 +1267,49 @@ runProcess(function()
-- Parse animations from anim_scene, which was loaded by the loading screen:
LoadAnimations(anim_scene)

-- Create characters from root Entity handles that were loaded by loading screen
local player = Character(character_entities[1], Vector(0,0.5,0), Vector(0,0,1), true, anim_scene)
local npcs = {
-- Patrolling NPC IDs: 1,2,3
Character(character_entities[2], Vector(4,0.1,4), Vector(0,0,-1), false, anim_scene),
Character(character_entities[3], Vector(-8,1,4), Vector(-1,0,0), false, anim_scene),
Character(character_entities[4], Vector(-2,0.1,8), Vector(-1,0,0), false, anim_scene),

-- stationary NPC IDs: 3,4....
Character(character_entities[5], Vector(-1,0.1,-6), Vector(0,0,1), false, anim_scene),
--Character(character_entities[6], Vector(10.8,0.1,4.1), Vector(0,0,-1), false, anim_scene),
--Character(character_entities[7], Vector(11.1,4,7.2), Vector(-1,0,0), false, anim_scene),
}
-- Create characters from scene metadata components:
local player = nil
local npcs = {}
for i,entity in ipairs(scene.Entity_GetMetadataArray()) do
local metadata = scene.Component_GetMetadata(entity)
local transform = scene.Component_GetTransform(entity)
if metadata ~= nil and transform ~= nil then
if player == nil and metadata.GetPreset() == MetadataPreset.Player then
player = Character(character_scene, transform, true, anim_scene)
end
if metadata.GetPreset() == MetadataPreset.NPC then
local npc = Character(character_scene, transform, false, anim_scene)
-- Add patrol waypoints if found:
local visited = {} -- avoid infinite loop
while metadata ~= nil and metadata.HasString("waypoint") do
local waypoint_name = metadata.GetString("waypoint")
local waypoint_entity = scene.Entity_FindByName(waypoint_name)
if waypoint_entity ~= INVALID_ENTITY then
if visited[waypoint_entity] then
break
else
metadata = scene.Component_GetMetadata(waypoint_entity) -- chain waypoints
visited[waypoint_entity] = true
end
local waypoint = {
entity = waypoint_entity,
wait = metadata.GetFloat("wait")
}
if metadata.HasString("state") then
waypoint.state = metadata.GetString("state")
end
table.insert(npc.patrol_waypoints, waypoint) -- add waypoint to NPC
end
end
table.insert(npcs, npc) -- add NPC
end
end
end

-- if player was not created from a metadata component, create a default player:
if player == nil then
player = Character(character_scene, TransformComponent(), true, anim_scene)
end

local camera = ThirdPersonCamera(player)

Expand Down Expand Up @@ -1364,188 +1391,6 @@ runProcess(function()
npc.dialogs = dialogtree
end

-- Patrol waypoints:

local waypoints = {
scene.Entity_FindByName("waypoint1"),
scene.Entity_FindByName("waypoint2"),

scene.Entity_FindByName("waypoint3"),
scene.Entity_FindByName("waypoint4"),
scene.Entity_FindByName("waypoint5"),
scene.Entity_FindByName("waypoint6"),

scene.Entity_FindByName("waypoint7"),
scene.Entity_FindByName("waypoint8"),
scene.Entity_FindByName("waypoint9"),
scene.Entity_FindByName("waypoint10"),
scene.Entity_FindByName("waypoint11"),
scene.Entity_FindByName("waypoint12"),
scene.Entity_FindByName("waypoint13"),
scene.Entity_FindByName("waypoint14"),
scene.Entity_FindByName("waypoint15"),
scene.Entity_FindByName("waypoint16"),
scene.Entity_FindByName("waypoint17"),
scene.Entity_FindByName("waypoint18"),
scene.Entity_FindByName("waypoint19"),
scene.Entity_FindByName("waypoint20"),
scene.Entity_FindByName("waypoint21"),
scene.Entity_FindByName("waypoint22"),
scene.Entity_FindByName("waypoint23"),
scene.Entity_FindByName("waypoint24"),
scene.Entity_FindByName("waypoint25"),
}

-- Simplest 1-2 patrol:
if(
waypoints[1] ~= INVALID_ENTITY and
waypoints[2] ~= INVALID_ENTITY
) then
npcs[1].patrol_waypoints = {
{
entity = waypoints[1],
wait = 0,
},
{
entity = waypoints[2],
wait = 2,
},
}
end

-- Some more advanced, toggle between walk and jog, also swimming (because waypoints are across water mesh in test level):
if(
waypoints[3] ~= INVALID_ENTITY and
waypoints[4] ~= INVALID_ENTITY and
waypoints[5] ~= INVALID_ENTITY and
waypoints[6] ~= INVALID_ENTITY
) then
npcs[2].patrol_waypoints = {
{
entity = waypoints[3],
wait = 0,
state = States.JOG,
},
{
entity = waypoints[4],
wait = 0,
},
{
entity = waypoints[5],
wait = 2,
},
{
entity = waypoints[6],
wait = 0,
state = States.JOG,
},
}
end


-- Run long circle:
if(
waypoints[7] ~= INVALID_ENTITY and
waypoints[8] ~= INVALID_ENTITY and
waypoints[9] ~= INVALID_ENTITY and
waypoints[10] ~= INVALID_ENTITY and
waypoints[11] ~= INVALID_ENTITY and
waypoints[12] ~= INVALID_ENTITY and
waypoints[13] ~= INVALID_ENTITY and
waypoints[14] ~= INVALID_ENTITY and
waypoints[15] ~= INVALID_ENTITY and
waypoints[16] ~= INVALID_ENTITY and
waypoints[17] ~= INVALID_ENTITY and
waypoints[18] ~= INVALID_ENTITY and
waypoints[19] ~= INVALID_ENTITY and
waypoints[20] ~= INVALID_ENTITY and
waypoints[21] ~= INVALID_ENTITY and
waypoints[22] ~= INVALID_ENTITY and
waypoints[23] ~= INVALID_ENTITY and
waypoints[24] ~= INVALID_ENTITY and
waypoints[25] ~= INVALID_ENTITY
) then
npcs[3].patrol_waypoints = {
{
entity = waypoints[7],
state = States.JOG,
},
{
entity = waypoints[8],
state = States.JOG,
},
{
entity = waypoints[9],
state = States.JOG,
},
{
entity = waypoints[10],
state = States.JOG,
},
{
entity = waypoints[11],
state = States.JOG,
},
{
entity = waypoints[12],
state = States.JOG,
},
{
entity = waypoints[13],
state = States.JOG,
},
{
entity = waypoints[14],
state = States.JOG,
},
{
entity = waypoints[15],
state = States.JOG,
},
{
entity = waypoints[16],
state = States.JOG,
},
{
entity = waypoints[17],
state = States.JOG,
},
{
entity = waypoints[18],
state = States.JOG,
wait = 2, -- little wait at top of slope
},
{
entity = waypoints[19],
state = States.JOG,
},
{
entity = waypoints[20],
state = States.JOG,
},
{
entity = waypoints[21],
state = States.JOG,
},
{
entity = waypoints[22],
state = States.JOG,
},
{
entity = waypoints[23],
state = States.JOG,
},
{
entity = waypoints[24],
state = States.JOG,
},
{
entity = waypoints[25],
state = States.JOG,
},
}
end

-- Main loop:
while true do

Expand Down
Loading

0 comments on commit 6ba8f79

Please sign in to comment.