bool LifeTap(uint32 i, Spell* s) { Player* playerTarget = s->GetPlayerTarget(); if(!s->p_caster || !playerTarget) return false; uint32 mod; // spirit bonus coefficient multiplied by 2 if(s->GetProto()->Id == 1454) mod = 2; else if(s->GetProto()->Id == 1455) mod = 3; else if(s->GetProto()->Id == 1456) mod = 4; else if(s->GetProto()->Id == 11687) mod = 5; else mod = 6; uint32 damage = s->GetProto()->EffectBasePoints[i] + 1 + mod * playerTarget->GetStat(STAT_SPIRIT) / 2; if(damage >= playerTarget->GetHealth()) return false; s->p_caster->DealDamage(playerTarget, damage, 0, 0, s->GetProto()->Id); damage = damage * (100 + playerTarget->m_lifetapbonus) / 100; // Apply improved life tap if(playerTarget->GetPower(POWER_TYPE_MANA) + damage > playerTarget->GetMaxPower(POWER_TYPE_MANA)) playerTarget->SetPower(POWER_TYPE_MANA, playerTarget->GetMaxPower(POWER_TYPE_MANA)); else playerTarget->SetPower(POWER_TYPE_MANA, playerTarget->GetPower(POWER_TYPE_MANA) + damage); s->SendHealManaSpellOnPlayer(s->p_caster, playerTarget, damage, POWER_TYPE_MANA, s->GetProto()->Id); return true; }
uint8 AoeHealValue::Calculate() { Group* group = bot->GetGroup(); if (!group) return 0; float range = 0; if (qualifier == "low") range = sPlayerbotAIConfig.lowHealth; else if (qualifier == "medium") range = sPlayerbotAIConfig.mediumHealth; else if (qualifier == "critical") range = sPlayerbotAIConfig.criticalHealth; uint8 count = 0; Group::MemberSlotList const& groupSlot = group->GetMemberSlots(); for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++) { Player *player = sObjectMgr->GetPlayerByLowGUID(itr->guid); if( !player || !player->IsAlive()) continue; float percent = (static_cast<float> (player->GetHealth()) / player->GetMaxHealth()) * 100; if (percent <= range) count++; } return count; }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { CHECK_PACKET_SIZE(recv_data,8); sLog.outDebug("WORLD RECIEVED CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recv_data >> Guid; Player *player = objmgr.GetPlayer(Guid); if(!player) return; WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+1+2+2+1+2*6+8+1+8); data.append(player->GetPackGUID()); uint32 mask1 = 0x7FFC0BFF; // real flags used 0x000040BFF //0x7FFC1BFF; // for hunters etc (GROUP_UPDATE_FLAG_PET_MODEL_ID) Powers powerType = player->getPowerType(); data << (uint32) mask1; // group update mask data << (uint8) MEMBER_STATUS_ONLINE; // member's online status data << (uint16) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP data << (uint16) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION data << (uint64) 0xFF00000000000000LL; // GROUP_UPDATE_FLAG_AURAS //data << (uint16) player->GetPet()->GetUInt32Value(UNIT_FIELD_DISPLAYID); // GROUP_UPDATE_FLAG_PET_MODEL_ID, for hunters etc... data << (uint8) 0x00; // GROUP_UPDATE_FLAG_PET_NAME data << (uint64) 0xFF00000000000000LL; // GROUP_UPDATE_FLAG_PET_AURAS SendPacket(&data); }
void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) { Player* target = GetTarget()->ToPlayer(); if (dmgInfo.GetDamage() < target->GetHealth() || target->HasSpellCooldown(ROGUE_SPELL_CHEAT_DEATH_COOLDOWN) || !roll_chance_i(absorbChance)) return; target->CastSpell(target, ROGUE_SPELL_CHEAT_DEATH_COOLDOWN, true); target->AddSpellCooldown(ROGUE_SPELL_CHEAT_DEATH_COOLDOWN, 0, time(NULL) + 60); uint32 health10 = target->CountPctFromMaxHealth(10); // hp > 10% - absorb hp till 10% if (target->GetHealth() > health10) absorbAmount = dmgInfo.GetDamage() - target->GetHealth() + health10; // hp lower than 10% - absorb everything else absorbAmount = dmgInfo.GetDamage(); }
void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) { Player* target = GetTarget()->ToPlayer(); if (dmgInfo.GetDamage() < target->GetHealth() || target->GetSpellHistory()->HasCooldown(SPELL_ROGUE_CHEAT_DEATH_COOLDOWN) || !roll_chance_i(absorbChance)) return; target->CastSpell(target, SPELL_ROGUE_CHEAT_DEATH_COOLDOWN, true); target->GetSpellHistory()->AddCooldown(SPELL_ROGUE_CHEAT_DEATH_COOLDOWN, 0, std::chrono::minutes(1)); uint32 health10 = target->CountPctFromMaxHealth(10); // hp > 10% - absorb hp till 10% if (target->GetHealth() > health10) absorbAmount = dmgInfo.GetDamage() - target->GetHealth() + health10; // hp lower than 10% - absorb everything else absorbAmount = dmgInfo.GetDamage(); target->CastSpell(target, 45182); // cheat death aura }
void RemoveBite() { if (!pInstance) return; Map::PlayerList const &PlayerList = pInstance->instance->GetPlayers(); if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { Player* pPlayer = i->getSource(); if (pPlayer && pPlayer->HasAura(SPELL_GRIEVOUS_BITE) && (pPlayer->GetHealth() == pPlayer->GetMaxHealth())) pPlayer->RemoveAurasDueToSpell(SPELL_GRIEVOUS_BITE); } }
void Player::RollAttack(Player& defender, string& writeOut) { int AttackRoll = D20Role(); int DamageRoll = AttackDmg(); stringstream toStrHlth; stringstream toStrDmg; string strDmg; if (AttackRoll == 20) { DamageRoll = DamageRoll*2; toStrDmg << DamageRoll; strDmg = toStrDmg.str(); defender.RemoveHealth(DamageRoll); toStrHlth << defender.GetHealth(); string strHlth = toStrHlth.str(); writeOut = ("Critical hit! " + name + " deals " + strDmg + " damage! " + defender.GetName() + " has " + strHlth + " health left."); } else { toStrDmg << DamageRoll; strDmg = toStrDmg.str(); if ((AttackRoll + attackBonus) > defender.GetAC()) { defender.RemoveHealth(DamageRoll); toStrHlth << defender.GetHealth(); string strHlth = toStrHlth.str(); writeOut = ( GetName() + " deals " + strDmg + " damage. " + defender.GetName() + " has " + strHlth + " health left."); } else writeOut = ( GetName() + " misses!"); } }
void bot_ai::BuffAndHealGroup(Player *gPlayer) { if(m_creature->IsNonMeleeSpellCasted(true)) return; // if I'm already casting std::list<Unit*> unitList; gPlayer->GetRaidMember(unitList,30); if(!unitList.empty()){ for (std::list<Unit*>::iterator itr = unitList.begin() ; itr!=unitList.end();++itr) { Player *tPlayer = ((Player *)master)->GetObjPlayer((*itr)->GetGUID()); if(tPlayer == NULL) continue; if(tPlayer->isDead()) continue; if(m_creature->GetAreaId() != gPlayer->GetAreaId()) continue; //if(tPlayer->GetGUID() == GetPlayerBot()->GetGUID()) continue; //if(m_creature->GetDistance(tPlayer) > 30) continue; (HealTarget(tPlayer, tPlayer->GetHealth()*100 / tPlayer->GetMaxHealth())); BuffTarget(tPlayer); } } }
void Roller::Update(const jutil::GameTime& elapsed, Player& player) { bool collided = false; if (player.GetHealth() <= 0) return; for (int i = 0; i < sprites.size(); i++) { sprites[i].SetNumFrames(2); sprites[i].Update(elapsed); if (!collided && player.CheckCollision(&sprites[i])) { if (_direction) player.GetRigidBody()->ApplyForce(jmath::vec3(0.40f, 0, 0)); else player.GetRigidBody()->ApplyForce(jmath::vec3(-0.40f, 0, 0)); collided = true; } } }
void HUD::DrawHUD() { if (sf::Keyboard::isKeyPressed(sf::Keyboard::F9)) { isShowingHud = false; } else { isShowingHud = true; if (isShowingHud) { pixelFontForHealth.loadFromFile("fonts/pixel.ttf"); health.setFont(pixelFontForHealth); health.setString("Health "); health.setPosition(25, 25); health.setStyle(sf::Text::Style::Regular); healthText.setFont(pixelFontForHealth); healthText.setString(sf::String(std::to_string(playerHealth.GetHealth()))); } } }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 guid; recvData >> guid; Player* player = HashMapHolder<Player>::Find(guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } Pet* pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 mask1 = GROUP_UPDATE_FULL; if (!pet) mask1 &= ~GROUP_UPDATE_PET; Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status, GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8 (powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION // GROUP_UPDATE_FLAG_AURAS data << uint8(1); uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << uint64(pet->GetGUID()); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8 (petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER // GROUP_UPDATE_FLAG_PET_AURAS data << uint8(1); uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } // else not needed, flags do not include any PET_ update // GROUP_UPDATE_FLAG_PHASE data << uint32(8); // either 0 or 8, same unk found in SMSG_PHASESHIFT data << uint32(0); // count // for (count) *data << uint16(phaseId) SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recv_data >> Guid; Player *player = sObjectMgr.GetPlayer(Guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Unit *pet = player->GetCharmOrPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0xFFFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 aura = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aura); data << uint8(1); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 petaura = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(petaura); data << uint8(1); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS data << (uint32) player->m_movementInfo.GetTransportDBCSeat(); } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
//============================================================================== void GameServer::tick() { /*float dt = (time_.elapsed() - lastTime_) * 0.001f;*/ lastTime_ = time_.elapsed(); /*if (actors_.size() < 100 && !testingStageActive_) { GenMonsters_(); }*/ auto collideWithGrid = [=](Actor* actor, EActorDirection direction) { auto& p = *actor; float x = p.GetPosition().x; float y = p.GetPosition().y; bool collided = false; if ((levelMap_.GetCell(x + 0.49f, y - 0.51f) != '.' || levelMap_.GetCell(x + 0.49f, y + 0.49f) != '.') && levelMap_.GetCell(x - slideThreshold_+ 0.5f, y) == '.' && (direction == EActorDirection::NORTH || direction == EActorDirection::SOUTH)) { p.SetPosition(Vector2(x - slideThreshold_+ 0.0001f, p.GetPosition().y)); } if (levelMap_.GetCell(x + slideThreshold_- 0.5f, y) == '.' &&((levelMap_.GetCell(x - 0.5f, y - 0.51f) != '.' || levelMap_.GetCell(x - 0.5f, y + 0.49f) != '.') && (direction == EActorDirection::NORTH || direction == EActorDirection::SOUTH))) { p.SetPosition(Vector2(x + slideThreshold_- 0.0001f, p.GetPosition().y)); } if (levelMap_.GetCell(x, y - slideThreshold_ + 0.5f) == '.' && (levelMap_.GetCell(x - 0.51f, y + 0.49f) != '.' || levelMap_.GetCell(x + 0.49f, y + 0.49f) != '.') && (direction == EActorDirection::EAST || direction == EActorDirection::WEST)) { p.SetPosition(Vector2(p.GetPosition().x, y - slideThreshold_+ 0.0001f)); } if ((levelMap_.GetCell(x + 0.49f, y - 0.5f) != '.' || levelMap_.GetCell(x - 0.51f, y - 0.5f) != '.') && levelMap_.GetCell(x, y + slideThreshold_- 0.5f) == '.' && (direction == EActorDirection::EAST || direction == EActorDirection::WEST)) { p.SetPosition(Vector2(p.GetPosition().x, y + slideThreshold_ - 0.001f)); } if (levelMap_.GetCell(x + 0.5f, y) != '.') { p.SetPosition(Vector2(round(x + 0.5f) - 0.5f, p.GetPosition().y)); collided = true; } if (levelMap_.GetCell(x - 0.51f, y) != '.') { p.SetPosition(Vector2(round(x - 0.5f) + 0.5f, p.GetPosition().y)); collided = true; } if (levelMap_.GetCell(x, y + 0.5f) != '.') { p.SetPosition(Vector2(p.GetPosition().x, round(y + 0.5f) - 0.5f)); collided = true; } if (levelMap_.GetCell(x, y - 0.51f) != '.') { p.SetPosition(Vector2(p.GetPosition().x, round(y - 0.5f) + 0.5f)); collided = true; } if (collided) { actor->OnCollideWorld(); } }; for (Actor* actor: actors_) { if (actor->GetType() == EActorType::MONSTER) { Monster* monster = dynamic_cast<Monster*>(actor); Creature* target = monster->target; float distance2; Vector2 m_pos = actor->GetPosition(); if (target && target != nullptr) { Vector2 t_pos = target->GetPosition(); distance2 = Sqr(m_pos.x - t_pos.x) + Sqr(m_pos.y - t_pos.y); if (distance2 < 25) { if (abs(m_pos.x - t_pos.x - 1.0f) < playerVelocity_ && m_pos.x - t_pos.x - 1.0f != 0) { monster->SetPosition(Vector2(t_pos.x + 1.0f, m_pos.y)); monster->SetDirection(EActorDirection::NONE); } if (abs(m_pos.y - t_pos.y + 1.0f) < playerVelocity_ && m_pos.y - t_pos.y + 1.0f != 0) { monster->SetPosition(Vector2(m_pos.x, t_pos.y - 1.0f)); monster->SetDirection(EActorDirection::NONE); } if (m_pos.x < t_pos.x - 1.0f) { monster->SetDirection(EActorDirection::EAST); } else if (m_pos.x > t_pos.x + 1.0f) { monster->SetDirection(EActorDirection::WEST); } else if (m_pos.y < t_pos.y - 1.0f) { monster->SetDirection(EActorDirection::SOUTH); } else if (m_pos.y > t_pos.y + 1.0f) { monster->SetDirection(EActorDirection::NORTH); } } } if (!target || target == nullptr || distance2 >= 5) { for (Actor* tar : actors_) { if (tar != monster) { bool b = false; if (tar->GetType() != EActorType::ITEM && tar->GetType () != EActorType::PROJECTILE) { Creature* m = dynamic_cast<Creature*>(tar); QStringList str = monster->Flags.filter("HATE"); for (QString hate: str) { if (Hates[hate] == m->GetRace()) { b = true; break; } } if (b) { Vector2 t_pos = tar->GetPosition(); distance2 = Sqr(m_pos.x - t_pos.x) + Sqr(m_pos.y - t_pos.y); // Dasha told 5^2 is a protocol defined const if (distance2 < 25) { monster->target = m; break; } } } } } } } if (actor->GetType() == EActorType::MONSTER || actor->GetType() == EActorType::PLAYER) { Creature* monster = dynamic_cast<Creature*>(actor); if (monster->GetHealth() <= 0) { KillActor_(actor); break; } } } for (Actor* actor: actors_) { if (!actor || actor == nullptr) { break; } auto v = directionToVector[static_cast<unsigned>(actor->GetDirection())] ; actor->SetVelocity(v); float dt = playerVelocity_; Vector2 old_pos = actor->GetPosition(); Vector2 new_pos = old_pos + v * (dt + 0.001); Vector2 old_pos2 = old_pos + v * 0.51; levelMap_.RemoveActor(actor); EActorDirection d = actor->GetDirection(); float x = new_pos.x; float y = new_pos.y; if (levelMap_.GetCell(old_pos2.x, old_pos2.y) != '#' && d != EActorDirection::NONE && (((levelMap_.GetCell(x - slideThreshold_+ 0.5f, y) == '.' && levelMap_.GetCell(x + slideThreshold_- 0.5f, y) == '.') && (d == EActorDirection::NORTH || d == EActorDirection::SOUTH)) || ((levelMap_.GetCell(x, y - slideThreshold_+ 0.5f) == '.' && levelMap_.GetCell(x, y + slideThreshold_- 0.5f) == '.') && (d == EActorDirection::EAST || d == EActorDirection::WEST)))) { if (levelMap_.GetCell(new_pos.x, new_pos.y) == '.') { if (!actor->Update(dt) && actor->GetType () == EActorType::PROJECTILE) { static_cast<Projectile*>(actor)->death = true; } collideWithGrid(actor, d); } else if (levelMap_.GetCell(x , y) != '.' && playerVelocity_ >= 1) { bool b = false; for (float i = 0.01; i <= dt; i += 0.01) { new_pos = old_pos + v * i + v * 0.5f; if (levelMap_.GetCell(new_pos.x, new_pos.y) == '#' && !b) { actor->Update(i - 0.01); b = true; } } } else { if (actor->GetType () == EActorType::PROJECTILE) { static_cast<Projectile*>(actor)->death = true; } } } else { if (actor && actor != nullptr) { if (actor->GetType () == EActorType::PROJECTILE) { static_cast<Projectile*>(actor)->death = true; } else { actor->OnCollideWorld(); } } } if (actor->GetType() == EActorType::PLAYER) { Player* player = dynamic_cast<Player*>(actor); if (player->GetHealth() < player->GetMaxHealth()) { player->SetHealth(player->GetHealth() + 1); } } if (actor->GetType() == EActorType::MONSTER) { Monster* monster = dynamic_cast<Monster*>(actor); Creature* target = monster->target; if (target && target->GetHealth() > 0) { Vector2 m_pos = actor->GetPosition(); Vector2 t_pos = target->GetPosition(); float distance2 = Sqr(m_pos.x - t_pos.x) + Sqr(m_pos.y - t_pos.y); if (distance2 <= Sqr(pickUpRadius_)) { events_ << monster->atack(target); events_ << target->atack(monster); } } } for (Actor* neighbour : actors_) { if (actor == nullptr || neighbour == nullptr || actor == neighbour || neighbour->GetType() == EActorType::ITEM || (actor->GetType() == EActorType::PROJECTILE && neighbour->GetType() == EActorType::PROJECTILE)) { break; } Box box0(neighbour->GetPosition(), 0.9f, 0.9f); Box box1(actor->GetPosition(), 0.9f, 0.9f); if (box0.Intersect(box1)) { actor->OnCollideActor(neighbour); neighbour->OnCollideActor(actor); if (actor->GetType() == EActorType::PROJECTILE) { static_cast<Projectile*>(actor)->death = true; if (neighbour->GetType () == EActorType::MONSTER) { Monster* monster = dynamic_cast<Monster*>(neighbour); if (monster->GetHealth () <= 0) { GetItems(monster); } } } else if (neighbour->GetType() == EActorType::PROJECTILE) { static_cast<Projectile*>(neighbour)->death = true; if (actor->GetType() == EActorType::MONSTER) { Monster* monster = dynamic_cast<Monster*>(actor); if (monster->GetHealth () <= 0) { GetItems(monster); } } } else if (neighbour->GetType() != EActorType::ITEM) { actor->SetPosition(old_pos); } } } if (actor->GetType() == EActorType::PROJECTILE && static_cast<Projectile*>(actor)->death) { QVariantMap ans1; ans1["radius"] = 1.0f; ans1["x"] = actor->GetPosition ().x; ans1["y"] = actor->GetPosition ().y; QVariantMap ans; ans["explode"] = ans1; events_ << ans; idToActor_.erase(actor->GetId()); actors_.erase(std::remove(actors_.begin(), actors_.end(), actor), actors_.end()); delete actor; actor = nullptr; } else { levelMap_.IndexActor(actor); } } QVariantMap tickMessage; tickMessage["tick"] = tick_; tickMessage["events"] = events_; events_.clear(); emit broadcastMessage(QString(QJsonDocument::fromVariant(tickMessage).toJson())); tick_++; }
void WorldSession::SendPartyMemberStatsChanged(uint64 Guid, uint32 mask) { if (mask == GROUP_UPDATE_FLAG_NONE) return; Player *player = objmgr.GetPlayer(Guid); if(!player) //currently do not send update if player is offline return; /*if(!player && mask != GROUP_UPDATE_FLAG_ONLINE) //if player is offline - then send nothing, but OFFLINE status return;*/ if(mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); uint32 byteCount = 0; for (int i=1;i<GROUP_UPDATE_FLAGS_COUNT;++i) if (mask & 1<<i) byteCount += GroupUpdateLength[i]; WorldPacket data(SMSG_PARTY_MEMBER_STATS, 8+4+byteCount); if (player) data.append(player->GetPackGUID()); else data.appendPackGUID(Guid); data << (uint32) mask; if (mask & GROUP_UPDATE_FLAG_ONLINE) { if (player) { if (player->IsPvP()) data << uint8(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); else data << (uint8) MEMBER_STATUS_ONLINE; } else data << (uint8) MEMBER_STATUS_OFFLINE; } if (mask & GROUP_UPDATE_FLAG_CUR_HP) data << (uint16) player->GetHealth(); if (mask & GROUP_UPDATE_FLAG_MAX_HP) data << (uint16) player->GetMaxHealth(); Powers powerType = player->getPowerType(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) data << (uint8) powerType; if (mask & GROUP_UPDATE_FLAG_CUR_POWER) data << (uint16) player->GetPower(powerType); if (mask & GROUP_UPDATE_FLAG_MAX_POWER) data << (uint16) player->GetMaxPower(powerType); if (mask & GROUP_UPDATE_FLAG_LEVEL) data << (uint16) player->getLevel(); if (mask & GROUP_UPDATE_FLAG_ZONE) data << (uint16) player->GetZoneId(); if (mask & GROUP_UPDATE_FLAG_POSITION) data << (uint16) player->GetPositionX() << (uint16) player->GetPositionY(); //TODO: add missing group update flags (pets?) SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 guid; recvData >> guid; Player* player = HashMapHolder<Player>::Find(guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(guid); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); Powers powerType = player->getPowerType(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; if (powerType != POWER_MANA) updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; if (pet) updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; uint16 playerStatus = MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->IsAlive()) { if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; data << uint32(updateFlags); data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) data << uint8(powerType); data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION // GROUP_UPDATE_FLAG_AURAS data << uint8(1); uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) data << uint64(pet->GetGUID()); data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP) data << uint32(pet->GetHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP) data << uint32(pet->GetMaxHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE) data << (uint8)pet->getPowerType(); if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER) data << uint16(pet->GetPower(pet->getPowerType())); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER) data << uint16(pet->GetMaxPower(pet->getPowerType())); uint64 petAuraMask = 0; maskPos = data.wpos(); data << uint64(petAuraMask); // placeholder if (pet) { // GROUP_UPDATE_FLAG_PET_AURAS data << uint8(1); uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } // else not needed, flags do not include any PET_ update // GROUP_UPDATE_FLAG_PHASE data << uint32(8); // either 0 or 8, same unk found in SMSG_PHASESHIFT data << uint32(0); // count // for (count) *data << uint16(phaseId) data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]); SendPacket(&data); }
void PlayerbotPriestAI::DoNonCombatActions() { Player * m_bot = GetPlayerBot(); if (!m_bot) return; SpellSequence = SPELL_HOLY; // buff myself if (FORTITUDE > 0) (!m_bot->HasAura(FORTITUDE, 0) && GetAI()->CastSpell (FORTITUDE, *m_bot)); if (INNER_FIRE > 0) (!m_bot->HasAura(INNER_FIRE, 0) && GetAI()->CastSpell (INNER_FIRE, *m_bot)); if (TOUCH_OF_WEAKNESS > 0) (m_bot->getRace()==5 /* undead */ && GetAI()->CastSpell (TOUCH_OF_WEAKNESS, *m_bot)); // buff master if (FORTITUDE > 0) (!GetMaster()->HasAura(FORTITUDE,0) && GetAI()->CastSpell (FORTITUDE, *(GetMaster())) ); // mana check if (m_bot->getStandState() != UNIT_STAND_STATE_STAND) m_bot->SetStandState(UNIT_STAND_STATE_STAND); Item* pItem = GetAI()->FindDrink(); if (pItem != NULL && GetAI()->GetManaPercent() < 30) { GetAI()->TellMaster("I could use a drink."); GetAI()->UseItem(*pItem); GetAI()->SetIgnoreUpdateTime(30); return; } // hp check if (m_bot->getStandState() != UNIT_STAND_STATE_STAND) m_bot->SetStandState(UNIT_STAND_STATE_STAND); pItem = GetAI()->FindFood(); if (pItem != NULL && GetAI()->GetHealthPercent() < 30) { GetAI()->TellMaster("I could use some food."); GetAI()->UseItem(*pItem); GetAI()->SetIgnoreUpdateTime(30); return; } //(!GetMaster()->HasAura(FORTITUDE,0) && GetAI()->CastSpell (FORTITUDE, *(GetMaster())) ); // buff and heal master's group if (GetMaster()->GetGroup()) { Group::MemberSlotList const& groupSlot = GetMaster()->GetGroup()->GetMemberSlots(); for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++) { Player *tPlayer = objmgr.GetPlayer(uint64 (itr->guid)); if( !tPlayer ) continue; // first rezz em if ( !tPlayer->isAlive() && !tPlayer->IsPlayerbot() ) { std::string msg = "rezzing "; msg += tPlayer->GetName(); GetPlayerBot()->Say(msg, LANG_UNIVERSAL); GetAI()->CastSpell(REZZ, *tPlayer); // rez is only 10 sec, but give time for lag GetAI()->SetIgnoreUpdateTime(17); } else if( tPlayer->isAlive() ) { // buff and heal (!tPlayer->HasAura(FORTITUDE,0) && GetAI()->CastSpell (FORTITUDE, *tPlayer)); (HealTarget(*tPlayer, tPlayer->GetHealth()*100 / tPlayer->GetMaxHealth())); } } } } // end DoNonCombatActions
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recv_data) { sLog->outDebug("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recv_data >> Guid; Player *player = HashMapHolder<Player>::Find(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if (pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << (uint32) mask1; // group update mask data << (uint16) MEMBER_STATUS_ONLINE; // member's online status data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << (uint64) auramask; // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication * aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << (uint32) aurApp->GetBase()->GetId(); data << (uint8) 1; } } data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << (uint64) petauramask; // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication * auraApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << (uint32) auraApp->GetBase()->GetId(); data << (uint8) 1; } } data.put<uint64>(petMaskPos,petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
void PlayerbotShamanAI::DoNonCombatActions() { PlayerbotAI* ai = GetAI(); Player * m_bot = GetPlayerBot(); if (!m_bot) return; SpellSequence = SPELL_ENHANCEMENT; // buff master with EARTH_SHIELD if (EARTH_SHIELD > 0) (!GetMaster()->HasAura(EARTH_SHIELD, EFFECT_INDEX_0) && ai->CastSpell(EARTH_SHIELD, *(GetMaster()))); // buff myself with WATER_SHIELD, LIGHTNING_SHIELD if (WATER_SHIELD > 0) (!m_bot->HasAura(WATER_SHIELD, EFFECT_INDEX_0) && !m_bot->HasAura(LIGHTNING_SHIELD, EFFECT_INDEX_0) && ai->CastSpell(WATER_SHIELD, *m_bot)); else if (LIGHTNING_SHIELD > 0) (!m_bot->HasAura(LIGHTNING_SHIELD, EFFECT_INDEX_0) && !m_bot->HasAura(WATER_SHIELD, EFFECT_INDEX_0) && ai->CastSpell(LIGHTNING_SHIELD, *m_bot)); /* // buff myself weapon if (ROCKBITER_WEAPON > 0) (!m_bot->HasAura(ROCKBITER_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(EARTHLIVING_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(WINDFURY_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FLAMETONGUE_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FROSTBRAND_WEAPON, EFFECT_INDEX_0) && ai->CastSpell(ROCKBITER_WEAPON,*m_bot) ); else if (EARTHLIVING_WEAPON > 0) (!m_bot->HasAura(EARTHLIVING_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(EARTHLIVING_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FLAMETONGUE_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FROSTBRAND_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(ROCKBITER_WEAPON, EFFECT_INDEX_0) && ai->CastSpell(WINDFURY_WEAPON,*m_bot) ); else if (WINDFURY_WEAPON > 0) (!m_bot->HasAura(WINDFURY_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(EARTHLIVING_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FLAMETONGUE_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FROSTBRAND_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(ROCKBITER_WEAPON, EFFECT_INDEX_0) && ai->CastSpell(WINDFURY_WEAPON,*m_bot) ); else if (FLAMETONGUE_WEAPON > 0) (!m_bot->HasAura(FLAMETONGUE_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(EARTHLIVING_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(WINDFURY_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FROSTBRAND_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(ROCKBITER_WEAPON, EFFECT_INDEX_0) && ai->CastSpell(FLAMETONGUE_WEAPON,*m_bot) ); else if (FROSTBRAND_WEAPON > 0) (!m_bot->HasAura(FROSTBRAND_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(EARTHLIVING_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(WINDFURY_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FLAMETONGUE_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(ROCKBITER_WEAPON, EFFECT_INDEX_0) && ai->CastSpell(FROSTBRAND_WEAPON,*m_bot) ); */ // mana check if (m_bot->getStandState() != UNIT_STAND_STATE_STAND) m_bot->SetStandState(UNIT_STAND_STATE_STAND); Item* pItem = ai->FindDrink(); Item* fItem = ai->FindBandage(); if (pItem != NULL && ai->GetManaPercent() < 30) { ai->TellMaster("I could use a drink."); ai->UseItem(pItem); return; } // hp check if (m_bot->getStandState() != UNIT_STAND_STATE_STAND) m_bot->SetStandState(UNIT_STAND_STATE_STAND); pItem = ai->FindFood(); if (pItem != NULL && ai->GetHealthPercent() < 30) { ai->TellMaster("I could use some food."); ai->UseItem(pItem); return; } else if (pItem == NULL && fItem != NULL && !m_bot->HasAura(RECENTLY_BANDAGED, EFFECT_INDEX_0) && ai->GetHealthPercent() < 70) { ai->TellMaster("I could use first aid."); ai->UseItem(fItem); return; } // heal master's group if (GetMaster()->GetGroup()) { Group::MemberSlotList const& groupSlot = GetMaster()->GetGroup()->GetMemberSlots(); for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++) { Player *tPlayer = sObjectMgr.GetPlayer(itr->guid); if (!tPlayer || !tPlayer->isAlive()) continue; if (tPlayer->IsInDuelWith(GetMaster())) continue; // heal (HealTarget(*tPlayer, tPlayer->GetHealth() * 100 / tPlayer->GetMaxHealth())); } } } // end DoNonCombatActions
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recvData >> Guid; Player* player = HashMapHolder<Player>::Find(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); Powers powerType = player->getPowerType(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; if (powerType != POWER_MANA) updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; if (pet) updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; uint16 playerStatus = MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->isAlive()) { if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; data << uint32(updateFlags); data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) data << uint8(powerType); data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION uint64 auraMask = 0; size_t maskPos = data.wpos(); data << uint64(auraMask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auraMask |= uint64(1) << i; data << uint32(aurApp->GetBase()->GetId()); data << uint8(aurApp->GetFlags()); } } data.put<uint64>(maskPos, auraMask); // GROUP_UPDATE_FLAG_AURAS if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) data << uint64(pet->GetGUID()); data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP) data << uint32(pet->GetHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP) data << uint32(pet->GetMaxHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE) data << (uint8)pet->getPowerType(); if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER) data << uint16(pet->GetPower(pet->getPowerType())); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER) data << uint16(pet->GetMaxPower(pet->getPowerType())); uint64 petAuraMask = 0; maskPos = data.wpos(); data << uint64(petAuraMask); // placeholder if (pet) { for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petAuraMask |= uint64(1) << i; data << uint32(aurApp->GetBase()->GetId()); data << uint8(aurApp->GetFlags()); } } } data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]); SendPacket(&data); }
/** * GetHealTarget() * return Unit* Returns unit to be healed. First checks 'critical' Healer(s), next Tank(s), next Master (if different from:), next DPS. * If none of the healths are low enough (or multiple valid targets) against these checks, the lowest health is healed. Having a target * returned does not guarantee it's worth healing, merely that the target does not have 100% health. * * return NULL If NULL is returned, no healing is required. At all. * * Will need extensive re-write for co-operation amongst multiple healers. As it stands, multiple healers would all pick the same 'ideal' * healing target. */ Player* PlayerbotClassAI::GetHealTarget(JOB_TYPE type) { if (!m_ai) return nullptr; if (!m_bot) return nullptr; if (!m_bot->isAlive() || m_bot->IsInDuel()) return nullptr; // define seperately for sorting purposes - DO NOT CHANGE ORDER! std::vector<heal_priority> targets; // First, fill the list of targets if (m_bot->GetGroup()) { Group::MemberSlotList const& groupSlot = m_bot->GetGroup()->GetMemberSlots(); for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++) { Player *groupMember = sObjectMgr.GetPlayer(itr->guid); if (!groupMember || !groupMember->isAlive() || groupMember->IsInDuel()) continue; JOB_TYPE job = GetTargetJob(groupMember); if (job & type) targets.push_back( heal_priority(groupMember, (groupMember->GetHealth() * 100 / groupMember->GetMaxHealth()), job) ); } } else { targets.push_back( heal_priority(m_bot, m_bot->GetHealthPercent(), GetTargetJob(m_bot)) ); if (m_master && !m_master->IsInDuel()) targets.push_back( heal_priority(m_master, (m_master->GetHealth() * 100 / m_master->GetMaxHealth()), GetTargetJob(m_master)) ); } // Sorts according to type: Healers first, tanks next, then master followed by DPS, thanks to the order of the TYPE enum std::sort(targets.begin(), targets.end()); uint8 uCount = 0,i = 0; // x is used as 'target found' variable; i is used as the targets iterator throughout all 4 types. int16 x = -1; // Try to find a healer in need of healing (if multiple, the lowest health one) while (true) { // This works because we sorted it above if ( (uCount + i) >= targets.size() || !(targets.at(uCount).type & JOB_HEAL)) break; uCount++; } // We have uCount healers in the targets, check if any qualify for priority healing for (; uCount > 0; uCount--, i++) { if (targets.at(i).hp <= m_MinHealthPercentHealer) if (x == -1 || targets.at(x).hp > targets.at(i).hp) x = i; } if (x > -1) return targets.at(x).p; // Try to find a tank in need of healing (if multiple, the lowest health one) while (true) { if ( (uCount + i) >= targets.size() || !(targets.at(uCount).type & JOB_TANK)) break; uCount++; } for (; uCount > 0; uCount--, i++) { if (targets.at(i).hp <= m_MinHealthPercentTank) if (x == -1 || targets.at(x).hp > targets.at(i).hp) x = i; } if (x > -1) return targets.at(x).p; // Try to find master in need of healing (lowest health one first) if (m_MinHealthPercentMaster != m_MinHealthPercentDPS) { while (true) { if ( (uCount + i) >= targets.size() || !(targets.at(uCount).type & JOB_MASTER)) break; uCount++; } for (; uCount > 0; uCount--, i++) { if (targets.at(i).hp <= m_MinHealthPercentMaster) if (x == -1 || targets.at(x).hp > targets.at(i).hp) x = i; } if (x > -1) return targets.at(x).p; } // Try to find anyone else in need of healing (lowest health one first) while (true) { if ( (uCount + i) >= targets.size() ) break; uCount++; } for (; uCount > 0; uCount--, i++) { if (targets.at(i).hp <= m_MinHealthPercentDPS) if (x == -1 || targets.at(x).hp > targets.at(i).hp) x = i; } if (x > -1) return targets.at(x).p; // Nobody is critical, find anyone hurt at all, return lowest (let the healer sort out if it's worth healing or not) for (i = 0, uCount = targets.size(); uCount > 0; uCount--, i++) { if (targets.at(i).hp < 100) if (x == -1 || targets.at(x).hp > targets.at(i).hp) x = i; } if (x > -1) return targets.at(x).p; return nullptr; }
void DoNonCombatActions() { Feast(); if (isTimerReady(uiGc_Timer) && !me->HasAura(SPELL_LIGHTNING_SHIELD, 0)) doCast(me, SPELL_LIGHTNING_SHIELD); if (master->GetGroup()) { RezGroup(SPELL_ANCESTRAL_SPIRIT, master); BuffAndHealGroup(master); } /* TESTING */ Group::MemberSlotList const &a =((Player*)master)->GetGroup()->GetMemberSlots(); for (Group::member_citerator itr = a.begin(); itr != a.end(); itr++) { Player* tPlayer = ((Player *)master)->GetObjPlayer(itr->guid); if (tPlayer == NULL) continue; //healing others if (tPlayer->isAlive() && isTimerReady(uiOthersHeal_Timer) && tPlayer->GetGUID() != master->GetGUID() && tPlayer->GetHealth() * 100 / tPlayer->GetMaxHealth() < 75 && CanCast(tPlayer, GetSpellStore()->LookupEntry(SPELL_CHAIN_HEAL))) { doCast(tPlayer, SPELL_CHAIN_HEAL, false); uiOthersHeal_Timer = 100; } //rezzes if (tPlayer->isDead() && !me->isInCombat() && me->GetDistance(tPlayer) < 40 && isTimerReady(uiRez_Timer)) { char* str = (char *)malloc(32); sprintf(str, "Resucitando a %s", tPlayer->GetName()); me->MonsterSay(str, LANG_UNIVERSAL, NULL); free(str); doCast(tPlayer, SPELL_ANCESTRAL_SPIRIT, false); uiRez_Timer = 160; } } /* TESTING */ if ((master->GetHealth() * 100 / master->GetMaxHealth() < 90) && uiLesserHealing_Timer <= 0) { doCast(master, SPELL_LESSER_HEALING); uiLesserHealing_Timer = 90; uiHeal_Timer = uiHeal_Timer + 5; //wait 5 seconds before casting a real heal return; } else if (uiLesserHealing_Timer >= 0) --uiLesserHealing_Timer; if ((master->GetHealth() * 100 / master->GetMaxHealth() < 75) && isTimerReady(uiHeal_Timer)) { doCast(master, SPELL_CHAIN_HEAL); uiHeal_Timer = 10; } if (me->GetHealth() * 100 / me->GetMaxHealth() < 90) { if (uiSelfLesserHealing_Timer <= 0) { doCast(me, SPELL_LESSER_HEALING); uiSelfLesserHealing_Timer = 90; return; } else if (uiSelfLesserHealing_Timer >= 0) --uiSelfLesserHealing_Timer; } }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received opcode CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player* player = ObjectAccessor::FindPlayer(guid, false); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3 + 4 + 2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_POWER_TYPE | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_AURAS | GROUP_UPDATE_FLAG_PHASE; if (pet) mask1 = 0x7FEFFEFF; // full mask & ~(GROUP_UPDATE_FLAG_VEHICLE_SEAT | GROUP_UPDATE_FLAG_UNK) Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL // verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; uint16 iCoordZ = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); iCoordZ = player->GetPositionZ(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); iCoordX = loc.coord_x; iCoordY = loc.coord_y; iCoordZ = loc.coord_z; } else { // unknown player status. } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordZ); // GROUP_UPDATE_FLAG_POSITION data << uint8(1); // if true, client clears all auras that are not in auramask and whose index is lower amount sent below uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder, server sends 0xFFFFFFFFFFFFFFFF here, but with 1 above it seems no difference data << uint32(MAX_AURAS); // server sends here number of visible auras, but client checks // if aura is in auramask, so it seems no difference if there will be MAX_AURAS for (uint8 i = 0; i < MAX_AURAS; ++i) { if (SpellAuraHolder* holder = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(holder->GetId()); data << uint16(holder->GetAuraFlags()); if (holder->GetAuraFlags() & AFLAG_EFFECT_AMOUNT_SEND) for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) if (Aura* aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) data << int32(aura->GetModifier()->m_amount); else data << int32(0); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER data << uint8(1); // if true, client clears all auras that are not in auramask and whose index is lower amount sent below uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder, server sends 0xFFFFFFFFFFFFFFFF here, but with 1 above it seems no difference data << uint32(MAX_AURAS); // server sends here number of visible auras, but client checks // if aura is in auramask, so it seems no difference if there will be MAX_AURAS for (uint8 i = 0; i < MAX_AURAS; ++i) { if (SpellAuraHolder* holder = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(holder->GetId()); data << uint16(holder->GetAuraFlags()); if (holder->GetAuraFlags() & AFLAG_EFFECT_AMOUNT_SEND) for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) if (Aura* aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) data << int32(aura->GetModifier()->m_amount); else data << int32(0); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint8(1); // GROUP_UPDATE_FLAG_PET_AURAS data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS data << uint32(0); // GROUP_UPDATE_FLAG_PET_AURAS } data << uint32(8); // GROUP_UPDATE_FLAG_PHASE data << uint32(0); // GROUP_UPDATE_FLAG_PHASE data << uint8(0); // GROUP_UPDATE_FLAG_PHASE SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recvData >> Guid; Player* player = HashMapHolder<Player>::Find(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 mask1 = GROUP_UPDATE_FULL; // common mask, real flags used 0x000040BFF if (!pet) mask1 &= ~GROUP_UPDATE_PET; // for hunters and other classes with pets, real flags used 0x7FFFFFFF Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status, GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8 (powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; // GROUP_UPDATE_FLAG_AURAS // if true client clears auras that are not covered by auramask // TODO: looks like now client requires all active auras to be in the beginning of the auramask // e.g. if you have holes in the aura mask the values after are ignored. data << uint8(0); size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder data << uint32(MAX_AURAS); // if true client clears auras that are not covered by auramask for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << uint64(pet->GetGUID()); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8 (petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; // GROUP_UPDATE_FLAG_PET_AURAS // if true client clears auras that are not covered by auramask // TODO: looks like now client requires all active auras to be in the beginning of the auramask // e.g. if you have holes in the aura mask the values after are ignored. data << uint8(0); size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder data << uint32(MAX_AURAS); // client reads (64) Bits from auramask for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint8(0); // GROUP_UPDATE_FLAG_PET_AURAS data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS data << uint32(0); } SendPacket(&data); }
void PlayerbotPaladinAI::DoNonCombatActions() { PlayerbotAI* ai = GetAI(); Player * m_bot = GetPlayerBot(); if (!m_bot) return; // buff myself if (GREATER_BLESSING_OF_MIGHT > 0 && !m_bot->HasAura(GREATER_BLESSING_OF_MIGHT, EFFECT_INDEX_0)) ai->CastSpell (GREATER_BLESSING_OF_MIGHT, *m_bot); else if (BLESSING_OF_MIGHT > 0 && !m_bot->HasAura(GREATER_BLESSING_OF_MIGHT, EFFECT_INDEX_0) && !m_bot->HasAura(BLESSING_OF_MIGHT, EFFECT_INDEX_0)) ai->CastSpell (BLESSING_OF_MIGHT, *m_bot); if (DIVINE_FAVOR > 0 && !m_bot->HasAura(DIVINE_FAVOR, EFFECT_INDEX_0) && ai->GetManaPercent() >= 3) ai->CastSpell(DIVINE_FAVOR , *m_bot); /* if (SEAL_OF_COMMAND > 0) ai->CastSpell (SEAL_OF_COMMAND, *m_bot); // interferes with drinking/eating */ //Select Class buff seq. ///Process Who is my master --> get the player class --> aura already present if not then proced --> cast the spell //Priest if (BLESSING_OF_WISDOM > 0 && GetMaster()->getClass() == CLASS_PRIEST && !GetMaster()->HasAura(GREATER_BLESSING_OF_WISDOM, EFFECT_INDEX_0) && !GetMaster()->HasAura(BLESSING_OF_WISDOM, EFFECT_INDEX_0)) ai->CastSpell (BLESSING_OF_WISDOM, *(GetMaster())); if (GREATER_BLESSING_OF_WISDOM > 0 && GetMaster()->getClass() == CLASS_PRIEST && !GetMaster()->HasAura(GREATER_BLESSING_OF_WISDOM, EFFECT_INDEX_0)) ai->CastSpell (GREATER_BLESSING_OF_WISDOM, *(GetMaster())); //Mage if (BLESSING_OF_WISDOM > 0 && GetMaster()->getClass() == CLASS_MAGE && !GetMaster()->HasAura(GREATER_BLESSING_OF_WISDOM, EFFECT_INDEX_0) && !GetMaster()->HasAura(BLESSING_OF_WISDOM, EFFECT_INDEX_0)) ai->CastSpell (BLESSING_OF_WISDOM, *(GetMaster())); if (GREATER_BLESSING_OF_WISDOM > 0 && GetMaster()->getClass() == CLASS_MAGE && !GetMaster()->HasAura(GREATER_BLESSING_OF_WISDOM, EFFECT_INDEX_0)) ai->CastSpell (GREATER_BLESSING_OF_WISDOM, *(GetMaster())); //Paladin if (BLESSING_OF_WISDOM > 0 && GetMaster()->getClass() == CLASS_PALADIN && !GetMaster()->HasAura(GREATER_BLESSING_OF_WISDOM, EFFECT_INDEX_0) && !GetMaster()->HasAura(BLESSING_OF_WISDOM, EFFECT_INDEX_0)) ai->CastSpell (BLESSING_OF_WISDOM, *(GetMaster())); if (GREATER_BLESSING_OF_WISDOM > 0 && GetMaster()->getClass() == CLASS_PALADIN && !GetMaster()->HasAura(GREATER_BLESSING_OF_WISDOM, EFFECT_INDEX_0)) ai->CastSpell (GREATER_BLESSING_OF_WISDOM, *(GetMaster())); //Warlock if (BLESSING_OF_WISDOM > 0 && GetMaster()->getClass() == CLASS_WARLOCK && !GetMaster()->HasAura(GREATER_BLESSING_OF_WISDOM, EFFECT_INDEX_0) && !GetMaster()->HasAura(BLESSING_OF_WISDOM, EFFECT_INDEX_0)) ai->CastSpell (BLESSING_OF_WISDOM, *(GetMaster())); if (GREATER_BLESSING_OF_WISDOM > 0 && GetMaster()->getClass() == CLASS_WARLOCK && !GetMaster()->HasAura(GREATER_BLESSING_OF_WISDOM, EFFECT_INDEX_0)) ai->CastSpell (GREATER_BLESSING_OF_WISDOM, *(GetMaster())); //Warrior if (BLESSING_OF_MIGHT > 0 && GetMaster()->getClass() == CLASS_WARRIOR && !GetMaster()->HasAura(GREATER_BLESSING_OF_MIGHT, EFFECT_INDEX_0) && !GetMaster()->HasAura(BLESSING_OF_MIGHT, EFFECT_INDEX_0) && !GetMaster()->HasAura(DEFENSIVE_STANCE, EFFECT_INDEX_0)) ai->CastSpell (BLESSING_OF_MIGHT, *(GetMaster())); if (GREATER_BLESSING_OF_MIGHT > 0 && GetMaster()->getClass() == CLASS_WARRIOR && !GetMaster()->HasAura(GREATER_BLESSING_OF_MIGHT, EFFECT_INDEX_0) && !GetMaster()->HasAura(DEFENSIVE_STANCE, EFFECT_INDEX_0)) ai->CastSpell (GREATER_BLESSING_OF_MIGHT, *(GetMaster())); if (BLESSING_OF_KINGS > 0 && GetMaster()->getClass() == CLASS_WARRIOR && !GetMaster()->HasAura(GREATER_BLESSING_OF_KINGS, EFFECT_INDEX_0) && !GetMaster()->HasAura(BLESSING_OF_KINGS, EFFECT_INDEX_0) && !GetMaster()->HasAura(BERSERKER_STANCE, EFFECT_INDEX_0) && !GetMaster()->HasAura(BATTLE_STANCE, EFFECT_INDEX_0)) ai->CastSpell (BLESSING_OF_KINGS, *(GetMaster())); if (GREATER_BLESSING_OF_KINGS > 0 && GetMaster()->getClass() == CLASS_WARRIOR && !GetMaster()->HasAura(GREATER_BLESSING_OF_KINGS, EFFECT_INDEX_0) && !GetMaster()->HasAura(BERSERKER_STANCE, EFFECT_INDEX_0) && !GetMaster()->HasAura(BATTLE_STANCE, EFFECT_INDEX_0)) ai->CastSpell (GREATER_BLESSING_OF_KINGS, *(GetMaster())); //Rogue if (BLESSING_OF_MIGHT > 0 && GetMaster()->getClass() == CLASS_ROGUE && !GetMaster()->HasAura(GREATER_BLESSING_OF_MIGHT, EFFECT_INDEX_0) && !GetMaster()->HasAura(BLESSING_OF_MIGHT, EFFECT_INDEX_0)) ai->CastSpell (BLESSING_OF_MIGHT, *(GetMaster())); if (GREATER_BLESSING_OF_MIGHT > 0 && GetMaster()->getClass() == CLASS_ROGUE && !GetMaster()->HasAura(GREATER_BLESSING_OF_MIGHT, EFFECT_INDEX_0)) ai->CastSpell (GREATER_BLESSING_OF_MIGHT, *(GetMaster())); //Shaman if (BLESSING_OF_MIGHT > 0 && GetMaster()->getClass() == CLASS_SHAMAN && !GetMaster()->HasAura(GREATER_BLESSING_OF_MIGHT, EFFECT_INDEX_0) && !GetMaster()->HasAura(BLESSING_OF_MIGHT, EFFECT_INDEX_0)) ai->CastSpell (BLESSING_OF_MIGHT, *(GetMaster())); if (GREATER_BLESSING_OF_MIGHT > 0 && GetMaster()->getClass() == CLASS_SHAMAN && !GetMaster()->HasAura(GREATER_BLESSING_OF_MIGHT, EFFECT_INDEX_0)) ai->CastSpell (GREATER_BLESSING_OF_MIGHT, *(GetMaster())); // mana check if (m_bot->getStandState() != UNIT_STAND_STATE_STAND) m_bot->SetStandState(UNIT_STAND_STATE_STAND); Item* pItem = ai->FindDrink(); Item* fItem = ai->FindBandage(); if (pItem != NULL && ai->GetManaPercent() < 40) { ai->TellMaster("I could use a drink."); ai->UseItem(*pItem); ai->SetIgnoreUpdateTime(30); return; } // hp check original if (m_bot->getStandState() != UNIT_STAND_STATE_STAND) m_bot->SetStandState(UNIT_STAND_STATE_STAND); pItem = ai->FindFood(); if (pItem != NULL && ai->GetHealthPercent() < 40) { ai->TellMaster("I could use some food."); ai->UseItem(*pItem); ai->SetIgnoreUpdateTime(30); return; } else if (pItem == NULL && fItem != NULL && !m_bot->HasAura(RECENTLY_BANDAGED, EFFECT_INDEX_0) && ai->GetHealthPercent() < 70) { ai->TellMaster("I could use first aid."); ai->UseItem(*fItem); ai->SetIgnoreUpdateTime(8); return; } // heal group if (GetMaster()->GetGroup()) { Group::MemberSlotList const& groupSlot = GetMaster()->GetGroup()->GetMemberSlots(); for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++) { Player *tPlayer = sObjectMgr.GetPlayer(uint64 (itr->guid)); if( !tPlayer || !tPlayer->isAlive() ) continue; // heal player (HealTarget(*tPlayer, tPlayer->GetHealth()*100 / tPlayer->GetMaxHealth())); } } }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player * player = HashMapHolder<Player>::Find(guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets uint16 online_status = MEMBER_STATUS_ONLINE; Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(online_status); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL //verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); iCoordX = loc.coord_x; iCoordY = loc.coord_y; } else { //unknown player status. } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { MAPLOCK_READ(player,MAP_LOCK_TYPE_AURAS); if(uint32 aura = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aura); data << uint8(1); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { MAPLOCK_READ(pet,MAP_LOCK_TYPE_AURAS); if(uint32 petaura = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(petaura); data << uint8(1); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
void UpdateAI(const uint32 diff) { if(!UpdateVictim()) return; if(Cleanse_Timer < diff ) { std::list<Creature*> pList = FindFriendlyCC(30); if (!pList.empty()) { Unit* target = *(pList.begin()); DoCast(target,SPELL_CLEANSE_BW_VINDICATOR); } Cleanse_Timer = 3000+rand()%1000; } else Cleanse_Timer -= diff; if(FlashofLight_Timer < diff) { Unit* target = SelectLowestHpFriendly(50, 1000); if(target) { DoCast(target,SPELL_FLASHOFLIGHT_BW_VINDICATOR); if(target->GetHealth() <= target->GetMaxHealth()*0.5) FlashofLight_Timer = 2000; else FlashofLight_Timer = 2000 +rand()%7000; } } else FlashofLight_Timer -= diff; if(HammerofJustice_Timer < diff) { DoCast(m_creature->getVictim(),SPELL_HAMMEROFJUSTICE_BW_VINDICATOR); HammerofJustice_Timer = 18000; } else HammerofJustice_Timer -= diff; if(HammerofWrath_Timer < diff) { Map* pMap = m_creature->GetMap(); Map::PlayerList const &PlayerList = pMap->GetPlayers(); if (!PlayerList.isEmpty()) { for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { Player *p = i->getSource(); if(p->isAlive() && p->GetHealth() <= p->GetMaxHealth()*0.2) { DoCast(p, SPELL_HAMMEROFWRATH_BW_VINDICATOR); break; } } } HammerofWrath_Timer = 3000+rand()%2000; } else HammerofWrath_Timer -= diff; DoMeleeAttackIfReady(); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid Guid; recvData >> Guid; Player* player = ObjectAccessor::FindConnectedPlayer(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << Guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); Powers powerType = player->getPowerType(); std::set<uint32> const& phases = player->GetPhases(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; if (powerType != POWER_MANA) updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; if (pet) updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; if (!phases.empty()) updateFlags |= GROUP_UPDATE_FLAG_PHASE; uint16 playerStatus = MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->IsAlive()) { if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->IsFFAPvP()) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; data << uint32(updateFlags); data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) data << uint8(powerType); data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION // GROUP_UPDATE_FLAG_AURAS data << uint8(1); uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) data << uint64(pet->GetGUID()); data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP) data << uint32(pet->GetHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP) data << uint32(pet->GetMaxHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE) data << (uint8)pet->getPowerType(); if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER) data << uint16(pet->GetPower(pet->getPowerType())); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER) data << uint16(pet->GetMaxPower(pet->getPowerType())); // GROUP_UPDATE_FLAG_PET_AURAS uint64 petAuraMask = 0; data << uint8(1); maskPos = data.wpos(); data << uint64(petAuraMask); // placeholder data << uint32(MAX_AURAS); // count if (pet) { for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petAuraMask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } } data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]); if (updateFlags & GROUP_UPDATE_FLAG_PHASE) { data << uint32(phases.empty() ? 8 : 0); data << uint32(phases.size()); for (std::set<uint32>::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) data << uint16(*itr); } SendPacket(&data); }
//============================================================================== void GameServer::HandleUse_(const QVariantMap& request, QVariantMap& response) { auto sid = request["sid"].toByteArray(); Player* p = sidToPlayer_[sid]; if (!request["id"].toInt()) { WriteResult_(response, EFEMPResult::BAD_ID); return; } int id = request["id"].toInt(); Item* item = dynamic_cast<Item*>(idToActor_[request["id"].toInt()]); if (item) { if (request.find("x") == request.end() && request.find("y") == request.end()) { if (item->GetSubtype() != "consumable") { WriteResult_(response, EFEMPResult::BAD_ID); return; } else { p->SetHealth(p->GetHealth() + item->bonuses[EStatConst::HP]["value"].toFloat()); WriteResult_(response, EFEMPResult::OK); return; } } if ((item != p->GetSlot(left_hand) || item != p->GetSlot(right_hand)) && (p->GetSlot(left_hand) != 0 || p->GetSlot(right_hand)!= 0 ) && id != FistId_) { WriteResult_(response, EFEMPResult::BAD_SLOT); return; } WriteResult_ (response, EFEMPResult::OK); return; } if (!request["x"].toFloat() || !request["y"].toFloat()) { WriteResult_(response, EFEMPResult::BAD_PLACING); return; } for (Actor* actor : actors_) { if (actor->GetType() != EActorType::ITEM && actor->GetType() != EActorType::PROJECTILE) { Creature* target = static_cast<Creature*>(actor); if ((p->GetId() != target->GetId()) && (target->GetHealth() > 0)) { Vector2 player_pos = p->GetPosition(); Vector2 target_pos = target->GetPosition(); float distance2 = Sqr(player_pos.x - target_pos.x) + Sqr(player_pos.y - target_pos.y); if (distance2 <= Sqr(pickUpRadius_)) { QVariantMap a = p->atack(target, id); events_ << a; if (target->GetHealth() <= 0) { GetItems(target); p->SetExperience(p->GetExperience () + 300); int lev = p->GetLevel(); p->SetLevel (p->GetExperience() / 1000); if (lev < p->GetLevel()) { p->AddStat (); p->UpdateStat(); } } else { a = target->atack(p); events_ << a; } WriteResult_(response, EFEMPResult::OK); return; } } } } }
void UpdateAI(const uint32 uiDiff) override { if (m_uiPossessEndTimer) { // Check if the possessed player has been damaged if (m_uiPossessEndTimer <= uiDiff) { // If aura has expired, return to fight if (!m_creature->HasAura(SPELL_POSSESS_INV)) { m_uiPossessEndTimer = 0; return; } // Check for possessed player Player* pPlayer = m_creature->GetMap()->GetPlayer(m_possessedPlayer); if (!pPlayer || !pPlayer->IsAlive()) { m_creature->RemoveAurasDueToSpell(SPELL_POSSESS_INV); m_uiPossessEndTimer = 0; return; } // If possessed player has less than 50% health if (pPlayer->GetHealth() <= pPlayer->GetMaxHealth() * .5f) { m_creature->RemoveAurasDueToSpell(SPELL_POSSESS_INV); pPlayer->RemoveAurasDueToSpell(SPELL_POSSESSED); pPlayer->RemoveAurasDueToSpell(SPELL_POSSESS); m_uiPossessEndTimer = 0; return; } m_uiPossessEndTimer = 1000; } else { m_uiPossessEndTimer -= uiDiff; } } if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) { return; } // BansheeWail if (m_uiBansheeWailTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_BANSHEE_WAIL) == CAST_OK) { m_uiBansheeWailTimer = urand(2000, 3000); } } } else { m_uiBansheeWailTimer -= uiDiff; } // BansheeCurse if (m_uiBansheeCurseTimer < uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_BANSHEE_CURSE) == CAST_OK) { m_uiBansheeCurseTimer = 20000; } } else { m_uiBansheeCurseTimer -= uiDiff; } // Silence if (m_uiSilenceTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0)) { if (DoCastSpellIfCan(pTarget, SPELL_SILENCE) == CAST_OK) { m_uiSilenceTimer = 25000; } } } else { m_uiSilenceTimer -= uiDiff; } // Possess if (m_uiPossessTimer < uiDiff) { if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, SPELL_POSSESS, SELECT_FLAG_PLAYER)) { if (DoCastSpellIfCan(pTarget, SPELL_POSSESS) == CAST_OK) { DoCastSpellIfCan(pTarget, SPELL_POSSESSED, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_POSSESS_INV, CAST_TRIGGERED); m_possessedPlayer = pTarget->GetObjectGuid(); m_uiPossessEndTimer = 1000; m_uiPossessTimer = 30000; } } } else { m_uiPossessTimer -= uiDiff; } DoMeleeAttackIfReady(); }
void theNinthTrial(Player &player, vector<string>& questionList) { if (player.GetHealth() == 0) { return; } cout << "You enter a dirty village that has seen better days.\n"; forward(); cout << "The buildings have wood rotting at the sides, and dust\n"; cout << "fills the air.\n"; forward(); cout << "A burning is going on at the center of the village, with\n"; cout << "a group of villagers surrounding a large cross.\n"; forward(); cout << "The cross burns with unkept flame, and a large wolf is pinned\n"; cout << "to it.\n"; forward(); cout << "You hear their voices in unison in the crowd: 'Burn! Burn it to\n"; cout << "the ground!'\n"; forward(); cout << "You slowly move your way through the crowd so that few of them\n"; cout << "notice.\n"; int choice; string title = "What will you say amongst the crowd?"; questionList.push_back("(Keep silent)"); questionList.push_back("Burn! Burn it to the ground!"); questionList.push_back("Laugh and cheer on the burning."); questionList.push_back("Hey, stop this!"); questionList.push_back("Did that wolf really deserve this?"); choice = askQuestion(title, questionList); switch (choice) { case 1: player.SetApathy(player.GetApathy() + 2); cout << "The chant continues to ring in your ears.\n"; forward(); forward(); cout << "You remain safe for the time being as an onlooker.\n"; break; case 2: player.SetEvil(player.GetEvil() + 1); cout << "You join the chant of the villagers and it grows even\n"; cout << "stronger than before.\n"; forward(); forward(); cout << "The mood of the mob slightly intoxicates you with satisfaction.\n"; break; case 3: player.SetEvil(player.GetEvil() + 2); cout << "The villagers notice you but continue their chanting.\n"; forward(); forward(); cout << "Some of them like your mood and join in on the cheering.\n"; break; case 4: player.SetGoodness(player.GetGoodness() + 2); cout << "Some of the villagers give you dirty looks but continue\n"; cout << "with their chanting.\n"; forward(); forward(); cout << "It seems your words have no effect on the matter.\n"; break; default: player.SetGoodness(player.GetGoodness() + 1); cout << "A villager in tattered clothes responds, 'This foul beast\n"; cout << "dares to terrify our village! We struck back and were victorious!'\n"; forward(); forward(); cout << "You wonder if that was the whole truth of the situation.\n"; break; } forward(); cout << "Suddenly, the wolf starts howling and writhing in pain, jolting\n"; cout << "the cross side to side.\n"; forward(); cout << "The villagers run to their homes as the cross snaps and the wolf\n"; cout << "rolls desperately out of the fire.\n"; forward(); cout << "The beast resembles a large and menacingly dark dog, mangy and\n"; cout << "somewhat damaged from the licks of the flame behind it.\n"; forward(); cout << "It looks in your eyes and growls. It is ready to attack.\n"; forward(); char input; string item; do { displayHelp(); input = resolveDecision(player); if (input == 'l') { cout << "\nYou barely have time to glance at the creature as it\n"; cout << "charges at you.\n"; forward(); cout << "It looks as if it has no weaknesses and will not go down easily.\n"; input = 'r'; } if (input == 's') { cout << "\nThis beast does not understand your language and the villagers\n"; cout << "are too far away to help.\n"; forward(); cout << "Not that they would help you. They barely know you.\n"; input = 'r'; } if (input == 'u') { item = player.GetInventoryEntry(); if (item == "Granny Smith") { if (changeHealth(player, eatApple(true))) { return; } forward(); player.RemoveFromInventory("Granny Smith"); input = 'r'; } else if (item == "Obsidian Knife") { cout << "\nYou hold up the now shabby knife in an attempt to attack.\n"; forward(); forward(); cout << "The wolf senses the knife and lunges at you, catching your\n"; cout << "hand and mauling your arm for 5 points of damage.\n"; forward(); if (changeHealth(player, 5)) { return; } forward(); cout << "The knife breaks in its teeth, crumbling to the ground.\n"; forward(); cout << "It is a very strong wolf indeed.\n"; forward(); player.RemoveFromInventory("Obsidian Knife"); input = 'r'; } } } while (input == 'r'); if (input == 'u') { if (item == "Guardian Head") { cout << "\nYou toss the head into the beast's mouth.\n"; forward(); forward(); cout << "The guardian takes one last roar before disappearing in the wolf's jaws.\n"; forward(); cout << "You take this precious chance to get away with your life, running\n"; cout << "toward the end of the village with whatever stamina you can muster.\n"; } else if (item == "Deathknell") { cout << "\nYou fiercely rush your blade towards the wolf.\n"; forward(); forward(); cout << "It scratches you for a point of damage but your sword strike\n"; cout << "does not miss its mark and fells the beast, piercing the brain\n"; cout << "and impaling its head.\n"; forward(); if (changeHealth(player, 1)) { return; } forward(); cout << "The blade drinks the blood of the beast with a voracious hunger.\n"; } else { cout << "\nYou show the medallion to the beast.\n"; forward(); forward(); cout << "It is entranced by the medallion and calms itself immediately.\n"; forward(); cout << "As you place the object on the ground, the wolf stares directly\n"; cout << "at it and does not budge from the spot.\n"; forward(); cout << "You see no danger and find a chance to escape.\n"; } } else { cout << "\nWith only your hands and no weapon, you attempt to quickly\n"; cout << "scan the environment for available measures.\n"; title = "What will you do against the wolf?"; questionList.push_back("If I run fast enough, I can make the exit!"); questionList.push_back("I can use the fire to scare off the wolf!"); questionList.push_back("I can lure him toward the villagers and use them as bait!"); choice = askQuestion(title, questionList); if (choice == 1) { cout << "You run as fast as your legs can carry you.\n"; forward(); forward(); cout << "At this point, you are sure that running away never did you\n"; cout << "any good in previous playthroughs.\n"; forward(); cout << "The beast catches up to you and rips your body apart for\n"; cout << "10 points of damage.\n"; if (changeHealth(player, 10)) { return; } } else if (choice == 2) { player.SetGoodness(player.GetGoodness() + 2); cout << "You make your way around the fire and grab an actual\n"; cout << "torch without putting it in your inventory.\n"; forward(); forward(); cout << "Taking advantage of the wolf's trauma, you successfully\n"; cout << "scare it from the village without hurting it.\n"; forward(); cout << "The villagers carefully make their way out of the doors\n"; cout << "and look at you, bewildered in your accomplishments.\n"; forward(); cout << "Satisfied with saving them, you move your way to the end\n"; cout << "of the village.\n"; } else { player.SetEvil(player.GetEvil() + 2); cout << "You run quickly toward the villagers' houses and make a\n"; cout << "quick duck.\n"; forward(); forward(); cout << "The wolf leaps above you and crashes through the house of\n"; cout << "one of the villagers.\n"; forward(); cout << "You run for the end of the village and get away with your\n"; cout << "life as you hear screaming in the distance and the sounds\n"; cout << "of death.\n"; } } forward(); cout << "Nearly finished with your journey, you make your way into a \n"; cout << "dark forest for your final trial...\n"; forward(); }