Esempio n. 1
0
bool SW_SonarPulse::Activate(SuperClass* pThis, const CellStruct &Coords, bool IsPlayer)
{
	SuperWeaponTypeClass *pType = pThis->Type;
	SWTypeExt::ExtData *pData = SWTypeExt::ExtMap.Find(pType);

	if(!pData) {
		return false;
	}

	auto Detect = [&](TechnoClass* pTechno) -> bool {
		// is this thing affected at all?
		if(!pData->IsHouseAffected(pThis->Owner, pTechno->Owner)) {
			return true;
		}

		if(!pData->IsTechnoAffected(pTechno)) {
			return true;
		}

		// actually detect this
		if(pTechno->CloakState) {
			pTechno->Uncloak(1);
			pTechno->NeedsRedraw = 1;
			TechnoExt::ExtData *pExt = TechnoExt::ExtMap.Find(pTechno);
			if(pTechno) {
				pExt->CloakSkipTimer.Start(pData->Sonar_Delay);
			}
		}

		return true;
	};

	auto range = GetRange(pData);

	if(range.WidthOrRange < 0) {
		// decloak everything regardless of ranges
		for(int i=0; i<TechnoClass::Array->Count; ++i) {
			Detect(TechnoClass::Array->GetItem(i));
		}

	} else {
		// decloak everything in range
		Helpers::Alex::DistinctCollector<TechnoClass*> items;
		Helpers::Alex::for_each_in_rect_or_range<TechnoClass>(Coords, range.WidthOrRange, range.Height, std::ref(items));
		items.for_each(Detect);

		// radar event only if this isn't full map sonar
		if(pData->SW_RadarEvent) {
			RadarEventClass::Create(RadarEventType::SuperweaponActivated, Coords);
		}
	}

	return true;
}
Esempio n. 2
0
bool SW_PsychicDominator::AbortFire(SuperClass* pSW, bool IsPlayer)
{
	// be one with Yuri! and only one.
	if(PsyDom::Active()) {
		if(IsPlayer) {
			SWTypeExt::ExtData *pData = SWTypeExt::ExtMap.Find(pSW->Type);
			pData->PrintMessage(pData->Message_Abort, pSW->Owner);
		}
		return true;
	}
	return false;
}
Esempio n. 3
0
bool SW_LightningStorm::AbortFire(SuperClass* pSW, bool IsPlayer)
{
	// only one Lightning Storm allowed
	if(LightningStorm::Active || LightningStorm::HasDeferment()) {
		if(IsPlayer) {
			SWTypeExt::ExtData *pData = SWTypeExt::ExtMap.Find(pSW->Type);
			pData->PrintMessage(pData->Message_Abort, pSW->Owner);
		}
		return true;
	}
	return false;
}
Esempio n. 4
0
void SWTypeExt::CreateChronoAnim(SuperClass *pThis, CoordStruct *pCoords, AnimTypeClass *pAnimType)
{
	ClearChronoAnim(pThis);
	
	if(pAnimType && pCoords) {
		if(auto pAnim = GameCreate<AnimClass>(pAnimType, *pCoords)) {
			SWTypeExt::ExtData *pData = SWTypeExt::ExtMap.Find(pThis->Type);
			pAnim->Invisible = !pData->IsAnimVisible(pThis->Owner);
			pThis->Animation = pAnim;
			PointerExpiredNotification::NotifyInvalidAnim.Add(pThis);
		}
	}
}
Esempio n. 5
0
void PsychicDominatorStateMachine::Update()
{
	// waiting. lurking in the shadows.
	if(this->Deferment > 0) {
		if(--this->Deferment) {
			return;
		}
	}

	SWTypeExt::ExtData *pData = SWTypeExt::ExtMap.Find(this->Super->Type);

	switch(PsyDom::Status) {
	case PsychicDominatorStatus::FirstAnim:
		{
			// here are the contents of PsyDom::Start().
			CellClass *pTarget = MapClass::Instance->GetCellAt(this->Coords);
			CoordStruct coords = pTarget->GetCoords();
			coords.Z += pData->Dominator_FirstAnimHeight;

			AnimClass* pAnim = nullptr;
			if(AnimTypeClass* pAnimType = pData->Dominator_FirstAnim.Get(RulesClass::Instance->DominatorFirstAnim)) {
				pAnim = GameCreate<AnimClass>(pAnimType, coords);
			}
			PsyDom::Anim = pAnim;
		
			auto sound = pData->SW_ActivationSound.Get(RulesClass::Instance->PsychicDominatorActivateSound);
			if(sound != -1) {
				VocClass::PlayAt(sound, coords, nullptr);
			}

			pData->PrintMessage(pData->Message_Activate, this->Super->Owner);
			
			PsyDom::Status = PsychicDominatorStatus::Fire;

			// most likely LightUpdateTimer
			ScenarioClass::Instance->AmbientTimer.Start(1);
			ScenarioClass::UpdateLighting();

			return;
		}
	case PsychicDominatorStatus::Fire:
		{
			// wait for some percentage of the first anim to be
			// played until we strike.
			AnimClass* pAnim = PsyDom::Anim;
			if(pAnim) {
				int currentFrame = pAnim->Animation.Value;
				short frameCount = pAnim->Type->GetImage()->Frames;
				int percentage = pData->Dominator_FireAtPercentage.Get(RulesClass::Instance->DominatorFireAtPercentage);
				if(frameCount * percentage / 100 > currentFrame) {
					return;
				}
			}

			PsyDom::Fire();

			PsyDom::Status = PsychicDominatorStatus::SecondAnim;
			return;
		}
	case PsychicDominatorStatus::SecondAnim:
		{
			// wait for the second animation to finish. (there may be up to
			// 10 frames still to be played.)
			AnimClass* pAnim = PsyDom::Anim;
			if(pAnim) {
				int currentFrame = pAnim->Animation.Value;
				short frameCount = pAnim->Type->GetImage()->Frames;

				if(frameCount - currentFrame > 10) {
					return;
				}
			}

			PsyDom::Status = PsychicDominatorStatus::Reset;
			return;
		}
	case PsychicDominatorStatus::Reset:
		{
			// wait for the last frame... WTF? 
			AnimClass* pAnim = PsyDom::Anim;
			if(pAnim) {
				int currentFrame = pAnim->Animation.Value;
				short frameCount = pAnim->Type->GetImage()->Frames;

				if(frameCount - currentFrame > 1) {
					return;
				}
			}

			PsyDom::Status = PsychicDominatorStatus::Over;

			PsyDom::Coords = CellStruct::Empty;
			PsyDom::Anim = nullptr;
			ScenarioClass::UpdateLighting();

			return;
		}
	case PsychicDominatorStatus::Over:
		{
			// wait for the light to go away.
			if(ScenarioClass::Instance->AmbientCurrent != ScenarioClass::Instance->AmbientTarget) {
				return;
			}

			// clean up
			SW_PsychicDominator::CurrentPsyDom = nullptr;
			PsyDom::Status = PsychicDominatorStatus::Inactive;
			ScenarioClass::UpdateLighting();
			this->Clock.TimeLeft = 0;
		}
	}
}