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(); } } } }
Shot* Weapon::FireBarrel(int n) { const Point& base_vel = ship->Velocity(); Shot* shot = 0; SimRegion* region = ship->GetRegion(); if (!region || n < 0 || n >= nbarrels || Game::Paused()) return 0; firing = 1; Aim(); Camera rail_cam; rail_cam.Clone(aim_cam); Point shotpos = muzzle_pts[n]; if (design->length > 0) shotpos = shotpos + aim_cam.vpn() * design->length; // guns may be slewed towards target: if (design->primary) { shot = CreateShot(shotpos, aim_cam, design, ship); if (shot) { shot->SetVelocity(shot->Velocity() + base_vel); } } // missiles always launch in rail direction: else { // unless they are on a mobile launcher if (turret && design->self_aiming) { shot = CreateShot(shotpos, aim_cam, design, ship); shot->SetVelocity(base_vel); } else { shot = CreateShot(shotpos, rail_cam, design, ship); if (shot /* && !turret */) { Matrix orient = ship->Cam().Orientation(); if (aim_azimuth != 0) orient.Yaw(aim_azimuth); if (aim_elevation != 0) orient.Pitch(aim_elevation); Point eject = design->eject * orient; shot->SetVelocity(base_vel + eject); } } if (shot && visible_stores[n]) { GRAPHIC_DESTROY(visible_stores[n]); } } if (shot) { if (ammo > 0) ammo--; if (guided && target) shot->SeekTarget(target, subtarget); float shot_load; if (energy > design->charge) shot_load = design->charge; else shot_load = energy; energy -= shot_load; shot->SetCharge(shot_load * availability); if (target && design->flak && !design->guided) { double speed = shot->Velocity().length(); double range = (target->Location() - shot->Location()).length(); if (range > design->min_range && range < design->max_range) { shot->SetFuse(range / speed); } } region->InsertObject(shot); if (beams) { beams[n] = shot; Observe(beams[n]); // aim beam at target: SetBeamPoints(true); } if (ship) { ShipStats* stats = ShipStats::Find(ship->Name()); if (design->primary) stats->AddGunShot(); else if (design->decoy_type == 0 && design->damage > 0) stats->AddMissileShot(); } } return shot; }