This commit is contained in:
2025-09-16 20:38:29 +03:00
parent 1aa002d8ba
commit 190318e5c4
20 changed files with 925 additions and 243 deletions

View File

@@ -118,6 +118,19 @@ if(OGRE_STATIC)
target_link_options(Procedural PRIVATE -static-libstdc++ -static-libgcc)
endif()
add_dependencies(Procedural stage_files import_buildings)
file(GLOB FONTS_SRC ${CMAKE_SOURCE_DIR}/assets/fonts/*.ttf)
set(FONT_OUTPUT_FILES)
foreach(FONT_FILE ${FONTS_SRC})
get_filename_component(FILE_NAME ${FONT_FILE} NAME_WE)
set(FONT_OUTPUT_FILE ${CMAKE_BINARY_DIR}/resources/fonts/${FILE_NAME}.ttf)
add_custom_command(
OUTPUT ${FONT_OUTPUT_FILE}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/resources/fonts
COMMAND ${CMAKE_COMMAND} -E copy ${FONT_FILE} ${FONT_OUTPUT_FILE}
DEPENDS ${FONT_FILE})
list(APPEND FONT_OUTPUT_FILES ${FONT_OUTPUT_FILE})
endforeach()
add_custom_target(fonts ALL DEPENDS ${FONT_OUTPUT_FILES})
file(GLOB BUILDINGS_SRC ${CMAKE_SOURCE_DIR}/assets/blender/buildings/*.blend)
set(BUILDING_OUTPUT_FILES)
foreach(BUILDING_FILE ${BUILDINGS_SRC})
@@ -273,7 +286,6 @@ endforeach()
file(GLOB VRM_FILES RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/assets/vroid/*.vrm)
file(GLOB MIXAMO_FILES RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/assets/blender/mixamo/**/*.fbx)
file(GLOB EDITED_BLENDS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/assets/blender/edited-*.blend)
set(VRM_SOURCE)
foreach(VRM_FILE ${VRM_FILES} ${MIXAMO_FILES})
set(OUTPUT_FILE "${CMAKE_BINARY_DIR}/${VRM_FILE}")
@@ -303,6 +315,7 @@ set(EDITED_BLENDS_LIST
female
)
set(EDITED_BLEND_TARGETS)
set(CHARACTER_GLBS)
foreach(EDITED_BLEND ${EDITED_BLENDS_LIST})
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/assets/blender/edited-normal-${EDITED_BLEND}.blend
@@ -314,24 +327,21 @@ add_custom_command(
COMMAND ${BLENDER} -b -Y
${CMAKE_BINARY_DIR}/assets/blender/edited-normal-${EDITED_BLEND}.blend
-P ${CMAKE_SOURCE_DIR}/assets/blender/scripts/copy_animations.py --
${CMAKE_BINARY_DIR}/assets/blender/vrm-vroid-normal-male.blend
${CMAKE_BINARY_DIR}/assets/blender/vrm-vroid-normal-${EDITED_BLEND}.blend ${EDITED_BLEND}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
list(APPEND EDITED_BLEND_TARGETS ${CMAKE_BINARY_DIR}/assets/blender/edited-normal-${EDITED_BLEND}.blend)
list(APPEND CHARACTER_GLBS ${CMAKE_BINARY_DIR}/characters/${EDITED_BLEND}/normal-${EDITED_BLEND}.glb)
endforeach()
add_custom_target(edited-blends DEPENDS ${EDITED_BLEND_TARGETS})
add_custom_target(edited-blends ALL DEPENDS ${EDITED_BLEND_TARGETS})
set(CHARACTER_GLBS
${CMAKE_BINARY_DIR}/characters/male/normal-male.glb
${CMAKE_BINARY_DIR}/characters/female/normal-female.glb
)
add_custom_command(
OUTPUT ${CHARACTER_GLBS}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CREATE_DIRECTORIES}
COMMAND ${BLENDER} -b -Y -P ${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_models.py
COMMAND ${CMAKE_COMMAND} -E touch ${CHARACTER_GLBS}
DEPENDS ${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_models.py ${VRM_IMPORTED_BLENDS}
DEPENDS ${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_models.py ${VRM_IMPORTED_BLENDS} ${EDITED_BLEND_TARGETS}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
#add_custom_command(
# OUTPUT ${CMAKE_SOURCE_DIR}/characters/female/vroid-normal-female.scene

View File

@@ -210,6 +210,7 @@ public:
bool updated = false;
if (isGuiEnabled())
return false;
std::cout << "GUI not enabled\n";
if (evt.keysym.sym == OgreBites::SDLK_ESCAPE) {
OgreAssert(ECS::get().has<ECS::GUI>(), "");
setGuiEnabled(true);
@@ -616,7 +617,6 @@ public:
OGRE_NEW OgreBites::InputListenerChain(
app.listeners);
addInputListener(app.mInput);
std::cout << "Update listeners\n";
});
#if 0
ECS::get()
@@ -758,7 +758,8 @@ void KeyboardListener::frameRendered(const Ogre::FrameEvent &evt)
fps_timer.reset();
}
update(evt.timeSinceLastFrame);
if (!isGuiEnabled()) {
if (!isGuiEnabled() ||
(isGuiEnabled() && ECS::get<ECS::GUI>().narrationBox)) {
mApp->updateWorld(evt.timeSinceLastFrame);
if (mInitDelay >= 0.0f)
mInitDelay -= evt.timeSinceLastFrame;

BIN
assets/blender/buildings/altar.blend (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/fonts/Kenney Bold.ttf (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -36,4 +36,38 @@ function foo()
end
v = Vector3(0, 1, 2)
end
foo()
narration = {
position = 1,
narration_start = {
"The party was hot, girls were sexy the wine, beer and whisky were in \
enormous numbers. It was anniversary since you set sail with your friends. \
The sea was calm and everything promised you another great night.",
"The whole year with your friends on your ship over vast seas of the world in decay was almost over.\
It was so good year full of adventure, romance, indecency and luxury.",
"Your trusted friends decided that you have too much, they have too much of you and you owe them a lot.",
"They found you drunk in your room and moved to the deck and used ropes to \
restrain you and attach a bucket of stones or something else heavy to your body.",
"After a few hours passed two strong people pulled you to the side and \
dropped you into the sea. Last thing you heard before you hit the water was happy laugher..."
},
progress = function(this)
if #this.narration_start < this.position then
return ""
end
local ret = this.narration_start[this.position]
this.position = this.position + 1
return ret
end,
}
setup_handler(function(event)
print(event)
if event == "startup" then
main_menu()
elseif event == "narration_progress" then
narrate(narration:progress())
elseif event == "new_game" then
narrate(narration:progress())
end
end)

View File

@@ -22,6 +22,7 @@ FileSystem=skybox
FileSystem=resources/buildings
FileSystem=resources/vehicles
FileSystem=resources/debug
FileSystem=resources/fonts
# PBR media must come before the scripts that reference it
#FileSystem=./Media/PBR
#FileSystem=./Media/PBR/filament

View File

@@ -1,5 +1,5 @@
project(gamedata)
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain Overlay CONFIG)
add_library(GameData STATIC GameData.cpp CharacterModule.cpp WaterModule.cpp SunModule.cpp TerrainModule.cpp GUIModule.cpp)
target_link_libraries(GameData PUBLIC OgreMain OgreBites OgreBullet OgrePaging OgreTerrain OgreOverlay flecs::flecs_static)
add_library(GameData STATIC GameData.cpp CharacterModule.cpp WaterModule.cpp SunModule.cpp TerrainModule.cpp GUIModule.cpp LuaData.cpp WorldMapModule.cpp)
target_link_libraries(GameData PUBLIC OgreMain OgreBites OgreBullet OgrePaging OgreTerrain OgreOverlay flecs::flecs_static lua)
target_include_directories(GameData PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -97,7 +97,8 @@ CharacterModule::CharacterModule(flecs::world &ecs)
Ogre::ANIMBLEND_CUMULATIVE);
Ogre::String
animNames[AnimationControl::NUM_ANIMS] = {
"idle", "walking", "running"
"idle", "walking", "running",
"treading_water", "swimming"
};
for (i = 0; i < AnimationControl::NUM_ANIMS;
i++) {
@@ -165,11 +166,11 @@ CharacterModule::CharacterModule(flecs::world &ecs)
if (anim.currentAnim != anim.nextAnim)
setAnimation(anim);
});
ecs.system<EngineData, CharacterBase, AnimationControl>(
"HandleAnimations1")
ecs.system<const EngineData, const Input, CharacterBase,
AnimationControl>("HandleAnimations1")
.kind(flecs::OnUpdate)
.each([this](EngineData &eng, CharacterBase &ch,
AnimationControl &anim) {
.each([this](const EngineData &eng, const Input &input,
CharacterBase &ch, AnimationControl &anim) {
float delta = eng.delta;
Ogre::Real animSpeed = 1;
if (anim.currentAnim != AnimationControl::ANIM_NONE) {
@@ -177,6 +178,11 @@ CharacterModule::CharacterModule(flecs::world &ecs)
AnimationControl::ANIM_WALK)
anim.mAnims[anim.currentAnim]->addTime(
delta * 1.0f);
else if (anim.currentAnim ==
AnimationControl::ANIM_SWIMMING &&
input.fast)
anim.mAnims[anim.currentAnim]->addTime(
delta * 20.0f);
else
anim.mAnims[anim.currentAnim]->addTime(
delta * animSpeed);
@@ -186,6 +192,24 @@ CharacterModule::CharacterModule(flecs::world &ecs)
return;
ch.mBoneMotion = ch.mRootBone->getPosition();
});
ecs.system<CharacterBase>()
.kind(flecs::OnUpdate)
.with<TerrainReady>()
.with<WaterReady>()
.with<InWater>()
.each([this](flecs::entity e, CharacterBase &ch) {
float full_subm = 2.0f;
Ogre::Vector3 pos = ch.mBodyNode->getPosition();
float current_subm = -Ogre::Math::Clamp(
pos.y + Ogre::Math::Sin(ch.mTimer * 0.13f +
130.0f) *
0.07f,
-full_subm, 0.0f);
if (current_subm > 0.9f)
ch.is_submerged = true;
else if (current_subm < 0.8f)
ch.is_submerged = false;
});
ecs.system<const EngineData, const CharacterBase, CharacterVelocity>(
"HandleGravity")
.kind(flecs::OnUpdate)
@@ -222,6 +246,24 @@ CharacterModule::CharacterModule(flecs::world &ecs)
}
gr.gvelocity *= 0.99;
});
ecs.system<const EngineData, const AnimationControl,
const CharacterBase, CharacterVelocity>("HandleSwimming")
.kind(flecs::OnUpdate)
.with<TerrainReady>()
.with<WaterReady>()
.each([this](flecs::entity e, const EngineData &eng,
const AnimationControl &anim,
const CharacterBase &ch, CharacterVelocity &gr) {
if (anim.currentAnim ==
AnimationControl::ANIM_SWIMMING) {
float h = Ogre::Math::Clamp(
0.2f - ch.mBodyNode->getPosition().y,
0.0f, 2000.0f);
if (h > 0.2 && h < 2.0f)
gr.gvelocity.y += 1.2 * (h + 1.0f) * h *
eng.delta;
}
});
ecs.system<const EngineData, const CharacterBase, CharacterVelocity>(
"HandleRootMotionVelocity")
.kind(flecs::OnUpdate)
@@ -287,34 +329,72 @@ CharacterModule::CharacterModule(flecs::world &ecs)
}
}
});
ecs.system<const Input, AnimationControl>("HandlePlayerAnimations")
ecs.system<const Input, const CharacterBase, AnimationControl>(
"HandlePlayerAnimations")
.kind(flecs::OnUpdate)
.with<Character>()
.with<Player>()
.each([](const Input &input, AnimationControl &anim) {
.each([](flecs::entity e, const Input &input,
const CharacterBase &ch, AnimationControl &anim) {
if (!anim.configured)
return;
bool controls_idle = input.motion.zeroLength();
bool anim_is_idle = anim.currentAnim ==
AnimationControl::ANIM_IDLE;
bool anim_is_idle =
anim.currentAnim ==
AnimationControl::ANIM_IDLE ||
anim.currentAnim ==
AnimationControl::ANIM_TREADING_WATER;
bool anim_is_walking = anim.currentAnim ==
AnimationControl::ANIM_WALK;
bool anim_is_running = anim.currentAnim ==
AnimationControl::ANIM_RUN;
bool anim_is_swimming = anim.currentAnim ==
AnimationControl::ANIM_SWIMMING;
bool anim_is_motion = anim_is_walking ||
anim_is_running;
anim_is_running ||
anim_is_swimming;
if (controls_idle) {
if (anim.currentAnim ==
AnimationControl::ANIM_IDLE &&
ch.is_submerged)
anim.nextAnim = AnimationControl::
ANIM_TREADING_WATER;
else if (anim.currentAnim ==
AnimationControl::
ANIM_TREADING_WATER &&
!ch.is_submerged)
anim.nextAnim =
AnimationControl::ANIM_IDLE;
}
if (!controls_idle && anim_is_idle) {
anim.reset = true;
if (input.fast)
anim.nextAnim =
AnimationControl::ANIM_RUN;
else
anim.nextAnim =
AnimationControl::ANIM_WALK;
if (ch.is_submerged) {
if (input.fast)
anim.nextAnim =
AnimationControl::
ANIM_SWIMMING;
else
anim.nextAnim =
AnimationControl::
ANIM_SWIMMING;
} else {
if (input.fast)
anim.nextAnim =
AnimationControl::ANIM_RUN;
else
anim.nextAnim =
AnimationControl::
ANIM_WALK;
}
} else
anim.reset = false;
if (controls_idle && anim_is_motion)
anim.nextAnim = AnimationControl::ANIM_IDLE;
if (ch.is_submerged)
anim.nextAnim = AnimationControl::
ANIM_TREADING_WATER;
else
anim.nextAnim =
AnimationControl::ANIM_IDLE;
else if (!controls_idle && anim_is_motion) {
if (input.fast && anim_is_walking)
anim.nextAnim =
@@ -322,20 +402,42 @@ CharacterModule::CharacterModule(flecs::world &ecs)
else if (!input.fast && anim_is_running)
anim.nextAnim =
AnimationControl::ANIM_WALK;
if ((anim_is_walking || anim_is_running) &&
ch.is_submerged) {
if (input.fast)
anim.nextAnim =
AnimationControl::
ANIM_SWIMMING;
else
anim.nextAnim =
AnimationControl::
ANIM_SWIMMING;
} else if ((anim_is_swimming) &&
!ch.is_submerged) {
if (input.fast)
anim.nextAnim =
AnimationControl::ANIM_RUN;
else
anim.nextAnim =
AnimationControl::
ANIM_WALK;
}
}
});
ecs.system<const EngineData, CharacterBase, CharacterBody>(
"UpdateCharacterBase")
ecs.system<const EngineData, CharacterLocation, CharacterBase,
CharacterBody>("UpdateCharacterBase")
.kind(flecs::OnUpdate)
.with<Character>()
.each([](const EngineData &eng, CharacterBase &ch,
CharacterBody &body) {
.each([](const EngineData &eng, CharacterLocation &loc,
CharacterBase &ch, CharacterBody &body) {
if (!ch.mBodyNode) {
body.mController = nullptr;
ch.mBodyEnt = eng.mScnMgr->createEntity(
"normal-male.glb");
ch.mBodyNode = eng.mScnMgr->getRootSceneNode()
->createChildSceneNode();
ch.mBodyNode->setOrientation(loc.orientation);
ch.mBodyNode->setPosition(loc.position);
ch.mBodyNode->attachObject(ch.mBodyEnt);
ch.mSkeleton = ch.mBodyEnt->getSkeleton();
body.mGhostObject =
@@ -385,6 +487,11 @@ CharacterModule::CharacterModule(flecs::world &ecs)
"No root bone");
ch.mRootBone = ch.mSkeleton->getBone("Root");
OgreAssert(ch.mRootBone, "No root bone");
} else {
loc.orientation =
ch.mBodyNode->_getDerivedOrientation();
loc.position =
ch.mBodyNode->_getDerivedPosition();
}
});
ecs.system<const EngineData, CharacterBase, CharacterBody>(
@@ -592,16 +699,6 @@ CharacterModule::CharacterModule(flecs::world &ecs)
<< "\n";
});
#endif
/* Create player */
player = ecs.entity("player");
player.set<AnimationControl>({ AnimationControl::ANIM_NONE,
AnimationControl::ANIM_NONE, false,
false });
player.set<CharacterBase>(
{ "normal-male.glb", 0.0f, nullptr, nullptr, nullptr });
player.set<CharacterBody>({ nullptr, nullptr, nullptr, false, false });
player.add<Character>();
player.add<Player>();
}
void CharacterModule::setAnimation(AnimationControl &anim)

View File

@@ -16,6 +16,11 @@ struct CharacterBase {
Ogre::Node *mRootBone;
Ogre::Vector3 mBoneMotion;
Ogre::Vector3 mGoalDirection; // actual intended direction in world-space
bool is_submerged;
};
struct CharacterLocation {
Ogre::Quaternion orientation;
Ogre::Vector3 position;
};
struct CharacterBody {
btPairCachingGhostObject *mGhostObject;
@@ -33,6 +38,8 @@ struct AnimationControl {
ANIM_IDLE = 0,
ANIM_WALK,
ANIM_RUN,
ANIM_TREADING_WATER,
ANIM_SWIMMING,
NUM_ANIMS,
ANIM_NONE = NUM_ANIMS
};
@@ -48,7 +55,6 @@ struct AnimationControl {
Ogre::NodeAnimationTrack *mRootTracks[NUM_ANIMS];
};
struct CharacterModule {
flecs::entity player;
CharacterModule(flecs::world &ecs);
void setAnimation(AnimationControl &anim);
void fadeAnimations(AnimationControl &anim, Ogre::Real deltaTime);

View File

@@ -7,8 +7,10 @@
#include <OgreSceneNode.h>
#include <OgreApplicationContext.h>
#include <OgreImGuiInputListener.h>
#include <OgreFontManager.h>
#include "GameData.h"
#include "Components.h"
#include "LuaData.h"
#include "GUIModule.h"
namespace ECS
{
@@ -20,6 +22,50 @@ struct GUIData {
};
struct GUIListener : public Ogre::RenderTargetListener {
float panel_width;
bool enableEditor;
bool enableMapEditor;
ImFont *smallFont, *midFont, *bigFont;
Ogre::FontPtr _smallFont, _midFont, _bigFont;
GUIListener()
: Ogre::RenderTargetListener()
{
_midFont = createFont("midFont", "General",
"Jupiteroid-Regular.ttf", 18.0f);
_smallFont = createFont("smallFont", "General",
"Jupiteroid-Regular.ttf", 13.0f);
_bigFont = createFont("bigFont", "General", "Kenney Bold.ttf",
32.0f);
smallFont = ECS::get<GUIData>().mGuiOverlay->addFont(
"smallFont", "General");
OgreAssert(smallFont, "Could not load font");
midFont = ECS::get<GUIData>().mGuiOverlay->addFont("midFont",
"General");
OgreAssert(midFont, "Could not load font");
bigFont = ECS::get<GUIData>().mGuiOverlay->addFont("bigFont",
"General");
OgreAssert(bigFont, "Could not load font");
#if 0
Ogre::FontPtr _midFont = createFont("midFont", "General",
"Kenney Bold.ttf", 28.0f);
#endif
#if 0
ImGui::GetIO().Fonts->Build();
#endif
}
Ogre::FontPtr createFont(const Ogre::String &name,
const Ogre::String &group,
const Ogre::String &ttfname, float fontSize)
{
Ogre::FontPtr ret =
Ogre::FontManager::getSingleton().create(name, group);
ret->setType(Ogre::FontType::FT_TRUETYPE);
ret->setSource(ttfname);
ret->setTrueTypeSize(fontSize);
ret->setTrueTypeResolution(75);
ret->addCodePointRange(Ogre::Font::CodePointRange(30, 128));
ret->load();
return ret;
}
void
preViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override
{
@@ -36,14 +82,24 @@ struct GUIListener : public Ogre::RenderTargetListener {
ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(window_width, window_height),
ImGuiCond_Always);
ImGui::Begin("Dumb and Stupid");
ImGui::Begin("Control");
// if (ECS::get().get<GUI>().enabled)
// ECS::get().get<App>().app->setWindowGrab(true);
if (ImGui::Button("Shitty Quit button"))
if (ImGui::Button("Quit"))
Ogre::Root::getSingleton().queueEndRendering();
if (ImGui::Button("Chick-chick"))
if (ImGui::Button("Return"))
ECS::get().get<GUI>().finish();
ImGui::Text("We do stoopid...");
if (ImGui::Button("Enable/Disable item editor")) {
enableEditor ^= true;
if (enableEditor)
enableMapEditor = false;
}
if (ImGui::Button("Enable/Disable map editor")) {
enableMapEditor ^= true;
if (enableMapEditor)
enableEditor = false;
}
ImGui::Text("Text message...");
ImGui::End();
}
void create_entity_node(const Ogre::String &name, int key)
@@ -140,6 +196,9 @@ struct GUIListener : public Ogre::RenderTargetListener {
ImGui::Text("Name: %s", pname.c_str());
}
}
void map_editor()
{
}
void preview(const Ogre::RenderTargetViewportEvent &evt)
{
int i;
@@ -161,118 +220,214 @@ struct GUIListener : public Ogre::RenderTargetListener {
ImGuiWindowFlags_NoInputs);
// if (ECS::get().get<GUI>().enabled)
// ECS::get().get<App>().app->setWindowGrab(true);
ImGui::Text(
ImGui::PushFont(bigFont);
ImGui::TextWrapped(
"%s",
"This game does not autosave. Please use save function to keep your state");
ImGui::PopFont();
ImGui::End();
}
if (ECS::get().get<GUI>().enabled) {
buttons_panel();
buildings_editor();
ImVec2 size = ImGui::GetMainViewport()->Size;
float window_width = size.x * 0.2f;
if (window_width > panel_width)
window_width = panel_width;
float window_height = size.y * 0.5f - 20;
ImGui::SetNextWindowPos(ImVec2(size.x - window_width,
size.y * 0.5f + 20),
ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(window_width,
window_height),
ImGuiCond_Always);
// ImGui::Begin("Dumb and Stupid", &mKbd.gui_active);
ImGui::Begin("Panel...");
std::deque<Ogre::SceneNode *> tree_input_queue,
tree_output_queue;
std::vector<Ogre::SceneNode *> tree_list;
tree_input_queue.push_back(
ECS::get()
.get<EngineData>()
.mScnMgr->getRootSceneNode());
tree_input_queue.push_back(nullptr);
std::set<Ogre::SceneNode *> visited;
while (true) {
int new_nodes_count = 0;
while (!tree_input_queue.empty()) {
int child;
Ogre::SceneNode *item =
tree_input_queue.front();
tree_input_queue.pop_front();
if (item &&
visited.find(item) ==
visited.end()) { // new node
new_nodes_count++;
tree_output_queue.push_back(
item);
visited.insert(item);
const Ogre::Node::ChildNodeMap
&children =
item->getChildren();
for (child = 0;
child < children.size();
child++) {
tree_output_queue.push_back(
static_cast<
Ogre::SceneNode
*>(
children[child]));
} else if (ECS::get().get<GUI>().enabled) {
if (ECS::get().get<GUI>().narrationBox) {
ImVec2 size = ImGui::GetMainViewport()->Size;
ImGui::SetNextWindowPos(ImVec2(0,
size.y * 0.75f),
ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(size.x,
size.y * 0.25f),
ImGuiCond_Always);
ImGui::Begin("Narration...", NULL,
ImGuiWindowFlags_NoTitleBar);
ImGui::PushFont(midFont);
ImVec2 p = ImGui::GetCursorScreenPos();
ImGui::TextWrapped(
"%s", ECS::get()
.get<GUI>()
.narrationText.c_str());
ImGui::SetCursorScreenPos(p);
if (ImGui::InvisibleButton(
"Background",
ImGui::GetWindowSize()))
ECS::get<LuaBase>().mLua->call_handler(
"narration_progress");
ImGui::Spacing();
ImGui::PopFont();
ImGui::End();
} else if (ECS::get().get<GUI>().mainMenu) {
ImVec2 size = ImGui::GetMainViewport()->Size;
ImGui::SetNextWindowPos(ImVec2(0, 0),
ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(size.x, size.y),
ImGuiCond_Always);
ImGui::Begin(
"MainMenu", nullptr,
ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoDecoration |
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoFocusOnAppearing |
0);
// if (ECS::get().get<GUI>().enabled)
// ECS::get().get<App>().app->setWindowGrab(true);
ImGui::PushFont(bigFont);
ImGui::TextWrapped("%s", "Booo!!!!");
bool pressed = false;
bool new_game = false, cont = false,
load_game = false, opts = false,
quit = false;
ImGui::SetCursorPosY(size.y / 2.0f - 300.0f);
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
new_game = ImGui::Button("New Game");
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
cont = ImGui::Button("Continue");
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
load_game = ImGui::Button("Load Game");
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
opts = ImGui::Button("Options");
ImGui::SetCursorPosX(size.x / 2.0f - 300.0f);
quit = ImGui::Button("Quit###quit");
pressed = new_game || cont || load_game ||
opts || quit;
ImGui::PopFont();
ImGui::Spacing();
ImGui::End();
if (quit)
Ogre::Root::getSingleton()
.queueEndRendering();
if (pressed)
ECS::get().get<GUI>().finish();
if (new_game) {
ECS::get<LuaBase>().mLua->call_handler(
"new_game");
}
} else {
buttons_panel();
if (enableEditor)
buildings_editor();
if (enableMapEditor)
map_editor();
ImVec2 size = ImGui::GetMainViewport()->Size;
float window_width = size.x * 0.2f;
if (window_width > panel_width)
window_width = panel_width;
float window_height = size.y * 0.5f - 20;
ImGui::SetNextWindowPos(
ImVec2(size.x - window_width,
size.y * 0.5f + 20),
ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(window_width,
window_height),
ImGuiCond_Always);
// ImGui::Begin("Dumb and Stupid", &mKbd.gui_active);
ImGui::Begin("Panel...");
std::deque<Ogre::SceneNode *> tree_input_queue,
tree_output_queue;
std::vector<Ogre::SceneNode *> tree_list;
tree_input_queue.push_back(
ECS::get()
.get<EngineData>()
.mScnMgr->getRootSceneNode());
tree_input_queue.push_back(nullptr);
std::set<Ogre::SceneNode *> visited;
while (true) {
int new_nodes_count = 0;
while (!tree_input_queue.empty()) {
int child;
Ogre::SceneNode *item =
tree_input_queue.front();
tree_input_queue.pop_front();
if (item &&
visited.find(item) ==
visited.end()) { // new node
new_nodes_count++;
tree_output_queue
.push_back(
nullptr);
}
} else
tree_output_queue.push_back(
item);
item);
visited.insert(item);
const Ogre::Node::ChildNodeMap
&children =
item->getChildren();
for (child = 0;
child <
children.size();
child++) {
tree_output_queue
.push_back(static_cast<
Ogre::SceneNode
*>(
children[child]));
tree_output_queue
.push_back(
nullptr);
}
} else
tree_output_queue
.push_back(
item);
}
if (new_nodes_count == 0)
break;
tree_input_queue = tree_output_queue;
tree_output_queue.clear();
}
if (new_nodes_count == 0)
break;
tree_input_queue = tree_output_queue;
tree_output_queue.clear();
}
tree_list.insert(tree_list.begin(),
tree_output_queue.begin(),
tree_output_queue.end());
int count = 0;
int depth = 0;
std::vector<int> check_depth;
int max_depth = 0;
check_depth.push_back(0);
for (count = 0; count < tree_list.size(); count++) {
int t;
tree_list.insert(tree_list.begin(),
tree_output_queue.begin(),
tree_output_queue.end());
int count = 0;
int depth = 0;
std::vector<int> check_depth;
int max_depth = 0;
check_depth.push_back(0);
for (count = 0; count < tree_list.size();
count++) {
int t;
Ogre::SceneNode *node = tree_list[count];
if (node && max_depth >= depth) {
Ogre::String name = node->getName();
if (name.length() == 0) {
name = "Node #" +
Ogre::StringConverter::
toString(count);
Ogre::SceneNode *node =
tree_list[count];
if (node && max_depth >= depth) {
Ogre::String name =
node->getName();
if (name.length() == 0) {
name = "Node #" +
Ogre::StringConverter::
toString(
count);
}
if (ImGui::TreeNode(
name.c_str())) {
check_depth.push_back(
max_depth);
max_depth++;
ImGui::Text(
"%s",
(name +
"##caption")
.c_str());
position_editor(node);
ImGui::Separator();
orientation_editor(
node);
ImGui::Separator();
ImGui::Text(
"Attachments");
attachments_editor(
node);
}
} else if (!node &&
max_depth >= depth) {
max_depth = check_depth.back();
check_depth.pop_back();
ImGui::TreePop();
}
if (ImGui::TreeNode(name.c_str())) {
check_depth.push_back(
max_depth);
max_depth++;
ImGui::Text("%s",
(name + "##caption")
.c_str());
position_editor(node);
ImGui::Separator();
orientation_editor(node);
ImGui::Separator();
ImGui::Text("Attachments");
attachments_editor(node);
}
} else if (!node && max_depth >= depth) {
max_depth = check_depth.back();
check_depth.pop_back();
ImGui::TreePop();
if (tree_list[count])
depth++;
else
depth--;
}
if (tree_list[count])
depth++;
else
depth--;
ImGui::Spacing();
ImGui::End();
}
ImGui::Spacing();
ImGui::End();
}
}
};
@@ -293,7 +448,7 @@ GUIModule::GUIModule(flecs::world &ecs)
priv.mGuiOverlay = nullptr;
})
.add(flecs::Singleton);
ecs.set<GUI>({ false, true, false });
ecs.set<GUI>({ false, true, false, false, false });
ecs.set<GUIData>({ nullptr, {}, nullptr });
ui_wait =
ecs.system<const RenderWindow, App, GUIData>("SetupGUI")
@@ -311,9 +466,11 @@ GUIModule::GUIModule(flecs::world &ecs)
OgreAssert(app.mGuiOverlay,
"No ImGUI overlay");
gui.mGuiOverlay = app.mGuiOverlay;
gui.mGUIListener = new GUIListener();
gui.mGuiOverlay->setZOrder(300);
gui.mGuiOverlay->show();
gui.mGUIListener = new GUIListener();
gui.mGUIListener->panel_width = 300.0f;
gui.mGUIListener->enableEditor = false;
window.window->addListener(
gui.mGUIListener);
int i;

View File

@@ -10,6 +10,9 @@ struct GUI {
bool enabled;
bool grab;
bool grabChanged;
bool narrationBox;
bool mainMenu;
Ogre::String narrationText;
static void setWindowGrab(bool g = true)
{
ECS::GUI &gui = ECS::get().get_mut<ECS::GUI>();
@@ -23,6 +26,8 @@ struct GUI {
{
ECS::GUI &gui = ECS::get().get_mut<ECS::GUI>();
gui.enabled = false;
gui.mainMenu = false;
gui.narrationBox = false;
ECS::get().modified<ECS::GUI>();
setWindowGrab(true);
}

View File

@@ -7,10 +7,13 @@
#include "TerrainModule.h"
#include "SunModule.h"
#include "GUIModule.h"
#include "LuaData.h"
#include "WorldMapModule.h"
namespace ECS
{
static flecs::world ecs;
flecs::entity player;
void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
Ogre::SceneNode *cameraNode, Ogre::Camera *camera,
Ogre::RenderWindow *window)
@@ -37,6 +40,9 @@ void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
ecs.import <TerrainModule>();
ecs.import <SunModule>();
ecs.import <GUIModule>();
ecs.import <LuaModule>();
ecs.import <WorldMapModule>();
ecs.import <LuaModule>();
ecs.system<EngineData>("UpdateDelta")
.kind(flecs::OnUpdate)
.each([](EngineData &eng) {
@@ -84,6 +90,26 @@ void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
false,
{ 0, 0, 0 } });
std::cout << "Setup GameData done\n";
/* Create player */
player = ecs.entity("player");
Ogre::Vector3 playerPos(0, 0, 4);
player.set<CharacterLocation>({ { 0, 0, 0, 1 }, playerPos });
player.set<AnimationControl>({ AnimationControl::ANIM_NONE,
AnimationControl::ANIM_NONE, false,
false });
player.set<CharacterBase>({ "normal-male.glb",
0.0f,
nullptr,
nullptr,
nullptr,
nullptr,
{ 0, 0, 0 },
{ 0, 0, 0 },
false });
player.set<CharacterBody>({ nullptr, nullptr, nullptr, false, false });
player.add<Character>();
player.add<Player>();
}
void update(float delta)
{

View File

@@ -4,6 +4,7 @@
#include <flecs.h>
namespace ECS
{
extern flecs::entity player;
void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
Ogre::SceneNode *cameraNode, Ogre::Camera *camera,
Ogre::RenderWindow *window);

133
src/gamedata/LuaData.cpp Normal file
View File

@@ -0,0 +1,133 @@
#include "GameData.h"
#include "Components.h"
#include "GUIModule.h"
#include "LuaData.h"
namespace ECS
{
int LuaData::setup_handler()
{
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_pushvalue(L, 1);
int ref = luaL_ref(L, LUA_REGISTRYINDEX);
setup_handlers.push_back(ref);
return 0;
}
int LuaData::call_handler(const Ogre::String &event)
{
int i;
for (i = 0; i < setup_handlers.size(); i++) {
lua_rawgeti(L, LUA_REGISTRYINDEX, setup_handlers[i]);
lua_pushstring(L, event.c_str());
lua_pcall(L, 1, 0, 0);
}
return 0;
}
LuaData::LuaData()
: L(luaL_newstate())
{
luaopen_base(L);
luaopen_package(L);
lua_pushcfunction(L, [](lua_State *L) -> int {
OgreAssert(false, "Crash function called");
return 0;
});
lua_setglobal(L, "crash");
lua_pushcfunction(L, [](lua_State *L) -> int {
luaL_checktype(L, 1, LUA_TFUNCTION);
ECS::get<LuaBase>().mLua->setup_handler();
return 0;
});
lua_setglobal(L, "setup_handler");
lua_pushcfunction(L, [](lua_State *L) -> int {
luaL_checktype(L, 1, LUA_TSTRING);
size_t len;
Ogre::String message(luaL_tolstring(L, 1, &len));
if (message.length() == 0 && ECS::get_mut<GUI>().narrationBox) {
ECS::get_mut<GUI>().enabled = false;
ECS::get_mut<GUI>().grab = true;
ECS::get_mut<GUI>().grabChanged = true;
ECS::get_mut<GUI>().narrationText = message;
ECS::get_mut<GUI>().narrationBox = false;
ECS::modified<GUI>();
} else {
std::replace(message.begin(), message.end(), '\n', ' ');
std::replace(message.begin(), message.end(), '\r', ' ');
std::cout << "narrator message: " << message
<< std::endl;
ECS::get_mut<GUI>().enabled = true;
ECS::get_mut<GUI>().grab = false;
ECS::get_mut<GUI>().grabChanged = true;
ECS::get_mut<GUI>().narrationText = message;
ECS::get_mut<GUI>().narrationBox = true;
ECS::modified<GUI>();
}
return 0;
});
lua_setglobal(L, "narrate");
lua_pushcfunction(L, [](lua_State *L) -> int {
// ECS::get_mut<GUI>().mainMenu = true;
ECS::get_mut<GUI>().enabled = true;
ECS::get_mut<GUI>().mainMenu = true;
ECS::get_mut<GUI>().grab = false;
ECS::get_mut<GUI>().grabChanged = true;
ECS::modified<GUI>();
return 0;
});
lua_setglobal(L, "main_menu");
}
LuaData::~LuaData()
{
lua_close(L);
}
void LuaData::lateSetup()
{
Ogre::DataStreamList streams =
Ogre::ResourceGroupManager::getSingleton().openResources(
"*.lua", "LuaScripts");
while (!streams.empty()) {
Ogre::DataStreamPtr s = streams.front();
std::cout << "stream: " << s->getAsString() << "\n";
streams.pop_front();
if (luaL_dostring(L, s->getAsString().c_str()) != LUA_OK) {
std::cout << "error: " << lua_tostring(L, -1) << "\n";
OgreAssert(false, "Script failure");
}
}
const char *lua_code = "\n\
function stuff()\n\
return 4\n\
end\n\
x = stuff()\n\
";
luaL_dostring(L, lua_code);
lua_getglobal(L, "x");
int x = lua_tonumber(L, 1);
std::cout << "lua: " << x << "\n";
}
LuaModule::LuaModule(flecs::world &ecs)
{
ecs.component<LuaBase>().add(flecs::Singleton);
ecs.set<LuaBase>({ OGRE_NEW LuaData, false, false });
ecs.system<const EngineData, LuaBase>("LuaUpdate")
.kind(flecs::OnUpdate)
.each([](const EngineData &eng, LuaBase &lua) {
if (!lua.setup_called) {
lua.mLua->lateSetup();
lua.mLua->call_handler("setup");
lua.setup_called = true;
}
if (!lua.startup_called) {
if (eng.startupDelay <= 0.0f) {
lua.mLua->call_handler("startup");
lua.startup_called = true;
}
}
});
}
}

29
src/gamedata/LuaData.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef LUA_DATA_H
#define LUA_DATA_H
#include "lua.hpp"
#include <iostream>
#include <Ogre.h>
#include <OgreSerializer.h>
#include <flecs.h>
namespace ECS
{
struct LuaData {
lua_State *L;
std::vector<int> setup_handlers;
int setup_handler();
int call_handler(const Ogre::String &event);
LuaData();
virtual ~LuaData();
void lateSetup();
};
struct LuaBase {
LuaData *mLua;
bool setup_called;
bool startup_called;
};
struct LuaModule {
LuaModule(flecs::world &ecs);
};
}
#endif

View File

@@ -31,77 +31,30 @@
namespace ECS
{
class FlatTerrainDefiner
: public Ogre::TerrainPagedWorldSection::TerrainDefiner,
public Ogre::FrameListener {
Ogre::SceneManager *mScnMgr;
Ogre::Bullet::DynamicsWorld *mWorld;
struct gen_collider {
Ogre::TerrainGroup *group;
long x;
long y;
};
std::deque<struct gen_collider> collider_queue;
Ogre::Image img, img_noise, img_brushes;
public:
FlatTerrainDefiner(Ogre::SceneManager *scm,
Ogre::Bullet::DynamicsWorld *world)
: Ogre::TerrainPagedWorldSection::TerrainDefiner()
, Ogre::FrameListener()
, mScnMgr(scm)
, mWorld(world)
#define BRUSH_SIZE 64
struct HeightData {
Ogre::Image img;
Ogre::Image img_brushes;
Ogre::Image img_noise;
static HeightData *singleton;
HeightData()
{
Ogre::Root::getSingleton().addFrameListener(this);
img.load(
"world_map.png",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
img_noise.load(
"terrain.png",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
img_brushes.load(
"brushes.png",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
img_noise.load(
"terrain.png",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
}
private:
float get_noise_height(const Ogre::Vector2 &worldOffset, int x, int y)
static HeightData *get_singleton()
{
int h;
Ogre::Vector2 noisePoint;
struct noise_types {
Ogre::Vector2 noiseOfft;
float noiseMul;
float noiseBias;
float noiseAmp;
};
static struct noise_types noise_pass[] = {
{ { -100.0f, 70.0f }, 10.2f, -0.55f, 5.0f },
{ { -130.0f, 55.0f }, 5.35f, -0.55f, 1.0f }
};
static float noise_values[] = { 0.0f, 0.0f };
for (h = 0; h < (int)sizeof(noise_values) /
(int)sizeof(noise_values[0]);
h++) {
noisePoint = (worldOffset + Ogre::Vector2(x, y) +
noise_pass[h].noiseOfft) *
noise_pass[h].noiseMul;
int noise_x =
(int)(noisePoint.x + img_noise.getWidth() / 2) %
img_noise.getWidth();
int noise_y = (int)(noisePoint.y +
img_noise.getHeight() / 2) %
img_noise.getHeight();
Ogre::ColourValue noise_color =
img_noise.getColourAt(noise_x, noise_y, 0);
noise_values[h] =
(noise_color.r + noise_pass[h].noiseBias) *
noise_pass[h].noiseAmp;
}
return noise_values[0] + noise_values[1];
if (!singleton)
singleton = new HeightData();
return singleton;
}
#define BRUSH_SIZE 64
float get_brush_height(int id, int x, int y)
{
int m = 0;
@@ -149,7 +102,96 @@ private:
out:
return height;
}
float get_noise_height(const Ogre::Vector2 &worldOffset, int x, int y)
{
int h;
Ogre::Vector2 noisePoint;
struct noise_types {
Ogre::Vector2 noiseOfft;
float noiseMul;
float noiseBias;
float noiseAmp;
};
static struct noise_types noise_pass[] = {
{ { -100.0f, 70.0f }, 10.2f, -0.55f, 5.0f },
{ { -130.0f, 55.0f }, 5.35f, -0.55f, 1.0f }
};
static float noise_values[] = { 0.0f, 0.0f };
for (h = 0; h < (int)sizeof(noise_values) /
(int)sizeof(noise_values[0]);
h++) {
noisePoint = (worldOffset + Ogre::Vector2(x, y) +
noise_pass[h].noiseOfft) *
noise_pass[h].noiseMul;
int noise_x =
(int)(noisePoint.x + img_noise.getWidth() / 2) %
img_noise.getWidth();
int noise_y = (int)(noisePoint.y +
img_noise.getHeight() / 2) %
img_noise.getHeight();
Ogre::ColourValue noise_color =
img_noise.getColourAt(noise_x, noise_y, 0);
noise_values[h] =
(noise_color.r + noise_pass[h].noiseBias) *
noise_pass[h].noiseAmp;
}
return noise_values[0] + noise_values[1];
}
float get_height(Ogre::TerrainGroup *terrainGroup, long x, long y,
int j, int i)
{
uint16_t terrainSize = terrainGroup->getTerrainSize();
Ogre::Vector2 worldOffset(Ogre::Real(x * (terrainSize - 1)),
Ogre::Real(y * (terrainSize - 1)));
float brush_height0 =
HeightData::get_singleton()->get_brush_height(
0, j % BRUSH_SIZE, i % BRUSH_SIZE) -
0.55f;
float brush_height1 =
HeightData::get_singleton()->get_brush_height(
1, j % BRUSH_SIZE, i % BRUSH_SIZE) -
0.55f;
float mheight =
Ogre::Math::lerp(
brush_height1, brush_height0,
HeightData::get_singleton()->get_base_height(
worldOffset, j, i)) *
120.0f;
float height = mheight;
if (mheight > 0.5f)
height += 2.0f + get_noise_height(worldOffset, j, i);
else if (mheight < -0.5f)
height -= 2.0f + get_noise_height(worldOffset, j, i);
return height;
}
};
HeightData *HeightData::singleton = nullptr;
class FlatTerrainDefiner
: public Ogre::TerrainPagedWorldSection::TerrainDefiner,
public Ogre::FrameListener {
Ogre::SceneManager *mScnMgr;
Ogre::Bullet::DynamicsWorld *mWorld;
struct gen_collider {
Ogre::TerrainGroup *group;
long x;
long y;
};
std::deque<struct gen_collider> collider_queue;
public:
FlatTerrainDefiner(Ogre::SceneManager *scm,
Ogre::Bullet::DynamicsWorld *world)
: Ogre::TerrainPagedWorldSection::TerrainDefiner()
, Ogre::FrameListener()
, mScnMgr(scm)
, mWorld(world)
{
Ogre::Root::getSingleton().addFrameListener(this);
}
private:
public:
void define(Ogre::TerrainGroup *terrainGroup, long x, long y) override
{
@@ -158,37 +200,15 @@ public:
MEMCATEGORY_GEOMETRY);
// float *heightMapCollider = OGRE_ALLOC_T(
// float, terrainSize *terrainSize, MEMCATEGORY_GEOMETRY);
Ogre::Vector2 worldOffset(Ogre::Real(x * (terrainSize - 1)),
Ogre::Real(y * (terrainSize - 1)));
Ogre::Vector2 worldOrigin =
Ogre::Vector2(img.getWidth(), img.getHeight()) * 0.5f;
// Ogre::Vector2 worldOrigin =
// Ogre::Vector2(img.getWidth(), img.getHeight()) * 0.5f;
float chunk = 128.0f;
Ogre::Vector2 revisedValuePoint;
for (int i = 0; i < terrainSize; i++)
for (int j = 0; j < terrainSize; j++) {
float brush_height0 =
get_brush_height(0, j % BRUSH_SIZE,
i % BRUSH_SIZE) -
0.55f;
float brush_height1 =
get_brush_height(1, j % BRUSH_SIZE,
i % BRUSH_SIZE) -
0.55f;
float mheight =
Ogre::Math::lerp(
brush_height1, brush_height0,
get_base_height(worldOffset, j,
i)) *
120.0f;
float height = mheight;
if (mheight > 0.5f)
height += 2.0f +
get_noise_height(worldOffset,
j, i);
else if (mheight < -0.5f)
height -= 2.0f +
get_noise_height(worldOffset,
j, i);
float height =
HeightData::get_singleton()->get_height(
terrainGroup, x, y, j, i);
// height = -2.0f;
heightMap[i * terrainSize + j] = height;
@@ -277,6 +297,26 @@ public:
created = true;
}
collider_queue.pop_front();
// FIXME: create entities and components instead
Ogre::SceneNode *items =
terrain->_getRootSceneNode()
->createChildSceneNode();
for (int i = 0; i < ECS::get<PlacementObjects>()
.altar_items.size();
i++) {
const struct PlacementObjects::item &item =
ECS::get<PlacementObjects>()
.altar_items[i];
Ogre::Entity *ent =
group->getSceneManager()
->createEntity(
item.entity);
Ogre::SceneNode *what =
items->createChildSceneNode();
what->attachObject(ent);
what->setOrientation(item.rotation);
what->setPosition(item.position);
}
} else {
output.push_back(collider_queue.front());
collider_queue.pop_front();
@@ -433,6 +473,7 @@ TerrainModule::TerrainModule(flecs::world &ecs)
terrain.mTerrainGroup->freeTemporaryResources();
std::cout << "Terrain setup done\n";
ECS::get().set<PlacementObjects>({});
}
if (sun.mSun &&
priv.mSunUpdate.getMilliseconds() > 1000) {
@@ -468,5 +509,113 @@ TerrainModule::TerrainModule(flecs::world &ecs)
ECS::get().add<TerrainReady>();
}
});
ecs.system<const Terrain, PlacementObjects>("UpdatePlacementObjects")
.kind(flecs::OnUpdate)
.each([](const Terrain &terrain, PlacementObjects &placement) {
if (placement.altar_items.size() == 0) {
struct PlacementObjects::item item;
int i, j;
int worldSize = terrain.mTerrainGroup
->getTerrainWorldSize();
uint16_t terrainSize =
terrain.mTerrainGroup->getTerrainSize();
item.entity = "altar.glb";
item.rotation = Ogre::Quaternion(0, 0, 0, 1);
item.position = Ogre::Vector3(0, 0, 0);
float height =
HeightData::get_singleton()->get_height(
terrain.mTerrainGroup, 0, 0, 0,
0);
item.position.y = height;
placement.altar_items.push_back(item);
for (i = -64000; i < 64000; i += 1000)
for (j = -64000; j < 64000; j += 1000) {
if (i == 0 && j == 0)
continue;
Ogre::Vector3 position(i, 0, j);
long xslot, yslot;
terrain.mTerrainGroup
->convertWorldPositionToTerrainSlot(
position,
&xslot, &yslot);
Ogre::Vector3 slotpos;
terrain.mTerrainGroup
->convertTerrainSlotToWorldPosition(
xslot, yslot,
&slotpos);
Ogre::Vector3 offset =
(position - slotpos) *
terrainSize / worldSize;
height =
HeightData::get_singleton()
->get_height(
terrain.mTerrainGroup,
xslot,
yslot,
(int)offset.x +
(terrainSize -
1) / 2,
(int)offset.z +
(terrainSize -
1) / 2);
#if 0
height =
terrain.mTerrainGroup
->getHeightAtWorldPosition(
position);
#endif
if (height > -9.0f)
continue;
std::cout << "worldSize: "
<< worldSize - 1
<< std::endl;
std::cout << "height: " << i
<< " " << j << " "
<< height
<< std::endl;
item.entity = "altar.glb";
item.rotation =
Ogre::Quaternion(0, 0,
0, 1);
position.y = height;
item.position = position;
placement.altar_items.push_back(
item);
}
for (i = 0; i < placement.altar_items.size();
i++) {
std::cout << "placement: " << i << " "
<< placement.altar_items[i]
.position
<< std::endl;
}
}
flecs::entity player = ECS::player;
CharacterLocation &loc =
player.get_mut<CharacterLocation>();
float height =
get_height(terrain.mTerrainGroup, loc.position);
loc.position.y = height + 0.0f;
player.get<CharacterBase>().mBodyNode->setPosition(
loc.position);
player.get<CharacterBase>().mBodyNode->setOrientation(
Ogre::Quaternion());
player.modified<CharacterLocation>();
});
}
float TerrainModule::get_height(Ogre::TerrainGroup *group,
const Ogre::Vector3 &position)
{
int worldSize = group->getTerrainWorldSize();
uint16_t terrainSize = group->getTerrainSize();
long xslot, yslot;
group->convertWorldPositionToTerrainSlot(position, &xslot, &yslot);
Ogre::Vector3 slotpos;
group->convertTerrainSlotToWorldPosition(xslot, yslot, &slotpos);
Ogre::Vector3 offset = (position - slotpos) * terrainSize / worldSize;
float height = HeightData::get_singleton()->get_height(
group, xslot, yslot, (int)offset.x + (terrainSize - 1) / 2,
(int)offset.z + (terrainSize - 1) / 2);
return height;
}
}

View File

@@ -23,8 +23,18 @@ struct Terrain {
Ogre::Vector3 mTerrainPos;
};
struct PlacementObjects {
struct item {
Ogre::String entity;
Ogre::Quaternion rotation;
Ogre::Vector3 position;
};
std::vector<struct item> altar_items;
};
struct TerrainModule {
TerrainModule(flecs::world &ecs);
static float get_height(Ogre::TerrainGroup *group,
const Ogre::Vector3 &position);
};
}
#endif

View File

@@ -0,0 +1,6 @@
#include "WorldMapModule.h"
ECS::WorldMapModule::WorldMapModule(flecs::world &ecs)
{
ecs.component<WorldMap>();
}

View File

@@ -0,0 +1,11 @@
#ifndef WORLD_MAP_MODULE_H
#define WORLD_MAP_MODULE_H
#include <flecs.h>
namespace ECS
{
struct WorldMap {};
struct WorldMapModule {
WorldMapModule(flecs::world &ecs);
};
}
#endif

View File

@@ -19,7 +19,7 @@ foreach(LUA_FILE ${LUA_OBJ})
list(APPEND LUA_SRC lua-5.4.8/src/${LUA_SRC_ITEM})
endforeach()
add_library(lua ${LUA_SRC})
target_include_directories(lua PRIVATE lua-5.4.8/src)
target_include_directories(lua PUBLIC lua-5.4.8/src)
add_executable(luavm lua-5.4.8/src/lua.c)
target_link_libraries(luavm lua m)
target_include_directories(luavm PRIVATE lua-5.4.8/src)