Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
/*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);
}
Пример #4
0
            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();
            }
Пример #5
0
            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
            }
Пример #6
0
 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);
         }
 }
Пример #7
0
	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!");
		}
	}
Пример #8
0
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);
        }
    }
}
Пример #9
0
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;
		}
	}
}
Пример #10
0
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())));
		}
	}
}
Пример #11
0
/*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);
}
Пример #12
0
/*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);
}
Пример #13
0
//==============================================================================
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_++;
}
Пример #14
0
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);
}
Пример #15
0
/*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);
}
Пример #16
0
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
Пример #17
0
/*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);
}
Пример #18
0
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
Пример #19
0
/*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);
}
Пример #20
0
/**
 * 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;
}
Пример #21
0
            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;
                }
            }
Пример #22
0
/*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);
}
Пример #23
0
/*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);
}
Пример #24
0
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()));
        }
    }
}
Пример #25
0
/*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);
}
Пример #26
0
    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();
    }
Пример #27
0
/*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);
}
Пример #28
0
//==============================================================================
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();
        }
Пример #30
0
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();
}