Add event manager and use it to trigger sounds
parent
e53794868e
commit
6c14025b2d
|
@ -654,6 +654,10 @@ minetest.register_node("default:dirt_with_grass", {
|
||||||
is_ground_content = true,
|
is_ground_content = true,
|
||||||
groups = {crumbly=3},
|
groups = {crumbly=3},
|
||||||
drop = 'default:dirt',
|
drop = 'default:dirt',
|
||||||
|
sounds = {
|
||||||
|
--footstep = "default_grass_footstep",
|
||||||
|
footstep = {name="default_grass_footstep", gain=0.5},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("default:dirt_with_grass_footsteps", {
|
minetest.register_node("default:dirt_with_grass_footsteps", {
|
||||||
|
|
|
@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "noise.h" // easeCurve
|
#include "noise.h" // easeCurve
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
|
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
|
||||||
IGameDef *gamedef):
|
IGameDef *gamedef):
|
||||||
|
@ -177,8 +178,10 @@ void Camera::step(f32 dtime)
|
||||||
bool step = (was == 0 ||
|
bool step = (was == 0 ||
|
||||||
(was < 0.5f && m_view_bobbing_anim >= 0.5f) ||
|
(was < 0.5f && m_view_bobbing_anim >= 0.5f) ||
|
||||||
(was > 0.5f && m_view_bobbing_anim <= 0.5f));
|
(was > 0.5f && m_view_bobbing_anim <= 0.5f));
|
||||||
if(step)
|
if(step){
|
||||||
m_gamedef->sound()->playSound("default_grass_walk", false, 1.0);
|
MtEvent *e = new SimpleTriggerEvent("ViewBobbingStep");
|
||||||
|
m_gamedef->event()->put(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +193,8 @@ void Camera::step(f32 dtime)
|
||||||
{
|
{
|
||||||
m_digging_anim = 0;
|
m_digging_anim = 0;
|
||||||
m_digging_button = -1;
|
m_digging_button = -1;
|
||||||
m_gamedef->sound()->playSound("dig", false, 1.0);
|
MtEvent *e = new SimpleTriggerEvent("CameraDig");
|
||||||
|
m_gamedef->event()->put(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,12 +226,14 @@ Client::Client(
|
||||||
IWritableTextureSource *tsrc,
|
IWritableTextureSource *tsrc,
|
||||||
IWritableItemDefManager *itemdef,
|
IWritableItemDefManager *itemdef,
|
||||||
IWritableNodeDefManager *nodedef,
|
IWritableNodeDefManager *nodedef,
|
||||||
ISoundManager *sound
|
ISoundManager *sound,
|
||||||
|
MtEventManager *event
|
||||||
):
|
):
|
||||||
m_tsrc(tsrc),
|
m_tsrc(tsrc),
|
||||||
m_itemdef(itemdef),
|
m_itemdef(itemdef),
|
||||||
m_nodedef(nodedef),
|
m_nodedef(nodedef),
|
||||||
m_sound(sound),
|
m_sound(sound),
|
||||||
|
m_event(event),
|
||||||
m_mesh_update_thread(this),
|
m_mesh_update_thread(this),
|
||||||
m_env(
|
m_env(
|
||||||
new ClientMap(this, this, control,
|
new ClientMap(this, this, control,
|
||||||
|
@ -2330,4 +2332,8 @@ ISoundManager* Client::getSoundManager()
|
||||||
{
|
{
|
||||||
return m_sound;
|
return m_sound;
|
||||||
}
|
}
|
||||||
|
MtEventManager* Client::getEventManager()
|
||||||
|
{
|
||||||
|
return m_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ class IWritableNodeDefManager;
|
||||||
//class IWritableCraftDefManager;
|
//class IWritableCraftDefManager;
|
||||||
class ClientEnvironment;
|
class ClientEnvironment;
|
||||||
struct MapDrawControl;
|
struct MapDrawControl;
|
||||||
|
class MtEventManager;
|
||||||
|
|
||||||
class ClientNotReadyException : public BaseException
|
class ClientNotReadyException : public BaseException
|
||||||
{
|
{
|
||||||
|
@ -175,7 +176,8 @@ public:
|
||||||
IWritableTextureSource *tsrc,
|
IWritableTextureSource *tsrc,
|
||||||
IWritableItemDefManager *itemdef,
|
IWritableItemDefManager *itemdef,
|
||||||
IWritableNodeDefManager *nodedef,
|
IWritableNodeDefManager *nodedef,
|
||||||
ISoundManager *sound
|
ISoundManager *sound,
|
||||||
|
MtEventManager *event
|
||||||
);
|
);
|
||||||
|
|
||||||
~Client();
|
~Client();
|
||||||
|
@ -308,6 +310,7 @@ public:
|
||||||
virtual ITextureSource* getTextureSource();
|
virtual ITextureSource* getTextureSource();
|
||||||
virtual u16 allocateUnknownNodeId(const std::string &name);
|
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||||
virtual ISoundManager* getSoundManager();
|
virtual ISoundManager* getSoundManager();
|
||||||
|
virtual MtEventManager* getEventManager();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -335,6 +338,8 @@ private:
|
||||||
IWritableItemDefManager *m_itemdef;
|
IWritableItemDefManager *m_itemdef;
|
||||||
IWritableNodeDefManager *m_nodedef;
|
IWritableNodeDefManager *m_nodedef;
|
||||||
ISoundManager *m_sound;
|
ISoundManager *m_sound;
|
||||||
|
MtEventManager *m_event;
|
||||||
|
|
||||||
MeshUpdateThread m_mesh_update_thread;
|
MeshUpdateThread m_mesh_update_thread;
|
||||||
ClientEnvironment m_env;
|
ClientEnvironment m_env;
|
||||||
con::Connection m_con;
|
con::Connection m_con;
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EVENT_HEADER
|
||||||
|
#define EVENT_HEADER
|
||||||
|
|
||||||
|
class MtEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~MtEvent(){};
|
||||||
|
//virtual MtEvent* clone(){ return new IEvent; }
|
||||||
|
virtual const char* getType() const = 0;
|
||||||
|
|
||||||
|
MtEvent* checkIs(const std::string &type)
|
||||||
|
{
|
||||||
|
if(type == getType())
|
||||||
|
return this;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// An event with no parameters and customizable name
|
||||||
|
class SimpleTriggerEvent: public MtEvent
|
||||||
|
{
|
||||||
|
const char *type;
|
||||||
|
public:
|
||||||
|
SimpleTriggerEvent(const char *type):
|
||||||
|
type(type)
|
||||||
|
{}
|
||||||
|
const char* getType() const
|
||||||
|
{return type;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MtEventReceiver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~MtEventReceiver(){};
|
||||||
|
virtual void onEvent(MtEvent *e) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*event_receive_func)(MtEvent *e, void *data);
|
||||||
|
|
||||||
|
class MtEventManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~MtEventManager(){};
|
||||||
|
virtual void put(MtEvent *e) = 0;
|
||||||
|
virtual void reg(const char *type, event_receive_func f, void *data) = 0;
|
||||||
|
// If data==NULL, every occurence of f is deregistered.
|
||||||
|
virtual void dereg(const char *type, event_receive_func f, void *data) = 0;
|
||||||
|
virtual void reg(MtEventReceiver *r, const char *type) = 0;
|
||||||
|
virtual void dereg(MtEventReceiver *r, const char *type) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EVENT_MANAGER_HEADER
|
||||||
|
#define EVENT_MANAGER_HEADER
|
||||||
|
|
||||||
|
#include "event.h"
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class EventManager: public MtEventManager
|
||||||
|
{
|
||||||
|
static void receiverReceive(MtEvent *e, void *data)
|
||||||
|
{
|
||||||
|
MtEventReceiver *r = (MtEventReceiver*)data;
|
||||||
|
r->onEvent(e);
|
||||||
|
}
|
||||||
|
struct FuncSpec{
|
||||||
|
event_receive_func f;
|
||||||
|
void *d;
|
||||||
|
FuncSpec(event_receive_func f, void *d):
|
||||||
|
f(f), d(d)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
struct Dest{
|
||||||
|
std::list<FuncSpec> funcs;
|
||||||
|
};
|
||||||
|
std::map<std::string, Dest> m_dest;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~EventManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void put(MtEvent *e)
|
||||||
|
{
|
||||||
|
std::map<std::string, Dest>::iterator i = m_dest.find(e->getType());
|
||||||
|
if(i != m_dest.end()){
|
||||||
|
std::list<FuncSpec> &funcs = i->second.funcs;
|
||||||
|
for(std::list<FuncSpec>::iterator i = funcs.begin();
|
||||||
|
i != funcs.end(); i++){
|
||||||
|
(*(i->f))(e, i->d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete e;
|
||||||
|
}
|
||||||
|
void reg(const char *type, event_receive_func f, void *data)
|
||||||
|
{
|
||||||
|
std::map<std::string, Dest>::iterator i = m_dest.find(type);
|
||||||
|
if(i != m_dest.end()){
|
||||||
|
i->second.funcs.push_back(FuncSpec(f, data));
|
||||||
|
} else{
|
||||||
|
std::list<FuncSpec> funcs;
|
||||||
|
Dest dest;
|
||||||
|
dest.funcs.push_back(FuncSpec(f, data));
|
||||||
|
m_dest[type] = dest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void dereg(const char *type, event_receive_func f, void *data)
|
||||||
|
{
|
||||||
|
if(type != NULL){
|
||||||
|
std::map<std::string, Dest>::iterator i = m_dest.find(type);
|
||||||
|
if(i != m_dest.end()){
|
||||||
|
std::list<FuncSpec> &funcs = i->second.funcs;
|
||||||
|
std::list<FuncSpec>::iterator i = funcs.begin();
|
||||||
|
while(i != funcs.end()){
|
||||||
|
bool remove = (i->f == f && (!data || i->d == data));
|
||||||
|
if(remove)
|
||||||
|
funcs.erase(i++);
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
for(std::map<std::string, Dest>::iterator
|
||||||
|
i = m_dest.begin(); i != m_dest.end(); i++){
|
||||||
|
std::list<FuncSpec> &funcs = i->second.funcs;
|
||||||
|
std::list<FuncSpec>::iterator i = funcs.begin();
|
||||||
|
while(i != funcs.end()){
|
||||||
|
bool remove = (i->f == f && (!data || i->d == data));
|
||||||
|
if(remove)
|
||||||
|
funcs.erase(i++);
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void reg(MtEventReceiver *r, const char *type)
|
||||||
|
{
|
||||||
|
reg(type, EventManager::receiverReceive, r);
|
||||||
|
}
|
||||||
|
void dereg(MtEventReceiver *r, const char *type)
|
||||||
|
{
|
||||||
|
dereg(type, EventManager::receiverReceive, r);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
77
src/game.cpp
77
src/game.cpp
|
@ -59,6 +59,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#if USE_AUDIO
|
#if USE_AUDIO
|
||||||
#include "sound_openal.h"
|
#include "sound_openal.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "event_manager.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -779,6 +780,58 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SoundMaker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ISoundManager *m_sound;
|
||||||
|
|
||||||
|
SimpleSoundSpec m_player_step_sound;
|
||||||
|
float m_player_step_timer;
|
||||||
|
|
||||||
|
SoundMaker(ISoundManager *sound):
|
||||||
|
m_sound(sound),
|
||||||
|
m_player_step_sound("default_grass_walk"),
|
||||||
|
m_player_step_timer(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void playPlayerStep()
|
||||||
|
{
|
||||||
|
if(m_player_step_timer <= 0 && m_player_step_sound.exists()){
|
||||||
|
m_player_step_timer = 0.03;
|
||||||
|
m_sound->playSound(m_player_step_sound, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void viewBobbingStep(MtEvent *e, void *data)
|
||||||
|
{
|
||||||
|
SoundMaker *sm = (SoundMaker*)data;
|
||||||
|
sm->playPlayerStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void playerRegainGround(MtEvent *e, void *data)
|
||||||
|
{
|
||||||
|
SoundMaker *sm = (SoundMaker*)data;
|
||||||
|
sm->playPlayerStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void playerJump(MtEvent *e, void *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerReceiver(MtEventManager *mgr)
|
||||||
|
{
|
||||||
|
mgr->reg("ViewBobbingStep", SoundMaker::viewBobbingStep, this);
|
||||||
|
mgr->reg("PlayerRegainGround", SoundMaker::playerRegainGround, this);
|
||||||
|
mgr->reg("PlayerJump", SoundMaker::playerJump, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void step(float dtime)
|
||||||
|
{
|
||||||
|
m_player_step_timer -= dtime;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void the_game(
|
void the_game(
|
||||||
bool &kill,
|
bool &kill,
|
||||||
bool random_input,
|
bool random_input,
|
||||||
|
@ -842,9 +895,18 @@ void the_game(
|
||||||
sound_is_dummy = true;
|
sound_is_dummy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Event manager
|
||||||
|
EventManager eventmgr;
|
||||||
|
|
||||||
|
// Sound maker
|
||||||
|
SoundMaker soundmaker(sound);
|
||||||
|
soundmaker.registerReceiver(&eventmgr);
|
||||||
|
|
||||||
// Test sounds
|
// Test sounds
|
||||||
sound->loadSound("default_grass_walk", porting::path_share + DIR_DELIM
|
sound->loadSound("default_grass_footstep", porting::path_share + DIR_DELIM
|
||||||
+ "sounds" + DIR_DELIM + "default_grass_walk3_mono.ogg");
|
+ "sounds" + DIR_DELIM + "default_grass_walk3_mono.ogg");
|
||||||
|
sound->loadSound("default_grass_footstep", porting::path_share + DIR_DELIM
|
||||||
|
+ "sounds" + DIR_DELIM + "default_grass_walk4_mono.ogg");
|
||||||
//sound->playSound("default_grass_walk", false, 1.0);
|
//sound->playSound("default_grass_walk", false, 1.0);
|
||||||
//sound->playSoundAt("default_grass_walk", true, 1.0, v3f(0,10,0)*BS);
|
//sound->playSoundAt("default_grass_walk", true, 1.0, v3f(0,10,0)*BS);
|
||||||
|
|
||||||
|
@ -879,7 +941,7 @@ void the_game(
|
||||||
MapDrawControl draw_control;
|
MapDrawControl draw_control;
|
||||||
|
|
||||||
Client client(device, playername.c_str(), password, draw_control,
|
Client client(device, playername.c_str(), password, draw_control,
|
||||||
tsrc, itemdef, nodedef, sound);
|
tsrc, itemdef, nodedef, sound, &eventmgr);
|
||||||
|
|
||||||
// Client acts as our GameDef
|
// Client acts as our GameDef
|
||||||
IGameDef *gamedef = &client;
|
IGameDef *gamedef = &client;
|
||||||
|
@ -1954,6 +2016,17 @@ void the_game(
|
||||||
camera.getCameraNode()->getTarget(),
|
camera.getCameraNode()->getTarget(),
|
||||||
camera.getCameraNode()->getUpVector());
|
camera.getCameraNode()->getUpVector());
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update sound maker
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
soundmaker.step(dtime);
|
||||||
|
|
||||||
|
ClientMap &map = client.getEnv().getClientMap();
|
||||||
|
MapNode n = map.getNodeNoEx(player->getStandingNodePos());
|
||||||
|
soundmaker.m_player_step_sound = nodedef->get(n).sound_footstep;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate what block is the crosshair pointing to
|
Calculate what block is the crosshair pointing to
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -28,6 +28,7 @@ class INodeDefManager;
|
||||||
class ICraftDefManager;
|
class ICraftDefManager;
|
||||||
class ITextureSource;
|
class ITextureSource;
|
||||||
class ISoundManager;
|
class ISoundManager;
|
||||||
|
class MtEventManager;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
An interface for fetching game-global definitions like tool and
|
An interface for fetching game-global definitions like tool and
|
||||||
|
@ -47,17 +48,19 @@ public:
|
||||||
// pointers in other threads than main thread will make things explode.
|
// pointers in other threads than main thread will make things explode.
|
||||||
virtual ITextureSource* getTextureSource()=0;
|
virtual ITextureSource* getTextureSource()=0;
|
||||||
|
|
||||||
virtual ISoundManager* getSoundManager()=0;
|
|
||||||
|
|
||||||
// Used for keeping track of names/ids of unknown nodes
|
// Used for keeping track of names/ids of unknown nodes
|
||||||
virtual u16 allocateUnknownNodeId(const std::string &name)=0;
|
virtual u16 allocateUnknownNodeId(const std::string &name)=0;
|
||||||
|
|
||||||
|
virtual ISoundManager* getSoundManager()=0;
|
||||||
|
virtual MtEventManager* getEventManager()=0;
|
||||||
|
|
||||||
// Shorthands
|
// Shorthands
|
||||||
IItemDefManager* idef(){return getItemDefManager();}
|
IItemDefManager* idef(){return getItemDefManager();}
|
||||||
INodeDefManager* ndef(){return getNodeDefManager();}
|
INodeDefManager* ndef(){return getNodeDefManager();}
|
||||||
ICraftDefManager* cdef(){return getCraftDefManager();}
|
ICraftDefManager* cdef(){return getCraftDefManager();}
|
||||||
ITextureSource* tsrc(){return getTextureSource();}
|
ITextureSource* tsrc(){return getTextureSource();}
|
||||||
ISoundManager* sound(){return getSoundManager();}
|
ISoundManager* sound(){return getSoundManager();}
|
||||||
|
MtEventManager* event(){return getEventManager();}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -78,6 +78,22 @@ void MaterialSpec::deSerialize(std::istream &is)
|
||||||
backface_culling = readU8(is);
|
backface_culling = readU8(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SimpleSoundSpec serialization
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void serializeSimpleSoundSpec(const SimpleSoundSpec &ss,
|
||||||
|
std::ostream &os)
|
||||||
|
{
|
||||||
|
os<<serializeString(ss.name);
|
||||||
|
writeF1000(os, ss.gain);
|
||||||
|
}
|
||||||
|
static void deSerializeSimpleSoundSpec(SimpleSoundSpec &ss, std::istream &is)
|
||||||
|
{
|
||||||
|
ss.name = deSerializeString(is);
|
||||||
|
ss.gain = readF1000(is);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ContentFeatures
|
ContentFeatures
|
||||||
*/
|
*/
|
||||||
|
@ -139,6 +155,7 @@ void ContentFeatures::reset()
|
||||||
selection_box = NodeBox();
|
selection_box = NodeBox();
|
||||||
legacy_facedir_simple = false;
|
legacy_facedir_simple = false;
|
||||||
legacy_wallmounted = false;
|
legacy_wallmounted = false;
|
||||||
|
sound_footstep = SimpleSoundSpec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentFeatures::serialize(std::ostream &os)
|
void ContentFeatures::serialize(std::ostream &os)
|
||||||
|
@ -185,6 +202,7 @@ void ContentFeatures::serialize(std::ostream &os)
|
||||||
selection_box.serialize(os);
|
selection_box.serialize(os);
|
||||||
writeU8(os, legacy_facedir_simple);
|
writeU8(os, legacy_facedir_simple);
|
||||||
writeU8(os, legacy_wallmounted);
|
writeU8(os, legacy_wallmounted);
|
||||||
|
serializeSimpleSoundSpec(sound_footstep, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentFeatures::deSerialize(std::istream &is)
|
void ContentFeatures::deSerialize(std::istream &is)
|
||||||
|
@ -236,6 +254,9 @@ void ContentFeatures::deSerialize(std::istream &is)
|
||||||
selection_box.deSerialize(is);
|
selection_box.deSerialize(is);
|
||||||
legacy_facedir_simple = readU8(is);
|
legacy_facedir_simple = readU8(is);
|
||||||
legacy_wallmounted = readU8(is);
|
legacy_wallmounted = readU8(is);
|
||||||
|
try{
|
||||||
|
deSerializeSimpleSoundSpec(sound_footstep, is);
|
||||||
|
}catch(SerializationError &e) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#ifndef NODEDEF_HEADER
|
#ifndef NODEDEF_HEADER
|
||||||
#define NODEDEF_HEADER
|
#define NODEDEF_HEADER
|
||||||
|
|
||||||
#include "common_irrlicht.h"
|
#include "irrlichttypes.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#endif
|
#endif
|
||||||
#include "itemgroup.h"
|
#include "itemgroup.h"
|
||||||
|
#include "sound.h" // SimpleSoundSpec
|
||||||
class IItemDefManager;
|
class IItemDefManager;
|
||||||
class ITextureSource;
|
class ITextureSource;
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
|
@ -200,6 +201,9 @@ struct ContentFeatures
|
||||||
// Set to true if wall_mounted used to be set to true
|
// Set to true if wall_mounted used to be set to true
|
||||||
bool legacy_wallmounted;
|
bool legacy_wallmounted;
|
||||||
|
|
||||||
|
// Sound properties
|
||||||
|
SimpleSoundSpec sound_footstep;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Methods
|
Methods
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "collision.h"
|
#include "collision.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
Player::Player(IGameDef *gamedef):
|
Player::Player(IGameDef *gamedef):
|
||||||
touching_ground(false),
|
touching_ground(false),
|
||||||
|
@ -367,6 +368,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
|
||||||
|
|
||||||
Player is allowed to jump when this is true.
|
Player is allowed to jump when this is true.
|
||||||
*/
|
*/
|
||||||
|
bool touching_ground_was = touching_ground;
|
||||||
touching_ground = false;
|
touching_ground = false;
|
||||||
|
|
||||||
/*std::cout<<"Checking collisions for ("
|
/*std::cout<<"Checking collisions for ("
|
||||||
|
@ -608,6 +610,11 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
|
||||||
collision_info->push_back(info);
|
collision_info->push_back(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!touching_ground_was && touching_ground){
|
||||||
|
MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround");
|
||||||
|
m_gamedef->event()->put(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d)
|
void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d)
|
||||||
|
@ -723,6 +730,9 @@ void LocalPlayer::applyControl(float dtime)
|
||||||
{
|
{
|
||||||
speed.Y = 6.5*BS;
|
speed.Y = 6.5*BS;
|
||||||
setSpeed(speed);
|
setSpeed(speed);
|
||||||
|
|
||||||
|
MtEvent *e = new SimpleTriggerEvent("PlayerJump");
|
||||||
|
m_gamedef->event()->put(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Use the oscillating value for getting out of water
|
// Use the oscillating value for getting out of water
|
||||||
|
|
|
@ -807,6 +807,25 @@ static void push_pointed_thing(lua_State *L, const PointedThing& pointed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SimpleSoundSpec
|
||||||
|
*/
|
||||||
|
|
||||||
|
static SimpleSoundSpec read_soundspec(lua_State *L, int index)
|
||||||
|
{
|
||||||
|
if(index < 0)
|
||||||
|
index = lua_gettop(L) + 1 + index;
|
||||||
|
SimpleSoundSpec spec;
|
||||||
|
if(lua_isnil(L, index)){
|
||||||
|
} else if(lua_istable(L, index)){
|
||||||
|
getstringfield(L, index, "name", spec.name);
|
||||||
|
getfloatfield(L, index, "gain", spec.gain);
|
||||||
|
} else if(lua_isstring(L, index)){
|
||||||
|
spec.name = lua_tostring(L, index);
|
||||||
|
}
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ItemDefinition
|
ItemDefinition
|
||||||
*/
|
*/
|
||||||
|
@ -1039,6 +1058,15 @@ static ContentFeatures read_content_features(lua_State *L, int index)
|
||||||
// Set to true if wall_mounted used to be set to true
|
// Set to true if wall_mounted used to be set to true
|
||||||
getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
|
getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
|
||||||
|
|
||||||
|
// Sound table
|
||||||
|
lua_getfield(L, index, "sounds");
|
||||||
|
if(lua_istable(L, -1)){
|
||||||
|
lua_getfield(L, -1, "footstep");
|
||||||
|
f.sound_footstep = read_soundspec(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
#include "utility_string.h"
|
#include "utility_string.h"
|
||||||
#include "sound.h" // dummySoundManager
|
#include "sound.h" // dummySoundManager
|
||||||
|
#include "event_manager.h"
|
||||||
|
|
||||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||||
|
|
||||||
|
@ -853,6 +854,7 @@ Server::Server(
|
||||||
m_itemdef(createItemDefManager()),
|
m_itemdef(createItemDefManager()),
|
||||||
m_nodedef(createNodeDefManager()),
|
m_nodedef(createNodeDefManager()),
|
||||||
m_craftdef(createCraftDefManager()),
|
m_craftdef(createCraftDefManager()),
|
||||||
|
m_event(new EventManager()),
|
||||||
m_thread(this),
|
m_thread(this),
|
||||||
m_emergethread(this),
|
m_emergethread(this),
|
||||||
m_time_of_day_send_timer(0),
|
m_time_of_day_send_timer(0),
|
||||||
|
@ -1065,9 +1067,9 @@ Server::~Server()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete Environment
|
// Delete things in the reverse order of creation
|
||||||
delete m_env;
|
delete m_env;
|
||||||
|
delete m_event;
|
||||||
delete m_itemdef;
|
delete m_itemdef;
|
||||||
delete m_nodedef;
|
delete m_nodedef;
|
||||||
delete m_craftdef;
|
delete m_craftdef;
|
||||||
|
@ -4275,6 +4277,10 @@ ISoundManager* Server::getSoundManager()
|
||||||
{
|
{
|
||||||
return &dummySoundManager;
|
return &dummySoundManager;
|
||||||
}
|
}
|
||||||
|
MtEventManager* Server::getEventManager()
|
||||||
|
{
|
||||||
|
return m_event;
|
||||||
|
}
|
||||||
|
|
||||||
IWritableItemDefManager* Server::getWritableItemDefManager()
|
IWritableItemDefManager* Server::getWritableItemDefManager()
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,6 +40,7 @@ typedef struct lua_State lua_State;
|
||||||
class IWritableItemDefManager;
|
class IWritableItemDefManager;
|
||||||
class IWritableNodeDefManager;
|
class IWritableNodeDefManager;
|
||||||
class IWritableCraftDefManager;
|
class IWritableCraftDefManager;
|
||||||
|
class EventManager;
|
||||||
|
|
||||||
class ServerError : public std::exception
|
class ServerError : public std::exception
|
||||||
{
|
{
|
||||||
|
@ -514,6 +515,7 @@ public:
|
||||||
virtual ITextureSource* getTextureSource();
|
virtual ITextureSource* getTextureSource();
|
||||||
virtual u16 allocateUnknownNodeId(const std::string &name);
|
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||||
virtual ISoundManager* getSoundManager();
|
virtual ISoundManager* getSoundManager();
|
||||||
|
virtual MtEventManager* getEventManager();
|
||||||
|
|
||||||
IWritableItemDefManager* getWritableItemDefManager();
|
IWritableItemDefManager* getWritableItemDefManager();
|
||||||
IWritableNodeDefManager* getWritableNodeDefManager();
|
IWritableNodeDefManager* getWritableNodeDefManager();
|
||||||
|
@ -684,6 +686,9 @@ private:
|
||||||
// Craft definition manager
|
// Craft definition manager
|
||||||
IWritableCraftDefManager *m_craftdef;
|
IWritableCraftDefManager *m_craftdef;
|
||||||
|
|
||||||
|
// Event manager
|
||||||
|
EventManager *m_event;
|
||||||
|
|
||||||
// Mods
|
// Mods
|
||||||
core::list<ModSpec> m_mods;
|
core::list<ModSpec> m_mods;
|
||||||
|
|
||||||
|
|
18
src/sound.h
18
src/sound.h
|
@ -33,6 +33,18 @@ public:
|
||||||
std::set<std::vector<char> > &dst_datas) = 0;
|
std::set<std::vector<char> > &dst_datas) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SimpleSoundSpec
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
float gain;
|
||||||
|
SimpleSoundSpec(std::string name="", float gain=1.0):
|
||||||
|
name(name),
|
||||||
|
gain(gain)
|
||||||
|
{}
|
||||||
|
bool exists() {return name != "";}
|
||||||
|
// Serialization intentionally left out
|
||||||
|
};
|
||||||
|
|
||||||
class ISoundManager
|
class ISoundManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -47,6 +59,7 @@ public:
|
||||||
const std::vector<char> &filedata) = 0;
|
const std::vector<char> &filedata) = 0;
|
||||||
|
|
||||||
virtual void updateListener(v3f pos, v3f vel, v3f at, v3f up) = 0;
|
virtual void updateListener(v3f pos, v3f vel, v3f at, v3f up) = 0;
|
||||||
|
|
||||||
// playSound functions return -1 on failure, otherwise a handle to the
|
// playSound functions return -1 on failure, otherwise a handle to the
|
||||||
// sound
|
// sound
|
||||||
virtual int playSound(const std::string &name, bool loop,
|
virtual int playSound(const std::string &name, bool loop,
|
||||||
|
@ -54,6 +67,11 @@ public:
|
||||||
virtual int playSoundAt(const std::string &name, bool loop,
|
virtual int playSoundAt(const std::string &name, bool loop,
|
||||||
float volume, v3f pos) = 0;
|
float volume, v3f pos) = 0;
|
||||||
virtual void stopSound(int sound) = 0;
|
virtual void stopSound(int sound) = 0;
|
||||||
|
|
||||||
|
int playSound(const SimpleSoundSpec &spec, bool loop)
|
||||||
|
{ return playSound(spec.name, loop, spec.gain); }
|
||||||
|
int playSoundAt(const SimpleSoundSpec &spec, bool loop, v3f pos)
|
||||||
|
{ return playSoundAt(spec.name, loop, spec.gain, pos); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class DummySoundManager: public ISoundManager
|
class DummySoundManager: public ISoundManager
|
||||||
|
|
Loading…
Reference in New Issue