示例#1
0
void CFlameProjectile::Update()
{
	if (!luaMoveCtrl) {
		SetPosition(pos + speed);
		UpdateGroundBounce();
		SetVelocityAndSpeed(speed + spread);
	}

	UpdateInterception();

	radius = radius + weaponDef->sizeGrowth;
	sqRadius = radius * radius;
	drawRadius = radius * weaponDef->collisionSize;

	curTime += invttl;
	if (curTime > physLife) {
		checkCol = false;
	}
	if (curTime > 1) {
		curTime = 1;
		deleteMe = true;
	}

	explGenHandler->GenExplosion(cegID, pos, speed, curTime, 0.0f, 0.0f, NULL, NULL);
}
示例#2
0
void CLightningProjectile::Update()
{
	if (--ttl <= 0) {
		deleteMe = true;
	} else {
		explGenHandler->GenExplosion(cegID, startPos + ((targetPos - startPos) / ttl), (targetPos - startPos), 0.0f, displacements[0], 0.0f, NULL, NULL);
	}

	for (size_t d = 1; d < displacements_size; ++d) {
		displacements[d]  += (gs->randFloat() - 0.5f) * 0.3f;
		displacements2[d] += (gs->randFloat() - 0.5f) * 0.3f;
	}

	UpdateInterception();
}
void CLargeBeamLaserProjectile::Update()
{
	if ((--ttl) <= 0) {
		deleteMe = true;
	} else {
		for (int i = 0; i < 3; i++) {
			coreColStart[i] = (unsigned char) (coreColStart[i] * decay);
			edgeColStart[i] = (unsigned char) (edgeColStart[i] * decay);
		}

		explGenHandler->GenExplosion(cegID, startPos + ((targetPos - startPos) / ttl), (targetPos - startPos), 0.0f, flaresize, 0.0f, NULL, NULL);
	}

	UpdateInterception();
}
void CLargeBeamLaserProjectile::Update()
{
	if (ttl > 0) {
		for (int i = 0; i < 3; i++) {
			coreColStart[i] = (unsigned char) (coreColStart[i] * decay);
			edgeColStart[i] = (unsigned char) (edgeColStart[i] * decay);
		}

		gCEG->Explosion(cegID, startpos + ((targetPos - startpos) / ttl), 0.0f, flaresize, NULL, 0.0f, NULL, targetPos - startpos);
		ttl--;
	}
	else {
		deleteMe = true;
	}

	UpdateInterception();
}
示例#5
0
void CBeamLaserProjectile::Update()
{
	ttl--;

	if (ttl <= 0) {
		deleteMe = true;
	} else {
		for (int i = 0; i < 3; i++) {
			coreColStart[i] *= decay;
			coreColEnd[i]   *= decay;
			edgeColStart[i] *= decay;
			edgeColEnd[i]   *= decay;
		}

		gCEG->Explosion(cegID, startpos + ((targetPos - startpos) / ttl), 0.0f, flaresize, 0x0, 0.0f, 0x0, targetPos - startpos);
	}

	UpdateInterception();
}
示例#6
0
void CFlameProjectile::Update()
{
	if (!luaMoveCtrl) {
		SetPosition(pos + speed);
		UpdateGroundBounce();
		SetVelocityAndSpeed(speed + spread);
	}

	UpdateInterception();

	radius = radius + weaponDef->sizeGrowth;
	sqRadius = radius * radius;
	drawRadius = radius * weaponDef->collisionSize;

	curTime += invttl;
	checkCol &= (curTime <= physLife);
	curTime = std::min(curTime, 1.0f);
	deleteMe |= (curTime >= 1.0f);

	explGenHandler->GenExplosion(cegID, pos, speed, curTime, 0.0f, 0.0f, nullptr, nullptr);
}
示例#7
0
void CFireBallProjectile::Update()
{
	if (checkCol) {
		if (!luaMoveCtrl) {
			pos += speed;

			if (weaponDef->gravityAffected) {
				speed.y += mygravity;
			}
		}

		if (weaponDef->noExplode && TraveledRange()) {
			checkCol = false;
		}

		EmitSpark();
	} else {
		if (sparks.empty()) {
			deleteMe = true;
		}
	}

	for (unsigned int i = 0; i < sparks.size(); i++) {
		sparks[i].ttl--;
		if (sparks[i].ttl == 0) {
			sparks.pop_back();
			break;
		}
		if (checkCol) {
			sparks[i].pos += sparks[i].speed;
		}
		sparks[i].speed *= 0.95f;
	}

	gCEG->Explosion(cegID, pos, ttl, !sparks.empty() ? sparks[0].size : 0.0f, NULL, 0.0f, NULL, speed);
	UpdateGroundBounce();
	UpdateInterception();
}
void CExplosiveProjectile::Update()
{
	CProjectile::Update();

	if (--ttl == 0) {
		Collision();
	} else {
		if (ttl > 0) {
			explGenHandler->GenExplosion(cegID, pos, speed, ttl, damages->damageAreaOfEffect, 0.0f, NULL, NULL);
		}
	}

	curTime += invttl;
	curTime = std::min(curTime, 1.0f);

	if (weaponDef->noExplode && TraveledRange()) {
		CProjectile::Collision();
		return;
	}

	UpdateGroundBounce();
	UpdateInterception();
}
示例#9
0
void CFlameProjectile::Update()
{
	if (!luaMoveCtrl) {
		pos += speed;
		UpdateGroundBounce();
		speed += spread;
	}
	UpdateInterception();

	radius = radius + weaponDef->sizeGrowth;
	sqRadius = radius * radius;
	drawRadius = radius * weaponDef->collisionSize;

	curTime += invttl;
	if (curTime > physLife) {
		checkCol = false;
	}
	if (curTime > 1) {
		curTime = 1;
		deleteMe = true;
	}

	gCEG->Explosion(cegID, pos, curTime, 0.0f, NULL, 0.0f, NULL, speed);
}
示例#10
0
void CEmgProjectile::Update()
{
	// disable collisions when ttl reaches 0 since the
	// projectile will travel far past its range while
	// fading out
	checkCol &= (ttl >= 0);
	deleteMe |= (intensity <= 0.0f);

	if (!luaMoveCtrl) {
		pos += speed;
	}
	if (ttl <= 0) {
		// fade out over the next 10 frames at most
		intensity -= 0.1f;
		intensity = std::max(intensity, 0.0f);
	} else {
		explGenHandler->GenExplosion(cegID, pos, speed, ttl, intensity, 0.0f, NULL, NULL);
	}

	UpdateGroundBounce();
	UpdateInterception();

	--ttl;
}
示例#11
0
void CWeaponProjectile::Update()
{
	CProjectile::Update();
	UpdateGroundBounce();
	UpdateInterception();
}
示例#12
0
void CStarburstProjectile::Update()
{
    ttl--;
    uptime--;
    missileAge++;

    if (target && weaponDef->tracks && owner()) {
        targetPos = target->pos;
        CUnit* u = dynamic_cast<CUnit*>(target);
        if (u) {
            targetPos = helper->GetUnitErrorPos(u, owner()->allyteam, true);
        }
    }

    if (uptime > 0) {
        if (!luaMoveCtrl) {
            if (curSpeed < maxSpeed) {
                curSpeed += weaponDef->weaponacceleration;
            }

            speed = dir * curSpeed;
        }
    } else if (doturn && ttl > 0 && distanceToTravel > 0.0f) {
        if (!luaMoveCtrl) {
            float3 dif(targetPos - pos);
            dif.Normalize();
            dif += aimError;
            dif.Normalize();

            if (dif.dot(dir) > 0.99f) {
                dir = dif;
                doturn = false;
            } else {
                dif = dif - dir;
                dif -= dir * (dif.dot(dir));
                dif.Normalize();

                if (weaponDef->turnrate != 0) {
                    dir += dif * weaponDef->turnrate;
                } else {
                    dir += dif * 0.06;
                }

                dir.Normalize();
            }
            speed = dir * curSpeed;
            if (distanceToTravel != MAX_PROJECTILE_RANGE) {
                distanceToTravel -= speed.Length2D();
            }
        }
    } else if (ttl > 0 && distanceToTravel > 0.0f) {
        if (!luaMoveCtrl) {
            if (curSpeed < maxSpeed) {
                curSpeed += weaponDef->weaponacceleration;
            }

            float3 dif = (targetPos - pos).Normalize();

            if (dif.dot(dir) > maxGoodDif) {
                dir = dif;
            } else {
                dif = dif - dir;
                dif -= dir * (dif.dot(dir));
                dif.SafeNormalize();
                dir += dif * tracking;
                dir.SafeNormalize();
            }

            speed = dir * curSpeed;

            if (distanceToTravel != MAX_PROJECTILE_RANGE) {
                distanceToTravel -= speed.Length2D();
            }
        }
    } else {
        if (!luaMoveCtrl) {
            dir.y += mygravity;
            dir.Normalize();
            curSpeed -= mygravity;
            speed = dir * curSpeed;
        }
    }

    if (!luaMoveCtrl) {
        pos += speed;
    }

    if (ttl > 0) {
        gCEG->Explosion(cegID, pos, ttl, areaOfEffect, NULL, 0.0f, NULL, dir);
    }


    {
        curTracerPart++;
        curTracerPart %= NUM_TRACER_PARTS;
        TracerPart* tracerPart = (GML::SimEnabled()) ? (TracerPart* volatile)(&tracerParts[curTracerPart]) : &tracerParts[curTracerPart];
        tracerPart->pos = pos;
        tracerPart->dir = dir;
        tracerPart->speedf = curSpeed;

        int newsize = 0;
        for (float aa = 0; aa < curSpeed + 0.6f; aa += TRACER_PARTS_STEP, ++newsize) {
            const float ageMod = (missileAge < 20) ? 1.0f : (0.6f + (rand() * 0.8f) / RAND_MAX);

            if (tracerPart->ageMods.size() <= newsize) {
                tracerPart->ageMods.push_back(ageMod);
            } else {
                tracerPart->ageMods[newsize] = ageMod;
            }
        }

        if (tracerPart->ageMods.size() != newsize) {
            tracerPart->ageMods.resize(newsize);
        }
    }

    age++;
    numParts++;

    if (weaponDef->visuals.smokeTrail && !(age & 7)) {
        if (curCallback) {
            curCallback->drawCallbacker = 0;
        }

        curCallback = new CSmokeTrailProjectile(pos, oldSmoke, dir, oldSmokeDir,
                                                owner(), age == 8, false, 7, SMOKE_TIME, 0.7f, drawTrail, this,
                                                weaponDef->visuals.texture2);

        oldSmoke = pos;
        oldSmokeDir = dir;
        numParts = 0;
        useAirLos = curCallback->useAirLos;

        if (!drawTrail) {
            const float3 camDir = (pos - camera->pos).ANormalize();
            const float camDist = (camera->pos.distance(pos) * 0.2f + (1 - math::fabs(camDir.dot(dir))) * 3000);

            drawTrail = (camDist > 300.0f);
        }
    }

    UpdateInterception();
}
void CTorpedoProjectile::Update()
{
	// tracking only works when we are underwater
	if (!weaponDef->submissile && pos.y > 0.0f) {
		if (!luaMoveCtrl) {
			// must update dir and speed.w here
			SetVelocityAndSpeed(speed + (UpVector * mygravity));
		}
	} else {
		if (--ttl > 0) {
			if (!luaMoveCtrl) {
				float3 targetVel;

				if (speed.w < maxSpeed)
					speed.w += std::max(0.2f, tracking);

				if (target != NULL) {
					const CSolidObject* so = dynamic_cast<const CSolidObject*>(target);
					const CWeaponProjectile* po = dynamic_cast<const CWeaponProjectile*>(target);

					targetPos = target->pos;

					if (so != NULL) {
						targetPos = so->aimPos;
						targetVel = so->speed;

						if (allyteamID != -1 && pos.SqDistance(so->aimPos) > Square(150.0f)) {
							const CUnit* u = dynamic_cast<const CUnit*>(so);

							if (u != NULL) {
								targetPos = u->GetErrorPos(allyteamID, true);
							}
						}
					}
					if (po != NULL) {
						targetVel = po->speed;
					}
				}

				if (!weaponDef->submissile && targetPos.y > 0.0f) {
					targetPos.y = 0.0f;
				}

				const float3 targetLeadVec = targetVel * (pos.distance(targetPos) / maxSpeed) * 0.7f;
				const float3 targetLeadDir = (targetPos + targetLeadVec - pos).Normalize();

				float3 targetDirDif = targetLeadDir - dir;

				if (targetDirDif.Length() < tracking) {
					dir = targetLeadDir;
				} else {
					// <tracking> is the projectile's turn-rate
					targetDirDif = (targetDirDif - (dir * targetDirDif.dot(dir))).SafeNormalize();
					dir = (dir + (targetDirDif * tracking)).SafeNormalize();
				}

				// do not need to update dir or speed.w here
				CWorldObject::SetVelocity(dir * speed.w);
			}

			explGenHandler->GenExplosion(cegID, pos, speed, ttl, areaOfEffect, 0.0f, NULL, NULL);
		} else {
			if (!luaMoveCtrl) {
				// must update dir and speed.w here
				SetVelocityAndSpeed((speed * 0.98f) + (UpVector * mygravity));
			}
		}
	}

	if (!luaMoveCtrl) {
		SetPosition(pos + speed);
	}

	if (pos.y < -2.0f) {
		--nextBubble;

		if (nextBubble == 0) {
			nextBubble = 1 + (int) (gs->randFloat() * 1.5f);

			const float3 pspeed = (gs->randVector() * 0.1f) + float3(0.0f, 0.2f, 0.0f);

			new CBubbleProjectile(
				owner(),
				pos + gs->randVector(), pspeed, 40 + gs->randFloat() * GAME_SPEED,
				1 + gs->randFloat() * 2, 0.01f, 0.3f + gs->randFloat() * 0.3f
			);
		}
	}

	UpdateGroundBounce();
	UpdateInterception();
}
示例#14
0
void CMissileProjectile::Update()
{
	if (--ttl > 0) {
		if (!luaMoveCtrl) {
			if (curSpeed < maxSpeed) {
				curSpeed += weaponDef->weaponacceleration;
			}

			float3 targSpeed(ZeroVector);

			if (weaponDef->tracks && target) {
				CSolidObject* so = dynamic_cast<CSolidObject*>(target);
				CWeaponProjectile* po = dynamic_cast<CWeaponProjectile*>(target);

				targetPos = target->pos;
				if (so) {
					targetPos = so->aimPos;
					targSpeed = so->speed;

					if (owner()) {
						CUnit* u = dynamic_cast<CUnit*>(so);
						if (u) {
							targetPos = CGameHelper::GetUnitErrorPos(u, owner()->allyteam, true);
						}
					}
				} if (po) {
					targSpeed = po->speed;
				}
			}


			if (isWobbling) {
				--wobbleTime;
				if (wobbleTime == 0) {
					float3 newWob = gs->randVector();
					wobbleDif = (newWob - wobbleDir) * (1.0f / 16);
					wobbleTime = 16;
				}

				wobbleDir += wobbleDif;

				dir += wobbleDir * weaponDef->wobble * (owner()? (1.0f - owner()->limExperience * 0.5f): 1);
				dir.Normalize();
			}

			if (isDancing) {
				--danceTime;
				if (danceTime <= 0) {
					danceMove = gs->randVector() * weaponDef->dance - danceCenter;
					danceCenter += danceMove;
					danceTime = 8;
				}

				pos += danceMove;
			}

			const float3 orgTargPos = targetPos;
			const float3 targetDir = (targetPos - pos).SafeNormalize();
			const float dist = pos.distance(targetPos) + 0.1f;

			if (extraHeightTime > 0) {
				extraHeight -= extraHeightDecay;
				--extraHeightTime;

				targetPos.y += extraHeight;

				if (dir.y <= 0.0f) {
					// missile has reached apex, smoothly transition
					// to targetDir (can still overshoot when target
					// is too close or height difference too large)
					const float horDiff = (targetPos - pos).Length2D() + 0.01f;
					const float verDiff = (targetPos.y - pos.y) + 0.01f;
					const float dirDiff = math::fabs(targetDir.y - dir.y);
					const float ratio = math::fabs(verDiff / horDiff);

					dir.y -= (dirDiff * ratio);
				} else {
					// missile is still ascending
					dir.y -= (extraHeightDecay / dist);
				}
			}


			float3 dif = (targetPos + targSpeed * (dist / maxSpeed) * 0.7f - pos).SafeNormalize();
			float3 dif2 = dif - dir;

			if (dif2.SqLength() < Square(weaponDef->turnrate)) {
				dir = dif;
			} else {
				dif2 -= (dir * (dif2.dot(dir)));
				dif2.SafeNormalize();
				dir += (dif2 * weaponDef->turnrate);
				dir.SafeNormalize();
			}

			targetPos = orgTargPos;
			speed = dir * curSpeed;
		}

		gCEG->Explosion(cegID, pos, ttl, areaOfEffect, NULL, 0.0f, NULL, dir);
	} else {
		if (weaponDef->selfExplode) {
			Collision();
		} else {
			// only when TTL <= 0 do we (missiles)
			// get influenced by gravity and drag
			if (!luaMoveCtrl) {
				speed *= 0.98f;
				speed.y += mygravity;
				dir = speed;
				dir.SafeNormalize();
			}
		}
	}

	if (!luaMoveCtrl) {
		pos += speed;
	}

	age++;
	numParts++;
	if (weaponDef->visuals.smokeTrail && !(age & 7)) {
		CSmokeTrailProjectile* tp = new CSmokeTrailProjectile(
			pos, oldSmoke,
			dir, oldDir, owner(), age == 8, false, 7, SMOKE_TIME, 0.6f, drawTrail, 0,
			weaponDef->visuals.texture2
		);

		oldSmoke = pos;
		oldDir = dir;
		numParts = 0;
		useAirLos = tp->useAirLos;

		if (!drawTrail) {
			const float3 camDir = (pos - camera->pos).ANormalize();

			if ((camera->pos.distance(pos) * 0.2f + (1 - math::fabs(camDir.dot(dir))) * 3000) > 300) {
				drawTrail = true;
			}
		}
	}

	UpdateInterception();
	UpdateGroundBounce();
}
示例#15
0
void CTorpedoProjectile::Update()
{
	if (!weaponDef->submissile && pos.y > -3.0f) {
		// tracking etc only works when we are underwater
		if (!luaMoveCtrl) {
			speed.y += mygravity;
			dir = speed;
			dir.Normalize();
		}
	} else {
		if (!weaponDef->submissile && pos.y-speed.y > -3.0f) {
			// level out torpedo a bit when hitting water
			if (!luaMoveCtrl) {
				dir.y *= 0.5f;
				dir.Normalize();
			}
		}

		if (--ttl > 0) {
			if (!luaMoveCtrl) {
				if (curSpeed < maxSpeed) {
					curSpeed += std::max(0.2f, tracking);
				}

				if (target) {
					CSolidObject* so = dynamic_cast<CSolidObject*>(target);
					CWeaponProjectile* po = dynamic_cast<CWeaponProjectile*>(target);

					targetPos = target->pos;
					float3 targSpeed(ZeroVector);
					if (so) {
						targetPos = so->aimPos;
						targSpeed = so->speed;

						if (pos.SqDistance(so->aimPos) > 150 * 150 && owner()) {
							CUnit* u = dynamic_cast<CUnit*>(so);
							if (u) {
								targetPos = helper->GetUnitErrorPos(u, owner()->allyteam, true);
							}
						}
					} if (po) {
						targSpeed = po->speed;
					}

					if (!weaponDef->submissile && targetPos.y > 0) {
						targetPos.y = 0;
					}

					const float dist = pos.distance(targetPos);
					float3 dif = (targetPos + targSpeed * (dist / maxSpeed) * 0.7f - pos).Normalize();
					float3 dif2 = dif - dir;

					if (dif2.Length() < tracking) {
						dir = dif;
					} else {
						dif2 -= dir * (dif2.dot(dir));
						dif2.SafeNormalize();
						dir += dif2 * tracking;
						dir.SafeNormalize();
					}
				}

				speed = dir * curSpeed;
			}

			gCEG->Explosion(cegID, pos, ttl, areaOfEffect, NULL, 0.0f, NULL, speed);
		} else {
			if (!luaMoveCtrl) {
				speed *= 0.98f;
				speed.y += mygravity;
				dir = speed;
				dir.SafeNormalize();
			}
		}
	}

	if (!luaMoveCtrl) {
		pos += speed;
	}

	if (pos.y < -2.0f) {
		--nextBubble;

		if (nextBubble == 0) {
			nextBubble = 1 + (int) (gs->randFloat() * 1.5f);

			const float3 pspeed = (gs->randVector() * 0.1f) + float3(0.0f, 0.2f, 0.0f);

			new CBubbleProjectile(
				pos + gs->randVector(), pspeed, 40 + gs->randFloat() * 30,
				1 + gs->randFloat() * 2, 0.01f, owner(), 0.3f + gs->randFloat() * 0.3f
			);
		}
	}

	UpdateGroundBounce();
	UpdateInterception();
}
void CStarburstProjectile::Update()
{
	ttl--;
	uptime--;
	missileAge++;

	if (target != nullptr && weaponDef->tracks) {
		const CSolidObject* so = dynamic_cast<const CSolidObject*>(target);

		if (so != NULL) {
			targetPos = so->aimPos;
			if (allyteamID != -1 && !ignoreError) {
				const CUnit* u = dynamic_cast<const CUnit*>(so);

				if (u != nullptr)
					targetPos = u->GetErrorPos(allyteamID, true);
			}
		} else {
			targetPos = target->pos;
		}

		targetPos += aimError;
	}

	if (!luaMoveCtrl) {
		UpdateTrajectory();
	}

	if (ttl > 0) {
		explGenHandler->GenExplosion(cegID, pos, dir, ttl, damages->damageAreaOfEffect, 0.0f, NULL, NULL);
	}


	{
		const unsigned int newTracerPart = (curTracerPart + 1) % NUM_TRACER_PARTS;

		curTracerPart = newTracerPart;
		TracerPart* tracerPart = &tracerParts[curTracerPart];
		tracerPart->pos = pos;
		tracerPart->dir = dir;
		tracerPart->speedf = speed.w;

		unsigned int newsize = 0;

		for (float aa = 0; aa < speed.w + 0.6f && newsize < MAX_NUM_AGEMODS; aa += TRACER_PARTS_STEP, ++newsize) {
			const float ageMod = (missileAge < 20) ? 1.0f : (0.6f + (rand() * 0.8f) / RAND_MAX);
			tracerPart->ageMods[newsize] = ageMod;
		}

		if (tracerPart->numAgeMods != newsize) {
			tracerPart->numAgeMods = newsize;
		}
	}

	age++;
	numParts++;

	if (weaponDef->visuals.smokeTrail) {
		if (smokeTrail) {
			smokeTrail->UpdateEndPos(pos, dir);
			oldSmoke = pos;
			oldSmokeDir = dir;
		}

		if ((age % 8) == 0) {
			smokeTrail = new CSmokeTrailProjectile(
				owner(),
				pos,
				oldSmoke,
				dir,
				oldSmokeDir,
				age == 8,
				false,
				7,
				SMOKE_TIME,
				0.7f,
				weaponDef->visuals.texture2
			);

			numParts = 0;
			useAirLos = smokeTrail->useAirLos;
		}
	}

	UpdateInterception();
}