/* Copyright (c) 2013 yvt based on code of pysnip (c) Mathias Kaerlev 2011-2012. This file is part of OpenSpades. OpenSpades 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 3 of the License, or (at your option) any later version. OpenSpades 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 OpenSpades. If not, see . */ #include #include "Client.h" #include #include #include #include "IAudioChunk.h" #include "IAudioDevice.h" #include "CTFGameMode.h" #include "GameMap.h" #include "IGameMode.h" #include "TCGameMode.h" #include "World.h" #include "GameProperties.h" #include "CenterMessageView.h" #include "ChatWindow.h" #include "ClientUI.h" #include "NetClient.h" DEFINE_SPADES_SETTING(cg_centerMessage, "2"); namespace spades { namespace client { #pragma mark - Server Packet Handlers void Client::LocalPlayerCreated() { freeCameraState.position = world->GetLocalPlayer()->GetEye(); weapInput = WeaponInput(); playerInput = PlayerInput(); keypadInput = KeypadInput(); toolRaiseState = .0f; } void Client::JoinedGame() { // Note: A local player doesn't exist yet // Prepare the spectate mode followCameraState.enabled = false; freeCameraState.position = MakeVector3(256, 256, 30); freeCameraState.velocity = MakeVector3(0, 0, 0); } void Client::PlayerCreatedBlock(spades::client::Player *p) { SPADES_MARK_FUNCTION(); if (!IsMuted()) { Handle c = audioDevice->RegisterSound("Sounds/Weapons/Block/Build.opus"); audioDevice->Play(c, p->GetEye() + p->GetFront(), AudioParam()); } } void Client::TeamCapturedTerritory(int teamId, int terId) { TCGameMode::Territory *ter = static_cast(world->GetMode())->GetTerritory(terId); int old = ter->ownerTeamId; std::string msg; std::string teamName = chatWindow->TeamColorMessage(world->GetTeam(teamId).name, teamId); if (old < 2) { std::string otherTeam = chatWindow->TeamColorMessage(world->GetTeam(old).name, old); msg = _Tr("Client", "{0} captured {1}'s territory", teamName, otherTeam); } else { msg = _Tr("Client", "{0} captured an neutral territory", teamName); } chatWindow->AddMessage(msg); if ((int)cg_centerMessage != 0) { teamName = world->GetTeam(teamId).name; if (old < 2) { std::string otherTeam = world->GetTeam(old).name; msg = _Tr("Client", "{0} captured {1}'s Territory", teamName, otherTeam); } else { msg = _Tr("Client", "{0} captured an Neutral Territory", teamName); } NetLog("%s", msg.c_str()); centerMessageView->AddMessage(msg); } if (world->GetLocalPlayer() && !IsMuted()) { if (teamId == world->GetLocalPlayer()->GetTeamId()) { Handle chunk = audioDevice->RegisterSound("Sounds/Feedback/TC/YourTeamCaptured.opus"); audioDevice->PlayLocal(chunk, AudioParam()); } else { Handle chunk = audioDevice->RegisterSound("Sounds/Feedback/TC/EnemyCaptured.opus"); audioDevice->PlayLocal(chunk, AudioParam()); } } } void Client::PlayerCapturedIntel(spades::client::Player *p) { std::string msg; { std::string holderName = chatWindow->TeamColorMessage(p->GetName(), p->GetTeamId()); std::string otherTeamName = chatWindow->TeamColorMessage( world->GetTeam(1 - p->GetTeamId()).name, 1 - p->GetTeamId()); msg = _Tr("Client", "{0} captured {1}'s intel", holderName, otherTeamName); chatWindow->AddMessage(msg); } if ((int)cg_centerMessage != 0) { std::string holderName = p->GetName(); std::string otherTeamName = world->GetTeam(1 - p->GetTeamId()).name; msg = _Tr("Client", "{0} captured {1}'s Intel.", holderName, otherTeamName); NetLog("%s", msg.c_str()); centerMessageView->AddMessage(msg); } if (world->GetLocalPlayer() && !IsMuted()) { if (p->GetTeamId() == world->GetLocalPlayer()->GetTeamId()) { Handle chunk = audioDevice->RegisterSound("Sounds/Feedback/CTF/YourTeamCaptured.opus"); audioDevice->PlayLocal(chunk, AudioParam()); } else { Handle chunk = audioDevice->RegisterSound("Sounds/Feedback/CTF/EnemyCaptured.opus"); audioDevice->PlayLocal(chunk, AudioParam()); } } } void Client::PlayerPickedIntel(spades::client::Player *p) { std::string msg; { std::string holderName = chatWindow->TeamColorMessage(p->GetName(), p->GetTeamId()); std::string otherTeamName = chatWindow->TeamColorMessage( world->GetTeam(1 - p->GetTeamId()).name, 1 - p->GetTeamId()); msg = _Tr("Client", "{0} picked up {1}'s intel", holderName, otherTeamName); chatWindow->AddMessage(msg); } if ((int)cg_centerMessage != 0) { std::string holderName = p->GetName(); std::string otherTeamName = world->GetTeam(1 - p->GetTeamId()).name; msg = _Tr("Client", "{0} picked up {1}'s Intel.", holderName, otherTeamName); NetLog("%s", msg.c_str()); centerMessageView->AddMessage(msg); } if (!IsMuted()) { Handle chunk = audioDevice->RegisterSound("Sounds/Feedback/CTF/PickedUp.opus"); audioDevice->PlayLocal(chunk, AudioParam()); } } void Client::PlayerDropIntel(spades::client::Player *p) { std::string msg; { std::string holderName = chatWindow->TeamColorMessage(p->GetName(), p->GetTeamId()); std::string otherTeamName = chatWindow->TeamColorMessage( world->GetTeam(1 - p->GetTeamId()).name, 1 - p->GetTeamId()); msg = _Tr("Client", "{0} dropped {1}'s intel", holderName, otherTeamName); chatWindow->AddMessage(msg); } if ((int)cg_centerMessage != 0) { std::string holderName = p->GetName(); std::string otherTeamName = world->GetTeam(1 - p->GetTeamId()).name; msg = _Tr("Client", "{0} dropped {1}'s Intel", holderName, otherTeamName); NetLog("%s", msg.c_str()); centerMessageView->AddMessage(msg); } } void Client::PlayerDestroyedBlockWithWeaponOrTool(spades::IntVector3 blk) { Vector3 origin = {blk.x + .5f, blk.y + .5f, blk.z + .5f}; if (!map->IsSolid(blk.x, blk.y, blk.z)) return; ; Handle c = audioDevice->RegisterSound("Sounds/Misc/BlockDestroy.opus"); if (!IsMuted()) { audioDevice->Play(c, origin, AudioParam()); } uint32_t col = map->GetColor(blk.x, blk.y, blk.z); IntVector3 colV = {(uint8_t)col, (uint8_t)(col >> 8), (uint8_t)(col >> 16)}; EmitBlockDestroyFragments(blk, colV); } void Client::PlayerDiggedBlock(spades::IntVector3 blk) { Vector3 origin = {blk.x + .5f, blk.y + .5f, blk.z + .5f}; Handle c = audioDevice->RegisterSound("Sounds/Misc/BlockDestroy.opus"); if (!IsMuted()) { audioDevice->Play(c, origin, AudioParam()); } for (int z = blk.z - 1; z <= blk.z + 1; z++) { if (z < 0 || z > 61) continue; if (!map->IsSolid(blk.x, blk.y, z)) continue; uint32_t col = map->GetColor(blk.x, blk.y, z); IntVector3 colV = {(uint8_t)col, (uint8_t)(col >> 8), (uint8_t)(col >> 16)}; EmitBlockDestroyFragments(IntVector3::Make(blk.x, blk.y, z), colV); } } void Client::PlayerLeaving(spades::client::Player *p) { // Choose the next player if a follow cam is active on this player if (FollowsNonLocalPlayer(GetCameraMode()) && &GetCameraTargetPlayer() == p) { FollowNextPlayer(false); // Still unable to find a substitute? if (&GetCameraTargetPlayer() == p) { // Turn off the follow cam mode followCameraState.enabled = false; } } { std::string msg; msg = _Tr("Client", "Player {0} has left", chatWindow->TeamColorMessage(p->GetName(), p->GetTeamId())); chatWindow->AddMessage(msg); } { std::string msg; msg = _Tr("Client", "Player {0} has left", p->GetName()); auto col = p->GetTeamId() < 2 ? world->GetTeam(p->GetTeamId()).color : IntVector3::Make(255, 255, 255); NetLog("%s", msg.c_str()); scriptedUI->RecordChatLog( msg, MakeVector4(col.x / 255.f, col.y / 255.f, col.z / 255.f, 0.8f)); } RemoveCorpseForPlayer(p->GetId()); } void Client::PlayerJoinedTeam(spades::client::Player *p) { std::string teamName = world->GetTeam(p->GetTeamId()).name; if (p->GetTeamId() >= 2) { teamName = _Tr("Client", "Spectator"); } { std::string msg; msg = _Tr("Client", "{0} joined {1} team", p->GetName(), chatWindow->TeamColorMessage(teamName, p->GetTeamId())); chatWindow->AddMessage(msg); } { std::string msg; msg = _Tr("Client", "{0} joined {1} team", p->GetName(), teamName); auto col = p->GetTeamId() < 2 ? world->GetTeam(p->GetTeamId()).color : IntVector3::Make(255, 255, 255); NetLog("%s", msg.c_str()); scriptedUI->RecordChatLog( msg, MakeVector4(col.x / 255.f, col.y / 255.f, col.z / 255.f, 0.8f)); } } void Client::PlayerSpawned(Player *p) { if (net->GetGameProperties()->clearCorpseOnRespawn) { RemoveCorpseForPlayer(p->GetId()); } } void Client::GrenadeDestroyedBlock(spades::IntVector3 blk) { for (int x = blk.x - 1; x <= blk.x + 1; x++) for (int y = blk.y - 1; y <= blk.y + 1; y++) for (int z = blk.z - 1; z <= blk.z + 1; z++) { if (z < 0 || z > 61 || x < 0 || x >= 512 || y < 0 || y >= 512) continue; if (!map->IsSolid(x, y, z)) continue; uint32_t col = map->GetColor(x, y, z); IntVector3 colV = {(uint8_t)col, (uint8_t)(col >> 8), (uint8_t)(col >> 16)}; EmitBlockDestroyFragments(IntVector3::Make(x, y, z), colV); } } void Client::TeamWon(int teamId) { std::string msg; msg = chatWindow->TeamColorMessage(world->GetTeam(teamId).name, teamId); msg = _Tr("Client", "{0} wins!", msg); chatWindow->AddMessage(msg); msg = world->GetTeam(teamId).name; msg = _Tr("Client", "{0} Wins!", msg); NetLog("%s", msg.c_str()); centerMessageView->AddMessage(msg); scriptedUI->RecordChatLog(msg, MakeVector4(1.f, 1.f, 1.f, 0.8f)); if (world->GetLocalPlayer()) { if (teamId == world->GetLocalPlayer()->GetTeamId()) { Handle chunk = audioDevice->RegisterSound("Sounds/Feedback/Win.opus"); audioDevice->PlayLocal(chunk, AudioParam()); } else { Handle chunk = audioDevice->RegisterSound("Sounds/Feedback/Lose.opus"); audioDevice->PlayLocal(chunk, AudioParam()); } } } } }