void NetGameClient::DoObjDamage(NetMsg* msg) { if (!msg) return; NetObjDamage obj_damage; obj_damage.Unpack(msg->Data()); Ship* ship = FindShipByObjID(obj_damage.GetObjID()); if (ship) { Sim* sim = Sim::GetSim(); Shot* shot = FindShotByObjID(obj_damage.GetShotID()); const Ship* owner = 0; const char* owner_name = "[NET]"; ship->InflictNetDamage(obj_damage.GetDamage(), shot); if (shot && sim) { if (shot->Owner()) { owner = shot->Owner(); owner_name = owner->Name(); } if (shot->IsMissile()) { SimRegion* region = ship->GetRegion(); float scale = ship->Design()->explosion_scale; if (scale <= 0) scale = ship->Design()->scale; if (owner) { const ShipDesign* owner_design = owner->Design(); if (owner_design && owner_design->scale < scale) scale = (float) owner_design->scale; } sim->CreateExplosion(shot->Location(), Point(), Explosion::SHOT_BLAST, 20.0f * scale, scale, region); } if (!shot->IsBeam()) { if (owner) { ShipStats* stats = ShipStats::Find(owner_name); if (stats) { if (shot->IsPrimary()) stats->AddGunHit(); else if (shot->Damage() > 0) stats->AddMissileHit(); } } shot->Destroy(); } } } }
void NetGameClient::DoSelfDestruct(NetMsg* msg) { if (!msg) return; NetSelfDestruct self_destruct; self_destruct.Unpack(msg->Data()); Ship* ship = FindShipByObjID(self_destruct.GetObjID()); if (ship) { ship->InflictNetDamage(self_destruct.GetDamage()); } }
void NetGameClient::DoObjKill(NetMsg* msg) { if (!msg) return; NetObjKill obj_kill; obj_kill.Unpack(msg->Data()); Ship* ship = FindShipByObjID(obj_kill.GetObjID()); if (ship) { Ship* killer = FindShipByObjID(obj_kill.GetKillerID()); Text killer_name = Game::GetText("NetGameClient.unknown"); if (killer) killer_name = killer->Name(); // log the kill: switch (obj_kill.GetKillType()) { default: case NetObjKill::KILL_MISC: Print("Ship '%s' destroyed (misc) (%s)\n", ship->Name(), FormatGameTime()); break; case NetObjKill::KILL_PRIMARY: case NetObjKill::KILL_SECONDARY: Print("Ship '%s' killed by '%s' (%s)\n", ship->Name(), killer_name.data(), FormatGameTime()); break; case NetObjKill::KILL_COLLISION: Print("Ship '%s' killed in collision with '%s' (%s)\n", ship->Name(), killer_name.data(), FormatGameTime()); break; case NetObjKill::KILL_CRASH: Print("Ship '%s' destroyed (crash) (%s)\n", ship->Name(), FormatGameTime()); case NetObjKill::KILL_DOCK: Print("Ship '%s' docked (%s)\n", ship->Name(), FormatGameTime()); } // record the kill in the stats: if (killer && obj_kill.GetKillType() != NetObjKill::KILL_DOCK) { ShipStats* kstats = ShipStats::Find(killer->Name()); if (kstats) { if (obj_kill.GetKillType() == NetObjKill::KILL_PRIMARY) kstats->AddEvent(SimEvent::GUNS_KILL, ship->Name()); else if (obj_kill.GetKillType() == NetObjKill::KILL_SECONDARY) kstats->AddEvent(SimEvent::MISSILE_KILL, ship->Name()); } if (killer && killer->GetIFF() != ship->GetIFF()) { if (ship->GetIFF() > 0 || killer->GetIFF() > 1) kstats->AddPoints(ship->Value()); } } ShipStats* killee = ShipStats::Find(ship->Name()); if (killee) { if (obj_kill.GetKillType() == NetObjKill::KILL_DOCK) killee->AddEvent(SimEvent::DOCK, killer_name); else killee->AddEvent(SimEvent::DESTROYED, killer_name); } if (obj_kill.GetKillType() == NetObjKill::KILL_DOCK) { FlightDeck* deck = killer->GetFlightDeck(obj_kill.GetFlightDeck()); sim->NetDockShip(ship, killer, deck); } else { ship->InflictNetDamage(ship->Integrity()); ship->DeathSpiral(); if (!obj_kill.GetRespawn()) ship->SetRespawnCount(0); else ship->SetRespawnLoc(obj_kill.GetRespawnLoc()); } } // this shouldn't happen in practice, // but if it does, this is what should be done: else { Shot* shot = FindShotByObjID(obj_kill.GetObjID()); if (shot) { ::Print("NetGameClient::DoObjKill destroying shot '%s'\n", shot->Name()); shot->Destroy(); } } }