Updates
This commit is contained in:
@@ -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
|
||||
|
||||
5
Game.cpp
5
Game.cpp
@@ -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
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
BIN
assets/fonts/Kenney Bold.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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})
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
133
src/gamedata/LuaData.cpp
Normal 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
29
src/gamedata/LuaData.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
6
src/gamedata/WorldMapModule.cpp
Normal file
6
src/gamedata/WorldMapModule.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "WorldMapModule.h"
|
||||
|
||||
ECS::WorldMapModule::WorldMapModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.component<WorldMap>();
|
||||
}
|
||||
11
src/gamedata/WorldMapModule.h
Normal file
11
src/gamedata/WorldMapModule.h
Normal 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
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user