void          CFSShip::ShipStatusWarped(IwarpIGC*   pwarp)
{
    SectorID   sectorID = pwarp->GetDestination()->GetCluster()->GetObjectID();
    for (SideLinkIGC*   psl = GetMission()->GetIGCMission()->GetSides()->first();
         (psl != NULL);
         psl = psl->next())
    {
        IsideIGC*   pside = psl->data();
        if ((GetIGCShip()->SeenBySide(pside)) && (pwarp->SeenBySide(pside)))
        {
            SideID      sideID = pside->GetObjectID();
            m_rgShipStatus[sideID].SetSectorID(sectorID);

            //Adjust the ship status for all of the children as well
            {
                for (ShipLinkIGC*   psl = GetIGCShip()->GetChildShips()->first();
                     (psl != NULL);
                     psl = psl->next())
                {
                    IshipIGC*   pship = psl->data();
                    ShipStatus* pss = ((CFSShip*)(pship->GetPrivateData()))->GetShipStatus(sideID);

                    pss->SetSectorID(sectorID);
                }
            }
        }
    } 
}
    //------------------------------------------------------------------------------
    void        SetCommandAction::Execute (void)
    {
        // get a pointer to the actual ship and the target
        IshipIGC*   pShip = static_cast<IshipIGC*> (static_cast<ImodelIGC*> (*m_pShip));
        ImodelIGC*  pTarget = static_cast<ImodelIGC*> (*m_pTarget);

        // the ship might not be there for any of a hundred reasons,
        // including that it was destroyed. If it's not there, we want
        // to skip setting its command.
        if (pShip)
        {
            // we want to use the pretty interface if this is a command for the player
            if ((pShip == trekClient.GetShip ()) and (m_command == c_cmdQueued))
            {
                TrekWindow* pWindow = GetWindow ();
                IshipIGC*   pCommander = g_pMission->GetCommanderShip ();
                ZString     strOrder = ZString (c_cdAllCommands[m_commandID].szVerb);
                if (pTarget)
                    strOrder = strOrder + " " + GetModelName (pTarget);
                pWindow->SetQueuedCommand (pCommander, m_commandID, pTarget);
                trekClient.PostText(true, "New orders from %s to %s: %s. Press [insert] to accept.", (const char*)GetModelName (pCommander), GetModelName (pShip), (const char*) strOrder);
            }
            else
                pShip->SetCommand (m_command, pTarget, m_commandID);
        }
    }
Ejemplo n.º 3
0
    //------------------------------------------------------------------------------
    void        Mission5::CreateUniverse (void)
    {
        LoadUniverse ("training_5", 412, 1050);    // an intercepter

        // put the commander ship in the station
        ImissionIGC*    pCore = trekClient.GetCore();
        ImodelIGC*      pStation = pCore->GetModel (OT_station, 1050);
        IshipIGC*       pCommander = pCore->GetShip (m_commanderID);
        pCommander->SetStation (static_cast<IstationIGC*> (pStation));
        pCommander->SetCommand (c_cmdAccepted, NULL, c_cidDoNothing);
        pCommander->SetCommand (c_cmdCurrent, NULL, c_cidDoNothing);
        pCommander->SetAutopilot (false);
    }
void          CFSShip::ShipStatusDocked(IstationIGC*   pstation)
{
    StationID   stationID = pstation->GetObjectID();
    SectorID    sectorID = pstation->GetCluster()->GetObjectID();
    HullID      hullID;
    {
        IhullTypeIGC*   pht = GetIGCShip()->GetBaseHullType();
        hullID = pht ? pht->GetObjectID() : NA;
    }
    IsideIGC*   psideMe = GetIGCShip()->GetSide();

    for (SideLinkIGC*   psl = GetMission()->GetIGCMission()->GetSides()->first();
         (psl != NULL);
         psl = psl->next())
    {
        IsideIGC*   pside = psl->data();
        if ((pside == psideMe || pside->AlliedSides(pside,psideMe)) || // #ALLY Imago 7/8/09 VISIBILITY?
            (GetIGCShip()->SeenBySide(pside) && pstation->SeenBySide(pside)))
        {
            SideID      sideID = pside->GetObjectID();
            ShipStatus* pss = &(m_rgShipStatus[sideID]);
			pss->SetStateTime(g.timeNow.clock());
            pss->SetState(c_ssDocked);
            pss->SetParentID(NA);
            pss->SetStationID(stationID);
            pss->SetSectorID(sectorID);
            pss->SetHullID(hullID);

            //Adjust the ship status for all of the children as well
            {
                for (ShipLinkIGC*   psl = GetIGCShip()->GetChildShips()->first();
                     (psl != NULL);
                     psl = psl->next())
                {
                    IshipIGC*   pship = psl->data();
                    ShipStatus* pss = ((CFSShip*)(pship->GetPrivateData()))->GetShipStatus(sideID);

                    assert ((pship->GetTurretID() == NA)
                            ? (pss->GetState() == c_ssObserver)
                            : (pss->GetState() == c_ssTurret));
                    assert (pss->GetParentID() == GetIGCShip()->GetObjectID());
                    assert (pss->GetHullID() == NA);

                    pss->SetStationID(stationID);
                    pss->SetSectorID(sectorID);

                }
            }
        }
    } 
}
Ejemplo n.º 5
0
//------------------------------------------------------------------------------
void        Mission4::CreateUniverse (void)
{
    LoadUniverse ("training_3", 486, 1030);    // an advanced stealth fighter

    // stuff for setup
    IshipIGC*           pShip = trekClient.GetShip();

    // set a global attribute to increase the overall energy of the ship
    IsideIGC*           pSide = pShip->GetSide ();
    GlobalAttributeSet  gas = pSide->GetGlobalAttributeSet ();
    gas.SetAttribute (c_gaMaxEnergy, 10.0f);
    pSide->SetGlobalAttributeSet (gas);

    // put the commander ship in the station
    ImissionIGC*        pCore = trekClient.GetCore();
    ImodelIGC*          pStation = pCore->GetModel (OT_station, 1030);
    IshipIGC*           pCommander = pCore->GetShip (m_commanderID);
    pCommander->SetStation (static_cast<IstationIGC*> (pStation));
    pCommander->SetCommand (c_cmdAccepted, NULL, c_cidDoNothing);
    pCommander->SetCommand (c_cmdCurrent, NULL, c_cidDoNothing);
    pCommander->SetAutopilot (false);

    // activate all the starting weapons
    trekClient.fGroupFire = true;

    // take the missiles off the ship
    IpartIGC*           pPart = pShip->GetMountedPart (ET_Magazine, 0);
    if (pPart)
        pPart->Terminate ();

}
void CFSShip::ShipStatusSpotted(IsideIGC* pside)
{
    SideID  sideID = pside->GetObjectID();

    SectorID    sectorID;
    {
        IclusterIGC*    pcluster = GetIGCShip()->GetCluster();
        if (pcluster == NULL)
        {
            IstationIGC*    pstation = GetIGCShip()->GetStation();
            assert (pstation);
            pcluster = pstation->GetCluster();
        }

        sectorID = pcluster->GetObjectID();
    }

    ShipStatus* pss = &m_rgShipStatus[sideID];
	pss->SetStateTime(g.timeNow.clock());
    pss->SetState(c_ssFlying);
    pss->SetParentID(NA);
    pss->SetHullID(GetIGCShip()->GetHullType()->GetObjectID());
    pss->SetSectorID(sectorID);

    //Flag that we have been detected as well
    IsideIGC*   mySide = GetSide();
    SideID  mySideID = mySide->GetObjectID();
	if (mySide != pside && !mySide->AlliedSides(mySide, pside)) //#ALLY -was: mySide != pside (Imago fixed 7/8/09)
        m_rgShipStatus[mySideID].SetDetected(true);

    //Adjust the ship status for all of the children as well
    {
        for (ShipLinkIGC*   psl = GetIGCShip()->GetChildShips()->first();
             (psl != NULL);
             psl = psl->next())
        {
            IshipIGC*   pship = psl->data();
            CFSShip*    pfsship = ((CFSShip*)(pship->GetPrivateData()));
            ShipStatus* pss = pfsship->GetShipStatus(sideID);

            pss->SetState((pship->GetTurretID() == NA) ? c_ssObserver : c_ssTurret); 
            pss->SetHullID(NA);
            pss->SetSectorID(sectorID);
            pss->SetParentID(GetShipID());

			if (mySide != pside && !mySide->AlliedSides(mySide, pside)) //#ALLY -was != (Imago fixed 7/8/09)
                pfsship->GetShipStatus(mySideID)->SetDetected(true);
        }
    }
}
void          CFSShip::ShipStatusHidden(IsideIGC* pside)
{
    SideID  sideID = pside->GetObjectID();
    m_rgShipStatus[sideID].SetUnknown();

    IsideIGC*   mySide = GetSide();
    SideID      mySideID = mySide->GetObjectID();

    //Does anyone see us?
    bool    detectedF = false;
    {
        CFSMission* pmission = this->GetMission();
        if (pmission)  
        {
            for (SideLinkIGC*   psl = pmission->GetIGCMission()->GetSides()->first();
                 (psl != NULL);
                 psl = psl->next())
            {
				if (psl->data() != mySide && !mySide->AlliedSides(psl->data(), mySide)) //#ALLY -was: != (Imago fixed 7/8/09)
                {
                    ShipStatus* pss = GetShipStatus(psl->data()->GetObjectID());
                    if (!pss->GetUnknown())
                    {
                        detectedF = true;
                        break;
                    }
                }
            }
        }
    }

    m_rgShipStatus[mySideID].SetDetected(detectedF);

    //Adjust the ship status for all of the children as well
    {
        for (ShipLinkIGC*   psl = GetIGCShip()->GetChildShips()->first();
             (psl != NULL);
             psl = psl->next())
        {
            IshipIGC*   pship = psl->data();
            CFSShip*    pfsShip = ((CFSShip*)(pship->GetPrivateData()));
            ShipStatus* pss = pfsShip->GetShipStatus(sideID);

            pss->SetUnknown();

            pfsShip->GetShipStatus(mySideID)->SetDetected(detectedF);
        }
    }
}
Ejemplo n.º 8
0
    //------------------------------------------------------------------------------
    void        SetDroneNanAction::Execute (void)
    {
		IshipIGC*		nanShip = trekClient.GetSide()->GetShip(nanShipID);
		IpartIGC*       pPart = nanShip->GetMountedPart (ET_Weapon, 0);
		if (pPart)
			pPart->Terminate ();

		// Stick Nanite 2 on the front
		PartData        pd;
        pd.partID = 190;
        pd.mountID = 0;
        pd.amount = 0;
        nanShip->CreateAndAddPart (&pd);

    }
Ejemplo n.º 9
0
    //------------------------------------------------------------------------------
    void        Mission6::CreateUniverse (void)
    {
        LoadUniverse ("training_3", 488, 1030);    // a fighter 3

        // activate all the starting weapons
        trekClient.fGroupFire = true;

        // put the commander ship in the station
        ImissionIGC*    pCore = trekClient.GetCore();
        ImodelIGC*      pStation = pCore->GetModel (OT_station, 1030);
        IshipIGC*       pCommander = pCore->GetShip (m_commanderID);
        pCommander->SetStation (static_cast<IstationIGC*> (pStation));
        pCommander->SetCommand (c_cmdAccepted, NULL, c_cidDoNothing);
        pCommander->SetCommand (c_cmdCurrent, NULL, c_cidDoNothing);
        pCommander->SetAutopilot (false);
    }
Ejemplo n.º 10
0
 //------------------------------------------------------------------------------
 void        TurnToAction::Execute (void)
 {
     IshipIGC*   pShip = static_cast<IshipIGC*> (static_cast<ImodelIGC*> (*m_pObject));
     ImodelIGC*  pTarget = static_cast<ImodelIGC*> (*m_pTarget);
     if (pShip && pTarget)
     {
         Vector      delta = pTarget->GetPosition () - pShip->GetPosition ();
         turnToFace (delta, GetWindow ()->GetDeltaTime (), pShip, &g_setInputControls);
         g_setInputControls.jsValues[c_axisYaw] *= 0.5f;
         g_setInputControls.jsValues[c_axisPitch] *= 0.5f;
         g_setInputControls.jsValues[c_axisRoll] *= 0.5f;
     }
     else
     {
         g_setInputControls.jsValues[c_axisYaw] = NA;
         g_setInputControls.jsValues[c_axisPitch] = NA;
         g_setInputControls.jsValues[c_axisRoll] = NA;
     }
 }
Ejemplo n.º 11
0
bool CclusterIGC::IsFriendlyCluster(IsideIGC* pside, ClusterQuality cqlty) //Spunky #288
{
	int balanceOfPower = 0;
	//carrier or ASS in sector = not friendly - Spunky #290
	ShipLinkIGC* pshipl = GetShips()->first();
	if (pshipl)
	{
		do
		{
			IshipIGC* pship = pshipl->data();
			if (pship->GetParentShip() == NULL)
				if (pship->GetSide() != pside && pship->SeenBySide(pside) && !IsideIGC::AlliedSides(pside, pship->GetSide()))
				{
					if (pship->GetHullType()->HasCapability(c_habmIsRipcordTarget | c_habmIsLtRipcordTarget))
						return false;
					if (pship->GetBaseHullType()->GetScannerRange() > 800 && cqlty & cqNoEye)
						return false;
					balanceOfPower--;
				}
				else if (pship->GetSide() == pside || IsideIGC::AlliedSides(pside, pship->GetSide()))
					balanceOfPower++;
			pshipl = pshipl->next();
		} while (pshipl);
	}
	if (balanceOfPower < 0 && cqlty & cqPositiveBOP)
		return false;
		
	
	//Spunky #333
	StationLinkIGC* psl = GetStations()->first();
	bool ourBaseInCluster = false;
    if (psl)
	{
		do
		{
			IstationIGC*    ps = psl->data();
			if (!ps->GetStationType()->HasCapability(c_sabmPedestal) && ps->SeenBySide(pside))
			{
				if (pside != ps->GetSide() && !IsideIGC::AlliedSides(pside, ps->GetSide())) // #ALLY FIXED 7/10/09 imago
					return false;
				else 
					ourBaseInCluster = true;
			}
			psl = psl->next();
		}
		while (psl != NULL);
	}
	
	if (cqlty & cqIncludeNeutral || ourBaseInCluster)
		return true;
	else
		return false;
}
void CFSPlayer::Dock(IstationIGC * pstation)
{
  IshipIGC * pship = GetIGCShip();

  CFSCluster*       pfsCluster = (CFSCluster*)(pstation->GetCluster()->GetPrivateData());
  SetDPGroup(pfsCluster, false);

  ShipStatus* pss = GetShipStatus(pship->GetSide()->GetObjectID());
  pss->SetStationID(pstation->GetObjectID());
  pss->SetSectorID(pstation->GetCluster()->GetObjectID());

  // Tell them what station they're at
  BEGIN_PFM_CREATE(g.fm, pfmDocked, S, DOCKED)
  END_PFM_CREATE
  pfmDocked->stationID = pstation->GetObjectID();
  g.fm.SendMessages(GetConnection(), FM_GUARANTEED, FM_FLUSH);

  //CFSShip::Dock(pstation);
}
Ejemplo n.º 13
0
//------------------------------------------------------------------------------
/* ImodelIGC* */    CurrentTarget::operator ImodelIGC* (void)
{
    // first, get the ship and its target
    IshipIGC*   pShip = static_cast<IshipIGC*> (static_cast<ImodelIGC*> (*m_pTarget));
    assert (pShip);
    ImodelIGC*  pTarget = pShip->GetCommandTarget (c_cmdCurrent);

    // there is an option to cache the target the first time this target is evaluated.
    // if that option is set...
    if (m_bLockOnFirstFetch)
    {

        // first check to see if we have done a fetch at all
        if (not m_pFetched)
        {
            // we haven't cached a target yet, so we need to get the target
            m_pFetched = new TypeIDTarget (pTarget ? pTarget->GetObjectType () : NA, pTarget ? pTarget->GetObjectID () : NA);
        }
        else
        {
            // we have cached a target, but the reason we want to cache the target is to
            // determine if a kill has happened, e.g. has the target been eliminated. The
            // problem is that the player may choose to change the target before
            // eliminating it, and then we are stuck waiting on the original target. Here
            // we check to see if the target has been changed w/o eliminating the
            // original target, and if so, adjust to compensate.
            ImodelIGC*  pFetched = *m_pFetched;
            if ((pFetched != pTarget) and pFetched and pTarget)
            {
                // there has been such a change, so set up a new abstract target
                delete m_pFetched;
                m_pFetched = new TypeIDTarget (pTarget ? pTarget->GetObjectType () : NA, pTarget ? pTarget->GetObjectID () : NA);
            }
        }
        return (*m_pFetched);
    }

    // that option wasn't requested, so we just return the actual found target
    return pTarget;
}
Ejemplo n.º 14
0
    static int MannedTurrets(IshipIGC* pshipParent)
    {
        // loop through all of the ships on that side and count the ones 
        // that are turrets of this.
        int cMannedTurrets = 0;
        
        const ShipListIGC* shipList = pshipParent->GetSide()->GetShips();
        for (const ShipLinkIGC* lShip = shipList->first(); lShip; lShip = lShip->next())
        {
            IshipIGC* pship = lShip->data();
            PlayerInfo* pplayer = (PlayerInfo*)pship->GetPrivateData();

            if (pplayer->LastSeenState() == c_ssTurret)                
            {
                PlayerInfo* pplayerParent = trekClient.FindPlayer(pplayer->LastSeenParent());

                if (pplayerParent && pplayerParent->GetShip() == pshipParent)
                    cMannedTurrets++;
            }
        }

        return cMannedTurrets;
    }
Ejemplo n.º 15
0
void    CweaponIGC::SetMountID(Mount newVal)
{
	assert(m_ship);

	if (newVal != m_mountID)
	{
		Deactivate();
		if (m_pshipGunner)
			SetGunner(NULL);

		m_ship->MountPart(this, newVal, &m_mountID);

		if (newVal >= 0)
		{
			//Get the corresponding hardpoint: we know one exists because the
			//ship allowed the part to be mounted.
			const IhullTypeIGC* pht = m_ship->GetBaseHullType();
			assert(pht);

			m_pposition = &(pht->GetWeaponPosition(newVal));
			m_porientation = &(pht->GetWeaponOrientation(newVal));

			//Is there a turret gunner in this position (who does not have a gun)
			{
				for (ShipLinkIGC* psl = m_ship->GetChildShips()->first(); (psl != NULL); psl = psl->next())
				{
					IshipIGC*   pship = psl->data();
					if (pship->GetTurretID() == newVal)
					{
						SetGunner(pship);
						break;
					}
				}
			}
		}
	}
}
Ejemplo n.º 16
0
    //------------------------------------------------------------------------------
    void        Mission5::SetupShipAndCamera (void)
    {
        // needed parameters
        IshipIGC*       pShip = trekClient.GetShip ();
        ImissionIGC*    pCore = trekClient.GetCore ();
        IstationIGC*    pStation = pCore->GetStation (1050);
        IclusterIGC*    pCluster = pCore->GetCluster(GetStartSectorID ());

        // set up the ship
        trekClient.ResetClusterScanners(pShip->GetSide());

        // put the ship in the station
        pShip->SetStation (pStation);

        // set up the outside view from the station
        trekClient.SetViewCluster (pCluster);

        // set up the camera
        TrekWindow*     pWindow = GetWindow ();
        pWindow->SetViewMode (TrekWindow::vmCommand);
        pWindow->PositionCommandView (NULL, 0.0);
        pWindow->SetRadarMode (RadarImage::c_rlAll);
        pWindow->EnableDisplacementCommandView (true);
    }
Ejemplo n.º 17
0
    //------------------------------------------------------------------------------
    void        CreateDroneAction::Execute (void)
    {
        if (m_sectorID == NA)
        {
            // figure some default location
        }
        IshipIGC*   pShip = g_pMission->CreateDrone (m_name, m_shipID, m_hullID, m_sideID, m_pilotType);
        pShip->SetPosition (m_position);
        pShip->SetOrientation (m_orientation);
        pShip->SetCluster (trekClient.GetCore ()->GetCluster(m_sectorID));

        if (m_stationTypeID != NA)
            pShip->SetBaseData (trekClient.GetCore ()->GetStationType (m_stationTypeID));
        else if (m_expendableTypeID != NA)
            pShip->SetBaseData (trekClient.GetCore ()->GetExpendableType (m_expendableTypeID));
    }
Ejemplo n.º 18
0
//------------------------------------------------------------------------------
void        DoDamageAction::Execute (void)
{
    IshipIGC*   pShip = trekClient.GetShip ();
    if (not m_bHull)
    {
        IshieldIGC* pShield = static_cast<IshieldIGC*> (pShip->GetMountedPart (ET_Shield, 0));
        if (pShield and (pShield->GetFraction () > 0.2f))
            pShip->ReceiveDamage (c_dmgidCollision, pShield->GetMaxStrength () * 0.03f, Time::Now (), Vector (-1.0f, 0.0f, 0.0f), Vector (1.0f, 0.0f, 0.0f), 0);

    }
    else
    {
        IshieldIGC* pShield = static_cast<IshieldIGC*> (pShip->GetMountedPart (ET_Shield, 0));
        if (pShield and (pShield->GetFraction () > 0.25f))
            pShield->SetFraction (0.2f);
        else if (pShip->GetFraction () > 0.5f)
            pShip->ReceiveDamage (c_dmgidCollision, 7.5f, Time::Now (), Vector (-1.0f, 0.0f, 0.0f), Vector (1.0f, 0.0f, 0.0f), 0);
    }
}
Ejemplo n.º 19
0
    //------------------------------------------------------------------------------
    void        RepairRearmAction::Execute (void)
    {
        IshipIGC*   pShip = trekClient.GetShip ();

        // heal the ship entirely
        IshieldIGC* pShield = static_cast<IshieldIGC*> (pShip->GetMountedPart (ET_Shield, 0));
        if (pShield)
            pShield->SetFraction (1.0f);
        pShip->SetFraction (1.0f);

        // reload the ammunition, energy, and fuel
        pShip->SetEnergy (pShip->GetHullType ()->GetMaxEnergy ());
        pShip->SetAmmo (pShip->GetHullType ()->GetMaxAmmo ());
        pShip->SetFuel (pShip->GetHullType ()->GetMaxFuel ());

		// mdvalley: i needs defining outside the fors

		int i;

        // fill the first empty cargo slot with missiles
        for (i = -1; i > -c_maxCargo; i--)
            if (pShip->GetMountedPart (NA, i) == 0)
            {
                g_pMission->AddPartToShip (150, i, 0x7fff);
                break;
            }

        // fill the second empty cargo slot with ammo
        for (; i > -c_maxCargo; i--)
            if (pShip->GetMountedPart (NA, i) == 0)
                g_pMission->AddPartToShip (24, i, 0x7fff);

        // fill all subsequent slots with missiles
        for (; i > -c_maxCargo; i--)
            if (pShip->GetMountedPart (NA, i) == 0)
                g_pMission->AddPartToShip (150, i, 0x7fff);
    }
//This should only be called from the ChangeCluster() callback.
void CFSPlayer::SetCluster(IclusterIGC* pcluster, bool bViewOnly)
{
  CFSShip::SetCluster(pcluster, bViewOnly);

  if (pcluster)
  {
    SetDPGroup((CFSCluster*)(pcluster->GetPrivateData()), true);

    IshipIGC*   pshipParent = GetIGCShip()->GetParentShip();
    if ((pshipParent == NULL) || bViewOnly)
    {
        ShipID      shipID = GetIGCShip()->GetObjectID();
        assert(0 == g.fm.CbUsedSpaceInOutbox());
        if (!bViewOnly)
        {
            //Move the player to his destination
            BEGIN_PFM_CREATE(g.fm, pfmSetCluster, S, SET_CLUSTER)
            END_PFM_CREATE
            pfmSetCluster->sectorID = pcluster->GetObjectID();

            //Send the position of the parent ship if we are a child, otherwise our position
            IshipIGC*   pshipSource = pshipParent ? pshipParent : GetIGCShip();
            pshipSource->ExportShipUpdate(&(pfmSetCluster->shipupdate));
            pfmSetCluster->cookie = NewCookie();
        }

        {
            for (ShipLinkIGC*   pshiplink = pcluster->GetShips()->first(); pshiplink; pshiplink = pshiplink->next())
            {
                IshipIGC * pshipExist = pshiplink->data();
                if ((pshipExist != GetIGCShip()) && (pshipExist != pshipParent))
                {
                  IshipIGC*   pshipExistParent = pshipExist->GetParentShip();

                  //Tell the new player where the existing ship is/was
                  //provided the existing ship is not the child of some other ship
                  //and is not the parent of the new ship
                  if (pshipExistParent == NULL) 
                  {
                    CFSShip * pfsShipExist = (CFSShip *) pshipExist->GetPrivateData();

                    pfsShipExist->QueueLoadoutChange();

                    BEGIN_PFM_CREATE(g.fm, pfmSSU, S, SINGLE_SHIP_UPDATE)
                    END_PFM_CREATE

                    //Always use the ship update based on the server's current view of the universe
                    //(this shouldn't be a lot worse than anything the player sent and it is easier)
                    pshipExist->ExportShipUpdate(&(pfmSSU->shipupdate));

                    {
                        ImodelIGC*  pmodelTarget = pshipExist->GetCommandTarget(c_cmdCurrent);
                        if (pmodelTarget)
                        {
                            pfmSSU->otTarget = pmodelTarget->GetObjectType();
                            pfmSSU->oidTarget = pmodelTarget->GetObjectID();
                        }
                        else
                        {
                            pfmSSU->otTarget = NA;
                            pfmSSU->oidTarget = NA;
                        }                    
                    }
                    pfmSSU->bIsRipcording = pshipExist->fRipcordActive();
                  }
                }
            }
        }

        {
            // Let's build up a list of station updates so we can batch 'em down
            IsideIGC* pside = GetIGCShip()->GetSide();

            {
                const StationListIGC * pstnlist = pcluster->GetStations();
                int nStations = 0;
                {
                    //Count the number of visible stations
                    for (StationLinkIGC* pstnlink = pstnlist->first(); pstnlink; pstnlink = pstnlink->next())
                    {
                        IstationIGC*  pstation = pstnlink->data();
                        if (pstation->SeenBySide(pside))
                            nStations++;
                    }
                }

                if (nStations != 0)
                {
                    // tell the client what happened
                    BEGIN_PFM_CREATE(g.fm, pfmStationsUpdate, S, STATIONS_UPDATE)
                      FM_VAR_PARM(NULL, nStations * sizeof(StationState))
                    END_PFM_CREATE

                    StationState* pss = (StationState*)(FM_VAR_REF(pfmStationsUpdate, rgStationStates));
                    for (StationLinkIGC* pstnlink = pstnlist->first(); pstnlink; pstnlink = pstnlink->next())
                    {
                        IstationIGC * pstation = pstnlink->data();
                        if (pstation->SeenBySide(pside))
                        {
                            pss->stationID            = pstation->GetObjectID();
                            pss->bpHullFraction       = pstation->GetFraction();
                            (pss++)->bpShieldFraction = pstation->GetShieldFraction();
                        }
                    }
                }
            }

            {
                //Let's build up a list of probe updates and batch them on down (only damage & visible probes)
                const ProbeListIGC * pprblist = pcluster->GetProbes();
                int nProbes = 0;
                {
                    for (ProbeLinkIGC* pprblink = pprblist->first(); pprblink; pprblink = pprblink->next())
                    {
                        if (pprblink->data()->SeenBySide(pside))
                            nProbes++;
                    }
                }

                if (nProbes != 0)
                {
                    BEGIN_PFM_CREATE(g.fm, pfmProbesUpdate, S, PROBES_UPDATE)
                      FM_VAR_PARM(NULL, nProbes * sizeof(ProbeState))
                    END_PFM_CREATE

                    ProbeState* pps = (ProbeState*)(FM_VAR_REF(pfmProbesUpdate, rgProbeStates));
                    for (ProbeLinkIGC* pprblink = pprblist->first(); pprblink; pprblink = pprblink->next())
                    {
                        IprobeIGC * pprobe = pprblink->data();

                        if (pprobe->SeenBySide(pside))
                        {
                            pps->probeID        = pprobe->GetObjectID();
                            (pps++)->bpFraction = pprobe->GetFraction();
                        }
                    }
                }
            }

            {
                //Let's build up a list of asteroid updates and batch them on down
                const AsteroidListIGC * pastlist = pcluster->GetAsteroids();
                int nAsteroids = 0;
                {
                    for (AsteroidLinkIGC* pastlink = pastlist->first(); pastlink; pastlink = pastlink->next())
                    {
                        if (pastlink->data()->SeenBySide(pside))
                            nAsteroids++;
                    }
                }

                if (nAsteroids != 0)
                {
                    BEGIN_PFM_CREATE(g.fm, pfmAsteroidsUpdate, S, ASTEROIDS_UPDATE)
                      FM_VAR_PARM(NULL, nAsteroids * sizeof(AsteroidState))
                    END_PFM_CREATE

                    AsteroidState* pas = (AsteroidState*)(FM_VAR_REF(pfmAsteroidsUpdate, rgAsteroidStates));
                    for (AsteroidLinkIGC* pastlink = pastlist->first(); pastlink; pastlink = pastlink->next())
                    {
                        IasteroidIGC * pasteroid = pastlink->data();

                        if (pasteroid->SeenBySide(pside))
                        {
                            pas->asteroidID         = pasteroid->GetObjectID();
                            pas->ore                = short(pasteroid->GetOre());
                            pas->co.Set(pasteroid->GetOrientation());
                            (pas++)->bpFraction     = pasteroid->GetFraction();
                        }
                    }
                }
            }
        }
    
        //Also send the identical message to all of the ship's children]
		if (!bViewOnly) //TheRock 4-1-2010 fixed ships overlaying in f3 while on a turret
        {
            for (ShipLinkIGC*   psl = GetIGCShip()->GetChildShips()->first(); (psl != NULL); psl = psl->next())
            {
                CFSShip*    pfsShip = (CFSShip*)(psl->data()->GetPrivateData());
                assert (pfsShip->IsPlayer());
                pfsShip->GetPlayer()->ResetLastUpdate();
                g.fm.SendMessages(pfsShip->GetPlayer()->GetConnection(), FM_GUARANTEED, FM_DONT_FLUSH);
            }
        }
        g.fm.SendMessages(GetConnection(), FM_GUARANTEED, FM_FLUSH);
    }
  }
  else if (bViewOnly)
  {
    IstationIGC*    pstation = GetIGCShip()->GetStation();
    assert (pstation);

    CFSCluster*     pfsCluster = (CFSCluster*)(pstation->GetCluster()->GetPrivateData());
    SetDPGroup(pfsCluster, false);
  }
  else
    SetDPGroup(NULL, false);
}
Ejemplo n.º 21
0
HRESULT FedSrvLobbySite::OnAppMessage(FedMessaging * pthis, CFMConnection & cnxnFrom, FEDMESSAGE * pfm)
{
	HRESULT hr = S_OK;
	assert(&g.fmLobby == pthis);

	static CTempTimer timerOnAppMessage("in FedSrvLobbySite::OnAppMessage", .02f);
	timerOnAppMessage.Start();

	switch (pfm->fmid)
	{
		// KGJV #114 - reactivate create mission
	  //#if !defined(ALLSRV_STANDALONE)
	case FM_L_CREATE_MISSION_REQ:
	{
#if !defined(SRV_CHILD)
		CASTPFM(pfmCreateMissionReq, L, CREATE_MISSION_REQ, pfm);
		MissionParams mp;
		Strcpy(mp.strGameName, ZString(FM_VAR_REF(pfmCreateMissionReq, GameName)));// + "'s game");
		Strcpy(mp.szIGCStaticFile, ZString(FM_VAR_REF(pfmCreateMissionReq, IGCStaticFile)));
		mp.bScoresCount = false;// dont set to true till clients can change this!
		mp.iMaxImbalance = 0x7ffe;// added
		assert(!mp.Invalid());
#endif

		//Imago - give birth right here, feed it and off it goes...

#if defined(SRV_PARENT)
		//start missions as thier own process
		STARTUPINFO si;
		PROCESS_INFORMATION pi;
		ZeroMemory(&si, sizeof(si));
		si.cb = sizeof(si);
		ZeroMemory(&pi, sizeof(pi));
		char szCmd[255]; char szName[32]; char szFile[32];
		ZString strName = mp.strGameName;
		ZString strFile = mp.szIGCStaticFile;
		si.lpTitle = mp.strGameName;
		Strcpy(szName, (PCC)strName);
		Strcpy(szFile, (PCC)strFile);
		sprintf(szCmd, "AllSrv.exe \"%s\" %s %x", szName, szFile, pfmCreateMissionReq->dwCookie);

		// Create a NULL dacl to give "everyone" access
		SECURITY_DESCRIPTOR sd;
		SECURITY_ATTRIBUTES sa = { sizeof(sa), &sd, false };
		InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
		SetSecurityDescriptorDacl(&sd, true, NULL, FALSE);

		if (!CreateProcess(
			NULL,                   // No module name (use command line). 
			szCmd,
			NULL,
			NULL,
			FALSE,                  // Set handle inheritance to FALSE. 
			CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE, // we're destined to do amazing things
			NULL,                   // Use parent's environment block. 
			NULL,                   // Use parent's starting directory. 
			&si,                    // Pointer to STARTUPINFO structure.
			&pi)                   // Pointer to PROCESS_INFORMATION structure.
			)
		{
			debugf("CreateProcess failed (%d).\n", GetLastError());
		}

		// check to make sure the child is ready before restart
		char strFilename[10] = "\0";
		sprintf(strFilename, "%d.pid", pi.dwProcessId);
		HANDLE hFile = (HANDLE)CreateFile(strFilename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
		DWORD dwError = GetLastError();
		int i = 0;
		while (hFile == INVALID_HANDLE_VALUE || dwError == ERROR_FILE_NOT_FOUND) {
			if (i >= 14) //30s
				break;

			Sleep(2500);
			hFile = (HANDLE)CreateFile(strFilename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
			dwError = GetLastError();
			i++;
		}
		_Module.AddPID(pi.dwProcessId);
		CloseHandle(hFile);
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		g.bRestarting = true;
		PostQuitMessage(0);

#endif 

#if !defined(SRV_CHILD)
#if !defined(SRV_PARENT)
		// pkk 2011-07-24 - Create games only with IGCs from cores.txt
		bool ValidCore = false;
		for (int i = 0; i < g.cStaticCoreInfo; i++)
		{
			if (!strcmpi(mp.szIGCStaticFile, g.vStaticCoreInfo[i].cbIGCFile))
			{
				ValidCore = true;
				break; // quit loop
			}
		}
		if (ValidCore == true)
		{
			//Imago - start the mission in this thread as usual 
			FedSrvSite * psiteFedSrv = new FedSrvSite();
			CFSMission * pfsMissionNew = new CFSMission(mp, "", psiteFedSrv, psiteFedSrv, NULL, NULL);
			pfsMissionNew->SetCookie(pfmCreateMissionReq->dwCookie);
		}
		else
		{
			debugf("Lobby sent invalid core information %s, ignoring message\n", mp.szIGCStaticFile);
		}
		// pkk end
#endif
#endif
	} //Imago 6/22/08
	break;
	//#endif -- reactivate create mission

	case FM_L_NEW_MISSION_ACK:
	{
		CASTPFM(pfmNewMissionAck, L, NEW_MISSION_ACK, pfm);
		CFSMission * pfsm = CFSMission::GetMissionFromIGCMissionID(pfmNewMissionAck->dwIGCMissionID);
		if (pfsm)
		{
			pfsm->SetCookie(pfmNewMissionAck->dwCookie);
			// If we already have players (e.g. reconnect), tell the lobby who's in the game
			const ShipListIGC * plistShip = pfsm->GetIGCMission()->GetShips();
			for (ShipLinkIGC * plinkShip = plistShip->first(); plinkShip; plinkShip = plinkShip->next())
			{
				IshipIGC * pShip = plinkShip->data();
				CFSShip * pfsShip = GETFSSHIP(pShip);
				if (pfsShip->IsPlayer() && !pShip->IsGhost())
				{
					CFSPlayer* pfsPlayer = pfsShip->GetPlayer();
					BEGIN_PFM_CREATE(g.fmLobby, pfmPlayerJoined, S, PLAYER_JOINED)
						FM_VAR_PARM(pfsPlayer->GetName(), CB_ZTS)
						END_PFM_CREATE
						pfmPlayerJoined->dwMissionCookie = pfsm->GetCookie();
				}
			}
			HRESULT hr = pthis->SendMessages(pthis->GetServerConnection(), FM_GUARANTEED, FM_FLUSH);
		}
	}
	break;

	case FM_L_TOKEN:
	{
		CASTPFM(pfmToken, L, TOKEN, pfm);
		Strcpy(g.m_szToken, FM_VAR_REF(pfmToken, Token));
	}
	break;

	case FM_L_REMOVE_PLAYER:
	{
		CASTPFM(pfmRemovePlayer, L, REMOVE_PLAYER, pfm);
		CFSMission * pfsMission = CFSMission::GetMission(pfmRemovePlayer->dwMissionCookie);
		const char* szCharacterName = FM_VAR_REF(pfmRemovePlayer, szCharacterName);
		const char* szMessageParam = FM_VAR_REF(pfmRemovePlayer, szMessageParam);

		// try to find the player in question
		if (!pfsMission)
		{
			debugf("Asked to boot character %s from mission %x by lobby, "
				"but the mission was not found.\n",
				szCharacterName, pfmRemovePlayer->dwMissionCookie);
		}
		else if (!pfsMission->RemovePlayerByName(szCharacterName,
			(pfmRemovePlayer->reason == RPR_duplicateCDKey) ? QSR_DuplicateCDKey : QSR_DuplicateRemoteLogon,
			szMessageParam))
		{
			debugf("Asked to boot character %s from mission %x by lobby, "
				"but the character was not found.\n",
				szCharacterName, pfmRemovePlayer->dwMissionCookie);
		}
	}
	break;

	case FM_L_LOGON_SERVER_NACK:
	{
		char * szReason;

		CASTPFM(pfmLogonNack, L, LOGON_SERVER_NACK, pfm);

		szReason = FM_VAR_REF(pfmLogonNack, Reason);

		OnMessageBox(pthis, szReason ? szReason : "Error while try to log onto server.", "Allegiance Server Error", MB_SERVICE_NOTIFICATION);
		// TODO: consider firing out an event message
		PostQuitMessage(-1);
	}

	// BT - 12/21/2010 ACSS - The lobby server will relay the rank details back to the game server.
	case FM_LS_PLAYER_RANK:
	{
		CQLogonStats * pquery = new CQLogonStats(GotLogonDetails);
		CQLogonStatsData * pqd = pquery->GetData();

		CASTPFM(pfmPlayerRank, LS, PLAYER_RANK, pfm);

		Strcpy(pqd->szCDKey, FM_VAR_REF(pfmPlayerRank, szCDKey));
		Strcpy(pqd->szCharacterName, FM_VAR_REF(pfmPlayerRank, szCharacterName));
		Strcpy(pqd->szPassword, FM_VAR_REF(pfmPlayerRank, szPassword));
		Strcpy(pqd->szReason, FM_VAR_REF(pfmPlayerRank, szReason));

		pqd->characterID = pfmPlayerRank->characterID;
		pqd->fCanCheat = pfmPlayerRank->fCanCheat;
		pqd->fRetry = pfmPlayerRank->fRetry;
		pqd->dwCookie = pfmPlayerRank->dwCookie;
		pqd->fValid = pfmPlayerRank->fValid;
		pqd->dwConnectionID = pfmPlayerRank->dwConnectionID;

		pqd->rank = pfmPlayerRank->rank;
		pqd->sigma = pfmPlayerRank->sigma;
		pqd->mu = pfmPlayerRank->mu;
		pqd->commandRank = pfmPlayerRank->commandRank;
		pqd->commandSigma = pfmPlayerRank->commandSigma;
		pqd->commandMu = pfmPlayerRank->commandMu;

		PostThreadMessage(g.idReceiveThread, wm_sql_querydone, (WPARAM)NULL, (LPARAM)pquery);
		break;
	}

	break;
	}

	timerOnAppMessage.Stop("...for message type %s\n", g_rgszMsgNames[pfm->fmid]);
	return hr;
}
Ejemplo n.º 22
0
//------------------------------------------------------------------------------
Goal*       Mission4::CreateGoal03 (void)
{
    GoalList*       pGoalList = new GoalList;
    ImissionIGC*    pMission = trekClient.GetCore ();
    BuoyID          buoyID = pMission->GenerateNewBuoyID ();
    IshipIGC*       pShip = trekClient.GetShip ();

    // tm_4_07
    // The last means of communication is to receive an order from
    // your commander. I'm giving you a command to go to a
    // waypoint.
    pGoalList->AddGoal (CreatePlaySoundGoal (tm_4_07Sound));

    // wait half second
    pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f)));

    // tm_4_08
    // This red text denotes an objective from the commander.
    {
        Goal*   pGoal = CreatePlaySoundGoal (tm_4_08Sound);
        IwarpIGC*   pAleph = pMission->GetWarp (1030);
        Vector      delta = pAleph->GetPosition () - pShip->GetPosition ();
        Vector      position = pShip->GetPosition () + (delta * 0.25f) + (pAleph->GetOrientation ().GetUp () * (delta.Length () * 0.1f));
        pGoal->AddStartAction (new CreateWaypointAction (buoyID, position, 1030));
        pGoal->AddStartAction (new SetCommandAction (pShip, c_cmdQueued, OT_buoy, buoyID, c_cidGoto));
        //pGoal->AddStartAction (new SetHUDOverlayAction (CommandTrainingOverlay));
        pGoalList->AddGoal (pGoal);
    }

    // wait half second
    pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (0.5f)));

    // tm_4_08r
    // Press the INSERT key to accept this objective.
    {
        Goal*   pGoal = new Goal (new GetCommandCondition (trekClient.GetShip (), c_cidGoto));
        pGoal->AddStartAction (new MessageAction ("Press the INSERT key to accept the command."));
        pGoal->AddStartAction (new PlaySoundAction (tm_4_08rSound));
        pGoal->AddConstraintCondition (CreateTooLongCondition (30.0f, tm_4_08rSound));
        pGoalList->AddGoal (pGoal);
    }

    // wait a few seconds
    pGoalList->AddGoal (new Goal (new ElapsedTimeCondition (1.5f)));

    // tm_4_09
    // Good. Notice that autopilot is activated when you accept an
    // objective to fly you to your goal.
    {
        Goal*   pGoal = CreatePlaySoundGoal (tm_4_09Sound);
        //pGoal->AddStartAction (new SetHUDOverlayAction (NoTrainingOverlay));
        pGoalList->AddGoal (pGoal);
    }

    // (Wait for ship to get near waypoint)
    {
        Goal*   pGoal = new Goal (new ObjectWithinRadiusCondition (static_cast<ImodelIGC*> (pShip), OT_buoy, buoyID, 100.0f));
        pGoal->AddConstraintCondition (new ConditionalAction (new TrueCondition, new SetAutopilotAction (trekClient.GetShip (), true)));
        pGoalList->AddGoal (pGoal);
    }

    return new Goal (pGoalList);
}
void CFSPlayer::SetAutoDonate(CFSPlayer* pplayer, Money amount, bool bSend)
{
  assert (pplayer != this);

  ShipID    sidDonateBy = GetShipID();
  ShipID    sidDonateTo;

  IshipIGC* pship;
  if (pplayer)
  {
      pship = pplayer->GetIGCShip()->GetAutoDonate();
      if (pship == NULL)
          pship = pplayer->GetIGCShip();
      else
      {
          assert (pship->GetAutoDonate() == NULL);

          CFSPlayer*    pplayerNew = ((CFSShip*)(pship->GetPrivateData()))->GetPlayer();

          if (pplayerNew == this)
          {
              //We are trying to autodonate to someone who is already autodonating to us
              //Tell them to stop first (but don't send any messages)
              pplayer->SetAutoDonate(NULL, 0, false);

              //and then set our autodonate to go to them anyhow
              pship = pplayer->GetIGCShip();
          }
          else
          {
              //The person we would like to donate to was already donating to someone else
              //donate to who ever they were donating to.
              pplayer = pplayerNew;
          }
      }

      assert (pship->GetAutoDonate() == NULL);
      assert (pplayer->GetIGCShip() == pship);

      sidDonateTo = pship->GetObjectID();

      if (amount != 0)
      {
          TrapHack(GetMoney() >= amount);
          pplayer->SetMoney(amount + pplayer->GetMoney());
          SetMoney(GetMoney() - amount);
      }
  }
  else
  {
      pship = NULL;
      sidDonateTo = NA;
  }

  GetIGCShip()->SetAutoDonate(pship);

  BEGIN_PFM_CREATE(g.fm, pfmAD, S, AUTODONATE)
  END_PFM_CREATE
  pfmAD->sidDonateBy = sidDonateBy;
  pfmAD->sidDonateTo = sidDonateTo;
  pfmAD->amount = amount;

  if (bSend)
    g.fm.SendMessages(CFSSide::FromIGC(GetSide())->GetGroup(), FM_GUARANTEED, FM_FLUSH);
}
Ejemplo n.º 24
0
void        CclusterIGC::Update(Time now)
{
    if (now > m_lastUpdate)
    {
        float   dt = now - m_lastUpdate;

        bool    bStarted = m_pMission->GetMissionStage() == STAGE_STARTED;
        if (bStarted)
        {
            {
                //Have any stations launch docked drones
                for (StationLinkIGC*   l = m_stations.first();
                     (l != NULL);
                     l = l->next())
                {
                    IstationIGC*    pstation = l->data();

                    ShipLinkIGC*    pslNext;
                    for (ShipLinkIGC*   psl = pstation->GetShips()->first();
                         (psl != NULL);
                         psl = pslNext)
                    {
                        IshipIGC*   pship = psl->data();
                        pslNext = psl->next();             //Get the next link now since the ship may launch
                        // const MissionParams* pmp = m_pMission->GetMissionParams(); 04/08 commented out as not needed // mmf 10/07 added so we can get at bExperimental game type
                        if (pship->GetAutopilot() && (pship->GetPilotType() < c_ptPlayer))
                        {
                            //Docked non-players on autopilot never are observers/parents
                            assert (pship->GetParentShip() == NULL);
                            assert (pship->GetChildShips()->n() == 0);

							// mmf/yp 10/07 added this so drones launch when ordered to even if OkToLaunch might be false
							// intentionally left c_cidMine out of the list otherwise miners would launch with their AI
							// 'order' to mine
	
							if (pship->OkToLaunch(now) || (pship->GetCommandID(c_cmdAccepted) == c_cidGoto) ||
							   (pship->GetCommandID(c_cmdAccepted) == c_cidBuild) )
                                pship->SetStation(NULL);
							// if (pship->OkToLaunch(now))  // mmf orig code
							//	  pship->SetStation(NULL);
							
                        }
                    }
					
					//Are any ships buzzing around the stations that a side has yet to eye? #121 #120 Imago 8/10
					if (GetShips()->n() > 0 && pstation->GetRoidID() != NA) {
						Vector pos = pstation->GetRoidPos();
						float Sig = pstation->GetRoidSig();
						float Radius = pstation->GetRoidRadius();
						if (Sig != 0.0f && Radius != 0.0f) {
							//check if they have a ship eying where the rock would be
							for (ShipLinkIGC*   psl1 = GetShips()->first(); (psl1 != NULL); psl1 = psl1->next()) {
								IshipIGC*   pship = psl1->data();
								if (pship->GetParentShip() || pship->GetSide()->GetObjectID() == pstation->GetSide()->GetObjectID() || pstation->SeenBySide(pship->GetSide()) || !pstation->GetRoidSide(pship->GetSide()->GetObjectID()))
									continue;
								bool bEye = bSimpleEye(pship->GetHullType()->GetScannerRange(),GetMission()->GetModel(OT_ship,pship->GetObjectID()),Sig,pstation->GetSide()->GetGlobalAttributeSet().GetAttribute(c_gaSignature),Radius,pos);
								if (bEye) {
									//Turkey 3/13 #353: kill asteroids for all sides in that alliance.
									IsideIGC* pside1 = pship->GetSide();
									for (SideLinkIGC* sl = m_pMission->GetSides()->first(); sl != NULL; sl = sl->next())
									{
										IsideIGC* pside2 = sl->data();
										if (pside1->AlliedSides(pside1, pside2))
										{
											pstation->SetRoidSide(pside2->GetObjectID(),false);
											GetMission()->GetIgcSite()->KillAsteroidEvent(pstation->GetRoidID(),GetObjectID(),pside2);
										}
									}
								}
							}
						}
					}
                }
            }
            {
                m_fCost = m_pMission->GetFloatConstant(c_fcidBaseClusterCost);

                float   costLifepod = m_pMission->GetFloatConstant(c_fcidLifepodCost);
                float   costTurret = m_pMission->GetFloatConstant(c_fcidTurretCost);
                float   costPlayer = m_pMission->GetFloatConstant(c_fcidPlayerCost);
                float   costDrone = m_pMission->GetFloatConstant(c_fcidDroneCost);

                //Have miners and builders do any pre-plotted moves. Allow ships to suicide.
                ShipLinkIGC*        lNext;
                for (ShipLinkIGC*   l = m_ships.first();
                     (l != NULL);
                     l = lNext)
                {
                    IshipIGC*   s = l->data();
                    lNext = l->next();

                    if (s->GetPilotType() < c_ptPlayer)
                        m_fCost += costDrone;
                    else if (s->GetParentShip() != NULL)
                        m_fCost += costTurret;
                    else
                    {
                        IhullTypeIGC*   pht = s->GetBaseHullType();
                        assert (pht);
                        m_fCost += pht->HasCapability(c_habmLifepod)
                                  ? costLifepod
                                  : costPlayer;
                    }

                    s->PreplotShipMove(now);
                }

                if (m_fCost > 0.0f)
                {
                    m_fCost *= dt / m_pMission->GetFloatConstant(c_fcidClusterDivisor);
                }

                {
                    //Have all ships on autopilot plot their moves. Allow ships to suicide.
                    ShipLinkIGC*        lNext;
                    for (ShipLinkIGC*   l = m_ships.first();
                         (l != NULL);
                         l = lNext)
                    {
                        IshipIGC*   s = l->data();
                        lNext = l->next();

                        s->PlotShipMove(now);
                    }
                }
            }

            {
                //Have all ships execute their moves
                for (ShipLinkIGC*   l = m_ships.first();
                     (l != NULL);
                     l = l->next())
                {
                    IshipIGC*   s = l->data();

                    if (s->GetParentShip() == NULL)
                    {
                        s->ExecuteShipMove(now);
                    }
                }
            }
        }
        else
            m_fCost = 0.0f;

        {
            //Call the update method on all the contained models
            //models might self-terminate in the update and nuke earlier models in the update loop

            //NYI debugging variables
            //ObjectType  oldObjectType = NA;
            //ObjectType  newObjectType = NA;

            ModelLinkIGC*       lNext;
            for (ModelLinkIGC*     l = m_models.first();
                 (l != NULL);
                 l = lNext)
            {
                //oldObjectType = newObjectType;
                //newObjectType = l->data()->GetObjectType();

                lNext = l->next();

                l->data()->Update(now);
            }
        }

        if (m_data.activeF && bStarted)
        {
            {
                //Update the bounding boxes for all moving objects & projectiles
                for (ModelLinkIGC*     l = m_models.first();
                     (l != NULL);
                     l = l->next())
                {
                    l->data()->SetBB(m_lastUpdate, now, dt);
                }

                m_tMax = dt;
            }

            m_kdrStatic.update();
            m_kdrMoving.update();

            {
                //Cast rays through the KD tree for each object
                for (ModelLinkIGC*     l = m_modelsCastRay.first();
                     (l != NULL);
                     l = l->next())
                {
                    ImodelIGC*  m = l->data();

                    HitTest*    ht = m->GetHitTest();

                    if (!ht->GetDeadF())
                    {
                        m_kdrStatic.test(ht, &m_collisions);
                        m_kdrMoving.test(ht, &m_collisions);
                    }
                }
            }

            //Sort the collisions by the time they occur
            m_collisions.sort(0);

            //Process each collision (in order)
            {
                m_tOffset = 0.0f;
                for (m_collisionID = 0; (m_collisionID < m_collisions.n()); m_collisionID++)
                {
                    const CollisionEntry& entry = m_collisions[m_collisionID];

                    if (!(entry.m_pHitTest1->GetDeadF() || entry.m_pHitTest2->GetDeadF()))
                    {
                        Time    timeCollision = m_lastUpdate + (m_tOffset + entry.m_tCollision);

                        ImodelIGC*  pModelHitTest1 = (ImodelIGC*)(entry.m_pHitTest1->GetData());
                        assert (pModelHitTest1);

                        ImodelIGC*  pModelHitTest2 = (ImodelIGC*)(entry.m_pHitTest2->GetData());
                        assert (pModelHitTest2);

                        //Give each participant in the collision a chance to handle the collision
                        //but give the "1st" model first dibs.
                        if ((pModelHitTest1->GetCluster() == this) &&
                            (pModelHitTest2->GetCluster() == this))
                        {
                            pModelHitTest1->HandleCollision(timeCollision, entry.m_tCollision, entry, pModelHitTest2);
                        }
                    }
                }

                m_collisions.purge();
            }
            {
                //Apply any damage from mines
                //Kids always follow parents in the ship list, so go from back to front
                //so that the killing a parent doesn't mean hitting dead elements in the list
                ShipLinkIGC*        lTxen;
                for (ShipLinkIGC*   l = m_ships.last();
                     (l != NULL);
                     l = lTxen)
                {
                    IshipIGC*   s = l->data();
                    lTxen = l->txen();

                    s->ApplyMineDamage();
                }
            }

            //Move each object & projectile
            {
                for (ModelLinkIGC*  l = m_models.first();
                     (l != NULL);
                     l = l->next())
                {
                    l->data()->Move();
                }
            }

            if ((m_nPass++) % c_nPassesPerUpdate == 0)
            {
                for (ModelLinkIGC*  l = m_models.first();
                     (l != NULL);
                     l = l->next())
                {
                    l->data()->UpdateSeenBySide();
                }

                m_pMission->GetIgcSite()->ClusterUpdateEvent(this);
            }
        }


        //Draw and resolve any explosions
        if (m_nExplosions != 0)
        {
            const int c_maxDmgs = 500;
            IdamageIGC* pdmgs[c_maxDmgs];
            int         nDmgs = 0;

            //Copy the list of models in the sector that can be damaged into
            for (ModelLinkIGC*  l = m_modelsPickable.first();
                 (l != NULL);
                 l = l->next())
            {
                ImodelIGC*  pmodel = l->data();
                ObjectType  type = pmodel->GetObjectType();

                //Not everything that can take damage can be affected by an explosion.
                if ((type == OT_ship) || (type == OT_asteroid) ||
                    (type == OT_station) || (type == OT_missile) || (type == OT_probe))
                {
                    pmodel->AddRef();
                    pdmgs[nDmgs++] = (IdamageIGC*)pmodel;

                    if (nDmgs == c_maxDmgs)
                        break;
                }
            }

            ImineIGC*   pmines[c_maxDmgs];
            int         nMines = 0;
            {
                for (MineLinkIGC*   l = m_mines.first(); (l != NULL); l = l->next())
                {
                    ImineIGC*   pm = l->data();
                    pm->AddRef();
                    pmines[nMines++] = pm;

                    if (nMines == c_maxDmgs)
                        break;
                }
            }

            int i = 0;
            do
            {
                ExplosionData&  e = m_explosions[i];
                m_pClusterSite->AddExplosion(e.position, e.radius, e.explosionType);

                float   dt = (e.time - m_lastUpdate) - m_tOffset;

                //Now, the painful part: applying damage to everything in the sector that could be hit
                {
                    for (int j = 0; (j < nDmgs); j++)
                    {
                        IdamageIGC*  pTarget = pdmgs[j];
                        if (pTarget->GetCluster() == this)      //Make sure it wasn't already destroyed
                        {
                            //The target is still around
                            Vector  p = pTarget->GetPosition() + dt * pTarget->GetVelocity();
                            float   d = (e.position - p).Length() - pTarget->GetRadius();

                            if (d < e.radius)
                            {
                                float   amount = e.amount;
                                if (d > 0.0f)
                                {
                                    float   f = 1.0f - (d / e.radius);
                                    amount *= f * f;
                                }

                                pTarget->ReceiveDamage(e.damageType | c_dmgidNoWarn | c_dmgidNoDebris,
                                                       amount,
                                                       e.time,
                                                       p, e.position,
                                                       e.launcher);
                            }
                        }
                    }
                }
                {
                    for (int j = 0; (j < nMines); j++)
                    {
                        ImineIGC*  pTarget = pmines[j];
                        if (pTarget->GetCluster() == this)      //Make sure it wasn't already destroyed
                        {
                            //The target is still around
                            const Vector&   p = pTarget->GetPosition();
                            float           d = (e.position - p).Length() - pTarget->GetRadius();

                            if (d < e.radius)
                            {
                                float   amount = e.amount;
                                if (d > 0.0f)
                                {
                                    float   f = 1.0f - (d / e.radius);
                                    amount *= f * f;
                                }
                                pTarget->ReduceStrength(amount);
                            }
                        }
                    }
                }

                if (e.launcher)
                    e.launcher->Release();
            }
            while (++i < m_nExplosions);

            //Release all the cached pointers
            {
                while (--nDmgs >= 0)
                    pdmgs[nDmgs]->Release();
            }

            {
                while (--nMines >= 0)
                    pmines[nMines]->Release();
            }

            m_nExplosions = 0;
        }

        m_lastUpdate = now;
    }
}
Ejemplo n.º 25
0
        void Paint(ItemID pitemArg, Surface* psurface, bool bSelected, bool bFocus)
        {
            ImodelIGC* pDestination = (ImodelIGC*)pitemArg;
            IshipIGC* pship = NULL;
            IstationIGC* pstation = NULL;

            if (pDestination == NULL || trekClient.MyMission() == NULL)
                return;

            if (pDestination->GetObjectType() == OT_ship)
            {
                CastTo(pship, pDestination);
            }
            else
            {
                assert(pDestination->GetObjectType() == OT_station);
                CastTo(pstation, pDestination);
            }



            // draw the selection bar

            if (bSelected) {
                psurface->FillRect(
                    WinRect(0, 0, GetXSize(), GetYSize()),
                    Color::Red()
                );
            }

            TRef<IEngineFont> pfont;

            // show the place we currently are in bold
            if (pship && pship == trekClient.GetShip()->GetParentShip()
                || pstation && pstation == trekClient.GetShip()->GetStation())
            {
                pfont = TrekResources::SmallBoldFont();
            }
            else
            {
                pfont = TrekResources::SmallFont();
            }
         
            Color color;

            if (CanKeepCurrentShip(pDestination))
            {
                color = Color::White();
            }
            else
            {
                color = 0.75f * Color::White();
            }

            // draw the name

            psurface->DrawString(
                pfont, 
                color,
                WinPoint(0, 0),
                pship ? pship->GetName() : pstation->GetName()
            );


            // draw the ship type (if any)
            if (pship)
            {
                psurface->DrawString(
                    pfont, 
                    color,
                    WinPoint(m_viColumns[0], 0),
                    HullName(pDestination)
                );
            }
            
            // draw the cluster
            psurface->DrawString(
                pfont, 
                color,
                WinPoint(m_viColumns[1] + 2, 0),
                SectorName(pDestination)
            );

            // draw the total number of turrets (if appropriate)
            if (pship && NumTurrets(pship))
            {
                int nNumTurrets = NumTurrets(pship);

                if (nNumTurrets != 0)
                {
                    psurface->DrawString(
                        pfont,
                        color,
                        WinPoint(m_viColumns[2] + 2, 0), 
                        ZString((int)MannedTurrets(pship)) + ZString("/") + ZString(nNumTurrets)
                    );
                }
            }
        }