Example #1
0
		void Client::PlayerKilledPlayer(spades::client::Player *killer,
		                                spades::client::Player *victim, KillType kt) {
			// play hit sound
			if (kt == KillTypeWeapon || kt == KillTypeHeadshot) {
				// don't play on local: see BullethitPlayer
				if (victim != world->GetLocalPlayer()) {
					if (!IsMuted()) {
						Handle<IAudioChunk> c;
						switch (SampleRandomInt(0, 2)) {
							case 0:
								c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Flesh1.opus");
								break;
							case 1:
								c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Flesh2.opus");
								break;
							case 2:
								c = audioDevice->RegisterSound("Sounds/Weapons/Impacts/Flesh3.opus");
								break;
						}
						AudioParam param;
						param.volume = 4.f;
						audioDevice->Play(c, victim->GetEye(), param);
					}
				}
			}

			// The local player is dead; initialize the look-you-are-dead cam
			if (victim == world->GetLocalPlayer()) {
				followCameraState.enabled = false;

				Vector3 v = -victim->GetFront();
				followAndFreeCameraState.yaw = atan2(v.y, v.x);
				followAndFreeCameraState.pitch = 30.f * M_PI / 180.f;
			}

			// emit blood (also for local player)
			// FIXME: emiting blood for either
			// client-side or server-side hit?
			switch (kt) {
				case KillTypeGrenade:
				case KillTypeHeadshot:
				case KillTypeMelee:
				case KillTypeWeapon: Bleed(victim->GetEye()); break;
				default: break;
			}

			// create ragdoll corpse
			if (cg_ragdoll && victim->GetTeamId() < 2) {
				Corpse *corp;
				corp = new Corpse(renderer, map, victim);
				if (victim == world->GetLocalPlayer())
					lastMyCorpse = corp;
				if (killer != victim && kt != KillTypeGrenade) {
					Vector3 dir = victim->GetPosition() - killer->GetPosition();
					dir = dir.Normalize();
					if (kt == KillTypeMelee) {
						dir *= 6.f;
					} else {
						if (killer->GetWeapon()->GetWeaponType() == SMG_WEAPON) {
							dir *= 2.8f;
						} else if (killer->GetWeapon()->GetWeaponType() == SHOTGUN_WEAPON) {
							dir *= 4.5f;
						} else {
							dir *= 3.5f;
						}
					}
					corp->AddImpulse(dir);
				} else if (kt == KillTypeGrenade) {
					corp->AddImpulse(MakeVector3(0, 0, -4.f - SampleRandomFloat() * 4.f));
				}
				corp->AddImpulse(victim->GetVelocty() * 32.f);
				corpses.emplace_back(corp);

				if (corpses.size() > corpseHardLimit) {
					corpses.pop_front();
				} else if (corpses.size() > corpseSoftLimit) {
					RemoveInvisibleCorpses();
				}
			}

			// add chat message
			std::string s;
			s = ChatWindow::TeamColorMessage(killer->GetName(), killer->GetTeamId());

			std::string cause;
			bool isFriendlyFire = killer->GetTeamId() == victim->GetTeamId();
			if (killer == victim)
				isFriendlyFire = false;

			Weapon *w =
			  killer ? killer->GetWeapon() : nullptr; // only used in case of KillTypeWeapon
			switch (kt) {
				case KillTypeWeapon:
					switch (w ? w->GetWeaponType() : RIFLE_WEAPON) {
						case RIFLE_WEAPON: cause += _Tr("Client", "Rifle"); break;
						case SMG_WEAPON: cause += _Tr("Client", "SMG"); break;
						case SHOTGUN_WEAPON: cause += _Tr("Client", "Shotgun"); break;
					}
					break;
				case KillTypeFall:
					//! A cause of death shown in the kill feed.
					cause += _Tr("Client", "Fall");
					break;
				case KillTypeMelee:
					//! A cause of death shown in the kill feed.
					cause += _Tr("Client", "Melee");
					break;
				case KillTypeGrenade:
					cause += _Tr("Client", "Grenade");
					break;
				case KillTypeHeadshot:
					//! A cause of death shown in the kill feed.
					cause += _Tr("Client", "Headshot");
					break;
				case KillTypeTeamChange:
					//! A cause of death shown in the kill feed.
					cause += _Tr("Client", "Team Change");
					break;
				case KillTypeClassChange:
					//! A cause of death shown in the kill feed.
					cause += _Tr("Client", "Weapon Change");
					break;
				default:
					cause += "???";
					break;
			}

			s += " [";
			if (isFriendlyFire)
				s += ChatWindow::ColoredMessage(cause, MsgColorFriendlyFire);
			else if (killer == world->GetLocalPlayer() || victim == world->GetLocalPlayer())
				s += ChatWindow::ColoredMessage(cause, MsgColorGray);
			else
				s += cause;
			s += "] ";

			if (killer != victim) {
				s += ChatWindow::TeamColorMessage(victim->GetName(), victim->GetTeamId());
			}

			killfeedWindow->AddMessage(s);

			// log to netlog
			if (killer != victim) {
				NetLog("%s (%s) [%s] %s (%s)", killer->GetName().c_str(),
				       world->GetTeam(killer->GetTeamId()).name.c_str(), cause.c_str(),
				       victim->GetName().c_str(), world->GetTeam(victim->GetTeamId()).name.c_str());
			} else {
				NetLog("%s (%s) [%s]", killer->GetName().c_str(),
				       world->GetTeam(killer->GetTeamId()).name.c_str(), cause.c_str());
			}

			// show big message if player is involved
			if (victim != killer) {
				Player *local = world->GetLocalPlayer();
				if (killer == local || victim == local) {
					std::string msg;
					if (killer == local) {
						if ((int)cg_centerMessage == 2)
							msg = _Tr("Client", "You have killed {0}", victim->GetName());
					} else {
						msg = _Tr("Client", "You were killed by {0}", killer->GetName());
					}
					centerMessageView->AddMessage(msg);
				}
			}
		}