Example #1
0
bool CUnit::UseEnergy(float energy)
{
    if(energy<0) {
        AddEnergy(-energy);
        return true;
    }
    bool canUse=gs->Team(team)->UseEnergy(energy);
    if(canUse)
        energyUseI += energy;
    return canUse;
}
Example #2
0
void Margolus::SetEnergy(const string& name1, const string& name2,
        double* energyH, double* energyS) {
    for (Energy & en : energy) {
        if ((en.name1 == name1 && en.name2 == name2)
                || (en.name1 == name2 && en.name2 == name1) ) {
            en.energyH = energyH;
            en.energyS = energyS;
            return;
        }
    }
    AddEnergy(name1, name2, energyH, energyS);
}
Example #3
0
void MapMaster::FillAtmosphere()
{
    for (int z = 0; z < GetDepth(); ++z)
        for (int x = 0; x < GetWidth(); ++x)
            for (int y = 0; y < GetHeight(); ++y)
                if (   squares_[x][y][z]->GetTurf()
                    && squares_[x][y][z]->GetTurf()->GetAtmosState() != SPACE
                    && squares_[x][y][z]->GetTurf()->GetAtmosState() != NON_SIMULATED
                    && CanPass(squares_[x][y][z]->GetPassable(D_ALL), Passable::AIR))
                {
                    auto a = squares_[x][y][z]->GetAtmosHolder();
                    a->AddGase(NYTROGEN, 750);
                    a->AddGase(OXYGEN, 230);
                    a->AddGase(CO2, 1);
                    a->AddEnergy(1000);
                }
}
Example #4
0
void CUnit::SlowUpdate()
{
    --nextPosErrorUpdate;
    if(nextPosErrorUpdate==0) {
        float3 newPosError(gs->randVector());
        newPosError.y*=0.2;
        if(posErrorVector.dot(newPosError)<0)
            newPosError=-newPosError;
        posErrorDelta=(newPosError-posErrorVector)*(1.0/256);
        nextPosErrorUpdate=16;
    }

    for(int a=0; a<gs->activeAllyTeams; ++a) {
        if(losStatus[a] & LOS_INTEAM) {
        } else if(loshandler->InLos(this,a)) {
            if(!(losStatus[a]&LOS_INLOS)) {
                int prevLosStatus = losStatus[a];

                if(mobility || beingBuilt) {
                    losStatus[a]|=(LOS_INLOS | LOS_INRADAR);
                } else {
                    losStatus[a]|=(LOS_INLOS | LOS_INRADAR | LOS_PREVLOS | LOS_CONTRADAR);
                }

                if(!(prevLosStatus&LOS_INRADAR)) {
                    globalAI->UnitEnteredRadar(this,a);
                }
                globalAI->UnitEnteredLos(this,a);
            }
        } else if(radarhandler->InRadar(this,a)) {
            if((losStatus[a] & LOS_INLOS)) {
                globalAI->UnitLeftLos(this,a);
                losStatus[a]&= ~LOS_INLOS;
            } else if(!(losStatus[a] & LOS_INRADAR)) {
                losStatus[a]|= LOS_INRADAR;
                globalAI->UnitEnteredRadar(this,a);
            }
        } else {
            if((losStatus[a]&LOS_INRADAR)) {
                if((losStatus[a]&LOS_INLOS)) {
                    globalAI->UnitLeftLos(this,a);
                    globalAI->UnitLeftRadar(this,a);
                } else {
                    globalAI->UnitLeftRadar(this,a);
                }
                losStatus[a]&= ~(LOS_INLOS | LOS_INRADAR | LOS_CONTRADAR);
            }
        }
    }
    if(paralyzeDamage>0) {
        paralyzeDamage-=maxHealth*(16.f/30.f/40.f);
        if(paralyzeDamage<0)
            paralyzeDamage=0;
        if(paralyzeDamage<health)
            stunned=false;
    }
    if(stunned) {
        isCloaked=false;
        return;
    }

    if(selfDCountdown && !stunned) {
        selfDCountdown--;
        if(selfDCountdown<=1) {
            if(!beingBuilt)
                KillUnit(true,false,0);
            else
                KillUnit(false,true,0);	//avoid unfinished buildings making an explosion
            selfDCountdown=0;
            return;
        }
        ENTER_MIXED;
        if(selfDCountdown&1 && team==gu->myTeam)
            info->AddLine("%s: Self destruct in %i s",unitDef->humanName.c_str(),selfDCountdown/2);
        ENTER_SYNCED;
    }

    if(beingBuilt) {
        if(lastNanoAdd<gs->frameNum-200) {
            health-=maxHealth/(buildTime*0.03);
            buildProgress-=1/(buildTime*0.03);
            AddMetal(metalCost/(buildTime*0.03));
            if(health<0)
                KillUnit(false,true,0);
        }
        return;
    }
    //below is stuff that shouldnt be run while being built

    lastSlowUpdate=gs->frameNum;

    commandAI->SlowUpdate();
    moveType->SlowUpdate();

    metalMake = metalMakeI + metalMakeold;
    metalUse = metalUseI+ metalUseold;
    energyMake = energyMakeI + energyMakeold;
    energyUse = energyUseI + energyUseold;
    metalMakeold = metalMakeI;
    metalUseold = metalUseI;
    energyMakeold = energyMakeI;
    energyUseold = energyUseI;

    metalMakeI=metalUseI=energyMakeI=energyUseI=0;

    AddMetal(unitDef->metalMake*0.5f);
    if(activated)
    {
        if(UseEnergy(unitDef->energyUpkeep*0.5f))
        {
            if(unitDef->isMetalMaker) {
                AddMetal(unitDef->makesMetal*0.5f*uh->metalMakerEfficiency);
                uh->metalMakerIncome+=unitDef->makesMetal;
            } else {
                AddMetal(unitDef->makesMetal*0.5f);
            }
            if(unitDef->extractsMetal>0)
                AddMetal(metalExtract * 0.5f);
        }
        UseMetal(unitDef->metalUpkeep*0.5f);

        if(unitDef->windGenerator>0)
        {
            if(wind.curStrength > unitDef->windGenerator)
            {
                AddEnergy(unitDef->windGenerator*0.5f);
            }
            else
            {
                AddEnergy(wind.curStrength*0.5f);
            }
        }
    }
    AddEnergy(energyTickMake*0.5f);

    if(health<maxHealth)
    {
        health += unitDef->autoHeal;

        if(restTime > unitDef->idleTime)
        {
            health += unitDef->idleAutoHeal;
        }
        if(health>maxHealth)
            health=maxHealth;
    }

    bonusShieldSaved+=0.05f;
    residualImpulse*=0.6;

    if(wantCloak) {
        if(helper->GetClosestEnemyUnitNoLosTest(pos,unitDef->decloakDistance,allyteam)) {
            curCloakTimeout=gs->frameNum+cloakTimeout;
            isCloaked=false;
        }
        if(isCloaked || gs->frameNum>=curCloakTimeout) {
            float cloakCost=unitDef->cloakCost;
            if(speed.SqLength()>0.2)
                cloakCost=unitDef->cloakCostMoving;
            if(UseEnergy(cloakCost * 0.5f)) {
                isCloaked=true;
            } else {
                isCloaked=false;
            }
        } else {
            isCloaked=false;
        }
    } else {
        isCloaked=false;
    }


    if(uh->waterDamage && (physicalState==CSolidObject::Floating || (physicalState==CSolidObject::OnGround && pos.y<=-3 && readmap->mipHeightmap[1][int((pos.z/(SQUARE_SIZE*2))*gs->hmapx+(pos.x/(SQUARE_SIZE*2)))]<-1))) {
        DoDamage(DamageArray()*uh->waterDamage,0,ZeroVector);
    }

    if(unitDef->canKamikaze) {
        if(fireState==2) {
            CUnit* u=helper->GetClosestEnemyUnitNoLosTest(pos,unitDef->kamikazeDist,allyteam);
            if(u && u->physicalState!=CSolidObject::Flying && u->speed.dot(pos - u->pos)<=0)		//self destruct when unit start moving away from mine, should maximize damage
                KillUnit(true,false,0);
        }
        if(userTarget && userTarget->pos.distance(pos)<unitDef->kamikazeDist)
            KillUnit(true,false,0);
        if(userAttackGround && userAttackPos.distance(pos)<unitDef->kamikazeDist)
            KillUnit(true,false,0);
    }

    if(!weapons.empty()) {
        haveTarget=false;
        haveUserTarget=false;

        //aircraft does not want this
        if (moveType->useHeading) {
            frontdir=GetVectorFromHeading(heading);
            if(upright || !unitDef->canmove) {
                updir=UpVector;
                rightdir=frontdir.cross(updir);
            } else {
                updir=ground->GetNormal(pos.x,pos.z);
                rightdir=frontdir.cross(updir);
                rightdir.Normalize();
                frontdir=updir.cross(rightdir);
            }
        }

        if(!dontFire) {
            for(vector<CWeapon*>::iterator wi=weapons.begin(); wi!=weapons.end(); ++wi) {
                CWeapon* w=*wi;
                if(userTarget && !w->haveUserTarget && (haveDGunRequest || !unitDef->canDGun || !w->weaponDef->manualfire))
                    w->AttackUnit(userTarget,true);
                else if(userAttackGround && !w->haveUserTarget && (haveDGunRequest || !unitDef->canDGun || !w->weaponDef->manualfire))
                    w->AttackGround(userAttackPos,true);

                w->SlowUpdate();

                if(w->targetType==Target_None && fireState>0 && lastAttacker && lastAttack+200>gs->frameNum)
                    w->AttackUnit(lastAttacker,false);
            }
        }
    }

    if(moveType->progressState == CMoveType::Active)
    {
        if(/*physicalState == OnGround*/seismicSignature && !(losStatus[gu->myAllyTeam] & LOS_INLOS) &&  radarhandler->InSeismicDistance(this, gu->myAllyTeam))
            new CSimpleGroundFlash(pos + float3(radarhandler->radarErrorSize[gu->myAllyTeam]*(0.5f-gu->usRandFloat()),0,radarhandler->radarErrorSize[gu->myAllyTeam]*(0.5f-gu->usRandFloat())), ph->seismictex, 30, 15, 0, seismicSignature, 1, float3(0.8,0.0,0.0));
    }

    CalculateTerrainType();
    UpdateTerrainType();
}