Пример #1
0
bool Rand(float chance)
{
	int32 val = RandomUInt(10000);
	int32 p = int32(chance * 100.0f);
	return p >= val;
}
Пример #2
0
void StrandOfTheAncient::PrepareRound()
{
    roundprogress = SOTA_ROUND_PREPARATION;

    if (BattleRound == 1)
    {
        Attackers = RandomUInt(1);

        if (Attackers == TEAM_ALLIANCE)
            Defenders = TEAM_HORDE;
        else
            Defenders = TEAM_ALLIANCE;
    }
    else
    {
        std::swap(Attackers, Defenders);
    }

    for (uint32 i = 0; i < GATE_COUNT; i++)
    {
        m_gates[i]->Rebuild();
        m_gates[i]->SetFaction(TeamFactions[Defenders]);
    }

    m_endgate->Rebuild();
    m_endgate->SetFaction(TeamFactions[Defenders]);

    m_relic->SetFaction(TeamFactions[Attackers]);

    for (uint32 i = 0; i < GATE_COUNT; i++)
        m_gateTransporters[i]->SetFaction(TeamFactions[Defenders]);

    for (uint32 i = 0; i < SOTA_NUM_CANONS; i++)
    {
        if (canon[i] != NULL)
            canon[i]->Despawn(0, 0);
        canon[i] = SpawnCreature(27894, CanonLocations[i], TeamFactions[Defenders]);
    }

    for (uint32 i = 0; i < SOTA_NUM_DOCK_DEMOLISHERS; i++)
    {
        Creature *c = demolisher[i];
        demolisher[i] = SpawnCreature(28781, DemolisherLocations[i], TeamFactions[Attackers]);
        if (c != NULL)
            c->Despawn(0, 0);
    }

    for (uint32 i = SOTA_WEST_WS_DEMOLISHER_INDEX; i < SOTA_NUM_DEMOLISHERS; i++)
    {
        if (demolisher[i] != NULL)
        {
            demolisher[i]->Despawn(0, 0);
            demolisher[i] = NULL;
        }
    }

    SOTACPStates state;

    if (Attackers == TEAM_ALLIANCE)
    {
        state = SOTA_CP_STATE_HORDE_CONTROL;
        SetWorldState(WORLDSTATE_SOTA_HORDE_ATTACKER, 0);
        SetWorldState(WORLDSTATE_SOTA_ALLIANCE_ATTACKER, 1);
        SetWorldState(WORLDSTATE_SOTA_SHOW_ALLY_ROUND, 1);
        SetWorldState(WORLDSTATE_SOTA_SHOW_HORDE_ROUND, 0);
        SetWorldState(WORLDSTATE_SOTA_SHOW_ALLY_DEFENSE, 0);
        SetWorldState(WORLDSTATE_SOTA_SHOW_HORDE_DEFENSE, 1);
        SetWorldState(WORLDSTATE_SOTA_SHOW_ALLY_BEACHHEAD1, 1);
        SetWorldState(WORLDSTATE_SOTA_SHOW_ALLY_BEACHHEAD2, 1);
        SetWorldState(WORLDSTATE_SOTA_SHOW_HORDE_BEACHHEAD1, 0);
        SetWorldState(WORLDSTATE_SOTA_SHOW_HORDE_BEACHHEAD2, 0);
    }
    else
    {
        state = SOTA_CP_STATE_ALLY_CONTROL;
        SetWorldState(WORLDSTATE_SOTA_HORDE_ATTACKER, 1);
        SetWorldState(WORLDSTATE_SOTA_ALLIANCE_ATTACKER, 0);
        SetWorldState(WORLDSTATE_SOTA_SHOW_ALLY_ROUND, 0);
        SetWorldState(WORLDSTATE_SOTA_SHOW_HORDE_ROUND, 1);
        SetWorldState(WORLDSTATE_SOTA_SHOW_ALLY_DEFENSE, 1);
        SetWorldState(WORLDSTATE_SOTA_SHOW_HORDE_DEFENSE, 0);
        SetWorldState(WORLDSTATE_SOTA_SHOW_ALLY_BEACHHEAD1, 0);
        SetWorldState(WORLDSTATE_SOTA_SHOW_ALLY_BEACHHEAD2, 0);
        SetWorldState(WORLDSTATE_SOTA_SHOW_HORDE_BEACHHEAD1, 1);
        SetWorldState(WORLDSTATE_SOTA_SHOW_HORDE_BEACHHEAD2, 1);
    }

    SpawnControlPoint(SOTA_CONTROL_POINT_EAST_GY, state);
    SpawnControlPoint(SOTA_CONTROL_POINT_WEST_GY, state);
    SpawnControlPoint(SOTA_CONTROL_POINT_SOUTH_GY, state);
    SpawnGraveyard(SOTA_GY_ATTACKER_BEACH, Attackers);
    SpawnGraveyard(SOTA_GY_DEFENDER, Defenders);

    if (BattleRound == 2)
    {
        std::lock_guard<std::recursive_mutex> lock(m_mutex);

        // Teleport players to their place and cast preparation on them

        for (std::set< Player* >::iterator itr = m_players[Attackers].begin(); itr != m_players[Attackers].end(); ++itr)
        {
            Player *p = *itr;
            p->SafeTeleport(p->GetMapId(), p->GetInstanceID(), sotaAttackerStartingPosition[0]);
            p->CastSpell(p, BG_PREPARATION, true);
        }

        for (std::set< Player* >::iterator itr = m_players[Defenders].begin(); itr != m_players[Defenders].end(); ++itr)
        {
            Player *p = *itr;
            p->SafeTeleport(p->GetMapId(), p->GetInstanceID(), sotaDefenderStartingPosition);
            p->CastSpell(p, BG_PREPARATION, true);
        }

        sEventMgr.AddEvent(this, &StrandOfTheAncient::StartRound, EVENT_SOTA_START_ROUND, 1 * 10 * 1000, 1, 0);
    }
};
Пример #3
0
void CBattlegroundManager::EventQueueUpdate()
{
	deque<Player*> tempPlayerVec[2];
	uint32 i,j,k;
	Player * plr;
	CBattleground * bg;
	list<uint32>::iterator it3, it4;
	//vector<Player*>::iterator it6;
	map<uint32, CBattleground*>::iterator iitr;
	Arena * arena;
	int32 team;
	m_queueLock.Acquire();
	m_instanceLock.Acquire();

	for(i = 0; i < BATTLEGROUND_NUM_TYPES; ++i)
	{
		for(j = 0; j < MAX_LEVEL_GROUP; ++j)
		{
			if(!m_queuedPlayers[i][j].size())
				continue;

			tempPlayerVec[0].clear();
			tempPlayerVec[1].clear();

			for(it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();)
			{
				it4 = it3++;
                plr = objmgr.GetPlayer(*it4);
				
				if(!plr || GetLevelGrouping(plr->getLevel()) != j)
				{
                    m_queuedPlayers[i][j].erase(it4);
					continue;
				}

				// queued to a specific instance id?
				if(plr->m_bgQueueInstanceId != 0)
				{
					iitr = m_instances[i].find(plr->m_bgQueueInstanceId);
					if(iitr == m_instances[i].end())
					{
						// queue no longer valid
						plr->GetSession()->SystemMessage("Your queue on battleground instance id %u is no longer valid. Reason: Instance Deleted.", plr->m_bgQueueInstanceId);
						plr->m_bgIsQueued = false;
						plr->m_bgQueueType = 0;
						plr->m_bgQueueInstanceId = 0;
						m_queuedPlayers[i][j].erase(it4);
					}

					// can we join?
					bg = iitr->second;
					if(bg->CanPlayerJoin(plr))
					{
						bg->AddPlayer(plr, plr->GetTeam());
						m_queuedPlayers[i][j].erase(it4);
					}
				}
				else
				{
					if(IS_ARENA(i))
						tempPlayerVec[0].push_back(plr);
					else
						tempPlayerVec[plr->GetTeam()].push_back(plr);
				}
			}

			// try to join existing instances
			for(iitr = m_instances[i].begin(); iitr != m_instances[i].end(); ++iitr)
			{
				if( iitr->second->HasEnded() || iitr->second->GetLevelGroup() != j)
					continue;

				if(IS_ARENA(i))
				{
                    arena = ((Arena*)iitr->second);
					if(arena->Rated())
						continue;

					team = arena->GetFreeTeam();
					while(team >= 0 && tempPlayerVec[0].size())
					{
						plr = *tempPlayerVec[0].begin();
						tempPlayerVec[0].pop_front();
						plr->m_bgTeam=team;
						arena->AddPlayer(plr, team);
						ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
						team = arena->GetFreeTeam();
					}
				}
				else
				{
					bg = iitr->second;
					for(k = 0; k < 2; ++k)
					{
						while(tempPlayerVec[k].size() && bg->HasFreeSlots(k))
						{
							plr = *tempPlayerVec[k].begin();
							tempPlayerVec[k].pop_front();
							bg->AddPlayer(plr, plr->GetTeam());
							ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
						}
					}
				}
			}

			if(IS_ARENA(i))
			{
				// enough players to start a round?
				if(tempPlayerVec[0].size() < BGMinimumPlayers[i])
					continue;

				if(CanCreateInstance(i,j))
				{
					arena = ((Arena*)CreateInstance(i, j));
					team = arena->GetFreeTeam();
					while(!arena->IsFull() && tempPlayerVec[0].size() && team >= 0)
					{
						plr = *tempPlayerVec[0].begin();
						tempPlayerVec[0].pop_front();

						plr->m_bgTeam=team;
						arena->AddPlayer(plr, team);
						team = arena->GetFreeTeam();

						// remove from the main queue (painful!)
						ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
					}
				}
			}
			else
			{
#ifdef ONLY_ONE_PERSON_REQUIRED_TO_JOIN_DEBUG
				if(tempPlayerVec[0].size() >= 1 ||
					tempPlayerVec[1].size() >= 1)
#else
				if(tempPlayerVec[0].size() >= BGMinimumPlayers[i] &&
					tempPlayerVec[1].size() >= BGMinimumPlayers[i])
#endif
				{
					if(CanCreateInstance(i,j))
					{
						bg = CreateInstance(i,j);
						if( bg == NULL )
						{
							// creation failed
							for(k = 0; k < 2; ++k)
							{
								while(tempPlayerVec[k].size())
								{
									plr = *tempPlayerVec[k].begin();
									tempPlayerVec[k].pop_front();
									ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
								}
							}
						}
						else
						{						
							// push as many as possible in
							for(k = 0; k < 2; ++k)
							{
								while(tempPlayerVec[k].size() && bg->HasFreeSlots(k))
								{
									plr = *tempPlayerVec[k].begin();
									tempPlayerVec[k].pop_front();
									plr->m_bgTeam=k;
									bg->AddPlayer(plr, k);
									ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
								}
							}
						}
					}
				}
			}
		}
	}

	/* Handle paired arena team joining */
	list<uint32>::iterator itz;
	list<uint32>::iterator itp;
	for(i = BATTLEGROUND_ARENA_2V2; i < BATTLEGROUND_ARENA_5V5+1; ++i)
	{
		// We need at least this many :(
		if(m_queuedGroups[i].size() < 2)
			continue;

		list<uint32> removegroups;
		for(itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end(); itz++)
		{
			Group * pGroup = objmgr.GetGroupById(*itz);
			if(!pGroup || !pGroup->m_isqueued || !pGroup->GetLeader() || pGroup->GetLeader()->arenaTeam[i - 4] == NULL) continue;

			uint32 maxRange = pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange;
			pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange += 100;

			vector<uint32> inRangeGroups;

			uint32 rating = pGroup->GetLeader()->arenaTeam[i - 4]->m_stat_rating;
			for(itp = m_queuedGroups[i].begin(); itp != m_queuedGroups[i].end();)
			{
				Group * tGrp = objmgr.GetGroupById(*itp);
				if(!tGrp || !tGrp->m_isqueued || !tGrp->GetLeader() || tGrp->GetLeader()->arenaTeam[i - 4] == NULL)
				{
					itp = m_queuedGroups[i].erase(itp);
					continue;
				}

				++itp;

				if( pGroup == tGrp )
					continue;

				uint32 tRating = tGrp->GetLeader()->arenaTeam[i - 4]->m_stat_rating;

				int32 diff = (int32)tRating - (int32)rating;
				if(diff < 0)
					diff = -diff;

				if(diff > (int32)maxRange)
					continue;

				//Log.Notice("Debug", "EventQueueUpdate added 1 in range arena");

				inRangeGroups.push_back(tGrp->GetID());
			}

			// K, we have a giant list of groups that we could group with, hopefully!
			// or not, we can't go on :(
			if(!inRangeGroups.size())
				continue;

			// But if we're here, we can :D
			uint32 r = 0;
			if( inRangeGroups.size() > 1 )
				r = RandomUInt((uint32)inRangeGroups.size() - 1);

			Group * pairGroup = objmgr.GetGroupById(inRangeGroups[r]);
			if(!pairGroup) continue;

			// Now, let's create this rated Arena Match :)

			//Log.Notice("Debug", "EventQueueUpdate creating arena");
			Arena * arena = (Arena*)CreateInstance(i, LEVEL_GROUP_70);
			ArenaTeam *pTeamPair[2];

			if(arena)
			{
				//Log.Notice("Debug", "EventQueueUpdate arena created");
				removegroups.push_back(pGroup->GetID());
				removegroups.push_back(pairGroup->GetID());
				pGroup->m_isqueued = false;
				pairGroup->m_isqueued = false;
				arena->rated_match = true;
				if( pGroup->GetLeader()->arenaTeam[i - 4] != NULL )
				{
					arena->m_ratedTeams[0] = pGroup->GetLeader()->arenaTeam[i - 4]->m_id;
					pTeamPair[0] = pGroup->GetLeader()->arenaTeam[i - 4];
				}
				else
					pTeamPair[0] = NULL;
				
				if( pairGroup->GetLeader()->arenaTeam[i - 4] != NULL )
				{
					arena->m_ratedTeams[1] = pairGroup->GetLeader()->arenaTeam[i - 4]->m_id;
					pTeamPair[1] = pairGroup->GetLeader()->arenaTeam[i - 4];
				}
				else
					pTeamPair[1] = NULL;

				pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange = 100;
				pairGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange = 100;
				GroupMembersSet::iterator gitr;
				pGroup->Lock();
				for(gitr = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); gitr != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); gitr++)
				{
					PlayerInfo * pi = (*gitr);
					if(!pi->m_loggedInPlayer)
						continue;

					//Log.Notice("Debug", "EventQueueUpdate player lewp");
					pi->m_loggedInPlayer->m_bgTeam = 0;
					if(arena->HasFreeSlots(0))
					{
						arena->AddPlayer(pi->m_loggedInPlayer, 0);
						arena->m_RatedPlayers[0].insert(pi);
						if( pTeamPair[0] != NULL )
						{
							ArenaTeamMember * atm = pTeamPair[0]->GetMember(pi);
							if(atm)
							{
								atm->Played_ThisSeason++;
								atm->Played_ThisWeek++;
							}
							//Log.Notice("Debug", "EventQueueUpdate added player %s", pi->m_loggedInPlayer->GetName());
						}
					}
				}
				pGroup->Unlock();
				pairGroup->Lock();
				for(gitr = pairGroup->GetSubGroup(0)->GetGroupMembersBegin(); gitr != pairGroup->GetSubGroup(0)->GetGroupMembersEnd(); gitr++)
				{
					PlayerInfo * pi = (*gitr);
					if(!pi->m_loggedInPlayer || pi->arenaTeam[i-4] == NULL)
						continue;

					pi->m_loggedInPlayer->m_bgTeam = 1;
					if(arena->HasFreeSlots(1))
					{
						arena->AddPlayer(pi->m_loggedInPlayer, 1);
						arena->m_RatedPlayers[1].insert(pi);
						if( pTeamPair[1] != NULL )
						{
							ArenaTeamMember * atm = pTeamPair[1]->GetMember(pi);
							if(atm)
							{
								atm->Played_ThisSeason++;
								atm->Played_ThisWeek++;
							}
						}
					}
				}
				pairGroup->Unlock();
			}
		}


		for(itz = removegroups.begin(); itz != removegroups.end(); itz++)
		{
			m_queuedGroups[i].remove(*itz);
		}
	}

	m_queueLock.Release();
	m_instanceLock.Release();
}
Пример #4
0
void WintergraspScript::SpawnWarZones(bool apply)
{
    return; // Needs work and more base implementation before it's safe to enable it.

    // This one is simple.
    if(apply)
    {
        Herald("Multiple Battle groups have engaged!");

        uint32 Entry = 0, percent = 100;
        CreatureProto* ctrp = NULL;
        for(uint32 i = 0; i < MAX_BATTLE_ZONES; i++)
        {
            for(uint32 t = 0; t < MAX_UNITS_PER_ZONE/2; t++)
            {
                float x = Wintergrasp_WarZones[i][t].mX, y = Wintergrasp_WarZones[i][t].mY, z = Wintergrasp_WarZones[i][t].mZ, o = Wintergrasp_WarZones[i][t].mO;
                if(x == 0.0f || y == 0.0f || z == 0.0f)
                    continue;

                if(RandomUInt(percent) > (percent/2))
                    Entry = 00000;
                else
                    Entry = 00000;
                percent += 1;

                ctrp = CreatureProtoStorage.LookupEntry(Entry);
                if(ctrp == NULL)
                    continue;

                Creature* ctr = mgr->CreateCreature(Entry);
                if(ctr == NULL)
                    continue;

                ctr->SetMapId(mgr->GetMapId());
                ctr->SetInstanceID(mgr->GetInstanceID());

                if(ctr->Load(ctrp, mgr->iInstanceMode, x, y, z, o))
                {
                    if(!ctr->CanAddToWorld())
                    {
                        ctr->Destruct();
                        continue;
                    }

                    ctr->PushToWorld(mgr);

                    SpawnInfo* spI = new SpawnInfo();
                    spI->CreatureEntry = Entry;
                    spI->RespawnTime = 0;
                    spI->locationId = i;
                    spI->SpawnId = t;
                    spI->m_Spawn = ctr;
                    m_WarriorPool.insert(spI);
                }
                else ctr->Destruct();
            }

            for(uint32 t = MAX_UNITS_PER_ZONE/2; t < MAX_UNITS_PER_ZONE; t++)
            {
                float x = Wintergrasp_WarZones[i][t].mX, y = Wintergrasp_WarZones[i][t].mY, z = Wintergrasp_WarZones[i][t].mZ, o = Wintergrasp_WarZones[i][t].mO;
                if(x == 0.0f || y == 0.0f || z == 0.0f)
                    continue;

                if(RandomUInt(percent) > (percent/2))
                    Entry = 00000;
                else
                    Entry = 00000;
                percent += 1;

                ctrp = CreatureProtoStorage.LookupEntry(Entry);
                if(ctrp == NULL)
                    continue;

                Creature* ctr = mgr->CreateCreature(Entry);
                if(ctr == NULL)
                    continue;

                ctr->SetMapId(mgr->GetMapId());
                ctr->SetInstanceID(mgr->GetInstanceID());

                if(ctr->Load(ctrp, mgr->iInstanceMode, x, y, z, o))
                {
                    if(!ctr->CanAddToWorld())
                    {
                        ctr->Destruct();
                        continue;
                    }

                    ctr->PushToWorld(mgr);

                    SpawnInfo* spI = new SpawnInfo();
                    spI->CreatureEntry = Entry;
                    spI->RespawnTime = 0;
                    spI->locationId = i;
                    spI->SpawnId = t;
                    spI->m_Spawn = ctr;
                    m_WarriorPool.insert(spI);
                }
                else ctr->Destruct();
            }
        }
    }
    else
    {
        m_WarriorSoulPool.clear();
        float x = 0.0f, y = 0.0f;
        for(std::set<SpawnInfo*>::iterator itr = m_WarriorPool.begin(), it2; itr != m_WarriorPool.end();)
        {
            it2 = itr++;
            Creature* ctr = (*it2)->m_Spawn;
            if(ctr != NULL)
            {
                x = ctr->GetPositionX();
                y = ctr->GetPositionY();

                (*it2)->m_Spawn = NULL;
                ctr->RemoveFromWorld(false, true);
                ctr->Destruct();
            }

            delete (*it2);
        }
        m_WarriorPool.clear();
    }
}
Пример #5
0
void LootMgr::PushLoot(StoreLootList *list,Loot * loot, uint32 instance_difficulty)
{
	uint32 i;
	uint32 count;

	for( uint32 x = 0; x < list->count; x++ )
	{
		if( list->items[x].item.itemproto )// this check is needed until loot DB is fixed
		{
			float chance;

			if( instance_difficulty == INSTANCE_MODE_RAID_25_MAN_HEROIC )
				chance = list->items[x].chance2 ;
			else if( instance_difficulty == INSTANCE_MODE_RAID_10_MAN_HEROIC )
				chance = list->items[x].chance2 / 2.5f;
			else if( instance_difficulty == INSTANCE_MODE_RAID_10_MAN )
				chance = list->items[x].chance / 2.5f;
//			else if( instance_difficulty == INSTANCE_MODE_DUNGEON_HEROIC )
//				chance = list->items[x].chance * 2;
			else 
				chance = list->items[x].chance;

			if(chance == 0.0f) 
				continue;
			
			ItemPrototype *itemproto = list->items[x].item.itemproto;
			if( RandChance( chance * sWorld.getRate( RATE_DROP0 + itemproto->Quality ) ) )//|| itemproto->Class == ITEM_CLASS_QUEST)
			{
				if( list->items[x].mincount == list->items[x].maxcount )
					count = list->items[x].maxcount;
				else
					count = RandomUInt(list->items[x].maxcount - list->items[x].mincount) + list->items[x].mincount;

				for( i = 0; i < loot->items.size(); ++i )
				{
					//itemid rand match a already placed item, if item is stackable and unique(stack), increment it, otherwise skips
					if((loot->items[i].item.itemproto == list->items[x].item.itemproto) && itemproto->MaxCount && ((loot->items[i].iItemsCount + count) < itemproto->MaxCount))
					{
						if(itemproto->Unique && ((loot->items[i].iItemsCount+count) < itemproto->Unique))
						{
							loot->items[i].iItemsCount += count;
							break;
						}
						else if (!itemproto->Unique)
						{
							loot->items[i].iItemsCount += count;
							break;
						}
					}
				}

				if( i != loot->items.size() )
					continue;

				__LootItem itm;
				itm.item =list->items[x].item;
				itm.iItemsCount = count;
				itm.roll = NULL;
				itm.passed = false;
				itm.ffa_loot = list->items[x].ffa_loot;
				itm.has_looted.clear();
				
				if( itemproto->Quality > 1 && itemproto->ContainerSlots == 0 )
				{
					itm.iRandomProperty=GetRandomProperties( itemproto );
					itm.iRandomSuffix=GetRandomSuffix( itemproto );
				}
				else
				{
					// save some calls :P
					itm.iRandomProperty = NULL;
					itm.iRandomSuffix = NULL;
				}

				loot->items.push_back(itm);
			}
		}
	}
	if( loot->items.size() > sWorld.MaxLootListSize )
	{
		std::vector<__LootItem>::iterator item_to_remove;
		std::vector<__LootItem>::iterator itr;
		uint32 item_quality;
		bool quest_item;
		while( loot->items.size() > sWorld.MaxLootListSize )
		{
			item_to_remove = loot->items.begin();
			item_quality = 0;
			quest_item = false;
			for( itr = loot->items.begin(); itr != loot->items.end(); ++itr )
			{
				item_quality = (*itr).item.itemproto->Quality;
				quest_item = (*itr).item.itemproto->Class == ITEM_CLASS_QUEST;
				if( (*item_to_remove).item.itemproto->Quality > item_quality && !quest_item )
				{
					item_to_remove = itr;
					break;
				}
			}
			loot->items.erase( item_to_remove );
		}
	}

}
Пример #6
0
void LootRoll::PlayerRolled(Player *player, uint8 choice)
{
	if(m_NeedRolls.find(player->GetLowGUID()) != m_NeedRolls.end() || m_GreedRolls.find(player->GetLowGUID()) != m_GreedRolls.end())
		return; // dont allow cheaters

	/*
	0C BA 0E D0 0E 00 30 F1 Guid
	00 00 00 00 slot
	CB 26 4B 02 00 00 00 07 guid
	7A 16 00 00 item
	00 26 81 8E random factor
	00 00 00 00 F9 random id
	02 roll
	00 roll type

	4C 2A 05 0F 09 00 30 F1 
	01 00 00 00
	F0 BB 3E 02	00 00 00 07 
	C8 1C 00 00 
	60 7B 01 3D 
	08 04 00 00 F9
	02 
	00

	9B 29 05 C9 37 00 30 F1 
	02 00 00 00
	F0 BB 3E 02	00 00 00 07
	B2 19 00 00 
	80 B4 AD 9D 
	A8 03 00 00 F9
	02 
	00
	*/
	int roll = RandomUInt(99)+1;
	// create packet
	WorldPacket data(34);
	data.SetOpcode(SMSG_LOOT_ROLL);
	data << _guid << _slotid << player->GetGUID();
	data << _itemid << random_suffix_factor << random_suffix_id;

	//anti ninja - don't need on things you cannot wear
	if(choice == LOOT_ROLL_TYPE_NEED) 
	{
		ItemPrototype *ip = ItemPrototypeStorage.LookupEntry( _itemid );
		if( player->GetItemInterface()->CanEquipItem( ip, player ) != 0 )
		{
			choice = LOOT_ROLL_TYPE_GREED;
			player->BroadcastMessage("You cannot need on this item.Changing to greed roll");
		}
	}

	if(choice == LOOT_ROLL_TYPE_NEED) 
	{
		player->Event_AchiementCriteria_Received( ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT,roll,ACHIEVEMENT_UNUSED_FIELD_VALUE,1,ACHIEVEMENT_EVENT_ACTION_SET);
		player->Event_AchiementCriteria_Received( ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED,ACHIEVEMENT_UNUSED_FIELD_VALUE,ACHIEVEMENT_UNUSED_FIELD_VALUE,1,ACHIEVEMENT_EVENT_ACTION_ADD);
		m_NeedRolls.insert( std::make_pair(player->GetLowGUID(), roll) );
		data << uint8(roll) << uint8(LOOT_ROLL_TYPE_NEED);
	} 
	else if(choice == LOOT_ROLL_TYPE_GREED || choice == LOOT_ROLL_TYPE_DISENCHANT)
	{
		if( choice == LOOT_ROLL_TYPE_GREED )
		{
			player->Event_AchiementCriteria_Received( ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT,roll,ACHIEVEMENT_UNUSED_FIELD_VALUE,1,ACHIEVEMENT_EVENT_ACTION_SET);
			player->Event_AchiementCriteria_Received( ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED,ACHIEVEMENT_UNUSED_FIELD_VALUE,ACHIEVEMENT_UNUSED_FIELD_VALUE,1,ACHIEVEMENT_EVENT_ACTION_ADD);
		}
		else
		{
			player->Event_AchiementCriteria_Received( ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT,ACHIEVEMENT_UNUSED_FIELD_VALUE,ACHIEVEMENT_UNUSED_FIELD_VALUE,1,ACHIEVEMENT_EVENT_ACTION_ADD);
		}
		m_GreedRolls.insert( std::make_pair(player->GetLowGUID(), roll) );
		data << uint8(roll) << uint8(choice);

	}
	else
	{
		m_passRolls.insert( player->GetLowGUID() );
		data << uint8(128) << uint8(128);
	}
	data << uint8(unk_33_1);
	
	if(player->InGroup())
		player->GetGroup()->SendPacketToAll(&data);
	else
		player->GetSession()->SendPacket(&data);
	
	// check for early completion
	if(!--_remaining)
	{
		// kill event early
		//sEventMgr.RemoveEvents(this);
		Finalize();
	}
}
Пример #7
0
CBattleground* CBattlegroundManager::CreateInstance(uint32 Type, uint32 LevelGroup)
{
    if (bgMaps.find(Type) == bgMaps.end())
    {
        if (!IS_ARENA(Type))
        {
            LOG_ERROR("BattlegroundManager", "No map Id is registered for Battleground type %u", Type);
            return NULL;
        }
    }

    BattlegroundFactoryMethod cfunc = NULL;

    if (!IS_ARENA(Type))
        if (bgFactories.find(bgMaps[Type]) != bgFactories.end())
            cfunc = bgFactories[bgMaps[Type]];

    MapMgr* mgr = NULL;
    CBattleground* bg;
    bool isWeekend = false;
    struct tm tm;
    uint32 iid;
    time_t t;
    int n;

    if (IS_ARENA(Type))
    {
        /* arenas follow a different procedure. */
        uint32 arenaMapCount = arenaMaps.size();
        if (arenaMapCount == 0)
        {
            LOG_ERROR("BattlegroundManager", "There are no Arenas registered. Cannot create Arena.");
            return NULL;
        }

        uint32 index = RandomUInt(arenaMapCount - 1);
        uint32 mapid = arenaMaps[index];
        ArenaFactoryMethod arenaFactory = arenaFactories[index];
        uint32 players_per_side;

        mgr = sInstanceMgr.CreateBattlegroundInstance(mapid);
        if (mgr == NULL)
        {
            sLog.Error("BattlegroundManager", "Arena CreateInstance() call failed for map %u, type %u, level group %u", mapid, Type, LevelGroup);
            return NULL;      // Shouldn't happen
        }

        players_per_side = GetMaximumPlayers(Type);

        iid = ++m_maxBattlegroundId[Type];
        bg = arenaFactory(mgr, iid, LevelGroup, Type, players_per_side);
        mgr->m_battleground = bg;
        Log.Notice("BattlegroundManager", "Created arena battleground type %u for level group %u on map %u.", Type, LevelGroup, mapid);
        sEventMgr.AddEvent(bg, &CBattleground::EventCreate, EVENT_BATTLEGROUND_QUEUE_UPDATE, 1, 1, 0);
        m_instanceLock.Acquire();
        m_instances[Type].insert(make_pair(iid, bg));
        m_instanceLock.Release();
        return bg;
    }

    if (cfunc == NULL)
    {
        sLog.Error("BattlegroundManager", "Could not find CreateBattlegroundFunc pointer for type %u level group %u", Type, LevelGroup);
        return NULL;
    }

    t = time(NULL);
#ifdef WIN32
    //    localtime_s(&tm, &t);
    //zack : some luv for vs2k3 compiler
    tm = *localtime(&t);
#else
    localtime_r(&t, &tm);
#endif

    switch (Type)
    {
        case BATTLEGROUND_WARSONG_GULCH:
            n = 0;
            break;
        case BATTLEGROUND_ARATHI_BASIN:
            n = 1;
            break;
        case BATTLEGROUND_EYE_OF_THE_STORM:
            n = 2;
            break;
        case BATTLEGROUND_STRAND_OF_THE_ANCIENT:
            n = 3;
            break;
        default:
            n = 0;
            break;
    }
    if (((tm.tm_yday / 7) % 4) == n)
    {
        /* Set weekend from Thursday night at midnight until Tuesday morning */
        isWeekend = tm.tm_wday >= 5 || tm.tm_wday < 2;
    }

    /* Create Map Manager */
    mgr = sInstanceMgr.CreateBattlegroundInstance(bgMaps[Type]);
    if (mgr == NULL)
    {
        sLog.Error("BattlegroundManager", "CreateInstance() call failed for map %u, type %u, level group %u", bgMaps[Type], Type, LevelGroup);
        return NULL;      // Shouldn't happen
    }

    /* Call the create function */
    iid = ++m_maxBattlegroundId[Type];
    bg = cfunc(mgr, iid, LevelGroup, Type);
    bg->SetIsWeekend(isWeekend);
    mgr->m_battleground = bg;
    sEventMgr.AddEvent(bg, &CBattleground::EventCreate, EVENT_BATTLEGROUND_QUEUE_UPDATE, 1, 1, 0);
    Log.Notice("BattlegroundManager", "Created battleground type %u for level group %u.", Type, LevelGroup);

    m_instanceLock.Acquire();
    m_instances[Type].insert(make_pair(iid, bg));
    m_instanceLock.Release();

    return bg;
}
   void SpellCast(float val)
   {
        if(_unit->GetCurrentSpell() == NULL && _unit->GetAIInterface()->GetNextTarget())
        {
         float comulativeperc = 0;
          Unit* target = NULL;
         for(int i=0;i<nrspells;i++)
         {
            spells[i].casttime--;
            
            if (m_spellcheck[i])
            {               
               spells[i].casttime = spells[i].cooldown;
               target = _unit->GetAIInterface()->GetNextTarget();
               switch(spells[i].targettype)
               {
                  case TARGET_SELF:
                  case TARGET_VARIOUS:
                     _unit->CastSpell(_unit, spells[i].info, spells[i].instant); break;
                  case TARGET_ATTACKING:
                     _unit->CastSpell(target, spells[i].info, spells[i].instant); break;
                  case TARGET_DESTINATION:
                     _unit->CastSpellAoF(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(), spells[i].info, spells[i].instant); break;
               }

			   if (spells[i].info->Id == SAND_BREATH) //Sand Breath has 2 speeches, maybe there is an easier way to do it
			   {
			     switch(RandomUInt(1))
				 {
				 case 0:
                   _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Not so fast!");
                   _unit->PlaySoundToSet(spells[i].soundid);
				 break;
				 case 1:
                   _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Struggle as much as you like!");
                   _unit->PlaySoundToSet(spells[i].soundid);
				 break;
				 }
               }
               else
               {			   
                 if (spells[i].speech != "")
                 {
                    _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, spells[i].speech.c_str());
                    _unit->PlaySoundToSet(spells[i].soundid); 
                 }
				}   

               m_spellcheck[i] = false;
               return;
            }

            if ((val > comulativeperc && val <= (comulativeperc + spells[i].perctrigger)) || !spells[i].casttime)
            {
               _unit->setAttackTimer(spells[i].attackstoptimer, false);
               m_spellcheck[i] = true;
            }
            comulativeperc += spells[i].perctrigger;
         }
      }
   }
Пример #9
0
void LootRoll::PlayerRolled(PlayerInfo* pInfo, uint8 choice)
{
	if(m_NeedRolls.find(pInfo->guid) != m_NeedRolls.end() || m_GreedRolls.find(pInfo->guid) != m_GreedRolls.end() || m_DisenchantRolls.find(pInfo->guid) != m_DisenchantRolls.end())
		return; // dont allow cheaters

	ItemPrototype* proto = ItemPrototypeStorage.LookupEntry(_itemid);
	if(proto == NULL)
		return; // Shouldn't happen.

	mLootLock.Acquire();

	int roll = RandomUInt(99)+1;
	// create packet
	WorldPacket data(SMSG_LOOT_ROLL, 34);
	data << _guid << _slotid << uint64(pInfo->guid);
	data << _itemid << _randomsuffixid << _randompropertyid;

	if(!pInfo->m_loggedInPlayer)
		choice = PASS;
	bool acceptableroll = true;
	switch(choice)
 	{
	case NEED:
		{
			if(pInfo->m_loggedInPlayer->CanNeedItem(proto))
			{
				m_NeedRolls.insert( std::make_pair(pInfo->guid, roll) );
				data << uint8(roll) << uint8(NEED);
			}
			else
			{
				m_passRolls.insert( pInfo->guid );
				data << uint8(128) << uint8(128);
			}
		}break;
	case GREED:
		{
			m_GreedRolls.insert( std::make_pair(pInfo->guid, roll) );
			data << uint8(roll) << uint8(GREED);
		}break;
	case DISENCHANT:
		{
			if(acceptableroll)
			{
				if(proto->DisenchantReqSkill < 0)
					acceptableroll = false;
				else if(pInfo->m_Group)
					acceptableroll = pInfo->m_Group->HasAcceptableDisenchanters(proto->DisenchantReqSkill);
				else
					acceptableroll = (pInfo->m_loggedInPlayer->_HasSkillLine(333) && (pInfo->m_loggedInPlayer->_GetSkillLineCurrent(333) > uint32(proto->DisenchantReqSkill)));
			}

			if(acceptableroll)
			{
				m_DisenchantRolls.insert( std::make_pair(pInfo->guid, roll) );
				data << uint8(roll) << uint8(DISENCHANT);
			}
			else
			{
				m_passRolls.insert( pInfo->guid );
				data << uint8(128) << uint8(128);
			}
		}break;
	default: //pass
		{
			m_passRolls.insert( pInfo->guid );
			data << uint8(128) << uint8(128);
		}break;
 	}

	data << uint8(0);

	if(pInfo->m_Group)
		pInfo->m_Group->SendPacketToAll(&data);
	else if(pInfo->m_loggedInPlayer)
		pInfo->m_loggedInPlayer->GetSession()->SendPacket(&data);

	// check for early completion
	if(!--_remaining)
	{
		mLootLock.Release(); // so we can call the other lock in a sec.
		// kill event early
		//sEventMgr.RemoveEvents(this);
		Finalize();
		return;
	}

	mLootLock.Release();
}
Пример #10
0
void CBattlegroundManager::EventQueueUpdate(bool forceStart)
{
    deque<uint32> tempPlayerVec[2];
    uint32 i, j, k;
    Player* plr;
    CBattleground* bg;
    list<uint32>::iterator it3, it4;
    map<uint32, CBattleground*>::iterator iitr;
    Arena* arena;
    int32 team;
    uint32 plrguid;
    uint32 factionMap[MAX_PLAYER_TEAMS];
    uint32 count;
    std::queue< uint32 > teams[MAX_PLAYER_TEAMS];

    m_queueLock.Acquire();
    m_instanceLock.Acquire();

    for (i = 0; i < BATTLEGROUND_NUM_TYPES; ++i)
    {
        for (j = 0; j < MAX_LEVEL_GROUP; ++j)
        {
            if (!m_queuedPlayers[i][j].size())
                continue;

            tempPlayerVec[0].clear();
            tempPlayerVec[1].clear();

            // We try to add the players who queued for a specific Bg/Arena instance to
            // the Bg/Arena where they queued to, and add the rest to another list 
            for (it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();)
            {
                it4 = it3++;
                plrguid = *it4;
                plr = objmgr.GetPlayer(plrguid);

                // Player has left the game or switched level group since queuing (by leveling for example) 
                if (!plr || GetLevelGrouping(plr->getLevel()) != j)
                {
                    m_queuedPlayers[i][j].erase(it4);
                    continue;
                }

                // queued to a specific instance id?
                if (plr->m_bgQueueInstanceId != 0)
                {
                    iitr = m_instances[i].find(plr->m_bgQueueInstanceId);
                    if (iitr == m_instances[i].end())
                    {
                        // queue no longer valid, since instance has closed since queuing 
                        plr->GetSession()->SystemMessage(plr->GetSession()->LocalizedWorldSrv(52), plr->m_bgQueueInstanceId);
                        plr->m_bgIsQueued = false;
                        plr->m_bgQueueType = 0;
                        plr->m_bgQueueInstanceId = 0;
                        m_queuedPlayers[i][j].erase(it4);
                        continue;
                    }

                    // can we join the specified Bg instance?
                    bg = iitr->second;
                    if (bg->CanPlayerJoin(plr, bg->GetType()))
                    {
                        bg->AddPlayer(plr, plr->GetTeam());
                        m_queuedPlayers[i][j].erase(it4);
                    }
                }
                else
                {
                    if (IS_ARENA(i))
                        tempPlayerVec[plr->GetTeam()].push_back(plrguid);
                    else if (!plr->HasAura(BG_DESERTER))
                        tempPlayerVec[plr->GetTeam()].push_back(plrguid);
                }
            }

            // Now that we have a list of players who didn't queue for a specific instance
            // try to add them to a Bg/Arena that is already under way 
            for (iitr = m_instances[i].begin(); iitr != m_instances[i].end(); ++iitr)
            {
                if (iitr->second->HasEnded() || iitr->second->GetLevelGroup() != j)
                    continue;

                if (IS_ARENA(i))
                {
                    arena = TO< Arena* >(iitr->second);
                    if (arena->Rated())
                        continue;

                    factionMap[0] = arena->GetTeamFaction(0);
                    factionMap[1] = arena->GetTeamFaction(1);

                    team = arena->GetFreeTeam();
                    while ((team >= 0) && (tempPlayerVec[factionMap[team]].size() > 0))
                    {
                        plrguid = *tempPlayerVec[factionMap[team]].begin();
                        tempPlayerVec[factionMap[team]].pop_front();
                        plr = objmgr.GetPlayer(plrguid);
                        if (plr)
                        {
                            plr->m_bgTeam = team;
                            arena->AddPlayer(plr, team);
                            team = arena->GetFreeTeam();
                        }
                        ErasePlayerFromList(plrguid, &m_queuedPlayers[i][j]);
                    }
                }
                else
                {
                    bg = iitr->second;
                    int size = (int)min(tempPlayerVec[0].size(), tempPlayerVec[1].size());
                    for (int counter = 0; (counter < size) && (bg->IsFull() == false); counter++)
                    {
                        AddPlayerToBgTeam(bg, &tempPlayerVec[0], i, j, 0);
                        AddPlayerToBgTeam(bg, &tempPlayerVec[1], i, j, 1);
                    }

                    while (tempPlayerVec[0].size() > 0 && bg->HasFreeSlots(0, bg->GetType()))
                    {
                        AddPlayerToBgTeam(bg, &tempPlayerVec[0], i, j, 0);
                    }
                    while (tempPlayerVec[1].size() > 0 && bg->HasFreeSlots(1, bg->GetType()))
                    {
                        AddPlayerToBgTeam(bg, &tempPlayerVec[1], i, j, 1);
                    }
                }
            }

            // Now that that we added everyone we could to a running Bg/Arena
            // We shall see if we can start a new one! 
            if (IS_ARENA(i))
            {
                // enough players to start a round?
                uint32 minPlayers = BattlegroundManager.GetMinimumPlayers(i);
                if (!forceStart && ((tempPlayerVec[0].size() + tempPlayerVec[1].size()) < (minPlayers * 2)))
                    continue;

                if (CanCreateInstance(i, j))
                {
                    arena = TO< Arena* >(CreateInstance(i, j));
                    if (arena == NULL)
                    {
                        sLog.Error("BattlegroundMgr", "%s (%u): Couldn't create Arena Instance", __FILE__, __LINE__);
                        m_queueLock.Release();
                        m_instanceLock.Release();
                        return;
                    } // No alliance in the queue
                    if (tempPlayerVec[0].size() == 0)
                    {
                        count = GetMaximumPlayers(i) * 2;
                        while ((count > 0) && (tempPlayerVec[1].size() > 0))
                        {
                            if (teams[0].size() > teams[1].size())
                                teams[1].push(tempPlayerVec[1].front());
                            else
                                teams[0].push(tempPlayerVec[1].front());
                            tempPlayerVec[1].pop_front();
                            count--;
                        }
                    }
                    else // No horde in the queue
                        if (tempPlayerVec[1].size() == 0)
                        {
                            count = GetMaximumPlayers(i) * 2;
                            while ((count > 0) && (tempPlayerVec[0].size() > 0))
                            {
                                if (teams[0].size() > teams[1].size())
                                    teams[1].push(tempPlayerVec[0].front());
                                else
                                    teams[0].push(tempPlayerVec[0].front());
                                tempPlayerVec[0].pop_front();
                                count--;
                            }
                        }
                        else // There are both alliance and horde players in the queue
                        {
                            count = GetMaximumPlayers(i);
                            while ((count > 0) && (tempPlayerVec[0].size() > 0) && (tempPlayerVec[1].size() > 0))
                            {
                                teams[0].push(tempPlayerVec[0].front());
                                teams[1].push(tempPlayerVec[1].front());
                                tempPlayerVec[0].pop_front();
                                tempPlayerVec[1].pop_front();
                                count--;
                            }
                        }

                    // Now we just need to add the players to the Arena instance
                    while (teams[0].size() > 0)
                    {
                        for (uint32 team = 0; team < 2; team++)
                        {
                            plrguid = teams[team].front();
                            teams[team].pop();
                            plr = objmgr.GetPlayer(plrguid);
                            if (plr == NULL)
                                continue;

                            plr->m_bgTeam = team;
                            arena->AddPlayer(plr, plr->m_bgTeam);
                            // remove from the main queue (painful!)
                            ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
                        }
                    }
                }
            }
            else
            {
                uint32 minPlayers = BattlegroundManager.GetMinimumPlayers(i);
                if (forceStart || (tempPlayerVec[0].size() >= minPlayers && tempPlayerVec[1].size() >= minPlayers))
                {
                    if (CanCreateInstance(i, j))
                    {
                        bg = CreateInstance(i, j);
                        if (bg == NULL)
                        {
                            m_queueLock.Release();
                            m_instanceLock.Release();
                            return;
                        }

                        // push as many as possible in
                        if (forceStart)
                        {
                            for (k = 0; k < 2; ++k)
                            {
                                while (tempPlayerVec[k].size() && bg->HasFreeSlots(k, bg->GetType()))
                                {
                                    AddPlayerToBgTeam(bg, &tempPlayerVec[k], i, j, k);
                                }
                            }
                        }
                        else
                        {
                            int size = (int)min(tempPlayerVec[0].size(), tempPlayerVec[1].size());
                            for (int counter = 0; (counter < size) && (bg->IsFull() == false); counter++)
                            {
                                AddPlayerToBgTeam(bg, &tempPlayerVec[0], i, j, 0);
                                AddPlayerToBgTeam(bg, &tempPlayerVec[1], i, j, 1);
                            }
                        }
                    }
                }
            }
        }
    }

    /* Handle paired arena team joining */
    Group* group1, *group2;
    uint32 teamids[2] = { 0, 0 };
    uint32 avgRating[2] = { 0, 0 };
    uint32 n;
    list<uint32>::iterator itz;
    for (i = BATTLEGROUND_ARENA_2V2; i <= BATTLEGROUND_ARENA_5V5; ++i)
    {
        if (!forceStart && m_queuedGroups[i].size() < 2)      /* got enough to have an arena battle ;P */
        {
            continue;
        }

        for (j = 0; j < (uint32)m_queuedGroups[i].size(); j++)
        {
            group1 = group2 = NULL;
            n = RandomUInt((uint32)m_queuedGroups[i].size()) - 1;
            for (itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end() && n > 0; ++itz)
                --n;

            if (itz == m_queuedGroups[i].end())
                itz = m_queuedGroups[i].begin();

            if (itz == m_queuedGroups[i].end())
            {
                sLog.Error("BattlegroundMgr", "Internal error at %s:%u", __FILE__, __LINE__);
                m_queueLock.Release();
                m_instanceLock.Release();
                return;
            }

            group1 = objmgr.GetGroupById(*itz);
            if (group1 == NULL)
            {
                continue;
            }

            if (forceStart && m_queuedGroups[i].size() == 1)
            {
                if (CreateArenaType(i, group1, NULL) == -1) return;
                m_queuedGroups[i].remove(group1->GetID());
                continue;
            }

            teamids[0] = GetArenaGroupQInfo(group1, i, &avgRating[0]);

            list<uint32> possibleGroups;
            for (itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end(); ++itz)
            {
                group2 = objmgr.GetGroupById(*itz);
                if (group2)
                {
                    teamids[1] = GetArenaGroupQInfo(group2, i, &avgRating[1]);
                    uint32 delta = abs((int32)avgRating[0] - (int32)avgRating[1]);
                    if (teamids[0] != teamids[1] && delta <= sWorld.ArenaQueueDiff)
                    {
                        possibleGroups.push_back(group2->GetID());
                    }
                }
            }

            if (possibleGroups.size() > 0)
            {
                n = RandomUInt((uint32)possibleGroups.size()) - 1;
                for (itz = possibleGroups.begin(); itz != possibleGroups.end() && n > 0; ++itz)
                    --n;

                if (itz == possibleGroups.end())
                    itz = possibleGroups.begin();

                if (itz == possibleGroups.end())
                {
                    sLog.Error("BattlegroundMgr", "Internal error at %s:%u", __FILE__, __LINE__);
                    m_queueLock.Release();
                    m_instanceLock.Release();
                    return;
                }

                group2 = objmgr.GetGroupById(*itz);
                if (group2)
                {
                    if (CreateArenaType(i, group1, group2) == -1) return;
                    m_queuedGroups[i].remove(group1->GetID());
                    m_queuedGroups[i].remove(group2->GetID());
                }
            }
        }
    }

    m_queueLock.Release();
    m_instanceLock.Release();
}
Пример #11
0
void LootMgr::AddLoot(Loot* loot, uint32 itemid, uint32 mincount, uint32 maxcount, uint32 ffa_loot)
{
	uint32 i;
	uint32 count;
	ItemPrototype *itemproto = ItemPrototypeStorage.LookupEntry(itemid);

	if( itemproto )// this check is needed until loot DB is fixed
	{
		if( mincount == maxcount )
			count = maxcount;
		else
			count = RandomUInt(maxcount - mincount) + mincount;

		for( i = 0; i < loot->items.size(); i++ )
		{
			//itemid rand match a already placed item, if item is stackable and unique(stack), increment it, otherwise skips
			if((loot->items[i].item.itemproto == itemproto) && itemproto->MaxCount && ((loot->items[i].StackSize + count <= itemproto->MaxCount)))
			{
				if(itemproto->Unique && ((loot->items[i].StackSize+count) < itemproto->Unique))
				{
					loot->items[i].StackSize += count;
					break;
				}
				else if (!itemproto->Unique)
				{
					loot->items[i].StackSize += count;
					break;
				}
			}
		}

		if( i != loot->items.size() )
			return;

		_LootItem item;
		item.itemproto = itemproto;
		item.displayid = itemproto->DisplayInfoID;

		__LootItem itm;
		itm.item = item;
		itm.StackSize = count;
		itm.roll = NULLROLL;
		itm.passed = false;
		itm.ffa_loot = ffa_loot;
		itm.has_looted.clear();

		if( itemproto->Quality > 1 && itemproto->ContainerSlots == 0 )
		{
			itm.iRandomProperty=GetRandomProperties( itemproto );
			itm.iRandomSuffix=GetRandomSuffix( itemproto );
		}
		else
		{
			// save some calls :P
			itm.iRandomProperty = NULL;
			itm.iRandomSuffix = NULL;
		}

		loot->items.push_back(itm);
	}
}
Пример #12
0
void LootMgr::PushLoot(StoreLootList *list,Loot * loot, uint8 difficulty, uint8 team, bool disenchant)
{
	uint32 i;
	uint32 count;
	float nrand = 0;
	float ncount = 0;
	assert(difficulty < 4);

	if (disenchant)
	{
		nrand = RandomUInt(10000) / 100.0f;
		ncount = 0;
	}

	for( uint32 x = 0; x < list->count; x++ )
	{
		if( list->items[x].item.itemproto )// this check is needed until loot DB is fixed
		{
			float chance = list->items[x].chance[difficulty];
			if(chance == 0.0f)
				continue;

			ItemPrototype *itemproto = list->items[x].item.itemproto;
			if(!CheckItemFaction(itemproto->Faction, team))
				continue;

			int lucky;
			if (disenchant)
			{
				lucky = nrand >= ncount && nrand <= (ncount+chance);
				ncount+= chance;
			}
			else
				lucky = Rand( chance * sWorld.getRate( RATE_DROP0 + itemproto->Quality ) );

			if( lucky )
			{
				if( list->items[x].mincount == list->items[x].maxcount )
					count = list->items[x].maxcount;
				else
					count = RandomUInt(list->items[x].maxcount - list->items[x].mincount) + list->items[x].mincount;

				for( i = 0; i < loot->items.size(); i++ )
				{
					//itemid rand match a already placed item, if item is stackable and unique(stack), increment it, otherwise skips
					if((loot->items[i].item.itemproto == list->items[x].item.itemproto) && itemproto->MaxCount && ((loot->items[i].StackSize + count) < itemproto->MaxCount))
					{
						if(itemproto->Unique && ((loot->items[i].StackSize+count) < itemproto->Unique))
						{
							loot->items[i].StackSize += count;
							break;
						}
						else if (!itemproto->Unique)
						{
							loot->items[i].StackSize += count;
							break;
						}
					}
				}

				if( i != loot->items.size() )
					continue;

				__LootItem itm;
				itm.item =list->items[x].item;
				itm.StackSize = count;
				itm.roll = NULLROLL;
				itm.passed = false;
				itm.ffa_loot = list->items[x].ffa_loot;
				itm.has_looted.clear();

				if( itemproto->Quality > 1 && itemproto->ContainerSlots == 0 )
				{
					itm.iRandomProperty=GetRandomProperties( itemproto );
					itm.iRandomSuffix=GetRandomSuffix( itemproto );
				}
				else
				{
					// save some calls :P
					itm.iRandomProperty = NULL;
					itm.iRandomSuffix = NULL;
				}

				loot->items.push_back(itm);
			}
		}
	}

	if( loot->items.size() > 16 )
	{
		std::vector<__LootItem>::iterator item_to_remove;
		std::vector<__LootItem>::iterator itr;
		uint32 item_quality;
		bool quest_item;
		while( loot->items.size() > 16 )
		{
			item_to_remove = loot->items.begin();
			item_quality = 0;
			quest_item = false;
			for( itr = loot->items.begin(); itr != loot->items.end(); itr++ )
			{
				item_quality = (*itr).item.itemproto->Quality;
				quest_item = (*itr).item.itemproto->Class == ITEM_CLASS_QUEST;
				if( (*item_to_remove).item.itemproto->Quality > item_quality && !quest_item )
				{
					item_to_remove = itr;
				}
			}
			loot->items.erase( item_to_remove );
		}
	}

}
Пример #13
0
StrandOfTheAncients::StrandOfTheAncients(MapMgr* mgr, uint32 id, uint32 lgroup, uint32 t) : CBattleground(mgr,id,lgroup,t)
{
	Attackers = RandomUInt(2)-1;
	BattleRound = 1;
}
Пример #14
0
		int32 DoCalculateEffect(uint32 i, Unit* target, int32 value)
		{
			return 2 + RandomUInt(2);
		}
Пример #15
0
void LootMgr::PushLoot(StoreLootList* list, Loot* loot, uint32 type)
{
	uint32 i;
	uint32 count;

	if(type >= NUM_LOOT_TYPES)
		return;

	for(uint32 x = 0; x < list->count; x++)
	{
		if(list->items[x].item.itemproto)  // this check is needed until loot DB is fixed
		{
			float chance = 0.0f;

			switch(type)
			{
				case LOOT_NORMAL10:
					chance = list->items[x].chance;
					break;

				case LOOT_NORMAL25:
					chance = list->items[x].chance2;
					break;

				case LOOT_HEROIC10:
					chance = list->items[x].chance3;
					break;

				case LOOT_HEROIC25:
					chance = list->items[x].chance4;
					break;
			}

			// drop chance cannot be larger than 100% or smaller than 0%
			if(chance <= 0.0f || chance > 100.0f)
				continue;

			ItemPrototype* itemproto = list->items[x].item.itemproto;
			if(Rand(chance * sWorld.getRate(RATE_DROP0 + itemproto->Quality)))      //|| itemproto->Class == ITEM_CLASS_QUEST)
			{
				if(list->items[x].mincount == list->items[x].maxcount)
					count = list->items[x].maxcount;
				else
					count = RandomUInt(list->items[x].maxcount - list->items[x].mincount) + list->items[x].mincount;

				for(i = 0; i < loot->items.size(); ++i)
				{
					//itemid rand match a already placed item, if item is stackable and unique(stack), increment it, otherwise skips
					if((loot->items[i].item.itemproto == list->items[x].item.itemproto) && itemproto->MaxCount && ((loot->items[i].iItemsCount + count) < itemproto->MaxCount))
					{
						if(itemproto->Unique && ((loot->items[i].iItemsCount + count) < itemproto->Unique))
						{
							loot->items[i].iItemsCount += count;
							break;
						}
						else if(!itemproto->Unique)
						{
							loot->items[i].iItemsCount += count;
							break;
						}
					}
				}

				if(i != loot->items.size())
					continue;

				__LootItem itm;
				itm.item = list->items[x].item;
				itm.iItemsCount = count;
				itm.roll = NULL;
				itm.passed = false;
				itm.ffa_loot = list->items[x].ffa_loot;
				itm.has_looted.clear();

				if(itemproto->Quality > 1 && itemproto->ContainerSlots == 0)
				{
					itm.iRandomProperty = GetRandomProperties(itemproto);
					itm.iRandomSuffix = GetRandomSuffix(itemproto);
				}
				else
				{
					// save some calls :P
					itm.iRandomProperty = NULL;
					itm.iRandomSuffix = NULL;
				}

				loot->items.push_back(itm);
			}
		}
	}
	if(loot->items.size() > 16)
	{
		std::vector<__LootItem>::iterator item_to_remove;
		std::vector<__LootItem>::iterator itr;
		uint32 item_quality;
		bool quest_item;
		while(loot->items.size() > 16)
		{
			item_to_remove = loot->items.begin();
			item_quality = 0;
			quest_item = false;
			for(itr = loot->items.begin(); itr != loot->items.end(); ++itr)
			{
				item_quality = (*itr).item.itemproto->Quality;
				quest_item = (*itr).item.itemproto->Class == ITEM_CLASS_QUEST;
				if((*item_to_remove).item.itemproto->Quality > item_quality && !quest_item)
				{
					item_to_remove = itr;
				}
			}
			loot->items.erase(item_to_remove);
		}
	}

}
    void AIUpdate()
    {	
	    uint32 val = RandomUInt(1000);
        SpellCast(val);
    }
Пример #17
0
bool Rand(int32 chance)
{
	int32 val = RandomUInt(10000);
	int32 p = chance * 100;
	return p >= val;
}
Пример #18
0
//parse a group list and pick 1 item out of it
bool LootMgr::FillObjectLoot(Object *obj,SimpleVect<LootStoreStruct*> *source_list, LootStoreStruct *reference )
{
	uint32 max_ind = source_list->GetMaxSize();
	if( max_ind == 0 )
		return false;	//noway
	uint32 drops_added = 0;
	uint32 must_drop_counter = 0;
	float chance_sum = 0;
	//this should make list parsing "randomized". On highdroprate mods mobs would drop always the first 16 items if this would not exist
	uint32 random_start_index = RandomUInt() % max_ind;
//	uint32 random_increment_index = RandomUInt() % max_ind;
	for(uint32 li=random_start_index;li<max_ind+random_start_index;li++)
	{
		uint32 ti = li % max_ind;
//		uint32 ti = (li * random_increment_index ) % max_ind;	//need to avoid parsing the same item twice
		LootStoreStruct *ls = source_list->GetValue( ti );
		//reference list is parsed only if we manage to roll for it
		if( ls->ref_list )
		{
			//theoretically loot with reference list will have only 1 item, but this whole process is called N times
			if( ls->DropChance<=0 || RandChance( ls->DropChance * sWorld.getRate( RATE_DROP0 )) == true ) 
			{	
				if( FillObjectLoot( obj, ls->ref_list, ls ) )
				{
					drops_added++;
//					return true;
				}
			}
		}
		//explicit drops are parsed first
		else if( ls->DropChance >0 )
		{
			if( FillObjectLoot( obj, ls, reference ) == true )
			{
				if( ls->GroupID != 0 )
					return true;
				drops_added++;
			}
			//if explicit drops chance is >= 100 then we drop something from here
			chance_sum += ls->DropChance;
		}
		//we count equal chance drops and pick 1 at the end
		else if( ls->DropChance == 0 )
			must_drop_counter++;
	}
	//pick an equal-chanced drop (if there is any)
	if( must_drop_counter > 0 )
	{
		uint32 picked_value = RandomUInt() % must_drop_counter;
		uint32 counter = 0;
		for(uint32 li=0;li<max_ind;li++)
			if( source_list->GetValue( li )->DropChance == 0 && source_list->GetValue( li )->ref_list == NULL )
			{
				if( counter == picked_value )
				{
					FillObjectLoot( obj, source_list->GetValue( li ) );
					return true;
				}
				counter++;
			}
	}
	//if we still have no items rule says that if sum of chances is at least 100 then 1 item will be picked for sure
	if( drops_added == 0 && chance_sum >= 100 )
	{
		uint32 explicit_chanced_items = max_ind - must_drop_counter;
		uint32 picked_value = RandomUInt() % explicit_chanced_items;
		uint32 counter = 0;
		for(uint32 li=0;li<max_ind;li++)
			if( source_list->GetValue( li )->DropChance >= 0 && source_list->GetValue( li )->ref_list == NULL )
			{
				if( counter == picked_value )
				{
					FillObjectLoot( obj, source_list->GetValue( li ) );
					return true;
				}
				counter++;
			}
	}
	return false;
}
Пример #19
0
    void AIUpdate()
    {
        SetCanEnterCombat(false);
        SetCanMove(false);
        SetAllowMelee(false);
        SetAllowSpell(false);

        // ORB ONE
        if (IsTimerFinished(Phase_Timer) && GetPhase() == 0)
        {
            if (Phasepart == 0)
            {
                Spawncounter = 0;
                orb1 = _unit->GetMapMgr()->GetInterface()->GetGameObjectNearestCoords(482.929f, -151.114f, 43.654f, 183961);
                if (orb1)
                    orb1->SetState(GAMEOBJECT_STATE_OPEN);

                switch (RandomUInt(1))
                {
                    NPC_ID_Spawn = 0;
                case 0:
                    NPC_ID_Spawn = CN_BLAZING_TRICKSTER;
                    break;
                case 1:
                    NPC_ID_Spawn = CN_WARP_STALKER;
                    break;
                }
                ResetTimer(Phase_Timer, 8000);
                Phasepart = 1;
                return;
            }

            else if (Phasepart == 1)
            {
                if (!NPC_orb1 && NPC_ID_Spawn != 0 && Spawncounter == 0)
                {
                    ++Spawncounter;
                    NPC_orb1 = SpawnCreature(NPC_ID_Spawn, 475.672f, -147.086f, 42.567f, 3.184015f);
                    return;
                }
                else if (NPC_orb1 && !NPC_orb1->IsAlive())
                {
                    _unit->SendScriptTextChatMessage(SAY_MELLICHAR_03);
                    SetPhase(1);
                    Phasepart = 0;
                    ResetTimer(Phase_Timer, 6000);
                    return;
                }
                else
                {
                    return;
                }
                return;
            }
            //return;
        }

        // ORB TWO
        else if (IsTimerFinished(Phase_Timer) && GetPhase() == 1)
        {
            if (Phasepart == 0)
            {
                Spawncounter = 0;
                orb2 = _unit->GetMapMgr()->GetInterface()->GetGameObjectNearestCoords(409.062f, -152.161f, 43.653f, 183963);
                if (orb2)
                    orb2->SetState(GAMEOBJECT_STATE_OPEN);

                ResetTimer(Phase_Timer, 8000);
                Phasepart = 1;
                return;
            }

            else if (Phasepart == 1)
            {
                if (!NPC_orb2 && Spawncounter == 0)
                {
                    ++Spawncounter;
                    NPC_orb2 = SpawnCreature(CN_MILLHOUSE_MANASTORM, 413.192f, -148.586f, 42.569f, 0.024347f);
                    return;
                }
                else if (NPC_orb2 && NPC_orb2->IsAlive())
                {
                    Creature* millhouse = TO_CREATURE(ForceCreatureFind(CN_MILLHOUSE_MANASTORM));
                    if (millhouse)
                    {
                        millhouse->SendTimedScriptTextChatMessage(SAY_MILLHOUS_01, 2000);

                        _unit->SendTimedScriptTextChatMessage(SAY_MELLICHAR_04, 13000);

                        millhouse->SendTimedScriptTextChatMessage(SAY_MILLHOUS_02, 22000);
                    }
                    SetPhase(2);
                    Phasepart = 0;
                    ResetTimer(Phase_Timer, 25000);
                    return;
                }
                else
                {
                    return;
                }
                return;

            }
            //return;
        }

        // ORB THREE
        else if (IsTimerFinished(Phase_Timer) && GetPhase() == 2)
        {
            if (Phasepart == 0)
            {
                Spawncounter = 0;
                orb3 = _unit->GetMapMgr()->GetInterface()->GetGameObjectNearestCoords(415.167f, -174.338f, 43.654f, 183964);
                if (orb3)
                    orb3->SetState(GAMEOBJECT_STATE_OPEN);

                switch (RandomUInt(1))
                {
                    NPC_ID_Spawn = 0;
                case 0:
                    NPC_ID_Spawn = CN_SULFURON_MAGMA_THROWER;
                    break;
                case 1:
                    NPC_ID_Spawn = CN_AKKIRIS_LIGHTNING_WAKER;
                    break;
                }
                ResetTimer(Phase_Timer, 8000);
                Phasepart = 1;
                return;
            }

            else if (Phasepart == 1)
            {
                if (!NPC_orb3 && NPC_ID_Spawn != 0 && Spawncounter == 0)
                {
                    /// \todo investigate.... saying "1"... really?
                    _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "1");
                    ++Spawncounter;
                    NPC_orb3 = SpawnCreature(NPC_ID_Spawn, 420.050f, -173.500f, 42.580f, 6.110f);
                    return;
                }
                else if (!NPC_orb3)
                {
                    /// \todo investigate.... saying "2"... really?
                    _unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "2");
                    NPC_orb3 = GetNearestCreature(NPC_ID_Spawn);
                }
                else if (NPC_orb3 && !NPC_orb3->IsAlive())
                {
                    _unit->SendScriptTextChatMessage(SAY_MELLICHAR_05);
                    SetPhase(3);
                    Phasepart = 0;
                    ResetTimer(Phase_Timer, 8000);
                    return;
                }
                else
                {
                    return;
                }
                return;
            }
            //return;
        }

        // ORB FOUR
        else if (IsTimerFinished(Phase_Timer) && GetPhase() == 3)
        {
            if (Phasepart == 0)
            {
                Spawncounter = 0;
                orb4 = _unit->GetMapMgr()->GetInterface()->GetGameObjectNearestCoords(476.422f, -174.517f, 42.748f, 183962);
                if (orb4)
                    orb4->SetState(GAMEOBJECT_STATE_OPEN);

                switch (RandomUInt(1))
                {
                    NPC_ID_Spawn = 0;
                case 0:
                    NPC_ID_Spawn = CN_TWILIGHT_DRAKONAAR;
                    break;
                case 1:
                    NPC_ID_Spawn = CN_BLACKWING_DRAKONAAR;
                    break;
                }
                ResetTimer(Phase_Timer, 8000);
                Phasepart = 1;
                return;
            }

            else if (Phasepart == 1)
            {
                if (!NPC_orb4 && NPC_ID_Spawn != 0 && Spawncounter == 0)
                {
                    ++Spawncounter;
                    NPC_orb4 = SpawnCreature(NPC_ID_Spawn, 471.153f, -174.715f, 42.589f, 3.097f);
                    return;
                }
                else if (!NPC_orb4)
                {
                    NPC_orb4 = GetNearestCreature(NPC_ID_Spawn);
                }
                else if (NPC_orb4 && !NPC_orb4->IsAlive())
                {
                    _unit->SendScriptTextChatMessage(SAY_MELLICHAR_06);
                    SetPhase(4);
                    Phasepart = 0;
                    ResetTimer(Phase_Timer, 6000);
                    return;
                }
                else
                {
                    return;
                }
                return;
            }
            //return;
        }

        else if (IsTimerFinished(Phase_Timer) && GetPhase() == 4)
        {}

        ParentClass::AIUpdate();
        SetCanMove(false);
        SetAllowMelee(false);
        SetAllowSpell(false);
    }
Пример #20
0
void LootMgr::AddLoot(Loot * loot, uint32 itemid, uint32 mincount, uint32 maxcount, uint32 ffa_loot)
{
	uint32 i;
	uint32 count;
	ItemPrototype *itemproto = ItemPrototypeStorage.LookupEntry(itemid);

	if( itemproto )// this check is needed until loot DB is fixed
	{
		if( mincount == maxcount )
			count = maxcount;
		else
			count = RandomUInt(maxcount - mincount) + mincount;

		for( i = 0; i < loot->items.size(); ++i )
		{
			//itemid rand match a already placed item, if item is stackable and unique(stack), increment it, otherwise skips
			if((loot->items[i].item.itemproto == itemproto) && itemproto->MaxCount && ((loot->items[i].iItemsCount + count) < itemproto->MaxCount))
			{
				if(itemproto->Unique && ((loot->items[i].iItemsCount+count) < itemproto->Unique))
				{
					loot->items[i].iItemsCount += count;
					break;
				}
				else if (!itemproto->Unique)
				{
					loot->items[i].iItemsCount += count;
					break;
				}
			}
		}

		if( i != loot->items.size() )
		{ 
			return;
		}

		_LootItem item;
		item.itemproto = itemproto;
		item.displayid = itemproto->DisplayInfoID;

		__LootItem itm;
		itm.item = item;
		itm.iItemsCount = count;
		itm.roll = NULL;
		itm.passed = false;
		itm.ffa_loot = ffa_loot;
		itm.has_looted.clear();
		
		if( itemproto->Quality > ITEM_QUALITY_NORMAL_WHITE && itemproto->ContainerSlots == 0 )
		{
			itm.iRandomProperty=GetRandomProperties( itemproto );
			itm.iRandomSuffix=GetRandomSuffix( itemproto );
		}
		else
		{
			// save some calls :P
			itm.iRandomProperty = NULL;
			itm.iRandomSuffix = NULL;
		}

		loot->items.push_back(itm);
	}
	if( loot->items.size() > sWorld.MaxLootListSize )
	{
		std::vector<__LootItem>::iterator item_to_remove;
		std::vector<__LootItem>::iterator itr;
		uint32 item_quality;
		bool quest_item;
		while( loot->items.size() > sWorld.MaxLootListSize )
		{
			item_to_remove = loot->items.begin();
			item_quality = 0;
			quest_item = false;
			for( itr = loot->items.begin(); itr != loot->items.end(); ++itr )
			{
				item_quality = (*itr).item.itemproto->Quality;
				quest_item = (*itr).item.itemproto->Class == ITEM_CLASS_QUEST;
				if( (*item_to_remove).item.itemproto->Quality > item_quality && !quest_item )
				{
					item_to_remove = itr;
					break;
				}
			}
			loot->items.erase( item_to_remove );
		}
	}
}
Пример #21
0
bool ChatHandler::HandleGenerateWaypoints(const char* args, WorldSession * m_session)
{
	Creature* cr = m_session->GetPlayer()->GetMapMgr()->GetCreature(GET_LOWGUID_PART(m_session->GetPlayer()->GetSelection()));
	if(!cr)
	{
		SystemMessage(m_session, "You should select a creature.");
		return true;
	}

	if( cr->m_spawn == NULL )
	{
		SystemMessage(m_session, "You cannot add waypoints to a creature that is not saved.");
		return true;
	}

	if(cr->GetAIInterface() == NULL)
	{
		SystemMessage(m_session, "Creature was not initialized correctly.");
		return true;
	}

	if(cr->GetAIInterface()->GetWayPointsCount())//ALREADY HAVE WAYPOINTS
	{
		SystemMessage(m_session, "The creature already has waypoints");
		return false;
	}

	if(m_session->GetPlayer()->waypointunit != NULL)
	{
		SystemMessage(m_session, "You are already showing waypoints, hide them first.");
		return true;
	}

	if(!cr->GetSQL_id())
	{
		SystemMessage(m_session, "This creature did not get a valid spawn_id.");
		return true;
	}

	uint32 r;
	uint32 n;
	if(sscanf(args, "%u %u", &r, &n) != 2)
	{
		SystemMessage(m_session, "Randomly generate wps params: range count");
		return true;
	}

	for(uint32 i = 0; i < n; i++)
	{
		float ang = rand()/100.0f;
		float ran = (RandomUInt(r*10))/10.0f;
		while(ran < 1)
		{
			ran = (RandomUInt(r*10))/10.0f;
		}

		float x = cr->GetPositionX()+ran*sin(ang);
		float y = cr->GetPositionY()+ran*cos(ang);
		float z = cr->GetCHeightForPosition(true, x, y, cr->GetPositionZ());

		WayPoint* wp = new WayPoint;
		wp->id = (uint32)cr->GetAIInterface()->GetWayPointsCount()+1;
		wp->x = x;
		wp->y = y;
		wp->z = z;
		wp->orientation = 0.0f;
		wp->waittime = 5000;
		wp->flags = 0;
		wp->forwardInfo = NULL;
		wp->backwardInfo = NULL;
		cr->GetAIInterface()->addWayPoint(wp);
	}

	cr->GetAIInterface()->setMoveType(1);
	m_session->GetPlayer()->waypointunit = cr->GetAIInterface();
	cr->GetAIInterface()->showWayPoints(m_session->GetPlayer(),cr->GetAIInterface()->WayPointsShowingBackwards());
	return true;
}
Пример #22
0
void MoonScriptCreatureAI::SetGoldLoot(Unit *pTarget, uint32 pMinGold, uint32 pMaxGold)
{
	pTarget->GetLoot()->gold = RandomUInt(pMaxGold - pMinGold) + pMinGold;
}
 //type: 1 - normal, 0 - handler
 void SpawnInvader(uint32 type)
 {
     _unit->SendScriptTextChatMessage(SAY_NOVOS_SUMMONER_04);
     //x                y                z
     //-379.101227f    -824.835449f    60.0f
     uint32 mob_entry = 0;
     if (type)
     {
         mob_entry = 26627;
         CreatureProto* cp = CreatureProtoStorage.LookupEntry(mob_entry);
         CreatureInfo* ci = CreatureNameStorage.LookupEntry(mob_entry);
         Creature* c = NULL;
         if (cp && ci)
         {
             c = _unit->GetMapMgr()->CreateCreature(mob_entry);
             if (c)
             {
                 //position is guessed
                 c->Load(cp, -379.101227f, -824.835449f, 60.0f, 0.0f);
                 c->PushToWorld(_unit->GetMapMgr());
                 c->SetSummonedByGUID(_unit->GetGUID());
                 //path finding would be usefull :)
                 Player* p_target = GetRandomPlayerTarget();
                 if (p_target)
                 {
                     c->GetAIInterface()->SetRun();
                     c->GetAIInterface()->MoveTo(p_target->GetPositionX(), p_target->GetPositionY(), p_target->GetPositionZ(), p_target->GetOrientation());
                 }
             }
         }
     }
     else
     {
         for (uint8 i = 0; i < INVADERS_COUNT; i++)
         {
             mob_entry = 0;
             if (Rand(ELITE_CHANCE))
                 mob_entry = 27597;
             else
             {
                 uint32 mobs[2] = { 27598, 27600 };
                 mob_entry = mobs[RandomUInt(1)];
             }
             CreatureProto* cp = CreatureProtoStorage.LookupEntry(mob_entry);
             CreatureInfo* ci = CreatureNameStorage.LookupEntry(mob_entry);
             Creature* c = NULL;
             if (cp && ci)
             {
                 c = _unit->GetMapMgr()->CreateCreature(mob_entry);
                 if (c)
                 {
                     //position is guessed
                     c->Load(cp, -379.101227f, -824.835449f, 60.0f, 0.0f);
                     c->PushToWorld(_unit->GetMapMgr());
                     //path finding would be usefull :)
                     Player* p_target = GetRandomPlayerTarget();
                     if (p_target)
                     {
                         c->GetAIInterface()->SetRun();
                         c->GetAIInterface()->MoveTo(p_target->GetPositionX(), p_target->GetPositionY(), p_target->GetPositionZ(), p_target->GetOrientation());
                     }
                 }
             }
         }
     }
 }
Пример #24
0
CBattleground * CBattlegroundManager::CreateInstance(uint32 Type, uint32 LevelGroup)
{
	CreateBattlegroundFunc cfunc = BGCFuncs[Type];
	MapMgr * mgr = 0;
	CBattleground * bg;
	uint32 iid;

	if(Type == BATTLEGROUND_ARENA_2V2 || Type == BATTLEGROUND_ARENA_3V3 || Type == BATTLEGROUND_ARENA_5V5)
	{
		/* arenas follow a different procedure. */
		static const uint32 arena_map_ids[3] = { 559, 562, 572 };
		uint32 mapid = arena_map_ids[RandomUInt(2)];
		//mapid=562;
		uint32 players_per_side;
		mgr = sInstanceMgr.CreateBattlegroundInstance(mapid);
		if(mgr == NULL)
		{
			Log.Error("BattlegroundManager", "Arena CreateInstance() call failed for map %u, type %u, level group %u", mapid, Type, LevelGroup);
			return NULL;		// Shouldn't happen
		}

		switch(Type)
		{
		case BATTLEGROUND_ARENA_2V2:
			players_per_side = 2;
			break;

		case BATTLEGROUND_ARENA_3V3:
			players_per_side = 3;
			break;

		case BATTLEGROUND_ARENA_5V5:
			players_per_side = 5;
			break;
        default:
            players_per_side = 0;
            break;
		}

		iid = ++m_maxBattlegroundId;
        bg = new Arena(mgr, iid, LevelGroup, Type, players_per_side);
		mgr->m_battleground = bg;
		Log.Success("BattlegroundManager", "Created arena battleground type %u for level group %u on map %u.", Type, LevelGroup, mapid);
		sEventMgr.AddEvent(bg, &CBattleground::EventCreate, EVENT_BATTLEGROUND_QUEUE_UPDATE, 1, 1,0);
		m_instanceLock.Acquire();
		m_instances[Type].insert( make_pair(iid, bg) );
		m_instanceLock.Release();
		return bg;
	}


	if(cfunc == NULL)
	{
		Log.Error("BattlegroundManager", "Could not find CreateBattlegroundFunc pointer for type %u level group %u", Type, LevelGroup);
		return NULL;
	}

	/* Create Map Manager */
	mgr = sInstanceMgr.CreateBattlegroundInstance(BGMapIds[Type]);
	if(mgr == NULL)
	{
		Log.Error("BattlegroundManager", "CreateInstance() call failed for map %u, type %u, level group %u", BGMapIds[Type], Type, LevelGroup);
		return NULL;		// Shouldn't happen
	}

	/* Call the create function */
	iid = ++m_maxBattlegroundId;
	bg = cfunc(mgr, iid, LevelGroup, Type);	
	mgr->m_battleground = bg;
	sEventMgr.AddEvent(bg, &CBattleground::EventCreate, EVENT_BATTLEGROUND_QUEUE_UPDATE, 1, 1,0);
	Log.Success("BattlegroundManager", "Created battleground type %u for level group %u.", Type, LevelGroup);

	m_instanceLock.Acquire();
	m_instances[Type].insert( make_pair(iid, bg) );
	m_instanceLock.Release();

	return bg;
}
Пример #25
0
        void OnDied(Unit* pKiller)
        {
            Player* QuestHolder = NULL;
            if (pKiller->IsPlayer())
                QuestHolder = static_cast<Player*>(pKiller);
            else if (pKiller->IsPet() && static_cast<Pet*>(pKiller)->GetPetOwner() != NULL)
                QuestHolder = static_cast<Pet*>(pKiller)->GetPetOwner();

            if (QuestHolder == NULL)
                return;

            // M4ksiu: I don't think the method is correct, but it can stay the way it was until someone gives proper infos
            QuestLogEntry* Quest = QuestHolder->GetQuestLogForEntry(9670);
            Creature* RandomCreature = NULL;
            if (Quest == NULL)
            {
                // Creatures from Bloodmyst Isle
                uint32 Id[51] = { 17681, 17887, 17550, 17323, 17338, 17341, 17333, 17340, 17353, 17320, 17339, 17337, 17715, 17322, 17494, 17654, 17342, 17328, 17331, 17325, 17321, 17330, 17522, 17329, 17524, 17327, 17661, 17352, 17334, 17326, 17324, 17673, 17336, 17346, 17589, 17609, 17608, 17345, 17527, 17344, 17347, 17525, 17713, 17523, 17348, 17606, 17604, 17607, 17610, 17358, 17588 };
                RandomCreature = _unit->GetMapMgr()->GetInterface()->SpawnCreature(Id[RandomUInt(50)], _unit->GetPositionX(), _unit->GetPositionY(), _unit->GetPositionZ(), _unit->GetOrientation(), true, false, 0, 0);
                if (RandomCreature != NULL)
                {
                    RandomCreature->m_noRespawn = true;
                    RandomCreature->Despawn(60000, 0);
                }

                return;
            }
            else
            {
                uint32 Id[8] = { 17681, 17321, 17330, 17522, 17673, 17336, 17346, 17589 };
                RandomCreature = _unit->GetMapMgr()->GetInterface()->SpawnCreature(Id[RandomUInt(7)], _unit->GetPositionX(), _unit->GetPositionY(), _unit->GetPositionZ(), _unit->GetOrientation(), true, false, 0, 0);
                if (RandomCreature != NULL)
                {
                    RandomCreature->m_noRespawn = true;
                    RandomCreature->Despawn(60000, 0);
                    if (RandomCreature->GetEntry() == 17681 && Quest->GetMobCount(0) < Quest->GetQuest()->required_mobcount[0])
                    {
                        Quest->SetMobCount(0, Quest->GetMobCount(0) + 1);
                        Quest->SendUpdateAddKill(0);
                        Quest->UpdatePlayerFields();
                    }
                }
            }
        }
Пример #26
0
		void PhaseTwo()
		{
			if(_unit->GetHealthPct() <= 40)
			{
				m_phase = 3;
				_unit->SetCastSpeedMod(1.0f);
				if(_unit->GetCurrentSpell() != NULL)
					_unit->GetCurrentSpell()->cancel();
				_unit->GetAIInterface()->m_canMove = true;
				_unit->GetAIInterface()->SetAllowedToEnterCombat(false);
				//_unit->m_pacified++;
				_unit->GetAIInterface()->StopMovement(0);
				_unit->GetAIInterface()->SetAIState(STATE_SCRIPTMOVE);
				_unit->GetAIInterface()->setMoveType(MOVEMENTTYPE_WANTEDWP);
				_unit->GetAIInterface()->setWaypointToMove(8);

				return;
			}
			if(_unit->GetAIInterface()->getMoveType() == MOVEMENTTYPE_WANTEDWP)
				return;
			m_eFlamesCooldown--;
			if(!m_eFlamesCooldown && _unit->GetAIInterface()->getNextTarget())//_unit->getAttackTarget())
			{
				_unit->CastSpell(_unit->GetAIInterface()->getNextTarget(), infoSFireball, false);//(_unit->getAttackTarget(),
				m_eFlamesCooldown = 4;
				m_fCastCount--;
			}
			if(!m_fCastCount)
			{
				uint32 val = RandomUInt(1250);
				if(val < 250)//Move left
				{
					m_currentWP++;
					if(m_currentWP >= 8)
						m_currentWP = 3;

					_unit->GetAIInterface()->m_canMove = true;
					_unit->GetAIInterface()->SetAllowedToEnterCombat(false);
					//_unit->m_pacified++;
					_unit->GetAIInterface()->SetAIState(STATE_SCRIPTMOVE);
					_unit->GetAIInterface()->setMoveType(MOVEMENTTYPE_WANTEDWP);
					_unit->GetAIInterface()->setWaypointToMove(m_currentWP);
					m_fCastCount = 5;
				}
				else if(val > 1000)//Move right
				{
					m_currentWP--;
					if(m_currentWP < 3)
						m_currentWP = 7;

					_unit->GetAIInterface()->m_canMove = true;
					_unit->GetAIInterface()->SetAllowedToEnterCombat(false);
					//_unit->m_pacified++;
					_unit->GetAIInterface()->SetAIState(STATE_SCRIPTMOVE);
					_unit->GetAIInterface()->setMoveType(MOVEMENTTYPE_WANTEDWP);
					_unit->GetAIInterface()->setWaypointToMove(m_currentWP);
					m_fCastCount = 5;
				}
				else if(val < 350)
				{
					//Deep breath
					_unit->CastSpell(_unit, infoDeepBreath, false);
					m_fCastCount = 5;
				}
				else
					m_fCastCount = 5;
			}
			m_whelpCooldown--;
			if(!m_whelpCooldown)
			{
				Creature* cre = NULL;
				for(int i = 0; i < 6; i++)
				{
					cre = _unit->GetMapMgr()->GetInterface()->SpawnCreature(11262,
					        whelpCoords[i].x, whelpCoords[i].y,
					        whelpCoords[i].z, whelpCoords[i].o,
					        true, false, 0, 0);
					if(cre)
					{
						cre->GetAIInterface()->MoveTo(14.161f, -177.874f, -85.649f, 0.23f);
						cre->GetAIInterface()->setOutOfCombatRange(100000);
					}
					cre = _unit->GetMapMgr()->GetInterface()->SpawnCreature(11262,
					        whelpCoords[5 - i].x, whelpCoords[5 - i].y,
					        whelpCoords[5 - i].z, whelpCoords[5 - i].o,
					        true, false, 0, 0);
					if(cre)
					{
						cre->GetAIInterface()->MoveTo(27.133f, -232.030f, -84.188f, 0.44f);
						cre->GetAIInterface()->setOutOfCombatRange(100000);
					}
				}
				m_whelpCooldown = 30;
			}
		}
Пример #27
0
void GameObject::UseFishingNode(Player *player)
{
	sEventMgr.RemoveEvents( this );
	if( GetUInt32Value( GAMEOBJECT_FLAGS ) != 32 ) // Clicking on the bobber before something is hooked
	{
		player->GetSession()->OutPacket( SMSG_FISH_NOT_HOOKED );
		EndFishing( player, true );
		return;
	}
	
	/* Unused code: sAreaStore.LookupEntry(GetMapMgr()->GetAreaID(GetPositionX(),GetPositionY()))->ZoneId*/
	uint32 zone = player->GetAreaID();
	if( zone == 0 ) // If the player's area ID is 0, use the zone ID instead
		zone = player->GetZoneId();

	FishingZoneEntry *entry = FishingZoneStorage.LookupEntry( zone );
	if( entry == NULL ) // No fishing information found for area or zone, log an error, and end fishing
	{
		sLog.outError( "ERROR: Fishing zone information for zone %d not found!", zone );
		EndFishing( player, true );
		return;
	}
	uint32 maxskill = entry->MaxSkill;
	uint32 minskill = entry->MinSkill;

	if( player->_GetSkillLineCurrent( SKILL_FISHING, false ) < maxskill )	
		player->_AdvanceSkillLine( SKILL_FISHING, float2int32( 1.0f * sWorld.getRate( RATE_SKILLRATE ) ) );

	GameObject * school = NULL;
	this->AquireInrangeLock(); //make sure to release lock before exit function !
	for ( InRangeSet::iterator it = GetInRangeSetBegin(); it != GetInRangeSetEnd(); ++it )
	{
		if ( (*it) == NULL || (*it)->GetTypeId() != TYPEID_GAMEOBJECT || (*it)->GetUInt32Value(GAMEOBJECT_TYPE_ID) != GAMEOBJECT_TYPE_FISHINGHOLE)
			continue;
		school = static_cast<GameObject *>( *it );
		if ( !isInRange( school, (float)school->GetInfo()->sound1 ) )
		{
			school = NULL;
			continue;
		}
		else
			break;
	}
	this->ReleaseInrangeLock();

	if ( school != NULL ) // open school loot if school exists
	{
		lootmgr.FillGOLoot( &school->loot, school->GetEntry(), school->GetMapMgr() ? ( school->GetMapMgr()->iInstanceMode ? true : false ) : false );
		player->SendLoot( school->GetGUID(), LOOT_FISHING );
		EndFishing( player, false );
		school->CatchFish();
		if ( !school->CanFish() )
			sEventMgr.AddEvent( school, &GameObject::Despawn, ( 1800000 + RandomUInt( 3600000 ) ), EVENT_GAMEOBJECT_EXPIRE, 10000, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT ); // respawn in 30 - 90 minutes
	}
	else if( Rand( ( ( player->_GetSkillLineCurrent( SKILL_FISHING, true ) - minskill ) * 100 ) / maxskill ) ) // Open loot on success, otherwise FISH_ESCAPED.
	{
		lootmgr.FillFishingLoot( &loot, zone );
		player->SendLoot( GetGUID(), LOOT_FISHING );
		EndFishing( player, false );
	}
	else // Failed
	{
		player->GetSession()->OutPacket( SMSG_FISH_ESCAPED );
		EndFishing( player, true );
	}

}
Пример #28
0
bool Rand(uint32 chance)
{
	int32 val = RandomUInt(10000);
	int32 p = int32(chance * 100);
	return p >= val;
}
Пример #29
0
void AiAgentHealSupport::Update(uint32 p_time)
{
	_UpdateTimer(p_time);
	_UpdateMovement(p_time);

	if( !m_PetOwner )
		return; //oh noez, our master has abandoned us ! Where is te luv ?

	//we used this spell to create healbot. To avoid logout / login recreate we need to remove aura
	// lol, this will never work :(
	if( !m_Unit->isAlive() )
		m_PetOwner->RemoveAura( 36765 );

	if( m_Unit->GetMapMgr() != m_PetOwner->GetMapMgr() )
	{
		m_PetOwner->RemoveAura( 36765 );
		m_Unit->EventSummonPetExpire();
	}

	if( m_Unit->isCasting() )
		return; // we are already supporting someone ...get back later

	//we should be at same level at owner so we profit of fighting formulas same as owner
	if(	m_Unit->GetUInt32Value( UNIT_FIELD_LEVEL ) != m_PetOwner->GetUInt32Value( UNIT_FIELD_LEVEL ) )
	{
		m_Unit->SetUInt32Value( UNIT_FIELD_LEVEL, m_PetOwner->GetUInt32Value( UNIT_FIELD_LEVEL ) );
		DifficultyLevel = m_PetOwner->GetUInt32Value( UNIT_FIELD_LEVEL ) / 80.0f;
//printf("difficulty changed to %f \n",DifficultyLevel);
		//scale health and mana.when we level we max out our stats
		m_Unit->SetUInt32Value( UNIT_FIELD_MAXHEALTH , (uint32)(m_Unit->GetUInt32Value( UNIT_FIELD_BASE_HEALTH ) * ( 1 + DifficultyLevel ) * CREATURE_STATS_SCALE_WITH_DIFFICULTY) );
		m_Unit->SetUInt32Value( UNIT_FIELD_MAXPOWER1 , (uint32)(m_Unit->GetUInt32Value( UNIT_FIELD_BASE_MANA ) * ( 1 + DifficultyLevel ) * CREATURE_STATS_SCALE_WITH_DIFFICULTY) );
		m_Unit->SetUInt32Value( UNIT_FIELD_HEALTH , (uint32)(m_Unit->GetUInt32Value( UNIT_FIELD_HEALTH ) * ( 1 + DifficultyLevel ) * CREATURE_STATS_SCALE_WITH_DIFFICULTY) );
		m_Unit->SetUInt32Value( UNIT_FIELD_POWER1 , (uint32)(m_Unit->GetUInt32Value( UNIT_FIELD_POWER1 ) * ( 1 + DifficultyLevel ) * CREATURE_STATS_SCALE_WITH_DIFFICULTY) );
	}

	//if owner fights a long combat then we he desrvers to get lasy at the end ?
	if( m_PetOwner->CombatStatus.IsInCombat() )
		CombatDifficultyLevel += DIFFICULTY_UPDATE_SPEED;
	else CombatDifficultyLevel = 0;
	if( CombatDifficultyLevel > 1 )
		CombatDifficultyLevel = 1;

	uint32 Time_Now = getMSTime();

	std::list<healagentspell*>::iterator itr;
	SpellCastTargets targets( m_PetOwner->GetGUID() );
	healagentspell *m_castingSpell = NULL;
	Unit			*SpellTarget = m_PetOwner;

	//poor thing died. Res him. 
	//will never work
	if( !m_PetOwner->isAlive() && CheckCanCast( revive_spell.sp, SpellTarget ) )
	{
		m_castingSpell = &revive_spell;
//printf("master died, we are going to resurect him\n");
	}

	//if we are injusred we should try to survive it
	if ( m_castingSpell== NULL && m_Unit->GetUInt32Value( UNIT_FIELD_HEALTH ) < m_Unit->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) )
	{
//printf("we are injured, diff is %u \n",m_Unit->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) - m_Unit->GetUInt32Value( UNIT_FIELD_HEALTH ));
		if(	!Protect_self() ) //first we try to escape combat
		{
			m_castingSpell = PickSpellFromList( &m_healspells, m_Unit );
			SpellTarget = m_Unit;
		}
		else
		{
			m_castingSpell = &m_defend_self;
			SpellTarget = m_Unit;
		}
	}

	//select an augment spell if we have nothing better to do
	if( m_castingSpell== NULL && m_PetOwner->GetUInt32Value( UNIT_FIELD_HEALTH ) == m_PetOwner->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) )
	{
//printf("master is ok, we can try augment someone\n");
		m_castingSpell = PickSpellFromList( &m_AugmentSelf, m_Unit );
		//try augment owner ?
		if( !m_castingSpell )
		{
			m_castingSpell = PickSpellFromList( &m_AugmentTarget, m_PetOwner );
			SpellTarget = m_Unit;
		}
	}

	//master is injured, this should be most common case
	if( m_castingSpell==NULL && m_PetOwner->GetUInt32Value( UNIT_FIELD_HEALTH ) < m_PetOwner->GetUInt32Value( UNIT_FIELD_MAXHEALTH ) )
	{
//printf("master is injured, will try to heal him\n");
		m_castingSpell = PickSpellFromList( &m_healspells , m_PetOwner);
		SpellTarget = m_PetOwner;
	}

	if( m_castingSpell )
	{
//printf("we have a spell to cast\n");

		SpellCastTime *sd = dbcSpellCastTime.LookupEntry( m_castingSpell->sp->CastingTimeIndex );

		//do not stop for instant casts
		if(GetCastTime(sd) != 0)
		{
			StopMovement(0);
//printf("spell is not instant so we are going to stop movement \n");
		}

		float distance = m_Unit->GetDistanceSq( SpellTarget );
		if(	distance <= m_castingSpell->sp->base_range_or_radius_sqr || m_castingSpell->sp->base_range_or_radius_sqr == 0 )
		{

//printf("we are in range and going to cast spell \n");
			m_AIState = STATE_CASTING;
			
			Spell *nspell = SpellPool.PooledNew();
			nspell->Init(m_Unit, m_castingSpell->sp, false, NULL);

#ifdef SPELL_EFF_PCT_SCALE_WITH_DIFFICULTY
			if( m_castingSpell->max_scale )
			{
				nspell->forced_basepoints[ 0 ] = (uint32)( m_castingSpell->max_scale * ( DifficultyLevel + CombatDifficultyLevel) );
				if( nspell->forced_basepoints[ 0 ] > m_castingSpell->max_scale * 2)
					nspell->forced_basepoints[ 0 ] = m_castingSpell->max_scale * 2;
			}
#endif

			targets.m_unitTarget = SpellTarget->GetGUID();
			nspell->prepare( &targets );

			CastSpell( m_Unit, m_castingSpell->sp, targets );

			SetSpellDuration( m_castingSpell );

			//mana regen is to big, he can cast forever, double mana usage maybe regulates this
			m_Unit->ModSignedInt32Value( UNIT_FIELD_POWER1, -m_castingSpell->sp->manaCost );

		}
		else // Target out of Range -> Run to it
		{
//printf("we are going to move closer \n");
			m_moveRun = true;
			_CalcDestinationAndMove( SpellTarget, sqrt( m_castingSpell->sp->base_range_or_radius_sqr ) );
		}
	}

// check if pets regenrate mana, If not then we should implement that too
	//if owner is mounted then we mount too. Speed is not set though
	if( m_PetOwner->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) && m_Unit->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) == 0 )
	{
		if( Owner_side == OWNER_SIDE_ALIANCE )
			m_Unit->SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID, HELPER_MOUNT_A_DISPLAY );
		else
			m_Unit->SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID, OWNER_SIDE_HORDE );
		m_moveSprint =  true;
	}
	else if( m_PetOwner->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) == 0 && m_Unit->GetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID ) != 0 )
	{
		m_Unit->SetUInt32Value( UNIT_FIELD_MOUNTDISPLAYID, 0 );
		m_moveSprint = false;
	}

	//for fun : mimic master standstate. Note that this might give strange results
	if( m_PetOwner->GetStandState() != m_Unit->GetStandState() )
		m_Unit->SetStandState( m_PetOwner->GetStandState() );

	if( m_castingSpell == NULL )
	{
		if( First_noaction_stamp == 0 )
			First_noaction_stamp = Time_Now;

		float dist = m_Unit->CalcDistance( m_PetOwner );

//printf("we are far from owner, we should move closer , dist %f from %f \n",dist,(FollowDistance*FollowDistance));
		if ( dist > FollowDistance ) //if out of range
		{
			m_moveRun = true;

			if(dist > 20.0f)
				m_moveSprint = true;

			float delta_x = UnitToFollow->GetPositionX();
			float delta_y = UnitToFollow->GetPositionY();
			float d = 3;

			MoveTo(delta_x+(d*(cosf(m_fallowAngle+m_PetOwner->GetOrientation()))),
				delta_y+(d*(sinf(m_fallowAngle+m_PetOwner->GetOrientation()))),
				m_PetOwner->GetPositionZ(),m_PetOwner->GetOrientation());				
		}
	}
	else if(m_castingSpell != NULL )
		First_noaction_stamp = 0;

//if( First_noaction_stamp )printf("ms to say something %u and ms for say cooldown %u\n",First_noaction_stamp + BOREDOM_TIMER_TO_START_TRIGGERING - Time_Now,Boredom_cooldown - Time_Now );
	if( 
		First_noaction_stamp
		&& First_noaction_stamp + BOREDOM_TIMER_TO_START_TRIGGERING < Time_Now 
		&& Boredom_cooldown < Time_Now
		)
	{
		//some chance to say something
		if( Rand( 50 ) )
			m_Unit->SendChatMessage(CHAT_MSG_MONSTER_SAY, LANG_UNIVERSAL, bored_texts[ RandomUInt( BOREDOM_TEXTCOUNT ) ]);
		else
			m_Unit->SetUInt32Value ( UNIT_NPC_EMOTESTATE, bored_emotes[ RandomUInt( BOREDOM_EMOTECOUNT ) ] );
		Boredom_cooldown = Time_Now + BOREDOM_TRIGGER_INTERVAL;
	}
}