mirror of
https://github.com/moparisthebest/minetest
synced 2024-11-04 16:35:03 -05:00
Add event manager and use it to trigger sounds
This commit is contained in:
parent
e53794868e
commit
6c14025b2d
@ -654,6 +654,10 @@ minetest.register_node("default:dirt_with_grass", {
|
||||
is_ground_content = true,
|
||||
groups = {crumbly=3},
|
||||
drop = 'default:dirt',
|
||||
sounds = {
|
||||
--footstep = "default_grass_footstep",
|
||||
footstep = {name="default_grass_footstep", gain=0.5},
|
||||
},
|
||||
})
|
||||
|
||||
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 "gamedef.h"
|
||||
#include "sound.h"
|
||||
#include "event.h"
|
||||
|
||||
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
|
||||
IGameDef *gamedef):
|
||||
@ -177,8 +178,10 @@ void Camera::step(f32 dtime)
|
||||
bool step = (was == 0 ||
|
||||
(was < 0.5f && m_view_bobbing_anim >= 0.5f) ||
|
||||
(was > 0.5f && m_view_bobbing_anim <= 0.5f));
|
||||
if(step)
|
||||
m_gamedef->sound()->playSound("default_grass_walk", false, 1.0);
|
||||
if(step){
|
||||
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_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,
|
||||
IWritableItemDefManager *itemdef,
|
||||
IWritableNodeDefManager *nodedef,
|
||||
ISoundManager *sound
|
||||
ISoundManager *sound,
|
||||
MtEventManager *event
|
||||
):
|
||||
m_tsrc(tsrc),
|
||||
m_itemdef(itemdef),
|
||||
m_nodedef(nodedef),
|
||||
m_sound(sound),
|
||||
m_event(event),
|
||||
m_mesh_update_thread(this),
|
||||
m_env(
|
||||
new ClientMap(this, this, control,
|
||||
@ -2330,4 +2332,8 @@ ISoundManager* Client::getSoundManager()
|
||||
{
|
||||
return m_sound;
|
||||
}
|
||||
MtEventManager* Client::getEventManager()
|
||||
{
|
||||
return m_event;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ class IWritableNodeDefManager;
|
||||
//class IWritableCraftDefManager;
|
||||
class ClientEnvironment;
|
||||
struct MapDrawControl;
|
||||
class MtEventManager;
|
||||
|
||||
class ClientNotReadyException : public BaseException
|
||||
{
|
||||
@ -175,7 +176,8 @@ public:
|
||||
IWritableTextureSource *tsrc,
|
||||
IWritableItemDefManager *itemdef,
|
||||
IWritableNodeDefManager *nodedef,
|
||||
ISoundManager *sound
|
||||
ISoundManager *sound,
|
||||
MtEventManager *event
|
||||
);
|
||||
|
||||
~Client();
|
||||
@ -308,6 +310,7 @@ public:
|
||||
virtual ITextureSource* getTextureSource();
|
||||
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||
virtual ISoundManager* getSoundManager();
|
||||
virtual MtEventManager* getEventManager();
|
||||
|
||||
private:
|
||||
|
||||
@ -335,6 +338,8 @@ private:
|
||||
IWritableItemDefManager *m_itemdef;
|
||||
IWritableNodeDefManager *m_nodedef;
|
||||
ISoundManager *m_sound;
|
||||
MtEventManager *m_event;
|
||||
|
||||
MeshUpdateThread m_mesh_update_thread;
|
||||
ClientEnvironment m_env;
|
||||
con::Connection m_con;
|
||||
|
72
src/event.h
Normal file
72
src/event.h
Normal file
@ -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
|
||||
|
115
src/event_manager.h
Normal file
115
src/event_manager.h
Normal file
@ -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
|
||||
|
79
src/game.cpp
79
src/game.cpp
@ -59,6 +59,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#if USE_AUDIO
|
||||
#include "sound_openal.h"
|
||||
#endif
|
||||
#include "event_manager.h"
|
||||
#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(
|
||||
bool &kill,
|
||||
bool random_input,
|
||||
@ -841,10 +894,19 @@ void the_game(
|
||||
sound = &dummySoundManager;
|
||||
sound_is_dummy = true;
|
||||
}
|
||||
|
||||
// Event manager
|
||||
EventManager eventmgr;
|
||||
|
||||
// Sound maker
|
||||
SoundMaker soundmaker(sound);
|
||||
soundmaker.registerReceiver(&eventmgr);
|
||||
|
||||
// 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");
|
||||
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->playSoundAt("default_grass_walk", true, 1.0, v3f(0,10,0)*BS);
|
||||
|
||||
@ -879,7 +941,7 @@ void the_game(
|
||||
MapDrawControl 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
|
||||
IGameDef *gamedef = &client;
|
||||
@ -1257,7 +1319,7 @@ void the_game(
|
||||
if(object_hit_delay_timer >= 0)
|
||||
object_hit_delay_timer -= dtime;
|
||||
time_from_last_punch += dtime;
|
||||
|
||||
|
||||
g_profiler->add("Elapsed time", dtime);
|
||||
g_profiler->avg("FPS", 1./dtime);
|
||||
|
||||
@ -1954,6 +2016,17 @@ void the_game(
|
||||
camera.getCameraNode()->getTarget(),
|
||||
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
|
||||
*/
|
||||
|
@ -28,6 +28,7 @@ class INodeDefManager;
|
||||
class ICraftDefManager;
|
||||
class ITextureSource;
|
||||
class ISoundManager;
|
||||
class MtEventManager;
|
||||
|
||||
/*
|
||||
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.
|
||||
virtual ITextureSource* getTextureSource()=0;
|
||||
|
||||
virtual ISoundManager* getSoundManager()=0;
|
||||
|
||||
// Used for keeping track of names/ids of unknown nodes
|
||||
virtual u16 allocateUnknownNodeId(const std::string &name)=0;
|
||||
|
||||
virtual ISoundManager* getSoundManager()=0;
|
||||
virtual MtEventManager* getEventManager()=0;
|
||||
|
||||
// Shorthands
|
||||
IItemDefManager* idef(){return getItemDefManager();}
|
||||
INodeDefManager* ndef(){return getNodeDefManager();}
|
||||
ICraftDefManager* cdef(){return getCraftDefManager();}
|
||||
ITextureSource* tsrc(){return getTextureSource();}
|
||||
ISoundManager* sound(){return getSoundManager();}
|
||||
MtEventManager* event(){return getEventManager();}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -78,6 +78,22 @@ void MaterialSpec::deSerialize(std::istream &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
|
||||
*/
|
||||
@ -139,6 +155,7 @@ void ContentFeatures::reset()
|
||||
selection_box = NodeBox();
|
||||
legacy_facedir_simple = false;
|
||||
legacy_wallmounted = false;
|
||||
sound_footstep = SimpleSoundSpec();
|
||||
}
|
||||
|
||||
void ContentFeatures::serialize(std::ostream &os)
|
||||
@ -185,6 +202,7 @@ void ContentFeatures::serialize(std::ostream &os)
|
||||
selection_box.serialize(os);
|
||||
writeU8(os, legacy_facedir_simple);
|
||||
writeU8(os, legacy_wallmounted);
|
||||
serializeSimpleSoundSpec(sound_footstep, os);
|
||||
}
|
||||
|
||||
void ContentFeatures::deSerialize(std::istream &is)
|
||||
@ -236,6 +254,9 @@ void ContentFeatures::deSerialize(std::istream &is)
|
||||
selection_box.deSerialize(is);
|
||||
legacy_facedir_simple = 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
|
||||
#define NODEDEF_HEADER
|
||||
|
||||
#include "common_irrlicht.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "tile.h"
|
||||
#endif
|
||||
#include "itemgroup.h"
|
||||
#include "sound.h" // SimpleSoundSpec
|
||||
class IItemDefManager;
|
||||
class ITextureSource;
|
||||
class IGameDef;
|
||||
@ -200,6 +201,9 @@ struct ContentFeatures
|
||||
// Set to true if wall_mounted used to be set to true
|
||||
bool legacy_wallmounted;
|
||||
|
||||
// Sound properties
|
||||
SimpleSoundSpec sound_footstep;
|
||||
|
||||
/*
|
||||
Methods
|
||||
*/
|
||||
|
@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "collision.h"
|
||||
#include "environment.h"
|
||||
#include "gamedef.h"
|
||||
#include "event.h"
|
||||
|
||||
Player::Player(IGameDef *gamedef):
|
||||
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.
|
||||
*/
|
||||
bool touching_ground_was = touching_ground;
|
||||
touching_ground = false;
|
||||
|
||||
/*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);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@ -723,6 +730,9 @@ void LocalPlayer::applyControl(float dtime)
|
||||
{
|
||||
speed.Y = 6.5*BS;
|
||||
setSpeed(speed);
|
||||
|
||||
MtEvent *e = new SimpleTriggerEvent("PlayerJump");
|
||||
m_gamedef->event()->put(e);
|
||||
}
|
||||
}
|
||||
// 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
|
||||
*/
|
||||
@ -1038,6 +1057,15 @@ static ContentFeatures read_content_features(lua_State *L, int index)
|
||||
getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
|
||||
// Set to true if wall_mounted used to be set to true
|
||||
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;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "tool.h"
|
||||
#include "utility_string.h"
|
||||
#include "sound.h" // dummySoundManager
|
||||
#include "event_manager.h"
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
||||
@ -853,6 +854,7 @@ Server::Server(
|
||||
m_itemdef(createItemDefManager()),
|
||||
m_nodedef(createNodeDefManager()),
|
||||
m_craftdef(createCraftDefManager()),
|
||||
m_event(new EventManager()),
|
||||
m_thread(this),
|
||||
m_emergethread(this),
|
||||
m_time_of_day_send_timer(0),
|
||||
@ -1064,10 +1066,10 @@ Server::~Server()
|
||||
delete i.getNode()->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
// Delete Environment
|
||||
|
||||
// Delete things in the reverse order of creation
|
||||
delete m_env;
|
||||
|
||||
delete m_event;
|
||||
delete m_itemdef;
|
||||
delete m_nodedef;
|
||||
delete m_craftdef;
|
||||
@ -4275,6 +4277,10 @@ ISoundManager* Server::getSoundManager()
|
||||
{
|
||||
return &dummySoundManager;
|
||||
}
|
||||
MtEventManager* Server::getEventManager()
|
||||
{
|
||||
return m_event;
|
||||
}
|
||||
|
||||
IWritableItemDefManager* Server::getWritableItemDefManager()
|
||||
{
|
||||
|
@ -40,6 +40,7 @@ typedef struct lua_State lua_State;
|
||||
class IWritableItemDefManager;
|
||||
class IWritableNodeDefManager;
|
||||
class IWritableCraftDefManager;
|
||||
class EventManager;
|
||||
|
||||
class ServerError : public std::exception
|
||||
{
|
||||
@ -514,6 +515,7 @@ public:
|
||||
virtual ITextureSource* getTextureSource();
|
||||
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||
virtual ISoundManager* getSoundManager();
|
||||
virtual MtEventManager* getEventManager();
|
||||
|
||||
IWritableItemDefManager* getWritableItemDefManager();
|
||||
IWritableNodeDefManager* getWritableNodeDefManager();
|
||||
@ -684,6 +686,9 @@ private:
|
||||
// Craft definition manager
|
||||
IWritableCraftDefManager *m_craftdef;
|
||||
|
||||
// Event manager
|
||||
EventManager *m_event;
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
@ -47,6 +59,7 @@ public:
|
||||
const std::vector<char> &filedata) = 0;
|
||||
|
||||
virtual void updateListener(v3f pos, v3f vel, v3f at, v3f up) = 0;
|
||||
|
||||
// playSound functions return -1 on failure, otherwise a handle to the
|
||||
// sound
|
||||
virtual int playSound(const std::string &name, bool loop,
|
||||
@ -54,6 +67,11 @@ public:
|
||||
virtual int playSoundAt(const std::string &name, bool loop,
|
||||
float volume, v3f pos) = 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
|
||||
|
Loading…
Reference in New Issue
Block a user