CRepulseGfx::CRepulseGfx(CUnit* owner,CProjectile* repulsed,float maxDist,float3 color)
: CProjectile(repulsed?repulsed->pos:float3(0,0,0),repulsed?repulsed->speed:float3(0,0,0),owner, false),
	repulsed(repulsed),
	age(0),
	sqMaxDist(maxDist*maxDist+100),
	color(color)
{
	if (owner)
		AddDeathDependence(owner);
	if (repulsed)
		AddDeathDependence(repulsed);

	checkCol=false;
	useAirLos=true;
	SetRadius(maxDist);

	for(int y=0;y<5;++y){
		float yp=(y/4.0f-0.5f);
		for(int x=0;x<5;++x){
			float xp=(x/4.0f-0.5f);
			float d=sqrt(xp*xp+yp*yp);
			difs[y*5+x]=(1-cos(d*2))*20;
		}
	}
}
CWeaponProjectile::CWeaponProjectile(const float3& pos,const float3& speed,CUnit* owner, CUnit* target,const float3 &targetPos, WeaponDef *weaponDef,CWeaponProjectile* interceptTarget) : 
	CProjectile(pos,speed,owner),
	weaponDef(weaponDef),
	target(target),
	targetPos(targetPos),
	startpos(pos),
	targeted(false),
	interceptTarget(interceptTarget)
{
	if(target)
		AddDeathDependence(target);

	if(interceptTarget){
		interceptTarget->targeted=true;
		AddDeathDependence(interceptTarget);
	}
	if(weaponDef->interceptedByShieldType)
		interceptHandler.AddShieldInterceptableProjectile(this);

	if(!weaponDef->visuals.modelName.empty()){
		S3DOModel* model = modelParser->Load3DO(string("objects3d/")+weaponDef->visuals.modelName,1,0);
		if(model){
			s3domodel=model;
			if(s3domodel->rootobject3do)
				modelDispList= model->rootobject3do->displist;
			else
				modelDispList= model->rootobjects3o->displist;
		}
	}

	collisionFlags = weaponDef->collisionFlags;
}
CWaitCommandsAI::DeathWait::DeathWait(const Command& cmd)
: Wait(CMD_WAITCODE_DEATHWAIT)
{
	GML_RECMUTEX_LOCK(sel); // DeathWait

	const CUnitSet& selUnits = selectedUnits.selectedUnits;

	if (cmd.params.size() == 1) {
		const int unitID = (int)cmd.params[0];
		if ((unitID < 0) || (static_cast<size_t>(unitID) >= uh->MaxUnits())) {
			return;
		}
		CUnit* unit = uh->units[unitID];
		if (unit == NULL) {
			return;
		}
		if (selUnits.find(unit) != selUnits.end()) {
			return;
		}
		deathUnits.insert(unit);
	}
	else if (cmd.params.size() == 6) {
		const float3 pos0(cmd.params[0], cmd.params[1], cmd.params[2]);
		const float3 pos1(cmd.params[3], cmd.params[4], cmd.params[5]);
		CUnitSet tmpSet;
		SelectAreaUnits(pos0, pos1, tmpSet, false);
		CUnitSet::iterator it;
		for (it = tmpSet.begin(); it != tmpSet.end(); ++it) {
			if (selUnits.find(*it) == selUnits.end()) {
				deathUnits.insert(*it);
			}
		}
		if (deathUnits.empty()) {
			return;
		}
	}
	else {
		return; // unknown param config
	}

	valid = true;
	key = GetNewKey();

	waitUnits = selUnits;

	Command waitCmd(CMD_WAIT, cmd.options);
	waitCmd.params.push_back(code);
	waitCmd.params.push_back(GetFloatFromKey(key));
	selectedUnits.GiveCommand(waitCmd);

	CUnitSet::iterator it;
	for (it = waitUnits.begin(); it != waitUnits.end(); ++it) {
		AddDeathDependence((CObject*)(*it));
	}
	for (it = deathUnits.begin(); it != deathUnits.end(); ++it) {
		AddDeathDependence((CObject*)(*it));
	}

	return;
}
Exemple #4
0
void CAirMoveType::CheckForCollision(void)
{
	if (!collide) return;

	SyncedFloat3& pos = owner->midPos;
	SyncedFloat3& forward = owner->frontdir;
	float3 midTestPos = pos + forward * 121;

	std::vector<CUnit*> others = qf->GetUnitsExact(midTestPos, 115);

	float dist = 200;
	if (lastColWarning) {
		DeleteDeathDependence(lastColWarning);
		lastColWarning = 0;
		lastColWarningType = 0;
	}

	for (std::vector<CUnit*>::iterator ui = others.begin(); ui != others.end(); ++ui) {
		if (*ui == owner || !(*ui)->unitDef->canfly)
			continue;
		SyncedFloat3& op = (*ui)->midPos;
		float3 dif = op - pos;
		float3 forwardDif = forward * (forward.dot(dif));
		if (forwardDif.SqLength() < dist * dist) {
			float frontLength = forwardDif.Length();
			float3 ortoDif = dif - forwardDif;

			// note that the radii are multiplied by two since we rely on
			// aircraft having half-size hitspheres (see unitloader)
			//
			// FIXME: with the new collision volumes, is this still true?
			//
			// yes: for backward compatibility, aircraft that do not define
			// their own custom volumes get halved hitspheres by default

			float minOrtoDif = ((*ui)->radius + owner->radius) * 2 + frontLength * 0.1f + 10;
			if (ortoDif.SqLength() < minOrtoDif * minOrtoDif) {
				dist = frontLength;
				lastColWarning = (*ui);
			}
		}
	}
	if (lastColWarning) {
		lastColWarningType = 2;
		AddDeathDependence(lastColWarning);
		return;
	}
	for (std::vector<CUnit*>::iterator ui = others.begin(); ui != others.end(); ++ui) {
		if (*ui == owner)
			continue;
		if (((*ui)->midPos - pos).SqLength() < dist * dist) {
			lastColWarning = *ui;
		}
	}
	if (lastColWarning) {
		lastColWarningType = 1;
		AddDeathDependence(lastColWarning);
	}
	return;
}
Exemple #5
0
void CTAAirMoveType::CheckForCollision(void)
{
	if (!collide) return;

	SyncedFloat3& pos = owner->midPos;
	SyncedFloat3 forward = owner->speed;
	forward.Normalize();
	float3 midTestPos = pos + forward * 121;

	std::vector<CUnit*> others = qf->GetUnitsExact(midTestPos, 115);
	float dist = 200;

	if (lastColWarning) {
		DeleteDeathDependence(lastColWarning);
		lastColWarning = 0;
		lastColWarningType = 0;
	}

	for (std::vector<CUnit*>::iterator ui = others.begin(); ui != others.end(); ++ui) {
		if (*ui == owner || !(*ui)->unitDef->canfly)
			continue;

		SyncedFloat3& op = (*ui)->midPos;
		float3 dif = op - pos;
		float3 forwardDif = forward * (forward.dot(dif));

		if (forwardDif.SqLength() < dist * dist) {
			float frontLength = forwardDif.Length();
			float3 ortoDif = dif - forwardDif;
			// note: the radius is multiplied by two since we rely on aircraft
			// having small spheres (see unitloader)
			float minOrtoDif = ((*ui)->radius + owner->radius) * 2 + frontLength * 0.05f + 5;

			if (ortoDif.SqLength() < minOrtoDif * minOrtoDif) {
				dist = frontLength;
				lastColWarning = (*ui);
			}
		}
	}
	if (lastColWarning) {
		lastColWarningType = 2;
		AddDeathDependence(lastColWarning);
		return;
	}
	for (std::vector<CUnit*>::iterator ui = others.begin(); ui != others.end(); ++ui) {
		if (*ui == owner)
			continue;
		if (((*ui)->midPos - pos).SqLength() < dist * dist) {
			lastColWarning = *ui;
		}
	}
	if (lastColWarning) {
		lastColWarningType = 1;
		AddDeathDependence(lastColWarning);
	}
	return;
}
CWeaponProjectile::CWeaponProjectile(const float3& pos, const float3& speed,
		CUnit* owner, CUnit* target, const float3 &targetPos,
		const WeaponDef* weaponDef, CWeaponProjectile* interceptTarget,
		int ttl):
	CProjectile(pos, speed, owner, true, true, false),
	targeted(false),
	weaponDef(weaponDef),
	weaponDefName(weaponDef? weaponDef->name: std::string("")),
	target(target),
	targetPos(targetPos),
	cegTag(weaponDef? weaponDef->cegTag: std::string("")),
	cegID(-1U),
	colorTeam(0),
	startpos(pos),
	ttl(ttl),
	bounces(0),
	keepBouncing(true),
	interceptTarget(interceptTarget)
{
	projectileType = WEAPON_BASE_PROJECTILE;

	if (owner) {
		colorTeam = owner->team;
	}

	if (target) {
		AddDeathDependence(target, DEPENDENCE_WEAPONTARGET);
	}

	if (interceptTarget) {
		interceptTarget->targeted = true;
		AddDeathDependence(interceptTarget, DEPENDENCE_INTERCEPTTARGET);
	}

	assert(weaponDef != NULL);

	alwaysVisible = weaponDef->visuals.alwaysVisible;
	ignoreWater = weaponDef->waterweapon;

	model = weaponDef->LoadModel();

	collisionFlags = weaponDef->collisionFlags;

	ph->AddProjectile(this);
	ASSERT_SYNCED(id);

	if (weaponDef->interceptedByShieldType) {
		// this needs a valid projectile id set
		assert(id >= 0);
		interceptHandler.AddShieldInterceptableProjectile(this);
	}
}
CWeaponProjectile::CWeaponProjectile(const float3& pos, const float3& speed,
		CUnit* owner, CUnit* target, const float3 &targetPos,
		const WeaponDef* weaponDef, CWeaponProjectile* interceptTarget,
		bool synced, int ttl):
	CProjectile(pos, speed, owner, synced, true),
	weaponDef(weaponDef),
	weaponDefName(weaponDef? weaponDef->name: std::string("")),
	target(target),
	targetPos(targetPos),
	startpos(pos),
	targeted(false),
	interceptTarget(interceptTarget),
	colorTeam(0),
	bounces(0),
	keepBouncing(true),
	ttl(ttl),
	cegTag(weaponDef? weaponDef->cegTag: std::string(""))
{
	if (owner) {
		colorTeam = owner->team;
	}

	if (target) {
		AddDeathDependence(target);
	}

	if (interceptTarget) {
		interceptTarget->targeted = true;
		AddDeathDependence(interceptTarget);
	}
	if (weaponDef) {
		if(weaponDef->interceptedByShieldType) {
			interceptHandler.AddShieldInterceptableProjectile(this);
		}
		
		alwaysVisible = weaponDef->visuals.alwaysVisible;

		if (!weaponDef->visuals.modelName.empty()) {
			S3DOModel* model = modelParser->Load3DModel(string("objects3d/") + weaponDef->visuals.modelName, 1, colorTeam);
			if (model) {
				s3domodel = model;

				if (s3domodel->rootobject3do)
					modelDispList = model->rootobject3do->displist;
				else
					modelDispList = model->rootobjects3o->displist;
			}
		}
		collisionFlags = weaponDef->collisionFlags;
	}
}
CWaitCommandsAI::SquadWait::SquadWait(const Command& cmd)
: Wait(CMD_WAITCODE_SQUADWAIT)
{
	GML_RECMUTEX_LOCK(sel); // SquadWait

	if (cmd.params.size() != 1) {
		return;
	}

	squadCount = (int)cmd.params[0];
	if (squadCount < 2) {
		return;
	}

	const CUnitSet& selUnits = selectedUnits.selectedUnits;
	CUnitSet::const_iterator it;
	for (it = selUnits.begin(); it != selUnits.end(); ++it) {
		CUnit* unit = *it;
		if (dynamic_cast<CFactory*>(unit)) {
			buildUnits.insert(unit);
		} else {
			waitUnits.insert(unit);
		}
	}
	if (buildUnits.empty() && ((int)waitUnits.size() < squadCount)) {
		return;
	}

	valid = true;
	key = GetNewKey();

	Command waitCmd(CMD_WAIT, cmd.options);
	waitCmd.params.push_back(code);
	waitCmd.params.push_back(GetFloatFromKey(key));

	SendCommand(waitCmd, buildUnits);
	SendCommand(waitCmd, waitUnits);

	for (it = buildUnits.begin(); it != buildUnits.end(); ++it) {
		AddDeathDependence((CObject*)(*it));
	}
	for (it = waitUnits.begin(); it != waitUnits.end(); ++it) {
		AddDeathDependence((CObject*)(*it));
	}

	UpdateText();

	return;
}
Exemple #9
0
void AMoveType::ReservePad(CAirBaseHandler::LandingPad* lp)
{
	AddDeathDependence(lp);
	reservedPad = lp;
	padStatus = 0;
	SetGoal(lp->GetUnit()->pos);
}
bool CWeapon::AttackUnit(CUnit *unit,bool userTarget)
{
    if((!userTarget && weaponDef->noAutoTarget))
        return false;
    if(weaponDef->interceptor)
        return false;

    weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;
    if(weaponPos.y<ground->GetHeight2(weaponPos.x,weaponPos.z))
        weaponPos=owner->pos+10;		//hope that we are underground because we are a popup weapon and will come above ground later

    if(!unit) {
        if(targetType!=Target_Unit)			//make the unit be more likely to keep the current target if user start to move it
            targetType=Target_None;
        haveUserTarget=false;
        return false;
    }
    float3 targetPos(helper->GetUnitErrorPos(unit,owner->allyteam));
    targetPos+=errorVector*(weaponDef->targetMoveError*30*unit->speed.Length()*(1.0-owner->limExperience));
    if(!TryTarget(targetPos,userTarget,unit))
        return false;

    if(targetUnit) {
        DeleteDeathDependence(targetUnit);
        targetUnit=0;
    }
    haveUserTarget=userTarget;
    targetType=Target_Unit;
    targetUnit=unit;
    targetPos=unit->midPos+float3(0,0.3,0)*unit->radius;
    AddDeathDependence(targetUnit);
    return true;
}
void CTransportUnit::AttachUnit(CUnit* unit, int piece)
{
	DetachUnit(unit);
	if(unit->inTransport)
		return;
	AddDeathDependence(unit);
	unit->inTransport=true;
	unit->toBeTransported=false;
	if (unit->unitDef->stunnedCargo)
		unit->stunned=true;	//make sure unit doesnt fire etc in transport
	unit->UnBlock();
	if(CTAAirMoveType* am=dynamic_cast<CTAAirMoveType*>(moveType))
		unit->moveType->useHeading=false;	
	TransportedUnit tu;
	tu.unit=unit;
	tu.piece=piece;
	tu.size=unit->xsize/2;
	tu.mass=unit->mass;
	transportCapacityUsed+=tu.size;
	transportMassUsed+=tu.mass;
	transported.push_back(tu);

	unit->CalculateTerrainType();
	unit->UpdateTerrainType();
}
void CAirMoveType::SlowUpdate(void)
{
	if(aircraftState!=AIRCRAFT_LANDED && owner->unitDef->maxFuel>0)
		owner->currentFuel = max (0.f, owner->currentFuel - (16.f/GAME_SPEED));

	if(!reservedPad && aircraftState==AIRCRAFT_FLYING && owner->health<owner->maxHealth*repairBelowHealth){
		CAirBaseHandler::LandingPad* lp=airBaseHandler->FindAirBase(owner,8000,owner->unitDef->minAirBasePower);
		if(lp){
			AddDeathDependence(lp);
			reservedPad=lp;
			padStatus=0;
			oldGoalPos=goalPos;
		}
	}
	if(owner->pos!=oldSlowUpdatePos){
		oldSlowUpdatePos=owner->pos;
		int newmapSquare=ground->GetSquare(owner->pos);
		if(newmapSquare!=owner->mapSquare){
			owner->mapSquare=newmapSquare;
			float oldlh=owner->losHeight;
			float h=owner->pos.y-ground->GetApproximateHeight(owner->pos.x,owner->pos.z);
			owner->losHeight=h+5;
			loshandler->MoveUnit(owner,false);
			if(owner->hasRadarCapacity)
				radarhandler->MoveUnit(owner);

			owner->losHeight=oldlh;
		}
		qf->MovedUnit(owner);
		owner->isUnderWater=owner->pos.y+owner->model->height<0;
	}
}
void CAirMoveType::SlowUpdate(void)
{
	if(!reservedPad && aircraftState==AIRCRAFT_FLYING && owner->health<owner->maxHealth*repairBelowHealth){
		CAirBaseHandler::LandingPad* lp=airBaseHandler->FindAirBase(owner,8000);
		if(lp){
			AddDeathDependence(lp);
			reservedPad=lp;
			padStatus=0;
			oldGoalPos=goalPos;
		}
	}
	if(owner->pos!=oldSlowUpdatePos){
		oldSlowUpdatePos=owner->pos;
		int newmapSquare=ground->GetSquare(owner->pos);
		if(newmapSquare!=owner->mapSquare){
			owner->mapSquare=newmapSquare;
			float oldlh=owner->losHeight;
			float h=owner->pos.y-ground->GetApproximateHeight(owner->pos.x,owner->pos.z);
			owner->losHeight=h+5;
			loshandler->MoveUnit(owner,false);
			if(owner->radarRadius || owner->jammerRadius || owner->sonarRadius)
				radarhandler->MoveUnit(owner);

			owner->losHeight=oldlh;
		}
		qf->MovedUnit(owner);
		owner->isUnderWater=owner->pos.y+owner->model->height<0;
	}
}
Exemple #14
0
void CFactory::StartBuild(const UnitDef* buildeeDef) {
	const float3& buildPos = CalcBuildPos();
	const bool blocked = groundBlockingObjectMap->GroundBlocked(buildPos, this);

	// wait until buildPos is no longer blocked (eg. by a previous buildee)
	//
	// it might rarely be the case that a unit got stuck inside the factory
	// or died right after completion and left some wreckage, but that is up
	// to players to fix (we no longer broadcast BuggerOff directives, since
	// those are indiscriminate and ineffective)
	if (blocked)
		return;

	CUnit* b = unitLoader->LoadUnit(buildeeDef, buildPos, team, true, buildFacing, this);

	if (!unitDef->canBeAssisted) {
		b->soloBuilder = this;
		b->AddDeathDependence(this, DEPENDENCE_BUILDER);
	}

	AddDeathDependence(b, DEPENDENCE_BUILD);
	script->StartBuilding();

	// set curBuildDef to NULL to indicate construction
	// has started, otherwise we would keep being called
	curBuild = b;
	curBuildDef = NULL;

	#if (PLAY_SOUNDS == 1)
	if (losStatus[gu->myAllyTeam] & LOS_INLOS) {
		Channels::General.PlayRandomSample(unitDef->sounds.build, buildPos);
	}
	#endif
}
Exemple #15
0
void RepairTask::SetRepairTarget (aiUnit *u)
{
    if (target) DeleteDeathDependence (target);

    target = u;
    if (u) AddDeathDependence (u);
}
void CSelectedUnits::AddUnit(CUnit* unit)
{
	// if unit is being transported by eg. Hulk or Atlas
	// then we should not be able to select it
	if (unit->transporter != NULL && !unit->transporter->unitDef->isFirePlatform) {
		return;
	}

	if (unit->noSelect) {
		return;
	}

	selectedUnits.insert(unit);
	AddDeathDependence(unit);
	selectionChanged = true;
	possibleCommandsChanged = true;

	if (!(unit->group) || unit->group->id != selectedGroup)
		selectedGroup = -1;

	PUSH_CODE_MODE;
	ENTER_MIXED;
	unit->commandAI->selected = true;
	POP_CODE_MODE;
}
void CTransportUnit::AttachUnit(CUnit* unit, int piece)
{
	DetachUnit(unit);

	if (!CanTransport(unit))
		return;

	AddDeathDependence(unit);
	unit->AddDeathDependence (this);
	unit->transporter = this;
	unit->toBeTransported=false;
	if (!unitDef->isfireplatform) {
		unit->stunned=true;	//make sure unit doesnt fire etc in transport
		selectedUnits.RemoveUnit(unit);
	}
	unit->UnBlock();
	loshandler->FreeInstance(unit->los);
	unit->los=0;
	if (dynamic_cast<CTAAirMoveType*>(moveType)) {
		unit->moveType->useHeading=false;
	}
	TransportedUnit tu;
	tu.unit=unit;
	tu.piece=piece;
	tu.size=unit->xsize/2;
	tu.mass=unit->mass;
	transportCapacityUsed+=tu.size;
	transportMassUsed+=tu.mass;
	transported.push_back(tu);

	unit->CalculateTerrainType();
	unit->UpdateTerrainType();

	luaCallIns.UnitLoaded(unit, this);
}
Exemple #18
0
CRepulseGfx::CRepulseGfx(CUnit* owner, CProjectile* repulsed, float maxDist, const float3& color):
	CProjectile(repulsed? repulsed->pos: ZeroVector, repulsed? repulsed->speed: ZeroVector, owner, false, false, false),
	repulsed(repulsed),
	sqMaxDist((maxDist * maxDist) + 100),
	age(0),
	color(color)
{
	if (repulsed) {
		AddDeathDependence(repulsed);
	}

	checkCol = false;
	useAirLos = true;
	SetRadius(maxDist);

	for (int y = 0; y < 5; ++y) {
		float yp = (y / 4.0f - 0.5f);

		for (int x = 0; x < 5; ++x) {
			float xp = (x / 4.0f - 0.5f);
			float d = 0;
			if (xp != 0 || yp != 0) {
				d = fastmath::apxsqrt2(xp * xp + yp * yp);
			}
			difs[y * 5 + x] = (1 - fastmath::cos(d * 2)) * 20;
		}
	}
}
Exemple #19
0
void CSelectedUnits::AddUnit(CUnit* unit)
{
	// if unit is being transported by eg. Hulk or Atlas
	// then we should not be able to select it
	CTransportUnit *trans=unit->GetTransporter();
	if (trans != NULL && !trans->unitDef->isFirePlatform) {
		return;
	}

	if (unit->noSelect) {
		return;
	}

	GML_RECMUTEX_LOCK(sel); // AddUnit

	selectedUnits.insert(unit);
	AddDeathDependence(unit);
	selectionChanged = true;
	possibleCommandsChanged = true;

	if (!(unit->group) || unit->group->id != selectedGroup)
		selectedGroup = -1;

	unit->commandAI->selected = true;
}
CTorpedoProjectile::CTorpedoProjectile(
		const float3& pos, const float3& speed,
		CUnit* owner,
		float areaOfEffect, float maxSpeed,
		float tracking, int ttl,
		CUnit* target,
		const WeaponDef* weaponDef)
	: CWeaponProjectile(pos, speed, owner, target, ZeroVector, weaponDef, NULL, ttl),
	tracking(tracking),
	maxSpeed(maxSpeed),
	areaOfEffect(areaOfEffect),
	target(target),
	nextBubble(4)
{
	projectileType = WEAPON_TORPEDO_PROJECTILE;
	curSpeed = speed.Length();
	dir = speed / curSpeed;

	if (target) {
		AddDeathDependence(target);
	}

	SetRadius(0.0f);
	drawRadius = maxSpeed * 8;

//	const float3 camDir = (pos - camera->pos).Normalize();
	texx = projectileDrawer->torpedotex->xstart - (projectileDrawer->torpedotex->xend - projectileDrawer->torpedotex->xstart) * 0.5f;
	texy = projectileDrawer->torpedotex->ystart - (projectileDrawer->torpedotex->yend - projectileDrawer->torpedotex->ystart) * 0.5f;
#ifdef TRACE_SYNC
	tracefile << "New projectile: ";
	tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n";
#endif

	cegID = gCEG->Load(explGenHandler, cegTag);
}
void CPlasmaRepulser::NewProjectile(CWeaponProjectile* p)
{
	if(weaponDef->smartShield && gs->AlliedTeams(p->owner->team,owner->team))
		return;

	float3 dir;
	if(p->targetPos!=ZeroVector)
		dir=p->targetPos-p->pos;	//assume that it will travel roughly in the direction of the targetpos if it have one
	else
		dir=p->speed;				//otherwise assume speed will hold constant
	dir.y=0;
	dir.Normalize();
	float3 dif=owner->pos-p->pos;

	if(weaponDef->exteriorShield && dif.SqLength() < sqRadius)
		return;

	float closeLength=dif.dot(dir);
	if(closeLength<0)
		closeLength=0;
	float3 closeVect=dif-dir*closeLength;

	if(closeVect.Length2D()<radius*1.5f+400){
		incoming.push_back(p);
		AddDeathDependence(p);
	}
}
CWaitCommandsAI::TimeWait::TimeWait(const Command& cmd, CUnit* _unit)
: Wait(CMD_WAITCODE_TIMEWAIT)
{
	if (cmd.params.size() != 1) {
		return;
	}

	valid = true;
	key = GetNewKey();

	unit = _unit;
	enabled = false;
	endFrame = 0;
	duration = GAME_SPEED * (int)cmd.params[0];
	factory = (dynamic_cast<CFactory*>(unit) != NULL);

	Command waitCmd(CMD_WAIT, cmd.options);
	waitCmd.params.push_back(code);
	waitCmd.params.push_back(GetFloatFromKey(key));

	selectedUnits.ClearSelected();
	selectedUnits.AddUnit(unit);
	selectedUnits.GiveCommand(waitCmd);

	AddDeathDependence((CObject*)unit);

	return;
}
CLightingProjectile::CLightingProjectile(const float3& pos,const float3& end,CUnit* owner,const float3& color, WeaponDef *weaponDef,int ttl,CWeapon* weap)
:	CWeaponProjectile(pos,ZeroVector, owner, 0, ZeroVector, weaponDef,0), //CProjectile(pos,ZeroVector,owner),
	ttl(ttl),
	color(color),
	endPos(end),
	weapon(weap)
{
	checkCol=false;
	drawRadius=pos.distance(endPos);

	displacements[0]=0;
	for(int a=1;a<10;++a)
		displacements[a]=(gs->randFloat()-0.5f)*drawRadius*0.05f;

	displacements2[0]=0;
	for(int a=1;a<10;++a)
		displacements2[a]=(gs->randFloat()-0.5f)*drawRadius*0.05f;

	if(weapon)
		AddDeathDependence(weapon);

#ifdef TRACE_SYNC
	tracefile << "New lighting: ";
	tracefile << pos.x << " " << pos.y << " " << pos.z << " " << end.x << " " << end.y << " " << end.z << "\n";
#endif
}
Exemple #24
0
void CPlasmaRepulser::NewProjectile(CWeaponProjectile* p)
{
	if (weaponDef->smartShield && teamHandler->AlliedTeams(p->owner()->team, owner->team)) {
		return;
	}

	float3 dir = p->speed;
	if (p->targetPos != ZeroVector) {
		dir = p->targetPos - p->pos; // assume that it will travel roughly in the direction of the targetpos if it have one
	}

	dir.y = 0.0f;
	dir.SafeNormalize();

	const float3 dif = owner->pos - p->pos;

	if (weaponDef->exteriorShield && (dif.SqLength() < sqRadius)) {
		return;
	}

	const float closeLength = std::max(0.0f, dif.dot(dir));
	const float3 closeVect = dif - dir * closeLength;
	const float closeDist = closeVect.SqLength2D();

	// TODO: this isn't good enough in case shield is mounted on a mobile unit,
	//       and this unit moves relatively fast compared to the projectile.
	// it should probably be: radius + closeLength / |projectile->speed| * |owner->speed|,
	// but this still doesn't solve anything for e.g. teleporting shields.
	if (closeDist < Square(radius * 1.5f)) {
		incomingProjectiles[p->id] = p;
		AddDeathDependence(p, DEPENDENCE_REPULSED);
	}
}
CWeaponProjectile::CWeaponProjectile(const float3& pos, const float3& speed,
		CUnit* owner, CUnit* target, const float3 &targetPos,
		const WeaponDef* weaponDef, CWeaponProjectile* interceptTarget,
		int ttl):
	CProjectile(pos, speed, owner, true, true, false),
	targeted(false),
	weaponDef(weaponDef),
	weaponDefName(weaponDef? weaponDef->name: std::string("")),
	target(target),
	targetPos(targetPos),
	cegTag(weaponDef? weaponDef->cegTag: std::string("")),
	cegID(-1U),
	colorTeam(0),
	startpos(pos),
	ttl(ttl),
	bounces(0),
	keepBouncing(true),
	interceptTarget(interceptTarget)
{
	projectileType = WEAPON_BASE_PROJECTILE;

	if (owner) {
		colorTeam = owner->team;
	}

	if (target) {
		AddDeathDependence(target);
	}

	if (interceptTarget) {
		interceptTarget->targeted = true;
		AddDeathDependence(interceptTarget);
	}
	if (weaponDef) {
		if(weaponDef->interceptedByShieldType) {
			interceptHandler.AddShieldInterceptableProjectile(this);
		}

		alwaysVisible = weaponDef->visuals.alwaysVisible;

		model = LoadModel(weaponDef);

		collisionFlags = weaponDef->collisionFlags;
	}

	ph->AddProjectile(this);
}
Exemple #26
0
void CAirCAI::ExecuteAreaAttack(Command &c)
{
	assert(owner->unitDef->canAttack);
	AAirMoveType* myPlane = (AAirMoveType*) owner->moveType;

	if (targetDied) {
		targetDied = false;
		inCommand = false;
	}

	const float3 pos(c.params[0], c.params[1], c.params[2]);
	const float radius = c.params[3];

	if (inCommand) {
		if (myPlane->aircraftState == AAirMoveType::AIRCRAFT_LANDED)
			inCommand = false;
		if (orderTarget && orderTarget->pos.SqDistance2D(pos) > Square(radius)) {
			inCommand = false;
			DeleteDeathDependence(orderTarget);
			orderTarget = 0;
		}
		if (owner->commandShotCount < 0) {
			if ((c.params.size() == 4) && (commandQue.size() > 1)) {
				owner->AttackUnit(0, true);
				FinishCommand();
			}
			else if (owner->userAttackGround) {
				// reset the attack position after each run
				float3 attackPos = pos + (gs->randVector() * radius);
					attackPos.y = ground->GetHeightAboveWater(attackPos.x, attackPos.z);

				owner->AttackGround(attackPos, false);
				owner->commandShotCount = 0;
			}
		}
	} else {
		owner->commandShotCount = -1;

		if (myPlane->aircraftState != AAirMoveType::AIRCRAFT_LANDED) {
			inCommand = true;

			std::vector<int> enemyUnitIDs;
			helper->GetEnemyUnits(pos, radius, owner->allyteam, enemyUnitIDs);

			if (enemyUnitIDs.empty()) {
				float3 attackPos = pos + gs->randVector() * radius;
				attackPos.y = ground->GetHeightAboveWater(attackPos.x, attackPos.z);
				owner->AttackGround(attackPos, false);
			} else {
				// note: the range of randFloat() is inclusive of 1.0f
				const unsigned int idx(gs->randFloat() * (enemyUnitIDs.size() - 1));

				orderTarget = uh->GetUnitUnsafe( enemyUnitIDs[idx] );
				owner->AttackUnit(orderTarget, false);
				AddDeathDependence(orderTarget);
			}
		}
	}
}
Exemple #27
0
bool CWeapon::AttackUnit(CUnit* unit, bool userTarget)
{
	if ((!userTarget && weaponDef->noAutoTarget))
		return false;
	if (weaponDef->interceptor)
		return false;

	weaponPos =
		owner->pos +
		owner->frontdir * relWeaponPos.z +
		owner->updir    * relWeaponPos.y +
		owner->rightdir * relWeaponPos.x;
	weaponMuzzlePos =
		owner->pos +
		owner->frontdir * relWeaponMuzzlePos.z +
		owner->updir    * relWeaponMuzzlePos.y +
		owner->rightdir * relWeaponMuzzlePos.x;

	if (weaponMuzzlePos.y < ground->GetHeightReal(weaponMuzzlePos.x, weaponMuzzlePos.z)) {
		// hope that we are underground because we are a popup weapon and will come above ground later
		weaponMuzzlePos = owner->pos + UpVector * 10;
	}

	if (!unit) {
		if (targetType != Target_Unit) {
			// make the unit be more likely to keep the current target if user starts to move it
			targetType = Target_None;
		}

		haveUserTarget = false;
		return false;
	}

	float3 tempTargetPos =
		helper->GetUnitErrorPos(unit, owner->allyteam) +
		errorVector * (weaponDef->targetMoveError * GAME_SPEED * unit->speed.Length() * (1.0f - owner->limExperience));

	const float appHeight = ground->GetApproximateHeight(tempTargetPos.x, tempTargetPos.z) + 2.0f;

	if (tempTargetPos.y < appHeight)
		tempTargetPos.y = appHeight;

	if (!TryTarget(tempTargetPos, userTarget, unit))
		return false;

	if (targetUnit) {
		DeleteDeathDependence(targetUnit, DEPENDENCE_TARGETUNIT);
		targetUnit = NULL;
	}

	haveUserTarget = userTarget;
	targetType = Target_Unit;
	targetUnit = unit;
	targetPos = tempTargetPos;

	AddDeathDependence(targetUnit, DEPENDENCE_TARGETUNIT);
	avoidTarget = false;
	return true;
}
CCobThread::CCobThread(CCobFile &script, CCobInstance *owner)
: owner(owner), script(script) 
{
	state = Init;
	owner->threads.push_back(this);
	AddDeathDependence(owner);
	signalMask = 42;
}
void CProjectile::Init (const float3& explosionPos, CUnit *owner)
{
	pos += explosionPos;
	SetRadius(1.7f);
	ph->AddProjectile(this);
	if(owner)
		AddDeathDependence(owner);
}
CMissileProjectile::CMissileProjectile(const float3& pos,const float3& speed,CUnit* owner,const DamageArray& damages,float areaOfEffect,float maxSpeed, int ttl,CUnit* target, WeaponDef *weaponDef,float3 targetPos)
: CWeaponProjectile(pos,speed,owner,target,ZeroVector,weaponDef,0),
	damages(damages),
	ttl(ttl),
	maxSpeed(maxSpeed),
	target(target),
	dir(speed),
	oldSmoke(pos),
	age(0),
	drawTrail(true),
	numParts(0),
	areaOfEffect(areaOfEffect),
	decoyTarget(0),
	targPos(targetPos),
	wobbleTime(1),
	wobbleDir(0,0,0),
	wobbleDif(0,0,0),
	isWobbling(weaponDef->wobble>0),
	extraHeightTime(0)
{
	curSpeed=speed.Length();
	dir.Normalize();
	oldDir=dir;
	if(target)
		AddDeathDependence(target);

	SetRadius(0.0);
	if(!weaponDef->visuals.modelName.empty()){
		S3DOModel* model = modelParser->Load3DO(string("objects3d/")+weaponDef->visuals.modelName,1,0);
		if(model){
			SetRadius(model->radius);
		}
	}

	drawRadius=radius+maxSpeed*8;
	ENTER_MIXED;
	float3 camDir=(pos-camera->pos).Normalize();
	if(camera->pos.distance(pos)*0.2+(1-fabs(camDir.dot(dir)))*3000 < 200)
		drawTrail=false;
	ENTER_SYNCED;
	castShadow=true;
#ifdef TRACE_SYNC
	tracefile << "New missile: ";
	tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n";
#endif
	if(target)
		target->IncomingMissile(this);

	if(weaponDef->trajectoryHeight>0){
		float dist=pos.distance(targPos);
		extraHeight=dist*weaponDef->trajectoryHeight;
		if(dist<maxSpeed)
			dist=maxSpeed;
		extraHeightTime=(int)(dist/*+pos.distance(targPos+UpVector*dist))*0.5*//maxSpeed);
		extraHeightDecay=extraHeight/extraHeightTime;
	}
}