Skip to content

Commit

Permalink
Items are now visible in the world
Browse files Browse the repository at this point in the history
  • Loading branch information
ataulien committed Sep 20, 2016
2 parents 395027e + c428736 commit 37cdde6
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 52 deletions.
5 changes: 5 additions & 0 deletions src/components/VobClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "VobClasses.h"
#include <engine/World.h>
#include <logic/PlayerController.h>
#include <logic/ItemController.h>
#include <logic/visuals/ModelVisual.h>
#include <utils/logger.h>
#include "EntityActions.h"
Expand Down Expand Up @@ -55,6 +56,10 @@ Handle::EntityHandle VobTypes::initItemFromScript(World::WorldInstance& world, D
userData->world = world.getMyHandle();
scriptObj.userPtr = userData;

// Setup itemcontroller
Components::LogicComponent& logic = world.getEntity<Components::LogicComponent>(e);
logic.m_pLogicController = new Logic::ItemController(world, e, scriptInstance);

// Assign a default visual
Vob::VobInformation vob = Vob::asVob(world, e);
Vob::setVisual(vob, scriptObj.visual);
Expand Down
72 changes: 51 additions & 21 deletions src/content/AudioEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,52 @@ AudioEngine::~AudioEngine()

}

int AudioEngine::adpcm_decode_data(uint8_t* infile, std::vector<uint8_t>& outfile, size_t num_samples, int num_channels , int block_size )
{
int samples_per_block = (block_size - num_channels * 4) * (num_channels ^ 3) + 1, percent;
int16_t *pcm_block;
uint8_t *adpcm_block;
size_t progress_divider = 0;


while (num_samples) {
int this_block_adpcm_samples = samples_per_block;
int this_block_pcm_samples = samples_per_block;

if (this_block_adpcm_samples > num_samples) {
this_block_adpcm_samples = ((num_samples + 6) & ~7) + 1;
block_size = (this_block_adpcm_samples - 1) / (num_channels ^ 3) + (num_channels * 4);
this_block_pcm_samples = num_samples;
}

// Read in-wav
adpcm_block = infile;
infile += block_size;

// Add to out-wav
size_t ofidx = outfile.size();
outfile.resize(outfile.size() + this_block_pcm_samples * num_channels * 2);
pcm_block = (int16_t*)&outfile[ofidx];

if (num_samples == 364)
{
fprintf(stderr, "364 samples");
}
if (adpcm_decode_block(pcm_block, adpcm_block, block_size, num_channels) != this_block_adpcm_samples) {
fprintf(stderr, "adpcm_decode_block() did not return expected value!\n");
return -1;
}

num_samples -= this_block_pcm_samples;
}

return 0;
}

Handle::AudioHandle AudioEngine::loadAudioVDF(const VDFS::FileIndex& idx, const std::string& name)
{
std::vector<uint8_t> data;

std::vector<uint8_t> outData;
// Check cache first
if(m_SoundMap.find(name) != m_SoundMap.end())
return m_SoundMap[name];
Expand All @@ -40,28 +82,16 @@ Handle::AudioHandle AudioEngine::loadAudioVDF(const VDFS::FileIndex& idx, const
AudioFile& a = m_Allocator.getElement(h);

// Decode the ADPCM compressed audio gothic uses

//
// ###### This is broken! Decode using new lib, load samples directly into sfml (44100 khz, 1 channel)
//

/*static bool s_initDone = false;
if(!s_initDone)
{
initDecode68000();
s_initDone = true;
}
std::vector<uint8_t> uncompressedWav;
decodeWAV(data, uncompressedWav);
// Load the buffer with the data from the VDF
if(!a.buffer.loadFromMemory(uncompressedWav.data(), uncompressedWav.size()))
{

// Gothics wav-files have a headersize of 60 bytes, 1 channel, blocksize of 1024
size_t numNibbles = (data.size() - 60) * 2;
adpcm_decode_data(data.data()+60, outData, numNibbles);

if (!a.buffer.loadFromSamples(reinterpret_cast<sf::Int16*>(outData.data()), outData.size()/2 , 1, 44100))
{
m_Allocator.removeObject(h);
return Handle::AudioHandle::makeInvalidHandle();
}*/
}

m_SoundMap[name] = h;

Expand Down
71 changes: 46 additions & 25 deletions src/engine/World.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ void WorldInstance::init(Engine::BaseEngine& engine, const std::string& zen)
// Call other overload
init(engine);

// Init daedalus-vm
std::string datPath = m_pEngine->getEngineArgs().gameBaseDirectory
+ "/_work/data/Scripts/_compiled/GOTHIC.DAT";
std::string datFile = Utils::getCaseSensitivePath(datPath);

if(Utils::fileExists(datFile))
{
m_ScriptEngine.loadDAT(datFile);
} else
{
LogError() << "Failed to find GOTHIC.DAT at: " << datFile;
}

// Load world
if(!zen.empty())
{
// Load ZEN
Expand Down Expand Up @@ -139,18 +153,41 @@ void WorldInstance::init(Engine::BaseEngine& engine, const std::string& zen)
for (const ZenLoad::zCVobData &v : vobs)
{
vobLoad(v.childVobs);

// Check for special vobs // FIXME: Should be somewhere else
Vob::VobInformation vob;
Handle::EntityHandle e;
if(v.objectClass == "oCItem:zCVob")
{
// Get item instance
if(getScriptEngine().hasSymbol(v.oCItem.instanceName))
{
Daedalus::GameState::ItemHandle h = getScriptEngine().getGameState().insertItem(v.oCItem.instanceName);

Handle::EntityHandle e = Vob::constructVob(*this);
Vob::VobInformation vob = Vob::asVob(*this, e);
e = VobTypes::initItemFromScript(*this, h);
vob = Vob::asVob(*this, e);
}
else{
LogWarn() << "Invalid item instance: " << v.oCItem.instanceName;
}
}
else {
// Normal zCVob or not implemented subclass
e = Vob::constructVob(*this);
vob = Vob::asVob(*this, e);
}

// Setup
if(!v.vobName.empty())
{
Vob::setName(vob, v.vobName);
if(!vob.isValid())
continue;

// Add to name-map
m_VobsByNames[v.vobName] = e;
}
// Setup
if(!v.vobName.empty())
{
Vob::setName(vob, v.vobName);

// Add to name-map
m_VobsByNames[v.vobName] = e;
}

// Set position
Math::Matrix m = Math::Matrix(v.worldMatrix.mv);
Expand All @@ -174,8 +211,6 @@ void WorldInstance::init(Engine::BaseEngine& engine, const std::string& zen)
getEntity<Components::ObjectComponent>(h).m_Name = v.vobName;
m_FreePoints[v.vobName] = h;
}


}
else
{
Expand Down Expand Up @@ -285,20 +320,6 @@ void WorldInstance::init(Engine::BaseEngine& engine, const std::string& zen)

void WorldInstance::initializeScriptEngineForZenWorld(const std::string& worldName)
{
// Default to the path G2 uses
std::string datPath = m_pEngine->getEngineArgs().gameBaseDirectory
+ "/_work/data/Scripts/_compiled/GOTHIC.DAT";
std::string datFile = Utils::getCaseSensitivePath(datPath);

// Check G2 variant
if(Utils::fileExists(datFile))
{
m_ScriptEngine.loadDAT(datFile);
} else
{
LogError() << "Failed to find GOTHIC.DAT at: " << datFile;
}

if(!worldName.empty())
{
LogInfo() << "Initializing scripts for world: " << worldName;
Expand Down
20 changes: 20 additions & 0 deletions src/logic/ItemController.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "ItemController.h"
#include <engine/World.h>
#include <components/Vob.h>

using namespace Logic;

ItemController::ItemController(World::WorldInstance& world, Handle::EntityHandle entity, Daedalus::GameState::ItemHandle scriptInstance) :
Controller(world, entity)
{
m_ScriptState.scriptInstance = scriptInstance;
}

void Logic::ItemController::updateVobFromScript()
{
Daedalus::GEngineClasses::C_Item& item = m_World.getScriptEngine().getGameState().getItem(m_ScriptState.scriptInstance);
Vob::VobInformation vob = Vob::asVob(m_World, m_Entity);

// Update visual
Vob::setVisual(vob, item.visual);
}
30 changes: 30 additions & 0 deletions src/logic/ItemController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once
#include <daedalus/DaedalusGameState.h>
#include <set>
#include "Controller.h"
#include "LogicDef.h"

namespace Logic
{
class ItemController : public Controller
{
public:
/**
* @param world World of the underlaying entity
* @param entity Entity owning this controller
*/
ItemController(World::WorldInstance& world, Handle::EntityHandle entity, Daedalus::GameState::ItemHandle scriptInstance);

/**
* Updates this vob from the script-side values (visual, etc)
*/
void updateVobFromScript();

protected:

struct {
Daedalus::GameState::ItemHandle scriptInstance;
}m_ScriptState;

};
}
17 changes: 12 additions & 5 deletions src/logic/scriptExternals/Externals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,10 @@ void ::Logic::ScriptExternals::registerEngineExternals(World::WorldInstance& wor
uint32_t self = vm.popVar();

VobTypes::NpcVobInformation npc = getNPCByInstance(self);
Daedalus::GameState::ItemHandle item = vm.getGameState().addInventoryItem(instance, VobTypes::getScriptHandle(npc));

if(npc.isValid())
{
Daedalus::GameState::ItemHandle item = vm.getGameState().addInventoryItem(instance, VobTypes::getScriptHandle(npc));
VobTypes::NPC_EquipWeapon(npc, item);
}
else{
Expand Down Expand Up @@ -260,12 +260,19 @@ void ::Logic::ScriptExternals::registerEngineExternals(World::WorldInstance& wor
World::WorldInstance& world = Vob::getWorld(vob);
size_t wpidx = World::Waynet::getWaypointIndex(world.getWaynet(), wpname);

float dist = (selfTransform.Translation() - world.getWaynet().waypoints[wpidx].position).length();
if(wpidx != World::Waynet::INVALID_WAYPOINT)
{
float dist = (selfTransform.Translation() - world.getWaynet().waypoints[wpidx].position).length();

// Convert to cm
dist *= 100.0f;
// Convert to cm
dist *= 100.0f;

vm.setReturn(static_cast<int32_t>(dist));
vm.setReturn(static_cast<int32_t>(dist));
}
else {
vm.setReturn(INT32_MAX);
}

});

vm->registerExternalFunction("npc_getdisttoitem", [=](Daedalus::DaedalusVM& vm){
Expand Down
4 changes: 3 additions & 1 deletion src/ui/PrintScreenMessages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ void PrintScreenMessages::drawTimedMessages(double dt, Render::RenderConfig& con
}

// Remove outtimed message
for(auto it=m_TimedMessages.begin();it!=m_TimedMessages.end();it++)
for(auto it=m_TimedMessages.begin();it!=m_TimedMessages.end();)
{
if((*it).timeLeft < 0)
it = m_TimedMessages.erase(it);
else
it++;
}
};

Expand Down

0 comments on commit 37cdde6

Please sign in to comment.