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