コード例 #1
0
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();
			}
		}
	}
}
コード例 #2
0
ファイル: CombatSetupWnd.cpp プロジェクト: anarsky/freeorion
void CombatSetupWnd::HandleMouseMoves(const GG::Pt& pt) {
    if (Ogre::SceneNode* node = PlaceableShipNode()) {
        std::pair<bool, Ogre::Vector3> intersection = m_intersect_mouse_with_ecliptic(pt);
        if (intersection.first) {
            Ship* ship = *Ogre::any_cast<Ship*>(&node->getUserAny());
            bool valid_location = ValidPlacement(ship, intersection.second);
            node->setVisible(true);
            node->setPosition(intersection.second);
            node->setOrientation(StarwardOrientationForPosition(intersection.second));
            if (valid_location) {
                Ogre::SceneNode::ObjectIterator iterator = node->getAttachedObjectIterator();
                assert(iterator.hasMoreElements());
                Ogre::Entity* entity = boost::polymorphic_downcast<Ogre::Entity*>(iterator.getNext());
                entity->setMaterialName(ShipMaterialName(*ship->Design(), ship->Owner()));
                entity->setRenderQueueGroup(Ogre::RENDER_QUEUE_MAIN);
            } else {
                std::string base_material_name = ShipMaterialName(*ship->Design(), ship->Owner());
                std::string material_name = UNPLACEABLE_MATERIAL_PREFIX + base_material_name;
                if (!Ogre::MaterialManager::getSingleton().resourceExists(material_name)) {
                    Ogre::MaterialPtr unmodified_material =
                        Ogre::MaterialManager::getSingleton().getByName(base_material_name);
                    Ogre::MaterialPtr material = unmodified_material->clone(material_name);
                    Ogre::Pass* pass = material->getTechnique(0)->getPass(1);
                    assert(pass->hasFragmentProgram());
                    pass->getFragmentProgramParameters()->setNamedConstant("alpha", 0.25f);
                }
                Ogre::SceneNode::ObjectIterator iterator = node->getAttachedObjectIterator();
                assert(iterator.hasMoreElements());
                Ogre::Entity* entity = boost::polymorphic_downcast<Ogre::Entity*>(iterator.getNext());
                entity->setMaterialName(material_name);
                entity->setRenderQueueGroup(ALPHA_OBJECTS_QUEUE);
            }
        } else {
            node->setVisible(false);
        }
    }
}
コード例 #3
0
void
TacticalAI::CheckTarget()
{
    SimObject* tgt = ship_ai->GetTarget();

    if (!tgt) return;

    if (tgt->GetRegion() != ship->GetRegion()) {
        ship_ai->DropTarget();
        return;
    }

    if (tgt->Type() == SimObject::SIM_SHIP) {
        Ship* target = (Ship*) tgt;

        // has the target joined our side?
        if (target->GetIFF() == ship->GetIFF() && !target->IsRogue()) {
            ship_ai->DropTarget();
            return;
        }

        // is the target already jumping/breaking/dying?
        if (target->InTransition()) {
            ship_ai->DropTarget();
            return;
        }

        // have we been ordered to pursue the target?
        if (directed_tgtid) {
            if (directed_tgtid != target->Identity()) {
                ship_ai->DropTarget();
            }

            return;
        }

        // can we catch the target?
        if (target->Design()->vlimit  <= ship->Design()->vlimit ||
                ship->Velocity().length() <= ship->Design()->vlimit)
        return;

        // is the target now out of range?
        WeaponDesign* wep_dsn = ship->GetPrimaryDesign();
        if (!wep_dsn)
        return;

        // compute the "give up" range:
        double drop_range = 3 * wep_dsn->max_range;
        if (drop_range > 0.75 * ship->Design()->commit_range)
        drop_range = 0.75 * ship->Design()->commit_range;

        double range = Point(target->Location() - ship->Location()).length();
        if (range < drop_range)
        return;

        // is the target closing or separating?
        Point  delta = (target->Location() + target->Velocity()) -
        (ship->Location()   + ship->Velocity());

        if (delta.length() < range)
        return;

        ship_ai->DropTarget();
    }

    else if (tgt->Type() == SimObject::SIM_DRONE) {
        Drone* drone = (Drone*) tgt;

        // is the target still a threat?
        if (drone->GetEta() < 1 || drone->GetTarget() == 0)
        ship_ai->DropTarget();
    }
}
コード例 #4
0
bool
MissionEvent::CheckTrigger()
{
	Sim* sim = Sim::GetSim();

	if (time > 0 && time > sim->MissionClock())
	return false;

	switch (trigger) {
	case TRIGGER_TIME: {
			if (time <= sim->MissionClock())
			Activate();
		}
		break;

	case TRIGGER_DAMAGE: {
			Ship* ship = sim->FindShip(trigger_ship);
			if (ship) {
				double damage = 100.0 * (ship->Design()->integrity - ship->Integrity()) /
				(ship->Design()->integrity);
				
				if (damage >= trigger_param[0])
				Activate();
			}
		}
		break;

	case TRIGGER_DETECT: {
			Ship* ship = sim->FindShip(trigger_ship);
			Ship* tgt  = sim->FindShip(trigger_target);
			
			if (ship && tgt) {
				if (ship->FindContact(tgt))
				Activate();
			}
			else {
				Skip();
			}
		}
		break;

	case TRIGGER_RANGE: {
			Ship* ship = sim->FindShip(trigger_ship);
			Ship* tgt  = sim->FindShip(trigger_target);
			
			if (ship && tgt) {
				double range     = (ship->Location() - tgt->Location()).length();
				double min_range = 0;
				double max_range = 1e12;

				if (trigger_param[0] > 0)
				min_range = trigger_param[0];
				else
				max_range = -trigger_param[0];

				if (range < min_range || range > max_range)
				Activate();
			}
			else {
				Skip();
			}
		}
		break;

	case TRIGGER_SHIPS_LEFT: {
			int alive   = 0;
			int count   = 0;
			int iff     = -1;
			int nparams = NumTriggerParams();

			if (nparams > 0) count = TriggerParam(0);
			if (nparams > 1) iff   = TriggerParam(1);

			ListIter<SimRegion> iter = sim->GetRegions();
			while (++iter) {
				SimRegion* rgn = iter.value();

				ListIter<Ship> s_iter = rgn->Ships();
				while (++s_iter) {
					Ship* ship = s_iter.value();

					if (ship->Type() >= Ship::STATION)
					continue;

					if (ship->Life() == 0 && ship->RespawnCount() < 1)
					continue;

					if (iff < 0 || ship->GetIFF() == iff)
					alive++;
				}
			}

			if (alive <= count)
			Activate();
		}
		break;

	case TRIGGER_EVENT_ALL: {
			bool  all     = true;
			int   nparams = NumTriggerParams();
			for (int i = 0; all && i < nparams; i++) {
				int trigger_id = TriggerParam(i);

				ListIter<MissionEvent> iter = sim->GetEvents();
				while (++iter) {
					MissionEvent* e = iter.value();
					if (e->EventID() == trigger_id) {
						if (e->Status() != COMPLETE)
						all = false;
						break;
					}

					else if (e->EventID() == -trigger_id) {
						if (e->Status() == COMPLETE)
						all = false;
						break;
					}
				}
			}

			if (all)
			Activate();
		}
		break;

	case TRIGGER_EVENT_ANY: {
			bool  any     = false;
			int   nparams = NumTriggerParams();
			for (int i = 0; !any && i < nparams; i++) {
				int trigger_id = TriggerParam(i);

				ListIter<MissionEvent> iter = sim->GetEvents();
				while (++iter) {
					MissionEvent* e = iter.value();
					if (e->EventID() == trigger_id) {
						if (e->Status() == COMPLETE)
						any = true;
						break;
					}
				}
			}

			if (any)
			Activate();
		}
		break;
	}

	return status == ACTIVE;
}