Ejemplo n.º 1
0
void BattleGroundEY::Update(uint32 diff)
{
    BattleGround::Update(diff);

    if (GetStatus() != STATUS_IN_PROGRESS)
        return;

    // resource counter
    if (m_resourceUpdateTimer < diff)
    {
        UpdateResources();
        m_resourceUpdateTimer = EY_RESOURCES_UPDATE_TIME;
    }
    else
        m_resourceUpdateTimer -= diff;

    // flag respawn
    if (m_flagState == EY_FLAG_STATE_WAIT_RESPAWN || m_flagState == EY_FLAG_STATE_ON_GROUND)
    {
        if (m_flagRespawnTimer < diff)
        {
            m_flagRespawnTimer = 0;
            if (m_flagState == EY_FLAG_STATE_WAIT_RESPAWN)
                RespawnFlag();
            else
                RespawnDroppedFlag();
        }
        else
            m_flagRespawnTimer -= diff;
    }
}
Ejemplo n.º 2
0
void TowerDefenseInstanceScript::TowerDefenseMapInstanceScript::SellGuard(uint64 guid)
{
    if(!guid)
        return;
    Player* player = GetPlayer();
    if(!player)
        return;
    Creature* creature = player->GetMap()->GetCreature(guid);
    if(!creature)
        return;
    uint32 entry = GUID_ENPART(guid);
    if (Guards.find(guid) != Guards.end())
    {
        GuardInfo* guard = Guards[guid];
        if(QueryResult queryResult = CharacterDatabase.PQuery("SELECT creatureName, creatureEntry, creatureCost FROM custom_td_base_stats WHERE creatureEntry = '%u'", entry))
        {   
            creature->CastSpell(creature, GetSpellIdByUniqueId(5),true);
            uint32 SellPrice = guard->GetSellPrice(guard->GetLevel());
            switch(GetEventMode())
            {
            case TD_EVENT_MODE_HARD:
                SellPrice = SellPrice - (SellPrice/4);
                break;
            case TD_EVENT_MODE_EXTREME:
                SellPrice = SellPrice - (SellPrice/2);
                break;
            }
            UpdateResources(TD_EVENT_INC,SellPrice);
            SendMessageToPlayer(TD_SYSTEM_MSG_SOLD_TOWER_FOR, creature->GetName(),SellPrice);
            creature->DisappearAndDie();
            Guards.erase(guid);
        }
    } 
}
Ejemplo n.º 3
0
void BattleGroundEY::Update(uint32 diff)
{
    BattleGround::Update(diff);

    if (GetStatus() != STATUS_IN_PROGRESS)
        return;

    // resource counter
    if (m_resourceUpdateTimer < diff)
    {
        UpdateResources();
        m_resourceUpdateTimer = EY_RESOURCES_UPDATE_TIME;
    }
    else
        m_resourceUpdateTimer -= diff;

    // flag respawn
    if (m_flagState == EY_FLAG_STATE_WAIT_RESPAWN || m_flagState == EY_FLAG_STATE_ON_GROUND)
    {
        if (m_flagRespawnTimer < diff)
        {
            m_flagRespawnTimer = 0;
            if (m_flagState == EY_FLAG_STATE_WAIT_RESPAWN)
                RespawnFlag();
            else
                RespawnDroppedFlag();
        }
        else
            m_flagRespawnTimer -= diff;
    }

    // workaround for Fel Reaver Ruins flag capture needed on 3.3.5 only
    // the original areatrigger (4514) is covered by a bigger one (4515) and is not triggered on client side
    if (IsFlagPickedUp())
    {
        if (m_felReaverFlagTimer < diff)
        {
            Player* flagCarrier = sObjectMgr.GetPlayer(GetFlagCarrierGuid());
            if (flagCarrier)
            {
                if (m_towerOwner[NODE_FEL_REAVER_RUINS] == flagCarrier->GetTeam())
                {
                    // coords and range taken from DBC of areatrigger (4514)
                    if (flagCarrier->IsWithinDist3d(2044.0f, 1729.729f, 1190.03f, 3.0f))
                        EventPlayerCapturedFlag(flagCarrier, NODE_FEL_REAVER_RUINS);
                }
            }
            m_felReaverFlagTimer = EY_FEL_REAVER_FLAG_UPDATE_TIME;
        }
        else
            m_felReaverFlagTimer -= diff;
    }
}
Ejemplo n.º 4
0
void CUnit::SlowUpdate()
{
	--nextPosErrorUpdate;
	if(nextPosErrorUpdate==0){
		float3 newPosError(gs->randVector());
		newPosError.y*=0.2f;
		if(posErrorVector.dot(newPosError)<0)
			newPosError=-newPosError;
		posErrorDelta=(newPosError-posErrorVector)*(1.0f/256);
		nextPosErrorUpdate=16;
	}

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

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

				if(!(prevLosStatus&LOS_INRADAR)){
					luaCallIns.UnitEnteredRadar(this, a);
					globalAI->UnitEnteredRadar(this, a);
				}
				luaCallIns.UnitEnteredLos(this, a);
				globalAI->UnitEnteredLos(this, a);
			}
		} else if (radarhandler->InRadar(this, a)) {
			if ((losStatus[a] & LOS_INLOS)) {
				luaCallIns.UnitLeftLos(this, a);
				globalAI->UnitLeftLos(this, a);
				losStatus[a] &= ~LOS_INLOS;
			} else if (!(losStatus[a] & LOS_INRADAR)) {
				losStatus[a] |= LOS_INRADAR;
				luaCallIns.UnitEnteredRadar(this, a);
				globalAI->UnitEnteredRadar(this, a);
			}
		} else {
			if ((losStatus[a] & LOS_INRADAR)) {
				if ((losStatus[a] & LOS_INLOS)) {
					luaCallIns.UnitLeftLos(this, a);
					luaCallIns.UnitLeftRadar(this, a);
					globalAI->UnitLeftLos(this, a);
					globalAI->UnitLeftRadar(this, a);
				} else {
					luaCallIns.UnitLeftRadar(this, a);
					globalAI->UnitLeftRadar(this, a);
				}
				losStatus[a] &= ~(LOS_INLOS | LOS_INRADAR | LOS_CONTRADAR);
			}
		}
	}

	if (paralyzeDamage > 0) {
		paralyzeDamage -= maxHealth * (16.0f / 30.0f / 40.0f);
		if (paralyzeDamage < 0) {
			paralyzeDamage = 0;
		}
		if (paralyzeDamage < health) {
			stunned = false;
		}
	}

	if (stunned) {
		isCloaked = false;
		UpdateResources();
		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)
			logOutput.Print("%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.03f);
			buildProgress-=1/(buildTime*0.03f);
			AddMetal(metalCost/(buildTime*0.03f));
			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();

	UpdateResources();

	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.6f;

	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.2f)
				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, -1);
	}

	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 and ScriptMoveType do not want this
		if (moveType->useHeading) {
			frontdir=GetVectorFromHeading(heading);
			if(transporter && transporter->unitDef->holdSteady) {
				updir = transporter->updir;
				rightdir=frontdir.cross(updir);
				rightdir.Normalize();
				frontdir=updir.cross(rightdir);
			} else 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 (seismicSignature) {
			float rx = gs->randFloat();
			float rz = gs->randFloat();

			const float* errorScale = radarhandler->radarErrorSize;
			if (!(losStatus[gu->myAllyTeam] & LOS_INLOS) &&
			    radarhandler->InSeismicDistance(this, gu->myAllyTeam)) {
				const float3 err(errorScale[gu->myAllyTeam] * (0.5f - rx), 0.0f,
				                 errorScale[gu->myAllyTeam] * (0.5f - rz));

				SAFE_NEW CSeismicGroundFlash(pos + err,
                                     ph->seismictex, 30, 15, 0, seismicSignature, 1,
                                     float3(0.8f,0.0f,0.0f));
			}
			for (int a=0; a<gs->activeAllyTeams; ++a) {
				if (radarhandler->InSeismicDistance(this, a)) {
					const float3 err(errorScale[a] * (0.5f - rx), 0.0f,
					                 errorScale[a] * (0.5f - rz));
					const float3 pingPos = (pos + err);
					luaCallIns.UnitSeismicPing(this, a, pingPos, seismicSignature);
					globalAI->SeismicPing(a, this, pingPos, seismicSignature);
				}
			}
		}
	}

	CalculateTerrainType();
	UpdateTerrainType();
}
Ejemplo n.º 5
0
void TowerDefenseInstanceScript::TowerDefenseMapInstanceScript::UpgradeGuard(uint64 guid)
{
    if(!guid)
        return;
    Player* player = GetPlayer();
    if(!player)
        return;

    Creature* creature = player->GetMap()->GetCreature(guid);
    if(!creature)
        return;
    uint32 currentLevel = 0;
    uint32 entry = GUID_ENPART(guid);
    if (Guards.find(guid) != Guards.end())
    {
        GuardInfo* guard = Guards[guid];
        currentLevel = guard->Level;
        uint32 newLevel = currentLevel +1;
        if(QueryResult queryResult = CharacterDatabase.PQuery("SELECT creatureName, creatureEntry, creatureCost FROM custom_td_base_stats WHERE creatureEntry = '%u'", entry))
        {   
            uint32 UpgradeCost = guard->GetUpgradeCost();
            switch(GetEventMode())
            {
            case TD_EVENT_MODE_HARD:
                UpgradeCost = UpgradeCost + (UpgradeCost/4);
                break;
            case TD_EVENT_MODE_EXTREME:
                UpgradeCost = UpgradeCost + (UpgradeCost/2);
                break;
            }
            if(GetResources() < UpgradeCost){
                SendMessageToPlayer(TD_SYSTEM_MSG_MORE_RESOURCES_UPG, UpgradeCost - GetResources());
                return;
            }
            if(QueryResult queryResult = CharacterDatabase.PQuery("SELECT * FROM custom_td_base_levels WHERE creatureEntry = '%u' AND creatureLevel = '%u'", entry, newLevel))
            {
                creature->CastSpell(creature, GetSpellIdByUniqueId(4),true); // upgrade level visual
                guard->SetLevel(newLevel);
                UpdateResources(TD_EVENT_DEC,UpgradeCost); // remove resource cost from player
                creature->RemoveAllAuras(); // remove all auras to apply new ones.
                SendMessageToPlayer(TD_SYSTEM_MSG_UPGRADED_TOWER_FOR, creature->GetName(),UpgradeCost);

                Field* Fields = queryResult->Fetch();

                uint32 newDefaultSpell = Fields[4].GetUInt32();
                if(newDefaultSpell)
                    guard->SetDefSpell(newDefaultSpell);

                uint32 newAttackSpeed = Fields[9].GetUInt32();
                if (newAttackSpeed)
                    guard->SetAttSpeed(newAttackSpeed);

                float newAttackDistance = Fields[8].GetFloat();
                if(newAttackDistance)
                    guard->SetAttackDistance(newAttackDistance);

                uint32 newAura = Fields[7].GetUInt32();
                if(newAura)
                    creature->CastSpell(creature,newAura,true);

                uint32 newDisplay = Fields[6].GetUInt32();
                if(newDisplay)
                    creature->SetDisplayId(newDisplay);

                float  newScale = Fields[5].GetFloat();
                if(newScale)
                    creature->SetObjectScale(newScale);

                uint32 newDamage = Fields[10].GetUInt32();
                if (newDamage)
                    guard->SetDamage(newDamage);

                uint32 newIsAntiAir = Fields[11].GetBool();
                if (newIsAntiAir)
                    guard->SetIsAntiAir(newIsAntiAir);

                uint32 newIsAntiGround = Fields[12].GetBool();
                if (newIsAntiGround)
                    guard->SetIsAntiGround(newIsAntiGround);
            }
        }
    } 
}
Ejemplo n.º 6
0
void TowerDefenseInstanceScript::TowerDefenseMapInstanceScript::SpawnGuard(uint32 entry)
{
    if (!entry)
        return;
    Player *player = GetPlayer();
    if(!player)
        return;

    GuardInfo* guard = new GuardInfo();
    bool found = false;
    float objectX, objectY, objectZ, objectO;
    uint32 objectLowGUID, objectId;
    uint16 objectMap, objectPhase;
    uint32 objectPool;
    GameEventMgr::ActiveEvents const& activeEventsList = sGameEventMgr->GetActiveEventList();

    std::ostringstream eventFilter;
    eventFilter << " AND (eventEntry IS NULL ";
    bool initString = true;

    for (GameEventMgr::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr)
    {
        if (initString)
        {
            eventFilter  <<  "OR eventEntry IN (" << *itr;
            initString = false;
        }
        else
            eventFilter << ',' << *itr;
    }

    if (!initString)
        eventFilter << "))";
    else
        eventFilter << ')';

    QueryResult queryResult = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, phaseMask, "
        "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject "
        "LEFT OUTER JOIN game_event_gameobject on gameobject.guid = game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 10",
        player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),player->GetMapId(), eventFilter.str().c_str());

    if (!queryResult)
    {  
        SendMessageToPlayer(TD_SYSTEM_MSG_NO_NEARBY_PLATFORM);  // if there were no nearby platforms to place guards.
        return;
    }
    do
    {
        Field* fields = queryResult->Fetch();
        objectLowGUID = fields[0].GetUInt32();
        objectId =      fields[1].GetUInt32();
        objectX =       fields[2].GetFloat();
        objectY =       fields[3].GetFloat();
        objectZ =       fields[4].GetFloat();
        objectO =       fields[5].GetFloat();
        objectMap =   fields[6].GetUInt16();
        objectPhase =   fields[7].GetUInt16();
        objectPool =  sPoolMgr->IsPartOfAPool<GameObject>(objectLowGUID);
        if (!objectPool || sPoolMgr->IsSpawnedObject<GameObject>(objectLowGUID))
            found = true;
    } while (queryResult->NextRow() && !found);

    if (!found)
    {
        SendMessageToPlayer(TD_SYSTEM_MSG_NEARBY_PLATFORM_NOT_EXIST); // no nearby platform found
        return;
    }

    GameObjectTemplate const* objectInfo = sObjectMgr->GetGameObjectTemplate(objectId);
    if (!objectInfo)
    {
        SendMessageToPlayer(TD_SYSTEM_MSG_NEARBY_PLATFORM_NOT_EXIST); // nearby platform is not an actual object
        return;
    }
    guard->Entry = entry;
    guard->X = objectX;
    guard->Y = objectY;
    guard->Z = objectZ + 0.5; // depends on size of platform object
    guard->O = objectO;
    if(player->GetDistance(objectX,objectY,objectZ) > 3)
    {
        SendMessageToPlayer(TD_SYSTEM_MSG_NEARBY_PLATFORM_TOO_FAR);
        return;
    }else 
    {
        if(QueryResult queryResult = CharacterDatabase.PQuery("SELECT creatureEntry FROM custom_td_base_stats WHERE creatureType = 'Guard' ORDER BY Id ASC LIMIT 1"))
        {
            do
            {
                Field *Fields = queryResult->Fetch();
                uint32 creatureEntry = Fields[0].GetUInt32();

                Creature* creature = player->FindNearestCreature(creatureEntry,2,true);
                if(creature){
                    SendMessageToPlayer(TD_SYSTEM_MSG_NEARBY_GUARD_TOO_CLOSE);
                    return;
                }
            }while(queryResult->NextRow());
        }

        if(QueryResult queryResult = CharacterDatabase.PQuery("SELECT creatureName, creatureEntry, creatureCost FROM custom_td_base_stats WHERE creatureEntry = '%u'", entry))
        {
            Field *Fields = queryResult->Fetch();
            std::string creatureName = Fields[0].GetString();
            uint32 creatureEntry = Fields[1].GetUInt32();
            uint32 creatureCost = Fields[2].GetUInt32();
            if(GetResources() < creatureCost)
            {
                SendMessageToPlayer(TD_SYSTEM_MSG_MORE_RESOURCES, creatureCost - GetResources());
                return;
            }else
            {
                guard->Spawn(player);
                Guards[guard->Guid] = guard;
                guard->SetDefSpell(guard->GetSpellIdByCastType(TD_CAST_DEFAULT_CAST_TARGET)); // set default spell
                UpdateResources(TD_EVENT_DEC,creatureCost);
                SendMessageToPlayer(TD_SYSTEM_MSG_BOUGHT_GUARD, creatureName.c_str(), creatureCost);
                RecordLog("TowerDefense: Event ID: [%u] has spawned Guard Entry: [%u] for [%u] resources.", GetEventId(), guard->Entry,creatureCost);
            }  
        }
    }
}