Ejemplo n.º 1
0
void CWeapon::SlowUpdate(bool noAutoTargetOverride)
{
#ifdef TRACE_SYNC
	tracefile << "Weapon slow update: ";
	tracefile << owner->id << " " << weaponNum <<  "\n";
#endif

	// If we can't get a line of fire from the muzzle, try
	// the aim piece instead (since the weapon may just be
	// turned in a wrong way)
	int weaponPiece = -1;
	bool weaponAimed = (useWeaponPosForAim == 0);

	if (!weaponAimed) {
		weaponPiece = owner->script->QueryWeapon(weaponNum);

		if (useWeaponPosForAim > 1)
			useWeaponPosForAim--;
	} else {
		weaponPiece = owner->script->AimFromWeapon(weaponNum);
	}

	relWeaponMuzzlePos = owner->script->GetPiecePos(weaponPiece);
	weaponMuzzlePos =
		owner->pos +
		owner->frontdir * relWeaponMuzzlePos.z +
		owner->updir    * relWeaponMuzzlePos.y +
		owner->rightdir * relWeaponMuzzlePos.x;
	weaponPos =
		owner->pos +
		owner->frontdir * relWeaponPos.z +
		owner->updir    * relWeaponPos.y +
		owner->rightdir * relWeaponPos.x;

	if (!weaponAimed) {
		weaponPiece = owner->script->AimFromWeapon(weaponNum);
	}

	relWeaponPos = owner->script->GetPiecePos(weaponPiece);

	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;
	}

	predictSpeedMod = 1.0f + (gs->randFloat() - 0.5f) * 2 * (1.0f - owner->limExperience);
	hasCloseTarget = ((targetPos - weaponPos).SqLength() < relWeaponPos.SqLength() * 16);


	if (targetType != Target_None && !TryTarget(targetPos, haveUserTarget, targetUnit)) {
		HoldFire();
	}

	if (targetType == Target_Unit) {
		// stop firing at cloaked targets
		if (targetUnit != NULL && targetUnit->isCloaked && !(targetUnit->losStatus[owner->allyteam] & (LOS_INLOS | LOS_INRADAR)))
			HoldFire();

		if (!haveUserTarget) {
			// stop firing at neutral targets (unless in FAW mode)
			// note: HoldFire sets targetUnit to NULL, so recheck
			if (targetUnit != NULL && targetUnit->neutral && owner->fireState <= FIRESTATE_FIREATWILL)
				HoldFire();

			// stop firing at allied targets
			//
			// this situation (unit keeps attacking its target if the
			// target or the unit switches to an allied team) should
			// be handled by /ally processing now
			if (targetUnit != NULL && teamHandler->Ally(owner->allyteam, targetUnit->allyteam))
				HoldFire();
		}
	}

	if (slavedTo) {
		// use targets from the thing we are slaved to
		if (targetUnit) {
			DeleteDeathDependence(targetUnit, DEPENDENCE_TARGETUNIT);
			targetUnit = NULL;
		}
		targetType = Target_None;

		if (slavedTo->targetType == Target_Unit) {
			const float3 tp =
				helper->GetUnitErrorPos(slavedTo->targetUnit, owner->allyteam) +
				errorVector * (weaponDef->targetMoveError * GAME_SPEED * slavedTo->targetUnit->speed.Length() * (1.0f - owner->limExperience));

			if (TryTarget(tp, false, slavedTo->targetUnit)) {
				targetType = Target_Unit;
				targetUnit = slavedTo->targetUnit;
				targetPos = tp;

				AddDeathDependence(targetUnit, DEPENDENCE_TARGETUNIT);
			}
		} else if (slavedTo->targetType == Target_Pos) {
			if (TryTarget(slavedTo->targetPos, false, 0)) {
				targetType = Target_Pos;
				targetPos = slavedTo->targetPos;
			}
		}
		return;
	}


	if (!noAutoTargetOverride && AllowWeaponTargetCheck()) {
		lastTargetRetry = gs->frameNum;

		std::multimap<float, CUnit*> targets;
		std::multimap<float, CUnit*>::const_iterator nextTargetIt;
		std::multimap<float, CUnit*>::const_iterator lastTargetIt;

		helper->GenerateWeaponTargets(this, targetUnit, targets);

		if (!targets.empty())
			lastTargetIt = --targets.end();

		for (nextTargetIt = targets.begin(); nextTargetIt != targets.end(); ++nextTargetIt) {
			CUnit* nextTargetUnit = nextTargetIt->second;

			if (nextTargetUnit->neutral && (owner->fireState <= FIRESTATE_FIREATWILL)) {
				continue;
			}

			// when only one target is available, <nextTarget> can equal <targetUnit>
			// and we want to attack whether it is in our bad target category or not
			// (if only bad targets are available and this is the last, just pick it)
			if (nextTargetUnit != targetUnit && (nextTargetUnit->category & badTargetCategory)) {
				if (nextTargetIt != lastTargetIt) {
					continue;
				}
			}

			const float weaponLead = weaponDef->targetMoveError * GAME_SPEED * nextTargetUnit->speed.Length();
			const float weaponError = weaponLead * (1.0f - owner->limExperience);

			float3 nextTargetPos = nextTargetUnit->midPos + (errorVector * weaponError);

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

			if (nextTargetPos.y < appHeight) {
				nextTargetPos.y = appHeight;
			}

			if (TryTarget(nextTargetPos, false, nextTargetUnit)) {
				if (targetUnit) {
					DeleteDeathDependence(targetUnit, DEPENDENCE_TARGETUNIT);
				}

				targetType = Target_Unit;
				targetUnit = nextTargetUnit;
				targetPos = nextTargetPos;

				AddDeathDependence(targetUnit, DEPENDENCE_TARGETUNIT);
				break;
			}
		}
	}

	if (targetType != Target_None) {
		owner->haveTarget = true;
		if (haveUserTarget) {
			owner->haveUserTarget = true;
		}
	} else {
		// if we can't target anything, try switching aim point
		if (useWeaponPosForAim == 1) {
			useWeaponPosForAim = 0;
		} else {
			useWeaponPosForAim = 1;
		}
	}
}
Ejemplo n.º 2
0
void CWeapon::SlowUpdate()
{
#ifdef TRACE_SYNC
    tracefile << "Weapon slow update: ";
    tracefile << owner->id << " " << weaponNum <<  "\n";
#endif

    std::vector<int> args;
    args.push_back(0);
    if(useWeaponPosForAim) {
        owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
        if(useWeaponPosForAim>1)
            useWeaponPosForAim--;
    } else {
        owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
    }
    relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
    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

    predictSpeedMod=1+(gs->randFloat()-0.5)*2*(1-owner->limExperience);

    if((targetPos-weaponPos).SqLength() < relWeaponPos.SqLength()*16)
        hasCloseTarget=true;
    else
        hasCloseTarget=false;

    if(targetType!=Target_None && !TryTarget(targetPos,haveUserTarget,targetUnit)) {
        HoldFire();
    }
    if(targetType==Target_Unit && targetUnit->isCloaked && !(targetUnit->losStatus[owner->allyteam] & (LOS_INLOS | LOS_INRADAR)))
        HoldFire();

    if(slavedTo) {	//use targets from the thing we are slaved to
        if(targetUnit) {
            DeleteDeathDependence(targetUnit);
            targetUnit=0;
        }
        targetType=Target_None;
        if(slavedTo->targetType==Target_Unit) {
            float3 tp=helper->GetUnitErrorPos(slavedTo->targetUnit,owner->allyteam);
            tp+=errorVector*(weaponDef->targetMoveError*30*slavedTo->targetUnit->speed.Length()*(1.0-owner->limExperience));
            if(TryTarget(tp,false,slavedTo->targetUnit)) {
                targetType=Target_Unit;
                targetUnit=slavedTo->targetUnit;
                targetPos=tp;
                AddDeathDependence(targetUnit);
            }
        } else if(slavedTo->targetType==Target_Pos) {
            if(TryTarget(slavedTo->targetPos,false,0)) {
                targetType=Target_Pos;
                targetPos=slavedTo->targetPos;
            }
        }
        return;
    }

    if(!weaponDef->noAutoTarget) {
        if(owner->fireState==2 && !haveUserTarget && (targetType==Target_None || (targetType==Target_Unit && (targetUnit->category & badTargetCategory)) || gs->frameNum>lastTargetRetry+65)) {
            std::map<float,CUnit*> targets;
            helper->GenerateTargets(this,targetUnit,targets);

            for(std::map<float,CUnit*>::iterator ti=targets.begin(); ti!=targets.end(); ++ti) {
                if(targetUnit && (ti->second->category & badTargetCategory))
                    continue;
                float3 tp(ti->second->midPos);
                tp+=errorVector*(weaponDef->targetMoveError*30*ti->second->speed.Length()*(1.0-owner->limExperience));
                if(TryTarget(tp,false,ti->second)) {
                    if(targetUnit) {
                        DeleteDeathDependence(targetUnit);
                    }
                    targetType=Target_Unit;
                    targetUnit=ti->second;
                    targetPos=tp;
                    AddDeathDependence(targetUnit);
                    break;
                }
            }
        }
    }
    if(targetType!=Target_None) {
        owner->haveTarget=true;
        if(haveUserTarget)
            owner->haveUserTarget=true;
    } else {	//if we cant target anything try switching aim point
        if(useWeaponPosForAim && useWeaponPosForAim==1) {
            useWeaponPosForAim=0;
        } else {
            useWeaponPosForAim=1;
        }
    }
}
Ejemplo n.º 3
0
void CWeapon::StopAttackingAllyTeam(int ally)
{
	if (targetUnit && targetUnit->allyteam == ally) {
		HoldFire();
	}
}
Ejemplo n.º 4
0
void CWeapon::SlowUpdate(bool noAutoTargetOverride)
{
#ifdef TRACE_SYNC
	tracefile << "Weapon slow update: ";
	tracefile << owner->id << " " << weaponNum <<  "\n";
#endif
	std::vector<int> args;
	args.push_back(0);
	if(useWeaponPosForAim){ //If we can't get a line of fire from the muzzle try the aim piece instead since the weapon may just be turned in a wrong way
		owner->cob->Call(COBFN_QueryPrimary+weaponNum,args);
		if(useWeaponPosForAim>1)
			useWeaponPosForAim--;
	} else {
		owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
	}
	relWeaponMuzzlePos=owner->localmodel->GetPiecePos(args[0]);
	weaponMuzzlePos=owner->pos+owner->frontdir*relWeaponMuzzlePos.z+owner->updir*relWeaponMuzzlePos.y+owner->rightdir*relWeaponMuzzlePos.x;

	owner->cob->Call(COBFN_AimFromPrimary+weaponNum,args);
	relWeaponPos=owner->localmodel->GetPiecePos(args[0]);
	weaponPos=owner->pos+owner->frontdir*relWeaponPos.z+owner->updir*relWeaponPos.y+owner->rightdir*relWeaponPos.x;

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

	predictSpeedMod=1+(gs->randFloat()-0.5f)*2*(1-owner->limExperience);

	if((targetPos-weaponPos).SqLength() < relWeaponPos.SqLength()*16)
		hasCloseTarget=true;
	else
		hasCloseTarget=false;

	if(targetType!=Target_None && !TryTarget(targetPos,haveUserTarget,targetUnit)){
		HoldFire();
	}
	if(targetType==Target_Unit && targetUnit->isCloaked && !(targetUnit->losStatus[owner->allyteam] & (LOS_INLOS | LOS_INRADAR)))
		HoldFire();

	if (targetType==Target_Unit && !haveUserTarget && targetUnit->neutral && owner->fireState < 3)
		HoldFire();

	//happens if the target or the unit has switched teams
	if (targetType==Target_Unit && !haveUserTarget && targetUnit->allyteam == owner->allyteam)
		HoldFire();

	if(slavedTo){	//use targets from the thing we are slaved to
		if(targetUnit){
			DeleteDeathDependence(targetUnit);
			targetUnit=0;
		}
		targetType=Target_None;
		if(slavedTo->targetType==Target_Unit){
			float3 tp=helper->GetUnitErrorPos(slavedTo->targetUnit,owner->allyteam);
			tp+=errorVector*(weaponDef->targetMoveError*30*slavedTo->targetUnit->speed.Length()*(1.0f-owner->limExperience));
			if(TryTarget(tp,false,slavedTo->targetUnit)){
				targetType=Target_Unit;
				targetUnit=slavedTo->targetUnit;
				targetPos=tp;
				AddDeathDependence(targetUnit);
			}
		} else if(slavedTo->targetType==Target_Pos){
			if(TryTarget(slavedTo->targetPos,false,0)){
				targetType=Target_Pos;
				targetPos=slavedTo->targetPos;
			}
		}
		return;
	}

/*		owner->fireState>=2 && !haveUserTarget &&
	if (!weaponDef->noAutoTarget && !noAutoTargetOverride) {
		    ((targetType == Target_None) ||
		     ((targetType == Target_Unit) &&
		      ((targetUnit->category & badTargetCategory) ||
		       (targetUnit->neutral && (owner->fireState < 3)))) ||
		     (gs->frameNum > lastTargetRetry + 65))) {
*/
	if (!noAutoTargetOverride && ShouldCheckForNewTarget()) {
		lastTargetRetry = gs->frameNum;
		std::map<float, CUnit*> targets;
		helper->GenerateTargets(this, targetUnit, targets);

		for (std::map<float,CUnit*>::iterator ti=targets.begin();ti!=targets.end();++ti) {
			if (ti->second->neutral && (owner->fireState < 3)) {
				continue;
			}
			if (targetUnit && (ti->second->category & badTargetCategory)) {
				continue;
			}
			float3 tp(ti->second->midPos);
			tp+=errorVector*(weaponDef->targetMoveError*30*ti->second->speed.Length()*(1.0f-owner->limExperience));
			float appHeight=ground->GetApproximateHeight(tp.x,tp.z)+2;
			if (tp.y < appHeight) {
				tp.y = appHeight;
			}

			if (TryTarget(tp, false, ti->second)) {
				if (targetUnit) {
					DeleteDeathDependence(targetUnit);
				}
				targetType = Target_Unit;
				targetUnit = ti->second;
				targetPos = tp;
				AddDeathDependence(targetUnit);
				break;
			}
		}
	}
	if (targetType != Target_None) {
		owner->haveTarget = true;
		if (haveUserTarget) {
			owner->haveUserTarget = true;
		}
	} else {	//if we cant target anything try switching aim point
		if (useWeaponPosForAim && (useWeaponPosForAim == 1)) {
			useWeaponPosForAim = 0;
		} else {
			useWeaponPosForAim = 1;
		}
	}
}