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); } } }
IclusterIGC* CPigShip::FindCluster(BSTR bstrSector) { if (!BSTRLen(bstrSector)) return NULL; USES_CONVERSION; LPCSTR pszSector = OLE2CA(bstrSector); const ClusterListIGC* pClusters = GetIGC()->GetMission()->GetClusters(); for (ClusterLinkIGC* it = pClusters->first(); it; it = it->next()) { IclusterIGC* pCluster = it->data(); if (0 == _stricmp(pCluster->GetName(), pszSector)) return pCluster; } return NULL; }
static ZString SectorName(ImodelIGC* pmodel) { IclusterIGC* psector; if (pmodel->GetObjectType() == OT_ship) { PlayerInfo* pplayer = (PlayerInfo*)((IshipIGC*)pmodel)->GetPrivateData(); psector = trekClient.GetCore()->GetCluster(pplayer->LastSeenSector()); } else { psector = pmodel->GetCluster(); } if (psector == NULL) return "unknown"; else return psector->GetName(); }
HRESULT CbuoyIGC::Initialize(ImissionIGC* pMission, Time now, const void* data, unsigned int dataSize) { TmodelIGC<IbuoyIGC>::Initialize(pMission, now, data, dataSize); ZRetailAssert (data && (dataSize == sizeof(DataBuoyIGC))); DataBuoyIGC* dataBuoy = (DataBuoyIGC*)data; LoadDecal("buoy", "buoyicon", Color(1.0f, 1.0f, 1.0f, 1.0f), false, 1.0f, c_mtStatic | c_mtPredictable); SetRadius(20.0f); SetPosition(dataBuoy->position); { Rotation r(Vector(0.0f, 0.0f, 1.0f), 0.5f); SetRotation(r); } m_type = dataBuoy->type; m_buoyID = (dataBuoy->buoyID == NA) ? pMission->GenerateNewBuoyID() : dataBuoy->buoyID; IclusterIGC* pcluster = pMission->GetCluster(dataBuoy->clusterID); if (dataBuoy->type == c_buoyCluster) SetSecondaryName(pcluster->GetName()); else SetSecondaryName("waypoint"); SetMass(0.0f); pMission->AddBuoy(this); SetCluster(pcluster); return S_OK; }
ImodelIGC* CPigShip::FindModel(BSTR bstrModel) { if (!BSTRLen(bstrModel)) return NULL; USES_CONVERSION; LPCSTR pszModel = OLE2CA(bstrModel); const ClusterListIGC* pClusters = GetIGC()->GetMission()->GetClusters(); for (ClusterLinkIGC* itCluster = pClusters->first(); itCluster; itCluster = itCluster->next()) { IclusterIGC* pCluster = itCluster->data(); const ModelListIGC* pModels = pCluster->GetModels(); for (ModelLinkIGC* it = pModels->first(); it; it = it->next()) { ImodelIGC* pModel = it->data(); if (0 == _stricmp(GetModelName(pModel), pszModel)) return pModel; } } return NULL; }
HRESULT CprobeIGC::Initialize(ImissionIGC* pMission, Time now, const void* data, int dataSize) { assert (pMission); m_pMission = pMission; ZRetailAssert (data && (dataSize > sizeof(DataProbeBase))); { DataProbeBase* dataProbeBase = (DataProbeBase*)data; if ((dataProbeBase->exportF) && ((DataProbeExport*)dataProbeBase)->createNow) { m_time0 = now; } else { m_time0 = pMission->GetIgcSite()->ClientTimeFromServerTime(dataProbeBase->time0); } TmodelIGC<IprobeIGC>::Initialize(pMission, now, data, dataSize); IshipIGC* pshipLauncher; IsideIGC* pside; IclusterIGC* pcluster; if (dataProbeBase->exportF) { assert (dataSize == sizeof(DataProbeExport)); DataProbeExport* dataProbeExport = (DataProbeExport*)dataProbeBase; m_probeType = (IprobeTypeIGC*)(pMission->GetExpendableType(dataProbeExport->probetypeID)); pside = pMission->GetSide(dataProbeExport->sideID); pcluster = pMission->GetCluster(dataProbeExport->clusterID); pshipLauncher = pside->GetShip(dataProbeExport->shipID); if (m_probeType->HasCapability(c_eabmShootOnlyTarget)) m_target = pMission->GetModel(dataProbeExport->otTarget, dataProbeExport->oidTarget); } else { assert (dataSize == sizeof(DataProbeIGC)); DataProbeIGC* dataProbe = (DataProbeIGC*)dataProbeBase; m_probeType = dataProbe->pprobetype; pside = dataProbe->pside; pcluster = dataProbe->pcluster; pshipLauncher = dataProbe->pship; if (m_probeType->HasCapability(c_eabmShootOnlyTarget)) m_target = dataProbe->pmodelTarget; } assert (m_probeType); assert (m_probeType->GetObjectType() == OT_probeType); m_probeType->AddRef(); m_ammo = m_probeType->GetAmmo(); DataProbeTypeIGC* dataProbeType = (DataProbeTypeIGC*)(m_probeType->GetData()); m_projectileType = m_probeType->GetProjectileType(); if (m_projectileType) { m_projectileType->AddRef(); m_bSeenByAll = false; if (pshipLauncher && (dataProbeType->launcherDef.price == 0)) m_launcher = pshipLauncher; } assert (pcluster); //Load the model for the probe assert (iswalpha(dataProbeType->modelName[0])); HRESULT hr = Load(0, dataProbeType->modelName, dataProbeType->textureName, dataProbeType->iconName, c_mtDamagable | c_mtHitable | c_mtStatic | c_mtSeenBySide | c_mtPredictable | c_mtScanner); assert (SUCCEEDED(hr)); SetRadius(dataProbeType->radius); SetSignature(dataProbeType->signature); SetSide(pside); SetSecondaryName(dataProbeType->launcherDef.name); { //Parts get a random orientation Vector v = Vector::RandomDirection(); Orientation o(v); SetOrientation(o); } //lifespan == 0 => immortal probe that can hit until it gets terminated on the next update; this is bad assert (dataProbeType->lifespan > 0.0f); m_timeExpire = m_time0 + dataProbeType->lifespan; assert (m_timeExpire != m_time0); m_nextFire = m_time0 + (m_probeType->HasCapability(c_eabmQuickReady) ? 5.0f //5 second delay : 30.0f); //30 second delay before we start to shoot assert (GetSide()); SetMass(0.0f); m_probeID = dataProbeBase->probeID; SetPosition(dataProbeBase->p0); SetCluster(pcluster); pMission->AddProbe(this); if ((dataProbeType->dtRipcord >= 0.0f) && ((GetMyLastUpdate() - m_time0) >= dataProbeType->dtRipcord)) { pMission->GetIgcSite()->ActivateTeleportProbe(this); } // mmf 04/08 destroy any probe near aleph (warp) tip as this is viewed as an exploit as the enemy // often cannot delete it // // if (experimental game type) mmf const MissionParams* pmp = pMission->GetMissionParams(); if (pmp->bExperimental) { Vector dV, probeV, warpV, tipdistV; Vector bV, tipV; float warp_rad, distance; Orientation warp_orient; Rotation warp_rot; // loop through list of warps for (WarpLinkIGC* pwl = pcluster->GetWarps()->first(); (pwl != NULL); pwl = pwl->next()) { IwarpIGC* pwarp = pwl->data(); warp_rad = pwarp->GetRadius(); warp_orient = pwarp->GetOrientation(); warpV = pwarp->GetPosition(); probeV = this->GetPosition(); dV= warpV-probeV; distance = dV.Length(); warp_rot = pwarp->GetRotation(); // if rotating (i.e. rotation is other than 0 0 1 0) abort check if (!((warp_rot.x()==0) && (warp_rot.y()==0) && (warp_rot.z()==1) && (warp_rot.angle()==0))) break; if (distance < (warp_rad * 2) ) { // only check if close to tip if reasonably close to warp center bV = warp_orient.GetBackward(); tipV = warpV + (bV*warp_rad); tipdistV = tipV-probeV; distance = tipdistV.Length(); if (distance < 30) { debugf("Destroying probe as it was dropped too close (within 30) of aleph(warp) tip. dist = $f\n",distance); return S_FALSE; // this will destroy the probe } } } } // mmf end // mmf added code to detect tp drop near asteroid and if too close destroy it // leave ActivateTeleProbe code above so enemy is alerted to the drop even though it may be destroyed if (dataProbeType->dtRipcord >= 0.0f) // check to see if this is a teleprobe { Vector dV; float asteroid_rad, distance; // loop through list of asteroids for (AsteroidLinkIGC* pal = pcluster->GetAsteroids()->first(); (pal != NULL); pal = pal->next()) { asteroid_rad = (pal->data()->GetRadius()); dV=this->GetPosition() - pal->data()->GetPosition(); distance = dV.Length(); if (distance < (asteroid_rad-5)) { debugf("Teleprobe dropped too close to asteroid (within -5) destroying probe. dist = %f, asteroid rad = %f\n", distance,asteroid_rad); // this->Terminate(); should be terminated when missionigc processes S_FALSE return S_FALSE; } } } // mmf end } return S_OK; }
void CprobeIGC::Update(Time now) { if (now >= m_timeExpire) GetMyMission()->GetIgcSite()->KillProbeEvent(this); else { { float dt = m_probeType->GetRipcordDelay(); if (dt >= 0.0f) { Time timeActivate = m_time0 + dt; if ((GetMyLastUpdate() < timeActivate) && (now >= timeActivate)) { GetMyMission()->GetIgcSite()->ActivateTeleportProbe(this); } } } if (m_projectileType) { if (m_nextFire < now) { IclusterIGC* pcluster = GetCluster(); assert (pcluster); //We'll be able to take a shot float lifespan = GetProjectileLifespan(); IsideIGC* pside = GetSide(); const Vector& myPosition = GetPosition(); float speed = m_projectileType->GetSpeed(); if (m_ammo != 0) speed *= GetSide()->GetGlobalAttributeSet().GetAttribute(c_gaSpeedAmmo); float accuracy = GetAccuracy(); float dtimeBurst = GetDtBurst(); float dispersion = m_probeType->GetDispersion(); Time lastUpdate = GetMyLastUpdate(); if (m_nextFire < lastUpdate) m_nextFire = lastUpdate; assert (m_nextFire <= now); TmodelIGC<IprobeIGC>::Update(now); float dtUpdate = m_nextFire - lastUpdate; //If we have a target ... find the closest enemy ship who is a valid target ExpendableAbilityBitMask eabm = m_probeType->GetCapabilities(); float distance2Min = speed * lifespan / 1.2f; distance2Min *= distance2Min; Vector directionMin; ImodelIGC* pmodelTarget = NULL; if (eabm & c_eabmShootOnlyTarget) { if (m_target && (m_target->GetCluster() == pcluster)) { ObjectType type = m_target->GetObjectType(); ValidTarget((type == OT_ship) ? ((IshipIGC*)(ImodelIGC*)m_target)->GetSourceShip() : m_target, pside, myPosition, dtUpdate, accuracy, speed, lifespan, type, &pmodelTarget, &distance2Min, &directionMin); } } else { if (eabm & c_eabmShootShips) { //Threats to stations get highest priority GetTarget((const ModelListIGC*)(pcluster->GetShips()), pside, myPosition, dtUpdate, accuracy, speed, lifespan, OT_ship, &pmodelTarget, &distance2Min, &directionMin); } if (eabm & c_eabmShootMissiles) { GetTarget((const ModelListIGC*)(pcluster->GetMissiles()), pside, myPosition, dtUpdate, accuracy, speed, lifespan, OT_missile, &pmodelTarget, &distance2Min, &directionMin); } if (eabm & c_eabmShootStations) { GetTarget((const ModelListIGC*)(pcluster->GetStations()), pside, myPosition, dtUpdate, accuracy, speed, lifespan, OT_station, &pmodelTarget, &distance2Min, &directionMin); } } if (pmodelTarget) { if (m_launcher && (m_launcher->GetMission() != GetMyMission())) m_launcher = NULL; //It is going to shoot ... make it visible to everyone in the sector if (!m_bSeenByAll) { m_bSeenByAll = true; for (SideLinkIGC* psl = m_pMission->GetSides()->first(); (psl != NULL); psl = psl->next()) { IsideIGC* psideOther = psl->data(); if (!SeenBySide(psideOther)) { //Does this side have any scanners in the sector? ClusterSite* pcs = pcluster->GetClusterSite(); const ScannerListIGC* psl = pcs->GetScanners(psideOther->GetObjectID()); if ((psl->n() != 0) || (m_pMission->GetMissionParams()->bAllowAlliedViz && psideOther->AlliedSides(psideOther,pside))) //ALLY 7/3/09 VISIBILITY 7/11/09 imago SetSideVisibility(psideOther, true); else m_bSeenByAll = false; } } } //We have a target ... fire along directionMin (modulo dispersion) Orientation o = GetOrientation(); o.TurnTo(directionMin); SetOrientation(o); Vector position = myPosition + m_probeType->GetEmissionPt() * o; DataProjectileIGC dataProjectile; dataProjectile.projectileTypeID = m_projectileType->GetObjectID(); short nShots = 0; do { //Permute the "forward" direction slightly by a random amount dataProjectile.forward = directionMin; if (dispersion != 0.0f) { float r = random(0.0f, dispersion); float a = random(0.0f, 2.0f * pi); dataProjectile.forward += (r * cos(a)) * o.GetRight(); dataProjectile.forward += (r * sin(a)) * o.GetUp(); dataProjectile.forward.SetNormalize(); } //We never move, so skip all the velocity calculations dataProjectile.velocity = speed * dataProjectile.forward; dataProjectile.lifespan = lifespan; IprojectileIGC* p = (IprojectileIGC*)(m_pMission->CreateObject(m_nextFire, OT_projectile, &dataProjectile, sizeof(dataProjectile))); assert (p); { p->SetLauncher(m_launcher ? ((ImodelIGC*)m_launcher) : ((ImodelIGC*)this)); p->SetPosition(position); p->SetCluster(pcluster); p->Release(); } nShots++; m_nextFire += dtimeBurst; } while (m_nextFire < now); if (m_ammo > 0) { m_ammo -= nShots; if (m_ammo <= 0) { m_ammo = 0; GetMyMission()->GetIgcSite()->KillProbeEvent(this); } } } else { //No shots this cycle m_nextFire = now; } } } TmodelIGC<IprobeIGC>::Update(now); } }