+class NodeDugEvent: public MtEvent
+{
+public:
+ v3s16 p;
+ MapNode n;
+
+ NodeDugEvent(v3s16 p, MapNode n):
+ p(p),
+ n(n)
+ {}
+ const char* getType() const
+ {return "NodeDug";}
+};
+
+class SoundMaker
+{
+ ISoundManager *m_sound;
+ INodeDefManager *m_ndef;
+public:
+ float m_player_step_timer;
+
+ SimpleSoundSpec m_player_step_sound;
+ SimpleSoundSpec m_player_leftpunch_sound;
+ SimpleSoundSpec m_player_rightpunch_sound;
+
+ SoundMaker(ISoundManager *sound, INodeDefManager *ndef):
+ m_sound(sound),
+ m_ndef(ndef),
+ 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)
+ {
+ //SoundMaker *sm = (SoundMaker*)data;
+ }
+
+ static void cameraPunchLeft(MtEvent *e, void *data)
+ {
+ SoundMaker *sm = (SoundMaker*)data;
+ sm->m_sound->playSound(sm->m_player_leftpunch_sound, false);
+ }
+
+ static void cameraPunchRight(MtEvent *e, void *data)
+ {
+ SoundMaker *sm = (SoundMaker*)data;
+ sm->m_sound->playSound(sm->m_player_rightpunch_sound, false);
+ }
+
+ static void nodeDug(MtEvent *e, void *data)
+ {
+ SoundMaker *sm = (SoundMaker*)data;
+ NodeDugEvent *nde = (NodeDugEvent*)e;
+ sm->m_sound->playSound(sm->m_ndef->get(nde->n).sound_dug, false);
+ }
+
+ void registerReceiver(MtEventManager *mgr)
+ {
+ mgr->reg("ViewBobbingStep", SoundMaker::viewBobbingStep, this);
+ mgr->reg("PlayerRegainGround", SoundMaker::playerRegainGround, this);
+ mgr->reg("PlayerJump", SoundMaker::playerJump, this);
+ mgr->reg("CameraPunchLeft", SoundMaker::cameraPunchLeft, this);
+ mgr->reg("CameraPunchRight", SoundMaker::cameraPunchRight, this);
+ mgr->reg("NodeDug", SoundMaker::nodeDug, this);
+ }
+
+ void step(float dtime)
+ {
+ m_player_step_timer -= dtime;
+ }
+};
+
+// Locally stored sounds don't need to be preloaded because of this
+class GameOnDemandSoundFetcher: public OnDemandSoundFetcher
+{
+ std::set<std::string> m_fetched;
+public:
+
+ void fetchSounds(const std::string &name,
+ std::set<std::string> &dst_paths,
+ std::set<std::string> &dst_datas)
+ {
+ if(m_fetched.count(name))
+ return;
+ m_fetched.insert(name);
+ std::string base = porting::path_share + DIR_DELIM + "testsounds";
+ dst_paths.insert(base + DIR_DELIM + name + ".ogg");
+ dst_paths.insert(base + DIR_DELIM + name + ".0.ogg");
+ dst_paths.insert(base + DIR_DELIM + name + ".1.ogg");
+ dst_paths.insert(base + DIR_DELIM + name + ".2.ogg");
+ dst_paths.insert(base + DIR_DELIM + name + ".3.ogg");
+ dst_paths.insert(base + DIR_DELIM + name + ".4.ogg");
+ dst_paths.insert(base + DIR_DELIM + name + ".5.ogg");
+ dst_paths.insert(base + DIR_DELIM + name + ".6.ogg");
+ dst_paths.insert(base + DIR_DELIM + name + ".7.ogg");
+ dst_paths.insert(base + DIR_DELIM + name + ".8.ogg");
+ dst_paths.insert(base + DIR_DELIM + name + ".9.ogg");
+ }
+};
+
+class GameGlobalShaderConstantSetter : public IShaderConstantSetter
+{
+ Sky *m_sky;
+ bool *m_force_fog_off;
+ f32 *m_fog_range;
+ Client *m_client;
+
+public:
+ GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off,
+ f32 *fog_range, Client *client):
+ m_sky(sky),
+ m_force_fog_off(force_fog_off),
+ m_fog_range(fog_range),
+ m_client(client)
+ {}
+ ~GameGlobalShaderConstantSetter() {}
+
+ virtual void onSetConstants(video::IMaterialRendererServices *services,
+ bool is_highlevel)
+ {
+ if(!is_highlevel)
+ return;
+
+ // Background color
+ video::SColor bgcolor = m_sky->getBgColor();
+ video::SColorf bgcolorf(bgcolor);
+ float bgcolorfa[4] = {
+ bgcolorf.r,
+ bgcolorf.g,
+ bgcolorf.b,
+ bgcolorf.a,
+ };
+ services->setPixelShaderConstant("skyBgColor", bgcolorfa, 4);
+
+ // Fog distance
+ float fog_distance = *m_fog_range;
+ if(*m_force_fog_off)
+ fog_distance = 10000*BS;
+ services->setPixelShaderConstant("fogDistance", &fog_distance, 1);
+
+ // Day-night ratio
+ u32 daynight_ratio = m_client->getEnv().getDayNightRatio();
+ float daynight_ratio_f = (float)daynight_ratio / 1000.0;
+ services->setPixelShaderConstant("dayNightRatio", &daynight_ratio_f, 1);
+ }
+};
+