📄 unit.cpp
字号:
if(canUse)
metalUseI += metal;
return canUse;
}
void CUnit::AddMetal(float metal)
{
if(metal<0){
UseMetal(-metal);
return;
}
metalMakeI += metal;
gs->Team(team)->AddMetal(metal);
}
bool CUnit::UseEnergy(float energy)
{
if(energy<0){
AddEnergy(-energy);
return true;
}
gs->Team(team)->energyPull += energy;
bool canUse=gs->Team(team)->UseEnergy(energy);
if(canUse)
energyUseI += energy;
return canUse;
}
void CUnit::AddEnergy(float energy)
{
if(energy<0){
UseEnergy(-energy);
return;
}
energyMakeI += energy;
gs->Team(team)->AddEnergy(energy);
}
void CUnit::Activate()
{
//if(unitDef->tidalGenerator>0)
// cob->Call(COBFN_SetSpeed, (int)(readmap->tidalStrength*3000.0f*unitDef->tidalGenerator));
if (activated)
return;
activated = true;
cob->Call(COBFN_Activate);
if (unitDef->targfac){
radarhandler->radarErrorSize[allyteam] /= radarhandler->targFacEffect;
}
if (hasRadarCapacity)
radarhandler->MoveUnit(this);
int soundIdx = unitDef->sounds.activate.getRandomIdx();
if (soundIdx >= 0) {
sound->PlayUnitActivate(
unitDef->sounds.activate.getID(soundIdx), this,
unitDef->sounds.activate.getVolume(soundIdx));
}
}
void CUnit::Deactivate()
{
if (!activated)
return;
activated = false;
cob->Call(COBFN_Deactivate);
if (unitDef->targfac){
radarhandler->radarErrorSize[allyteam] *= radarhandler->targFacEffect;
}
if (hasRadarCapacity)
radarhandler->RemoveUnit(this);
int soundIdx = unitDef->sounds.deactivate.getRandomIdx();
if (soundIdx >= 0) {
sound->PlayUnitActivate(
unitDef->sounds.deactivate.getID(soundIdx), this,
unitDef->sounds.deactivate.getVolume(soundIdx));
}
}
void CUnit::PushWind(float x, float z, float strength)
{
if(strength > unitDef->windGenerator)
{
cob->Call(COBFN_SetSpeed, (int)(unitDef->windGenerator*3000.0f));
}
else
{
cob->Call(COBFN_SetSpeed, (int)(strength*3000.0f));
}
cob->Call(COBFN_SetDirection, (int)GetHeadingFromVector(-x, -z));
}
void CUnit::LoadSave(CLoadSaveInterface* file, bool loading)
{
file->lsShort(heading);
file->lsFloat(buildProgress);
file->lsFloat(health);
file->lsFloat(experience);
if (loading) {
const float exp = experience;
experience = 0.0f;
limExperience = 0.0f;
AddExperience(exp);
}
file->lsInt(moveState);
file->lsInt(fireState);
file->lsBool(isCloaked);
file->lsBool(wantCloak);
commandAI->LoadSave(file, loading);
}
void CUnit::IncomingMissile(CMissileProjectile* missile)
{
if (unitDef->canDropFlare) {
incomingMissiles.push_back(missile);
AddDeathDependence(missile);
if (lastFlareDrop < (gs->frameNum - unitDef->flareReloadTime * 30)) {
SAFE_NEW CFlareProjectile(pos, speed, this, (int) (gs->frameNum + unitDef->flareDelay * (1 + gs->randFloat()) * 15));
lastFlareDrop = gs->frameNum;
}
}
}
void CUnit::TempHoldFire(void)
{
dontFire = true;
AttackUnit(0, true);
}
void CUnit::ReleaseTempHoldFire(void)
{
dontFire = false;
}
void CUnit::DrawS3O(void)
{
unitDrawer->SetS3OTeamColour(team);
Draw();
}
void CUnit::hitByWeaponIdCallback(int retCode, void *p1, void *p2)
{
((CUnit*)p1)->weaponHitMod = retCode*0.01f;
}
/******************************************************************************/
float CUnit::lodFactor = 1.0f;
void CUnit::SetLODFactor(float value)
{
lodFactor = (value * camera->lppScale);
}
void CUnit::SetLODCount(unsigned int count)
{
const unsigned int oldCount = lodCount;
lodCount = count;
lodLengths.resize(count);
for (unsigned int i = oldCount; i < count; i++) {
lodLengths[i] = -1.0f;
}
localmodel->SetLODCount(count);
for (int m = 0; m < LUAMAT_TYPE_COUNT; m++) {
luaMats[m].SetLODCount(count);
}
return;
}
unsigned int CUnit::CalcLOD(unsigned int lastLOD) const
{
if (lastLOD == 0) { return 0; }
const float3 diff = (pos - camera->pos);
const float dist = diff.dot(camera->forward);
const float lpp = max(0.0f, dist * lodFactor);
for (/* no-op */; lastLOD != 0; lastLOD--) {
if (lpp > lodLengths[lastLOD]) {
break;
}
}
return lastLOD;
}
unsigned int CUnit::CalcShadowLOD(unsigned int lastLOD) const
{
return CalcLOD(lastLOD); // FIXME
// FIXME -- the more 'correct' method
if (lastLOD == 0) { return 0; }
// FIXME: fix it, cap it for shallow shadows?
const float3& sun = gs->sunVector;
const float3 diff = (camera->pos - pos);
const float dot = diff.dot(sun);
const float3 gap = diff - (sun * dot);
const float lpp = max(0.0f, gap.Length() * lodFactor);
for (/* no-op */; lastLOD != 0; lastLOD--) {
if (lpp > lodLengths[lastLOD]) {
break;
}
}
return lastLOD;
}
/******************************************************************************/
void CUnit::PostLoad()
{
//HACK:Initializing after load
unitDef = unitDefHandler->GetUnitByName(unitDefName);
yardMap = unitDef->yardmaps[buildFacing];
model = unitDef->LoadModel(team);
SetRadius(model->radius);
cob = SAFE_NEW CCobInstance(GCobEngine.GetCobFile("scripts/" + unitDef->name+".cob"), this);
localmodel = modelParser->CreateLocalModel(model, &cob->pieces);
// Calculate the max() of the available weapon reloadtimes
int relMax = 0;
for (vector<CWeapon*>::iterator i = weapons.begin(); i != weapons.end(); ++i) {
if ((*i)->reloadTime > relMax)
relMax = (*i)->reloadTime;
if(dynamic_cast<CBeamLaser*>(*i))
relMax=150;
}
relMax *= 30; // convert ticks to milliseconds
// TA does some special handling depending on weapon count
if (weapons.size() > 1)
relMax = max(relMax, 3000);
// Call initializing script functions
cob->Call(COBFN_Create);
cob->Call("SetMaxReloadTime", relMax);
for (vector<CWeapon*>::iterator i = weapons.begin(); i != weapons.end(); ++i) {
(*i)->weaponDef = unitDef->weapons[(*i)->weaponNum].def;
}
cob->Call(COBFN_SetSFXOccupy, curTerrainType);
if (unitDef->windGenerator>0) {
if (wind.GetCurrentStrength() > unitDef->windGenerator) {
cob->Call(COBFN_SetSpeed, (int)(unitDef->windGenerator * 3000.0f));
} else {
cob->Call(COBFN_SetSpeed, (int)(wind.GetCurrentStrength() * 3000.0f));
}
cob->Call(COBFN_SetDirection, (int)GetHeadingFromVector(-wind.GetCurrentDirection().x, -wind.GetCurrentDirection().z));
}
if (activated) {
cob->Call(COBFN_Activate);
}
}
// Member bindings
CR_REG_METADATA(CUnit, (
//CR_MEMBER(unitDef),
CR_MEMBER(unitDefName),
CR_MEMBER(id),
CR_MEMBER(team),
CR_MEMBER(allyteam),
CR_MEMBER(lineage),
CR_MEMBER(aihint),
CR_MEMBER(frontdir),
CR_MEMBER(rightdir),
CR_MEMBER(updir),
CR_MEMBER(upright),
CR_MEMBER(relMidPos),
CR_MEMBER(power),
CR_MEMBER(luaDraw),
CR_MEMBER(noDraw),
CR_MEMBER(noSelect),
CR_MEMBER(noMinimap),
CR_MEMBER(travel),
CR_MEMBER(travelPeriod),
CR_RESERVED(8),
CR_MEMBER(maxHealth),
CR_MEMBER(health),
CR_MEMBER(paralyzeDamage),
CR_MEMBER(captureProgress),
CR_MEMBER(experience),
CR_MEMBER(limExperience),
CR_MEMBER(neutral),
CR_MEMBER(soloBuilder),
CR_MEMBER(beingBuilt),
CR_MEMBER(lastNanoAdd),
CR_MEMBER(transporter),
CR_MEMBER(toBeTransported),
CR_MEMBER(buildProgress),
CR_MEMBER(realLosRadius),
CR_MEMBER(realAirLosRadius),
CR_MEMBER(losStatus),
CR_MEMBER(inBuildStance),
CR_MEMBER(stunned),
CR_MEMBER(useHighTrajectory),
CR_MEMBER(groundLevelled),
CR_MEMBER(terraformLeft),
CR_RESERVED(11),
CR_MEMBER(deathCountdown),
CR_MEMBER(delayedWreckLevel),
CR_MEMBER(restTime),
CR_MEMBER(weapons),
CR_MEMBER(shieldWeapon),
CR_MEMBER(stockpileWeapon),
CR_MEMBER(reloadSpeed),
CR_MEMBER(maxRange),
CR_MEMBER(haveTarget),
CR_MEMBER(haveUserTarget),
CR_MEMBER(haveDGunRequest),
CR_MEMBER(lastMuzzleFlameSize),
CR_MEMBER(lastMuzzleFlameDir),
CR_RESERVED(16),
CR_MEMBER(armorType),
CR_MEMBER(category),
CR_MEMBER(quads),
CR_MEMBER(los),
CR_MEMBER(tempNum),
CR_MEMBER(lastSlowUpdate),
CR_MEMBER(mapSquare),
CR_MEMBER(controlRadius),
CR_MEMBER(losRadius),
CR_MEMBER(airLosRadius),
CR_MEMBER(losHeight),
CR_MEMBER(lastLosUpdate),
CR_RESERVED(16),
CR_MEMBER(radarRadius),
CR_MEMBER(sonarRadius),
CR_MEMBER(jammerRadius),
CR_MEMBER(sonarJamRadius),
CR_MEMBER(hasRadarCapacity),
CR_MEMBER(radarSquares),
CR_MEMBER(oldRadarPos),
CR_MEMBER(stealth),
CR_RESERVED(16),
CR_MEMBER(commandAI),
CR_MEMBER(moveType),
CR_MEMBER(prevMoveType),
CR_MEMBER(usingScriptMoveType),
CR_MEMBER(group),
CR_RESERVED(16),
CR_MEMBER(condUseMetal),
CR_MEMBER(condUseEnergy),
CR_MEMBER(condMakeMetal),
CR_MEMBER(condMakeEnergy),
CR_MEMBER(uncondUseMetal),
CR_MEMBER(uncondUseEnergy),
CR_MEMBER(uncondMakeMetal),
CR_MEMBER(uncondMakeEnergy),
CR_MEMBER(metalUse),
CR_MEMBER(energyUse),
CR_MEMBER(metalMake),
CR_MEMBER(energyMake),
CR_MEMBER(metalUseI),
CR_MEMBER(energyUseI),
CR_MEMBER(metalMakeI),
CR_MEMBER(energyMakeI),
CR_MEMBER(metalUseold),
CR_MEMBER(energyUseold),
CR_MEMBER(metalMakeold),
CR_MEMBER(energyMakeold),
CR_MEMBER(energyTickMake),
CR_MEMBER(metalExtract),
CR_MEMBER(metalCost),
CR_MEMBER(energyCost),
CR_MEMBER(buildTime),
CR_RESERVED(16),
CR_MEMBER(metalStorage),
CR_MEMBER(energyStorage),
CR_MEMBER(lastAttacker),
CR_MEMBER(lastAttack),
CR_MEMBER(lastDamage),
CR_MEMBER(lastFireWeapon),
CR_MEMBER(recentDamage),
CR_MEMBER(userTarget),
CR_MEMBER(userAttackPos),
CR_MEMBER(userAttackGround),
CR_MEMBER(commandShotCount),
CR_MEMBER(fireState),
CR_MEMBER(dontFire),
CR_MEMBER(moveState),
CR_MEMBER(activated),
CR_RESERVED(32),
//CR_MEMBER(model),
//CR_MEMBER(cob),
//CR_MEMBER(localmodel),
CR_MEMBER(tooltip),
CR_MEMBER(crashing),
CR_MEMBER(isDead),
CR_MEMBER(falling),
CR_MEMBER(fallSpeed),
CR_MEMBER(flankingBonusMode),
CR_MEMBER(flankingBonusDir),
CR_MEMBER(flankingBonusAvgDamage),
CR_MEMBER(flankingBonusDifDamage),
CR_MEMBER(flankingBonusMobility),
CR_MEMBER(flankingBonusMobilityAdd),
CR_MEMBER(armoredState),
CR_MEMBER(armoredMultiple),
CR_MEMBER(curArmorMultiple),
CR_RESERVED(16),
CR_MEMBER(wreckName),
CR_MEMBER(posErrorVector),
CR_MEMBER(posErrorDelta),
CR_MEMBER(nextPosErrorUpdate),
CR_MEMBER(hasUWWeapons),
CR_MEMBER(wantCloak),
CR_MEMBER(scriptCloak),
CR_MEMBER(cloakTimeout),
CR_MEMBER(curCloakTimeout),
CR_MEMBER(isCloaked),
CR_MEMBER(decloakDistance),
CR_MEMBER(lastTerrainType),
CR_MEMBER(curTerrainType),
CR_MEMBER(alphaThreshold),
CR_MEMBER(selfDCountdown),
CR_RESERVED(16),
//CR_MEMBER(directControl),
//CR_MEMBER(myTrack), //unused
CR_MEMBER(incomingMissiles),
CR_MEMBER(lastFlareDrop),
CR_MEMBER(seismicRadius),
CR_MEMBER(seismicSignature),
CR_MEMBER(maxSpeed),
CR_MEMBER(weaponHitMod),
CR_RESERVED(128),
CR_POSTLOAD(PostLoad)
));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -