diff options
author | Perttu Ahola <celeron55@gmail.com> | 2012-03-24 19:01:26 +0200 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2012-03-24 19:01:26 +0200 |
commit | 601d1936c9ab4787d43f55d67900ed7c46fd3452 (patch) | |
tree | b328ea7a66ee7dc37fffddd0ee063a0c7b1ea10f /src/server.cpp | |
parent | 06e93f8d9508a23e86751dfae2f6a7e550d8e1af (diff) | |
download | minetest-601d1936c9ab4787d43f55d67900ed7c46fd3452.tar.gz minetest-601d1936c9ab4787d43f55d67900ed7c46fd3452.tar.bz2 minetest-601d1936c9ab4787d43f55d67900ed7c46fd3452.zip |
Lua API for playing sounds
Diffstat (limited to 'src/server.cpp')
-rw-r--r-- | src/server.cpp | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/server.cpp b/src/server.cpp index e781f1284..745e55f83 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3126,6 +3126,24 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) <<action<<std::endl; } } + else if(command == TOSERVER_REMOVED_SOUNDS) + { + std::string datastring((char*)&data[2], datasize-2); + std::istringstream is(datastring, std::ios_base::binary); + + int num = readU16(is); + for(int k=0; k<num; k++){ + s32 id = readS32(is); + std::map<s32, ServerPlayingSound>::iterator i = + m_playing_sounds.find(id); + if(i == m_playing_sounds.end()) + continue; + ServerPlayingSound &psound = i->second; + psound.clients.erase(peer_id); + if(psound.clients.size() == 0) + m_playing_sounds.erase(i++); + } + } else { infostream<<"Server::ProcessData(): Ignoring " @@ -3575,6 +3593,107 @@ void Server::SendMovePlayer(Player *player) m_con.Send(player->peer_id, 0, data, true); } +s32 Server::playSound(const SimpleSoundSpec &spec, + const ServerSoundParams ¶ms) +{ + // Find out initial position of sound + bool pos_exists = false; + v3f pos = params.getPos(m_env, &pos_exists); + // If position is not found while it should be, cancel sound + if(pos_exists != (params.type != ServerSoundParams::SSP_LOCAL)) + return -1; + // Filter destination clients + std::set<RemoteClient*> dst_clients; + if(params.to_player != "") + { + Player *player = m_env->getPlayer(params.to_player.c_str()); + if(!player){ + infostream<<"Server::playSound: Player \""<<params.to_player + <<"\" not found"<<std::endl; + return -1; + } + if(player->peer_id == PEER_ID_INEXISTENT){ + infostream<<"Server::playSound: Player \""<<params.to_player + <<"\" not connected"<<std::endl; + return -1; + } + RemoteClient *client = getClient(player->peer_id); + dst_clients.insert(client); + } + else + { + for(core::map<u16, RemoteClient*>::Iterator + i = m_clients.getIterator(); i.atEnd() == false; i++) + { + RemoteClient *client = i.getNode()->getValue(); + Player *player = m_env->getPlayer(client->peer_id); + if(!player) + continue; + if(pos_exists){ + if(player->getPosition().getDistanceFrom(pos) > + params.max_hear_distance) + continue; + } + dst_clients.insert(client); + } + } + if(dst_clients.size() == 0) + return -1; + // Create the sound + s32 id = m_next_sound_id++; + // The sound will exist as a reference in m_playing_sounds + m_playing_sounds[id] = ServerPlayingSound(); + ServerPlayingSound &psound = m_playing_sounds[id]; + psound.params = params; + for(std::set<RemoteClient*>::iterator i = dst_clients.begin(); + i != dst_clients.end(); i++) + psound.clients.insert((*i)->peer_id); + // Create packet + std::ostringstream os(std::ios_base::binary); + writeU16(os, TOCLIENT_PLAY_SOUND); + writeS32(os, id); + os<<serializeString(spec.name); + writeF1000(os, spec.gain * params.gain); + writeU8(os, params.type); + writeV3F1000(os, pos); + writeU16(os, params.object); + writeU8(os, params.loop); + // Make data buffer + std::string s = os.str(); + SharedBuffer<u8> data((u8*)s.c_str(), s.size()); + // Send + for(std::set<RemoteClient*>::iterator i = dst_clients.begin(); + i != dst_clients.end(); i++){ + // Send as reliable + m_con.Send((*i)->peer_id, 0, data, true); + } + return id; +} +void Server::stopSound(s32 handle) +{ + // Get sound reference + std::map<s32, ServerPlayingSound>::iterator i = + m_playing_sounds.find(handle); + if(i == m_playing_sounds.end()) + return; + ServerPlayingSound &psound = i->second; + // Create packet + std::ostringstream os(std::ios_base::binary); + writeU16(os, TOCLIENT_STOP_SOUND); + writeS32(os, handle); + // Make data buffer + std::string s = os.str(); + SharedBuffer<u8> data((u8*)s.c_str(), s.size()); + // Send + for(std::set<u16>::iterator i = psound.clients.begin(); + i != psound.clients.end(); i++){ + // Send as reliable + m_con.Send(*i, 0, data, true); + } + // Remove sound reference + m_playing_sounds.erase(i); +} + void Server::sendRemoveNode(v3s16 p, u16 ignore_id, core::list<u16> *far_players, float far_d_nodes) { @@ -4511,6 +4630,21 @@ void Server::handlePeerChange(PeerChange &c) obj->m_known_by_count--; } + /* + Clear references to playing sounds + */ + for(std::map<s32, ServerPlayingSound>::iterator + i = m_playing_sounds.begin(); + i != m_playing_sounds.end();) + { + ServerPlayingSound &psound = i->second; + psound.clients.erase(c.peer_id); + if(psound.clients.size() == 0) + m_playing_sounds.erase(i++); + else + i++; + } + ServerRemotePlayer* player = static_cast<ServerRemotePlayer*>(m_env->getPlayer(c.peer_id)); |