Example #1
0
void WorldSession::HandleGossipHelloOpcode(WorldPacket& recv_data)
{
    DEBUG_LOG("WORLD: Received opcode CMSG_GOSSIP_HELLO");

    ObjectGuid guid;
    recv_data >> guid;

    Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
    if (!pCreature)
    {
        DEBUG_LOG("WORLD: HandleGossipHelloOpcode - %s not found or you can't interact with him.", guid.GetString().c_str());
        return;
    }

    // remove fake death
    if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

    if (!pCreature->IsStopped())
        pCreature->StopMoving();

    if (pCreature->isSpiritGuide())
        pCreature->SendAreaSpiritHealerQueryOpcode(_player);

    if (!sScriptMgr.OnGossipHello(_player, pCreature))
    {
        _player->PrepareGossipMenu(pCreature, pCreature->GetCreatureInfo()->GossipMenuId);
        _player->SendPreparedGossip(pCreature);
    }
}
bool WaypointMovementGenerator<Creature>::Update(Creature& creature, const uint32& diff)
{
    // Waypoint movement can be switched on/off
    // This is quite handy for escort quests and other stuff
    if (creature.hasUnitState(UNIT_STAT_NOT_MOVE))
    {
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
        return true;
    }

    // prevent a crash at empty waypoint path.
    if (!i_path || i_path->empty())
    {
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
        return true;
    }

    if (Stopped(creature))
    {
        if (CanMove(diff, creature))
            StartMove(creature);
    }
    else
    {
        if (creature.IsStopped())
            Stop(STOP_TIME_FOR_PLAYER);
        else if (creature.movespline->Finalized())
        {
            OnArrived(creature);
            StartMove(creature);
        }
    }
    return true;
}
Example #3
0
void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data)
{
    uint64 guid;
    recv_data >> guid;

    DEBUG_LOG ("WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u", GUID_LOPART(guid));

    Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);

    if (!pCreature)
    {
        DEBUG_LOG ("WORLD: HandleQuestgiverHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guid));
        return;
    }

    // remove fake death
    if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

    // Stop the npc if moving
    if (!pCreature->IsStopped())
        pCreature->StopMoving();

    if (sScriptMgr.GossipHello(_player, pCreature))
        return;

    _player->PrepareGossipMenu(pCreature, pCreature->GetCreatureInfo()->GossipMenuId);
    _player->SendPreparedGossip(pCreature);
}
void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recv_data)
{
    ObjectGuid guid;
    recv_data >> guid;

    DEBUG_LOG("WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from %s", guid.GetString().c_str());

    Creature* pCreature = GetPlayer()->GetMap()->GetCreature(guid);

    if (!pCreature)
        return;

    if (!pCreature->isBattleMaster())                       // it's not battlemaster
        return;

    // Stop the npc if moving
    if (!pCreature->IsStopped())
        pCreature->StopMoving();

    BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(pCreature->GetEntry());

    if (bgTypeId == BATTLEGROUND_TYPE_NONE)
        return;

    if (!_player->GetBGAccessByLevel(bgTypeId))
    {
        // temp, must be gossip message...
        SendNotification(LANG_YOUR_BG_LEVEL_REQ_ERROR);
        return;
    }

    SendBattlegGroundList(guid, bgTypeId);
}
void WorldSession::HandleBattlegroundHelloOpcode(WorldPacket& recv_data)
{
    uint64 guid;
    recv_data >> guid;
    sLog.outDebug("WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid)));

    Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
    if (!unit)
        return;

    if (!unit->IsBattleMaster())                             // it's not battlemaster
        return;

    // Stop the npc if moving
    if (!unit->IsStopped())
        unit->StopMoving();

    uint32 bgTypeId = sObjectMgr.GetBattleMasterBG(unit->GetEntry());

    if (!_player->GetBGAccessByLevel(bgTypeId))
    {
        // temp, must be gossip message...
        SendNotification(LANG_YOUR_BG_LEVEL_REQ_ERROR);
        return;
    }

    SendBattlegGroundList(guid, bgTypeId);
}
Example #6
0
void WorldSession::HandleGossipHelloOpcode(WorldPacket & recv_data)
{
    sLog.outDebug("WORLD: Received CMSG_GOSSIP_HELLO");

    uint64 guid;
    recv_data >> guid;

    Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);

    if (!pCreature)
    {
        sLog.outDebug("WORLD: HandleGossipHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
        return;
    }

    // remove fake death
    if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

    if (!pCreature->IsStopped())
        pCreature->StopMoving();

    if (pCreature->isSpiritGuide())
        pCreature->SendAreaSpiritHealerQueryOpcode(_player);

    if (!Script->GossipHello(_player, pCreature))
    {
        _player->TalkedToCreature(pCreature->GetEntry(), pCreature->GetGUID());
        _player->PrepareGossipMenu(pCreature, pCreature->GetCreatureInfo()->GossipMenuId);
        _player->SendPreparedGossip(pCreature);
    }
}
void
ConfusedMovementGenerator::Update(Creature &creature, const uint32 &diff)
{
    if(!&creature)
        return;
    if(creature.hasUnitState(UNIT_STAT_ROOT) || creature.hasUnitState(UNIT_STAT_STUNDED))
        return;
    i_nextMoveTime.Update(diff);
    i_destinationHolder.ResetUpdate();
    if( i_nextMoveTime.Passed() )
    {
        if( creature.IsStopped() )
        {
            assert( i_nextMove <= MAX_CONF_WAYPOINTS );
            const float x = i_waypoints[i_nextMove][0];
            const float y = i_waypoints[i_nextMove][1];
            const float z = i_waypoints[i_nextMove][2];
            creature.addUnitState(UNIT_STAT_ROAMING);
            CreatureTraveller traveller(creature);
            i_destinationHolder.SetDestination(traveller, x, y, z);
            traveller.Relocation(x,y,z);
            i_nextMoveTime.Reset( i_destinationHolder.GetTotalTravelTime() );
        }
        else
        {
            creature.StopMoving();
            creature.setMoveRunFlag(true);

            i_nextMove = (rand() % MAX_CONF_WAYPOINTS) + 1;
            i_nextMoveTime.Reset((rand() % 1500));
        }
    }
}
bool RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    if (creature.hasUnitState(UNIT_STAT_NOT_MOVE))
    {
        i_nextMoveTime.Update(i_nextMoveTime.GetExpiry());  // Expire the timer
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
        return true;
    }

    i_nextMoveTime.Update(diff);

    if (i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);

    if (!i_destinationHolder.HasArrived() && creature.IsStopped())
        creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

    CreatureTraveller traveller(creature);

    if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true))
    {
        if (!IsActive(creature))                        // force stop processing (movement can move out active zone with cleanup movegens list)
            return true;                                // not expire now, but already lost

        if (i_nextMoveTime.Passed())
        {
            float x,y,z;
            if(i_destinationHolder.HasDestination())
                i_destinationHolder.GetLocationNowNoMicroMovement(x,y,z);
            else
                creature.GetPosition(x,y,z);

            if (creature.canFly() && !(creature.canWalk() && creature.IsAtGroundLevel(x,y,z)))
                creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7);
            else
                creature.AddSplineFlag(SPLINEFLAG_WALKMODE);

            _setRandomLocation(creature);
        }
        else if (creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(), PET_FOLLOW_DIST+2.5f))
        {
            creature.AddSplineFlag(SPLINEFLAG_WALKMODE);
            _setRandomLocation(creature);
        }
    }
    return true;
}
bool RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    if (creature.IsStopped() || static_cast<MovementGenerator*>(this)->_recalculateTravel)
    {
        i_nextMoveTime.Update(diff);
        if (i_nextMoveTime.Passed() || static_cast<MovementGenerator*>(this)->_recalculateTravel)
            _setRandomLocation(creature);
    }
    return true;
}
bool
RandomMovementGenerator::Update(Creature &creature, const uint32 &diff)
{
    if(!&creature)
        return true;
    if(creature.hasUnitState(UNIT_STAT_ROOT) || creature.hasUnitState(UNIT_STAT_STUNDED))
        return true;
    i_nextMoveTime.Update(diff);
    #ifdef USE_INTERPOLATION
    CreatureTraveller traveller(creature);
    i_destinationHolder.UpdateTraveller(traveller, diff, false);
    #endif
    if( i_nextMoveTime.Passed() )
    {
        if( creature.IsStopped() )
        {
            assert( i_nextMove <= MAX_RAND_WAYPOINTS );
            const float x = i_waypoints[i_nextMove][0];
            const float y = i_waypoints[i_nextMove][1];
            const float z = i_waypoints[i_nextMove][2];
            creature.addUnitState(UNIT_STAT_ROAMING);
            CreatureTraveller traveller(creature);
            i_destinationHolder.SetDestination(traveller, x, y, z);
            #ifndef USE_INTERPOLATION
            traveller.Relocation(x,y,z);
            #endif
            i_nextMoveTime.Reset( i_destinationHolder.GetTotalTravelTime() );
        }
        else
        {
            creature.StopMoving();
            creature.setMoveRunFlag(!urand(0,10));

            if( creature.getMoveRandomFlag() )
            {
                i_nextMove = (rand() % MAX_RAND_WAYPOINTS) + 1;
                i_nextMoveTime.Reset((rand() % 7000));
            }
            else
            {
                ++i_nextMove;
                if( i_nextMove == MAX_RAND_WAYPOINTS )
                {
                    i_nextMove = 0;
                    i_nextMoveTime.Reset(rand() % 3000);
                }
                else
                {
                    i_nextMoveTime.Reset((rand() % 7000));
                }
            }
        }
    }
    return true;
}
Example #11
0
bool
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
    {
        i_nextMoveTime.Update(i_nextMoveTime.GetExpiry());    // Expire the timer
        creature.clearUnitState(UNIT_STAT_ROAMING);
        return true;
    }

    i_nextMoveTime.Update(diff);

    if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
        creature.clearUnitState(UNIT_STAT_ROAMING);

    if(!i_destinationHolder.HasArrived() && creature.IsStopped())
        creature.addUnitState(UNIT_STAT_ROAMING);

    CreatureTraveller traveller(creature);

    if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) )
    {
        if(i_nextMoveTime.Passed())
        {
            if (creature.canFly())
                creature.AddMonsterMoveFlag(MONSTER_MOVE_FLY);
            else if(irand(0,RUNNING_CHANCE_RANDOMMV) > 0)
                creature.AddMonsterMoveFlag(MONSTER_MOVE_WALK);
            else                                            // run with 1/RUNNING_CHANCE_RANDOMMV chance
                creature.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK);

            _setRandomLocation(creature);
        }
        else if(creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(),PET_FOLLOW_DIST+2.5f))
        {
           creature.AddMonsterMoveFlag(MONSTER_MOVE_WALK);
           _setRandomLocation(creature);
        }
    }
    return true;
}
Example #12
0
bool
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    if (creature.hasUnitState(UNIT_STAT_NOT_MOVE & ~UNIT_STAT_ON_VEHICLE))
    {
        i_nextMoveTime.Update(i_nextMoveTime.GetExpiry());  // Expire the timer
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);;
        return true;
    }

    i_nextMoveTime.Update(diff);

    if (i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);

    if (!i_destinationHolder.HasArrived() && creature.IsStopped())
        creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

    CreatureTraveller traveller(creature);

    if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true))
    {
        if (i_nextMoveTime.Passed())
        {
            if (creature.canFly())
                creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7);
            else
                creature.AddSplineFlag(SPLINEFLAG_WALKMODE);

            _setRandomLocation(creature);
        }
        else if (creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(), PET_FOLLOW_DIST+2.5f))
        {
            creature.AddSplineFlag(SPLINEFLAG_WALKMODE);
            _setRandomLocation(creature);
        }
    }
    return true;
}
Example #13
0
bool
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
    {
        i_nextMoveTime.Update(i_nextMoveTime.GetExpiry());    // Expire the timer
        creature.clearUnitState(UNIT_STAT_ROAMING);
        return true;
    }

    i_nextMoveTime.Update(diff);

    if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
        creature.clearUnitState(UNIT_STAT_ROAMING);

    if(!i_destinationHolder.HasArrived() && creature.IsStopped())
        creature.addUnitState(UNIT_STAT_ROAMING);

    CreatureTraveller traveller(creature);

    if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) )
    {
        if(i_nextMoveTime.Passed())
        {
            if (creature.canFly())
                creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
            else
                creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE);
            _setRandomLocation(creature);
        }
        else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f)
        {
           creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE);
           _setRandomLocation(creature);
        }
    }
    return true;
}
Example #14
0
void AssistanceMovementGenerator::Initialize(Creature& unit)
{
    if (unit.hasUnitState(UNIT_STAT_CAN_NOT_REACT | UNIT_STAT_CAN_NOT_MOVE))
        return;

    if (!unit.IsStopped())
        unit.StopMoving();

    unit.addUnitState(UNIT_STAT_ROAMING | UNIT_STAT_ROAMING_MOVE);
    Movement::MoveSplineInit init(unit, "AssistanceMovementGenerator::Initialize");
    init.MoveTo(i_x, i_y, i_z, (_options & (MOVE_PATHFINDING | MOVE_FORCE_DESTINATION)));
    init.SetWalk(true);
    init.SetVelocity(unit.GetFleeingSpeed());
    init.Launch();
}
bool RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    if (creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
    {
        i_nextMoveTime.Reset(0);  // Expire the timer
        creature.clearUnitState(UNIT_STAT_ROAMING);
        return true;
    }

    if (creature.IsStopped() || static_cast<MovementGenerator*>(this)->_recalculateTravel)
    {
        i_nextMoveTime.Update(diff);
        if (i_nextMoveTime.Passed() || static_cast<MovementGenerator*>(this)->_recalculateTravel)
            _setRandomLocation(creature);
    }
    return true;
}
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    // Waypoint movement can be switched on/off
    // This is quite handy for escort quests and other stuff
    if (creature.hasUnitState(UNIT_STAT_NOT_MOVE))
    {
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
        return true;
    }

    // prevent a crash at empty waypoint path.
    if (!i_path || i_path->empty())
    {
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
        return true;
    }

    if (Stopped())
    {
        if (CanMove(diff))
            StartMove(creature);
    }
    else
     {
        CreatureTraveller traveller(creature);
        if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true) && !IsActive(creature))
            return true;

        if (creature.IsStopped())
            Stop(STOP_TIME_FOR_PLAYER);

        if (i_destinationHolder.HasArrived())
        {
            OnArrived(creature);
            StartMove(creature);
        }
    }
    return true;
}
bool
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
	if(!&creature)
		return true;

	i_nextMoveTime.Update(diff);

	if(i_nextMoveTime.Passed())
	{
		if(creature.IsStopped())
		{
			assert( i_nextMove <= MAX_RAND_WAYPOINTS );
			uint16 x = i_waypoints[i_nextMove][0];
			uint16 y = i_waypoints[i_nextMove][1];
			creature.addUnitState(UNIT_STATE_ROAMING);
			creature.SendMonsterMove(x, y, 0);
//			sLog.outDebug("****** RandomMovementGenerator<Creature>::Update *******");
			i_nextMoveTime.Reset(urand(10000, 12000-1));
		}
		else
		{
			creature.StopMoving();

			++i_nextMove;
			if(i_nextMove == MAX_RAND_WAYPOINTS)
			{
				i_nextMove = 0;
				i_nextMoveTime.Reset(urand(0, 3000-1));
			}
			else
			{
				i_nextMoveTime.Reset(urand(0, 7000-1));
			}
		}
	}
	return true;
}
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    if(!&creature)
        return true;

    // Waypoint movement can be switched on/off
    // This is quite handy for escort quests and other stuff
    if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
        return true;

    // prevent a crash at empty waypoint path.
    if(!i_path || i_path->empty())
        return true;

    // i_path was modified by chat commands for example
    if(i_path->size() != i_hasDone.size())
        i_hasDone.resize(i_path->size());
    if(i_currentNode >= i_path->size())
        i_currentNode = 0;

    CreatureTraveller traveller(creature);

    i_nextMoveTime.Update(diff);
    i_destinationHolder.UpdateTraveller(traveller, diff, false, true);

    // creature has been stopped in middle of the waypoint segment
    if (!i_destinationHolder.HasArrived() && creature.IsStopped())
    {
        if( i_nextMoveTime.Passed()) // Timer has elapsed, meaning this part controlled it
        {
            SetStopedByPlayer(false);
            // Now we re-set destination to same node and start travel
            creature.addUnitState(UNIT_STAT_ROAMING);
            if (creature.canFly())
                creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
            const WaypointNode &node = i_path->at(i_currentNode);
            i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
            i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
        }
        else // if( !i_nextMoveTime.Passed())
        {   // unexpected end of timer && creature stopped && not at end of segment
            if (!IsStopedByPlayer())
            {   // Put 30 seconds delay
                i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER);
                i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
                SetStopedByPlayer(true);                        // Mark we did it
            }
        }
        return true;    // Abort here this update
    }

    if( creature.IsStopped())
    {
        uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1;

        if (!i_hasDone[idx])
        {
            if (i_path->at(idx).orientation !=100)
                creature.SetOrientation(i_path->at(idx).orientation);

            if(WaypointBehavior *behavior = i_path->at(idx).behavior)
            {
                if(behavior->emote != 0)
                    creature.SetUInt32Value(UNIT_NPC_EMOTESTATE,behavior->emote);
                if(behavior->spell != 0)
                    creature.CastSpell(&creature,behavior->spell, false);
                if(behavior->model1 != 0)
                    creature.SetDisplayId(behavior->model1);
                if(behavior->textid[0])
                {
                    // Not only one text is set
                    if( behavior->textid[1] )
                    {
                        // Select one from max 5 texts (0 and 1 laready checked)
                        int i = 2;
                        for( ; i < MAX_WAYPOINT_TEXT; ++i )
                            if( !behavior->textid[i] )
                                break;

                        creature.Say(behavior->textid[rand() % i], 0, 0);
                    }
                    else
                        creature.Say(behavior->textid[0], 0, 0);
                }

                i_hasDone[idx] = true;
                MovementInform(creature);
            }                                               // wpBehaviour found
        }                                                   // HasDone == false
    }                                                       // i_creature.IsStopped()

    if( i_nextMoveTime.Passed() ) // This is at the end of waypoint segment or has been stopped by player
    {
        if( creature.IsStopped() ) // If stopped then begin a new move segment
        {
            creature.addUnitState(UNIT_STAT_ROAMING);
            if (creature.canFly())
                creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
            const WaypointNode &node = i_path->at(i_currentNode);
            i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
            i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
            uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1;

            if (i_path->at(idx).orientation !=100)
                creature.SetOrientation(i_path->at(idx).orientation);

            if(WaypointBehavior *behavior = i_path->at(idx).behavior )
            {
                i_hasDone[idx] = false;
                if(behavior->model2 != 0)
                    creature.SetDisplayId(behavior->model2);

                creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
            }
        }
        else // If not stopped then stop it and set the reset of TimeTracker to waittime
        {
            creature.StopMoving();
            SetStopedByPlayer(false);
            i_nextMoveTime.Reset(i_path->at(i_currentNode).delay);
            ++i_currentNode;
            if( i_currentNode >= i_path->size() )
                i_currentNode = 0;
        }
    }
    return true;
}
Example #19
0
void WorldSession::SendListInventory(ObjectGuid vendorguid)
{
    DEBUG_LOG("WORLD: Sent SMSG_LIST_INVENTORY");

    Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);

    if (!pCreature)
    {
        DEBUG_LOG("WORLD: SendListInventory - %s not found or you can't interact with him.", vendorguid.GetString().c_str());
        _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, ObjectGuid(), 0);
        return;
    }

    // remove fake death
    if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

    // Stop the npc if moving
    if (!pCreature->IsStopped())
        pCreature->StopMoving();

    VendorItemData const* vItems = pCreature->GetVendorItems();
    VendorItemData const* tItems = pCreature->GetVendorTemplateItems();

    if (!vItems && !tItems)
    {
        WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + 1));
        data << ObjectGuid(vendorguid);
        data << uint8(0);                                   // count==0, next will be error code
        data << uint8(0);                                   // "Vendor has no inventory"
        SendPacket(&data);
        return;
    }

    uint8 customitems = vItems ? vItems->GetItemCount() : 0;
    uint8 numitems = customitems + (tItems ? tItems->GetItemCount() : 0);

    uint8 count = 0;

    WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + numitems * 7 * 4));
    data << ObjectGuid(vendorguid);

    size_t count_pos = data.wpos();
    data << uint8(count);

    float discountMod = _player->GetReputationPriceDiscount(pCreature);

    for (int i = 0; i < numitems; ++i)
    {
        VendorItem const* crItem = i < customitems ? vItems->GetItem(i) : tItems->GetItem(i - customitems);

        if (crItem)
        {
            uint32 itemId = crItem->item;
            ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId);
            if (pProto)
            {
                if (!_player->isGameMaster())
                {
                    // class wrong item skip only for bindable case
                    if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP)
                        continue;

                    // race wrong item skip always
                    if ((pProto->AllowableRace & _player->getRaceMask()) == 0)
                        continue;

                    // when no faction required but rank > 0 will be used faction id from the vendor faction template to compare the rank
                    if (!pProto->RequiredReputationFaction && pProto->RequiredReputationRank > 0 &&
                            ReputationRank(pProto->RequiredReputationRank) > _player->GetReputationRank(pCreature->getFactionTemplateEntry()->faction))
                        continue;
                }

                ++count;

                // reputation discount
                uint32 price = uint32(floor(pProto->BuyPrice * discountMod));

                data << uint32(count);
                data << uint32(itemId);
                data << uint32(pProto->DisplayInfoID);
                data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem));
                data << uint32(price);
                data << uint32(pProto->MaxDurability);
                data << uint32(pProto->BuyCount);
            }
        }
    }

    if (count == 0)
    {
        data << uint8(0);                                   // "Vendor has no inventory"
        SendPacket(&data);
        return;
    }

    data.put<uint8>(count_pos, count);
    SendPacket(&data);
}
Example #20
0
void WorldSession::SendListInventory(uint64 vendorguid)
{
    sLog.outDebug("WORLD: Sent SMSG_LIST_INVENTORY");

    Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);
    if (!pCreature)
    {
        sLog.outDebug("WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorguid)));
        _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0);
        return;
    }

    // remove fake death
    if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

    // Stop the npc if moving
    if (!pCreature->IsStopped())
        pCreature->StopMoving();

    VendorItemData const* vItems = pCreature->GetVendorItems();
    if (!vItems)
    {
        WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + 1));
        data << uint64(vendorguid);
        data << uint8(0);                                   // count==0, next will be error code
        data << uint8(0);                                   // "Vendor has no inventory"
        SendPacket(&data);
        return;
    }

    uint8 numitems = vItems->GetItemCount();
    uint8 count = 0;

    WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + numitems * 8 * 4));
    data << uint64(vendorguid);

    size_t count_pos = data.wpos();
    data << uint8(count);

    float discountMod = _player->GetReputationPriceDiscount(pCreature);

    for (uint8 i = 0; i < numitems; ++i)
    {
        if (VendorItem const* crItem = vItems->GetItem(i))
        {
            if (ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(crItem->item))
            {
                if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP && !_player->isGameMaster())
                    continue;

                ++count;

                // reputation discount
                uint32 price = uint32(floor(pProto->BuyPrice * discountMod));

                data << uint32(count);
                data << uint32(crItem->item);
                data << uint32(pProto->DisplayInfoID);
                data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem));
                data << uint32(price);
                data << uint32(pProto->MaxDurability);
                data << uint32(pProto->BuyCount);
                data << uint32(crItem->ExtendedCost);
            }
        }
    }

    if (count == 0)
    {
        data << uint8(0);                                   // "Vendor has no inventory"
        SendPacket(&data);
        return;
    }

    data.put<uint8>(count_pos, count);
    SendPacket(&data);
}
Example #21
0
void WorldSession::SendListInventory(uint64 vendorguid)
{
    sLog.outDebug("WORLD: Sent SMSG_LIST_INVENTORY");

    Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);

    if (!pCreature)
    {
        sLog.outDebug("WORLD: SendListInventory - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)));
        _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0);
        return;
    }

    // remove fake death
    if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

    // Stop the npc if moving
    if (!pCreature->IsStopped())
        pCreature->StopMoving();

    VendorItemData const* vItems = pCreature->GetVendorItems();

    if (!vItems)
    {
        _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0);
        return;
    }

    uint8 numitems = vItems->GetItemCount();
    uint8 count = 0;

    WorldPacket data( SMSG_LIST_INVENTORY, (8+1+numitems*8*4) );
    data << uint64(vendorguid);

    size_t count_pos = data.wpos();
    data << uint8(count);                                   // placeholder

    float discountMod = _player->GetReputationPriceDiscount(pCreature);

    for(uint8 vendorslot = 0; vendorslot < numitems; ++vendorslot )
    {
        if(VendorItem const* crItem = vItems->GetItem(vendorslot))
        {
            if(ItemPrototype const *pProto = ObjectMgr::GetItemPrototype(crItem->item))
            {
                if((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP && !_player->isGameMaster())
                    continue;

                ++count;

                // reputation discount
                uint32 price = crItem->IsExcludeMoneyPrice() ? 0 : uint32(floor(pProto->BuyPrice * discountMod));

                data << uint32(vendorslot +1);              // client size expected counting from 1
                data << uint32(crItem->item);
                data << uint32(pProto->DisplayInfoID);
                data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem));
                data << uint32(price);
                data << uint32(pProto->MaxDurability);
                data << uint32(pProto->BuyCount);
                data << uint32(crItem->GetExtendedCostId());
            }
        }
    }

    if ( count == 0 || data.size() != 8 + 1 + size_t(count) * 8 * 4 )
        return;

    data.put<uint8>(count_pos, count);
    SendPacket( &data );
}
Example #22
0
void WorldSession::SendListInventory(uint64 vendorguid)
{
    DEBUG_LOG("WORLD: Sent SMSG_LIST_INVENTORY");

    Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);

    if (!pCreature)
    {
        DEBUG_LOG("WORLD: SendListInventory - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)));
        _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0);
        return;
    }

    // remove fake death
    if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

    // Stop the npc if moving
    if (!pCreature->IsStopped())
        pCreature->StopMoving();

    VendorItemData const* vItems = pCreature->GetVendorItems();

    if (!vItems)
    {
        WorldPacket data( SMSG_LIST_INVENTORY, (8+1+1) );
        data << uint64(vendorguid);
        data << uint8(0);                                   // count==0, next will be error code
        data << uint8(0);                                   // "Vendor has no inventory"
        SendPacket(&data);
        return;
    }

    uint8 numitems = vItems->GetItemCount();
    uint8 count = 0;

    WorldPacket data( SMSG_LIST_INVENTORY, (8+1+numitems*8*4) );
    data << uint64(vendorguid);

    size_t count_pos = data.wpos();
    data << uint8(count);                                   // placeholder, client limit 150 items (as of 3.3.3)

    float discountMod = _player->GetReputationPriceDiscount(pCreature);

    for(uint8 vendorslot = 0; vendorslot < numitems; ++vendorslot )
    {
        if (VendorItem const* crItem = vItems->GetItem(vendorslot))
        {
            if (ItemPrototype const *pProto = ObjectMgr::GetItemPrototype(crItem->item))
            {
                if (!_player->isGameMaster())
                {
                    // class wrong item skip only for bindable case
                    if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP)
                        continue;

                    // race wrong item skip always
                    if ((pProto->Flags2 & ITEM_FLAGS2_HORDE_ONLY) && _player->GetTeam() != HORDE)
                        continue;

                    if ((pProto->Flags2 & ITEM_FLAGS2_ALLIANCE_ONLY) && _player->GetTeam() != ALLIANCE)
                        continue;

                    if ((pProto->AllowableRace & _player->getRaceMask()) == 0)
                        continue;
                }

                ++count;

                // reputation discount
                uint32 price = (crItem->ExtendedCost == 0 || pProto->Flags2 & ITEM_FLAGS2_EXT_COST_REQUIRES_GOLD) ? uint32(floor(pProto->BuyPrice * discountMod)) : 0;

                data << uint32(vendorslot +1);              // client size expected counting from 1
                data << uint32(crItem->item);
                data << uint32(pProto->DisplayInfoID);
                data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem));
                data << uint32(price);
                data << uint32(pProto->MaxDurability);
                data << uint32(pProto->BuyCount);
                data << uint32(crItem->ExtendedCost);
            }
        }
    }

    if (count == 0)
    {
        data << uint8(0);                                   // "Vendor has no inventory"
        SendPacket(&data);
        return;
    }

    data.put<uint8>(count_pos, count);
    SendPacket(&data);
}
Example #23
0
void WorldSession::SendListInventory(ObjectGuid vendorguid)
{
    DEBUG_LOG("WORLD: Sent SMSG_LIST_INVENTORY");

    Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);

    if (!pCreature)
    {
        DEBUG_LOG("WORLD: SendListInventory - %s not found or you can't interact with him.", vendorguid.GetString().c_str());
        _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, ObjectGuid(), 0);
        return;
    }

    // remove fake death
    if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

    // Stop the npc if moving
    if (!pCreature->IsStopped())
        pCreature->StopMoving();

    VendorItemData const* vItems = pCreature->GetVendorItems();
    VendorItemData const* tItems = pCreature->GetVendorTemplateItems();

    uint8 customitems = vItems ? vItems->GetItemCount() : 0;
    uint8 numitems = customitems + (tItems ? tItems->GetItemCount() : 0);

    std::vector<bool> bitFlags;

    float discountMod = _player->GetReputationPriceDiscount(pCreature);

    uint8 count = 0;
    ByteBuffer buffer;
    for (uint8 vendorslot = 0; vendorslot < numitems; ++vendorslot)
    {
        VendorItem const* crItem = vendorslot < customitems ? vItems->GetItem(vendorslot) : tItems->GetItem(vendorslot - customitems);

        if (crItem)
        {
            uint32 price, displayId, buyCount, maxDurability;
            int32 maxCount;

            if (crItem->type == VENDOR_ITEM_TYPE_ITEM)
            {
                ItemPrototype const * pProto = ObjectMgr::GetItemPrototype(crItem->item);
                if (!pProto)
                    continue;

                if (!_player->isGameMaster())
                {
                    // class wrong item skip only for bindable case
                    if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP)
                        continue;

                    // race wrong item skip always
                    if ((pProto->Flags2 & ITEM_FLAG2_HORDE_ONLY) && _player->GetTeam() != HORDE)
                        continue;

                    if ((pProto->Flags2 & ITEM_FLAG2_ALLIANCE_ONLY) && _player->GetTeam() != ALLIANCE)
                        continue;

                    if ((pProto->AllowableRace & _player->getRaceMask()) == 0)
                        continue;

                    if (crItem->conditionId && !sObjectMgr.IsPlayerMeetToCondition(crItem->conditionId, _player, pCreature->GetMap(), pCreature, CONDITION_FROM_VENDOR))
                        continue;
                }

                // possible item coverting for BoA case
                if (pProto->Flags & ITEM_FLAG_BOA)
                {
                    // convert if can use and then buy
                    if (pProto->RequiredReputationFaction && uint32(_player->GetReputationRank(pProto->RequiredReputationFaction)) >= pProto->RequiredReputationRank)
                    {
                        // checked at convert data loading as existed
                        if (uint32 newItemId = sObjectMgr.GetItemConvert(crItem->item, _player->getRaceMask()))
                            pProto = ObjectMgr::GetItemPrototype(newItemId);
                    }
                }

                ++count;
                if (count >= MAX_VENDOR_ITEMS)
                    break;

                // reputation discount
                maxDurability = pProto->MaxDurability;
                price = (crItem->ExtendedCost == 0 || pProto->Flags2 & ITEM_FLAG2_EXT_COST_REQUIRES_GOLD) ? uint32(floor(pProto->BuyPrice * discountMod)) : 0;
                displayId = pProto->DisplayInfoID;
                maxCount = crItem->maxcount <= 0 ? -1 : int32(pCreature->GetVendorItemCurrentCount(crItem));
                buyCount = pProto->BuyCount;

            }
            else if (crItem->type == VENDOR_ITEM_TYPE_CURRENCY)
            {
                CurrencyTypesEntry const * pCurrency = sCurrencyTypesStore.LookupEntry(crItem->item);
                if (!pCurrency)
                    continue;

                if (pCurrency->Category == CURRENCY_CATEGORY_META)
                    continue;

                ++count;
                if (count >= MAX_VENDOR_ITEMS)
                    break;

                maxDurability = 0;
                price = 0;
                displayId = 0;
                maxCount = -1;
                buyCount = crItem->maxcount;
            }
            else
                continue;

            bitFlags.push_back(crItem->ExtendedCost == 0);
            bitFlags.push_back(true);                       // unk

            buffer << uint32(vendorslot + 1);               // client size expected counting from 1
            buffer << uint32(maxDurability);

            if (crItem->ExtendedCost)
                buffer << uint32(crItem->ExtendedCost);

            buffer << uint32(crItem->item);
            buffer << uint32(crItem->type);
            buffer << uint32(price);
            buffer << uint32(displayId);
            buffer << int32(maxCount);
            buffer << uint32(buyCount);
        }
    }

    WorldPacket data(SMSG_LIST_INVENTORY, (8 + 3 + 1 + 1 + numitems * 8 * 4));

    data.WriteGuidMask<1, 0>(vendorguid);
    data.WriteBits(count, 21);
    data.WriteGuidMask<3, 6, 5, 2, 7>(vendorguid);

    for (uint32 i = 0; i < bitFlags.size(); ++i)
        data.WriteBit(bitFlags[i]);

    data.WriteGuidMask<4>(vendorguid);
    data.FlushBits();
    data.append(buffer);

    data.WriteGuidBytes<5, 4, 1, 0, 6>(vendorguid);
    data << uint8(count == 0);
    data.WriteGuidBytes<2, 3, 7>(vendorguid);

    SendPacket(&data);
}
bool
WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    if(!&creature)
        return true;

    // Waypoint movement can be switched on/off
    // This is quite handy for escort quests and other stuff

    if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
        return true;

    // prevent crash at empty waypoint path.
    if(i_path.Empty())
    {
        return true;
    }

    CreatureTraveller traveller(creature);

    /*
    if( npcIsStopped[creature.GetGUID()] )
    {
        i_nextMoveTime.Update(40000);
        i_destinationHolder.UpdateTraveller(traveller, ((diff)-40000), false);
        npcIsStopped[creature.GetGUID()] = false;
        return true;
    }
    */
    i_nextMoveTime.Update(diff);
    i_destinationHolder.UpdateTraveller(traveller, diff, false);

    if( creature.IsStopped() )
    {
        uint32 wpB = i_currentNode > 0 ? i_currentNode-1 : i_wpBehaviour.size()-1;

        if( i_wpBehaviour[wpB] != NULL )
        {
            struct WaypointBehavior *tmpBehavior = i_wpBehaviour[wpB];

            if (!tmpBehavior->HasDone)
            {
                if(tmpBehavior->emote != 0)
                {
                    creature.SetUInt32Value(UNIT_NPC_EMOTESTATE,tmpBehavior->emote);
                }
                if(tmpBehavior->aiscript != "")
                {
                    WPAIScript(creature, tmpBehavior->aiscript);
                }
                //sLog.outDebug("DEBUG: tmpBehavior->text[0] TEST");
                if(tmpBehavior->text[0] != "")
                {
                    //sLog.outDebug("DEBUG: tmpBehavior->text[0] != \"\"");
                    // Only one text is set
                    if( tmpBehavior->text[1] == "" )
                    {
                        //sLog.outDebug("DEBUG: tmpBehavior->text[1] == NULL");
                        creature.Say(tmpBehavior->text[0].c_str(), 0, 0);
                    }
                    else
                    {
                        // Select one from max 5 texts
                        for( int i = 0; i < 4; ++i )
                        {
                            if( tmpBehavior->text[i] == "" )
                            {
                                //sLog.outDebug("DEBUG: tmpBehavior->text[i] == \"\": %d", i);
                                //sLog.outDebug("DEBUG: rand() % (i): %d", rand() % (i));

                                creature.Say(tmpBehavior->text[rand() % i].c_str(), 0, 0);
                                break;
                            }
                        }
                    }
                }
                if(tmpBehavior->spell != 0)
                {
                    //sLog.outDebug("DEBUG: wpSys - spell");
                    creature.CastSpell(&creature,tmpBehavior->spell, false);
                }
                if (tmpBehavior->orientation !=100)
                {
                    //sLog.outDebug("DEBUG: wpSys - orientation");
                    creature.SetOrientation(tmpBehavior->orientation);
                }
                if(tmpBehavior->model1 != 0)
                {
                    //sLog.outDebug("DEBUG: wpSys - model1");
                    creature.SetUInt32Value(UNIT_FIELD_DISPLAYID, tmpBehavior->model1);
                }
                tmpBehavior->HasDone = true;
            }                                               // HasDone == false
        }                                                   // wpBehaviour found
    }                                                       // i_creature.IsStopped()

    if( i_nextMoveTime.Passed() )
    {
        if( creature.IsStopped() )
        {
            assert( i_currentNode < i_path.Size() );
            creature.addUnitState(UNIT_STAT_ROAMING);
            const Path::PathNode &node(i_path(i_currentNode));
            i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
            i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
            uint32 wpB = i_currentNode > 0 ? i_currentNode-1 : i_wpBehaviour.size()-1;

            if( i_wpBehaviour[wpB] != NULL )
            {
                struct WaypointBehavior *tmpBehavior = i_wpBehaviour[wpB];
                tmpBehavior->HasDone = false;
                if(tmpBehavior->model2 != 0)
                {
                    creature.SetUInt32Value(UNIT_FIELD_DISPLAYID, tmpBehavior->model2);
                }
                if (tmpBehavior->orientation !=100)
                {
                    creature.SetOrientation(tmpBehavior->orientation);
                }
                creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
            }
        }
        else
        {
            creature.StopMoving();
            i_nextMoveTime.Reset(i_delays[i_currentNode]);
            ++i_currentNode;
            if( i_currentNode >= i_path.Size() )
                i_currentNode = 0;
        }
    }
    return true;
}
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    if (!&creature)
        return true;

    // Waypoint movement can be switched on/off
    // This is quite handy for escort quests and other stuff
    if (creature.hasUnitState(UNIT_STAT_NOT_MOVE))
    {
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
        return true;
    }

    // prevent a crash at empty waypoint path.
    if (!i_path || i_path->empty())
    {
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
        return true;
    }

    if (i_currentNode >= i_path->size())
    {
        sLog.outError("WaypointMovement currentNode (%u) is equal or bigger than path size (creature entry %u)", i_currentNode, creature.GetEntry());
        i_currentNode = 0;
    }

    CreatureTraveller traveller(creature);

    i_nextMoveTime.Update(diff);

    if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true))
    {
        if (!IsActive(creature))                            // force stop processing (movement can move out active zone with cleanup movegens list)
            return true;                                    // not expire now, but already lost
    }

    // creature has been stopped in middle of the waypoint segment
    if (!i_destinationHolder.HasArrived() && creature.IsStopped())
    {
        // Timer has elapsed, meaning this part controlled it
        if (i_nextMoveTime.Passed())
        {
            SetStoppedByPlayer(false);

            creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

            if (creature.canFly())
                creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7);

            // Now we re-set destination to same node and start travel
            const WaypointNode &node = i_path->at(i_currentNode);
            i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
            i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
        }
        else // if( !i_nextMoveTime.Passed())
        {
            // unexpected end of timer && creature stopped && not at end of segment
            if (!IsStoppedByPlayer())
            {
                // Put 30 seconds delay
                i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER);
                i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
                SetStoppedByPlayer(true);                   // Mark we did it
            }
        }
        return true;                                        // Abort here this update
    }

    if (creature.IsStopped())
    {
        if (!m_isArrivalDone)
        {
            if (i_path->at(i_currentNode).orientation != 100)
                creature.SetOrientation(i_path->at(i_currentNode).orientation);

            if (i_path->at(i_currentNode).script_id)
            {
                DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature movement start script %u at point %u for creature %u (entry %u).", i_path->at(i_currentNode).script_id, i_currentNode, creature.GetDBTableGUIDLow(), creature.GetEntry());
                creature.GetMap()->ScriptsStart(sCreatureMovementScripts, i_path->at(i_currentNode).script_id, &creature, &creature);
            }

            // We have reached the destination and can process behavior
            if (WaypointBehavior *behavior = i_path->at(i_currentNode).behavior)
            {
                if (behavior->emote != 0)
                    creature.HandleEmote(behavior->emote);

                if (behavior->spell != 0)
                {
                    creature.CastSpell(&creature, behavior->spell, false);

                    if (!IsActive(creature))                // force stop processing (cast can change movegens list)
                        return true;                        // not expire now, but already lost
                }

                if (behavior->model1 != 0)
                    creature.SetDisplayId(behavior->model1);

                if (behavior->textid[0])
                {
                    // Not only one text is set
                    if (behavior->textid[1])
                    {
                        // Select one from max 5 texts (0 and 1 already checked)
                        int i = 2;
                        for(; i < MAX_WAYPOINT_TEXT; ++i)
                        {
                            if (!behavior->textid[i])
                                break;
                        }

                        creature.Say(behavior->textid[rand() % i], 0, 0);
                    }
                    else
                        creature.Say(behavior->textid[0], 0, 0);
                }
            }                                               // wpBehaviour found

            // Can only do this once for the node
            m_isArrivalDone = true;

            // Inform script
            MovementInform(creature);

            if (!IsActive(creature))                        // force stop processing (movement can move out active zone with cleanup movegens list)
                return true;                                // not expire now, but already lost

            // prevent a crash at empty waypoint path.
            if (!i_path || i_path->empty() || i_currentNode >= i_path->size())
            {
                creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
                return true;
            }
        }
    }                                                       // i_creature.IsStopped()

    // This is at the end of waypoint segment (incl. was previously stopped by player, extending the time)
    if (i_nextMoveTime.Passed())
    {
        // If stopped then begin a new move segment
        if (creature.IsStopped())
        {
            creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

            if (creature.canFly())
                creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7);

            if (WaypointBehavior *behavior = i_path->at(i_currentNode).behavior)
            {
                if (behavior->model2 != 0)
                    creature.SetDisplayId(behavior->model2);

                creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
            }

            // behavior for "departure" of the current node is done
            m_isArrivalDone = false;

            // Proceed with increment current node and then send to the next destination
            ++i_currentNode;

            // Oops, end of the line so need to start from the beginning
            if (i_currentNode >= i_path->size())
                i_currentNode = 0;

            if (i_path->at(i_currentNode).orientation != 100)
                creature.SetOrientation(i_path->at(i_currentNode).orientation);

            const WaypointNode &node = i_path->at(i_currentNode);
            i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
            i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
        }
        else
        {
            // If not stopped then stop it
            creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);

            SetStoppedByPlayer(false);

            // Set TimeTracker to waittime for the current node
            i_nextMoveTime.Reset(i_path->at(i_currentNode).delay);
        }
    }

    return true;
}
bool
TargetedMovementGenerator::Update(Creature &owner, const uint32 & time_diff)
{
    if( !&owner || !owner.isAlive() || !&i_target )
        return true;
    if( owner.hasUnitState(UNIT_STAT_ROOT) || owner.hasUnitState(UNIT_STAT_STUNDED) || owner.hasUnitState(UNIT_STAT_FLEEING))
        return true;
    if( !owner.isInCombat() && !owner.hasUnitState(UNIT_STAT_FOLLOW) )
    {
        //owner.AIM_Initialize();   This case must be the one, when a creature aggroed you. By Initalized a new AI, we prevented to Ai::_stopAttack() to be executed properly.
        return true;
    }

    // prevent crash after creature killed pet
    if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != &i_target)
        return true;

    Traveller<Creature> traveller(owner);

    if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
    {
        // put targeted movement generators on a higher priority
        if (owner.GetObjectSize())
            i_destinationHolder.ResetUpdate(50);

        float  dist = i_target.GetObjectSize() + owner.GetObjectSize() + OBJECT_CONTACT_DISTANCE;

        // try to counter precision differences
        if( i_destinationHolder.GetDistanceFromDestSq(i_target) > dist * dist + 0.1)
            _setTargetLocation(owner, 0);
        else if ( !owner.HasInArc( 0.1f, &i_target ) )
        {
            owner.SetInFront(&i_target);
            if( i_target.GetTypeId() == TYPEID_PLAYER )
                owner.SendUpdateToPlayer( (Player*)&i_target );
        }
        if( !owner.IsStopped() && i_destinationHolder.HasArrived())
        {
            owner.StopMoving();
            if(owner.canReachWithAttack(&i_target) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
                owner.Attack(&i_target);
        }
    }
    /*

         //SpellEntry* spellInfo;
        if( reach )
        {
            if( owner.GetDistance2dSq( &i_target ) > 0.0f )
            {
                DEBUG_LOG("MOVEMENT : Distance = %f",owner.GetDistance2dSq( &i_target ));
                owner.addUnitState(UNIT_STAT_CHASE);
                _setTargetLocation(owner, 0);
            }
            else if ( !owner.HasInArc( 0.0f, &i_target ) )
            {
                DEBUG_LOG("MOVEMENT : Orientation = %f",owner.GetAngle(&i_target));
                owner.SetInFront(&i_target);
                if( i_target.GetTypeId() == TYPEID_PLAYER )
                    owner.SendUpdateToPlayer( (Player*)&i_target );
            }
            if( !owner.isInCombat() )
            {
                owner.AIM_Initialize();
                return;
            }
        }
        else if( i_target.isAlive() )
        {
            if( !owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.isInCombat() )
            {
                if( spellInfo = owner.reachWithSpellAttack( &i_target ) )
                {
                    _spellAtack(owner, spellInfo);
                    return;
                }
            }
            if( owner.GetDistance2dSq( &i_target ) > 0.0f )
            {
                DEBUG_LOG("MOVEMENT : Distance = %f",owner.GetDistance2dSq( &i_target ));
                owner.addUnitState(UNIT_STAT_CHASE);
                _setTargetLocation(owner, 0);
            }
        }
        else if( !i_targetedHome )
        {
            if( !owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.isInCombat() && (spellInfo = owner.reachWithSpellAttack(&i_target)) )
            {
                _spellAtack(owner, spellInfo);
                return;
            }
            _setTargetLocation(owner, 0);
            if(reach)
            {
                if( reach && owner.canReachWithAttack(&i_target) )
                {
                    owner.StopMoving();
                    if(!owner.hasUnitState(UNIT_STAT_FOLLOW))
                        owner.Attack(&i_target);
                    owner.clearUnitState(UNIT_STAT_CHASE);
                    DEBUG_LOG("UNIT IS THERE");
                }
                else
                {
                    _setTargetLocation(owner, 0);
                    DEBUG_LOG("Continue to chase");
                }
            }
        }*/
    return true;
}
bool
WaypointMovementGenerator<Creature>::Update(Creature &unit, const uint32 &diff)
{
    if (!&unit)
        return true;

    if (!path_id)
        return false;

    // Waypoint movement can be switched on/off
    // This is quite handy for escort quests and other stuff
    if (unit.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
        return true;

    // Clear the generator if the path doesn't exist
    if (!waypoints || !waypoints->size())
        return false;

    Traveller<Creature> traveller(unit);

    i_nextMoveTime.Update(diff);
    i_destinationHolder.UpdateTraveller(traveller, diff, true);

    if (i_nextMoveTime.GetExpiry() < TIMEDIFF_NEXT_WP)
    {
        if (unit.IsStopped())
        {
            if (StopedByPlayer)
            {
                ASSERT(node);
                InitTraveller(unit, *node);
                i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z);
                i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
                StopedByPlayer = false;
                return true;
            }

            if (i_currentNode == waypoints->size() - 1) // If that's our last waypoint
            {
                if (repeating)         // If the movement is repeating
                    i_currentNode = 0; // Start moving all over again
                else
                {
                    unit.SetHomePosition(node->x, node->y, node->z, unit.GetOrientation());
                    unit.GetMotionMaster()->Initialize();
                    return false; // Clear the waypoint movement
                }
            }
            else
                ++i_currentNode;

            node = waypoints->at(i_currentNode);
            InitTraveller(unit, *node);
            i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z);
            i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());

            //Call for creature group update
            if (unit.GetFormation() && unit.GetFormation()->getLeader() == &unit)
                unit.GetFormation()->LeaderMoveTo(node->x, node->y, node->z);
        }
        else
        {
            //Determine waittime
            if (node->delay)
                i_nextMoveTime.Reset(node->delay);

            //note: disable "start" for mtmap
            if (node->event_id && urand(0,99) < node->event_chance)
                unit.GetMap()->ScriptsStart(sWaypointScripts, node->event_id, &unit, NULL/*, false*/);

            i_destinationHolder.ResetTravelTime();
            MovementInform(unit);
            unit.UpdateWaypointID(i_currentNode);
            unit.ClearUnitState(UNIT_STAT_ROAMING);
            unit.Relocate(node->x, node->y, node->z);
        }
    }
    else
    {
        if (unit.IsStopped() && !i_destinationHolder.HasArrived())
        {
            if (!StopedByPlayer)
            {
                i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER);
                i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
                StopedByPlayer = true;
            }
        }
    }
    return true;
}
Example #28
0
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    if (!&creature)
        return true;

    // Waypoint movement can be switched on/off
    // This is quite handy for escort quests and other stuff
    if (creature.hasUnitState(UNIT_STAT_NOT_MOVE))
    {
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
        return true;
    }

    // prevent a crash at empty waypoint path.
    if (!i_path || i_path->empty())
    {
        creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
        return true;
    }

    if (i_currentNode >= i_path->size())
        i_currentNode = 0;

    CreatureTraveller traveller(creature);

    i_nextMoveTime.Update(diff);
    if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true))
    {
        if (!IsActive(creature))                            // force stop processing (movement can move out active zone with cleanup movegens list)
            return true;                                    // not expire now, but already lost
    }

    // creature has been stopped in middle of the waypoint segment
    if (!i_destinationHolder.HasArrived() && creature.IsStopped())
    {
        // Timer has elapsed, meaning this part controlled it
        if (i_nextMoveTime.Passed())
        {
            SetStoppedByPlayer(false);

            creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

            if (creature.canFly())
                creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7);

            // Now we re-set destination to same node and start travel
            const WaypointNode &node = i_path->at(i_currentNode);
            i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
            i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
        }
        else // if( !i_nextMoveTime.Passed())
        {
            // unexpected end of timer && creature stopped && not at end of segment
            if (!IsStoppedByPlayer())
            {
                // Put 30 seconds delay
                i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER);
                i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
                SetStoppedByPlayer(true);                   // Mark we did it
            }
        }
        return true;                                        // Abort here this update
    }

    if (creature.IsStopped() && !i_hasDone) // creature is waiting on a waypoint and hasn't done the behavior yet
    {
        uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1;

        if (i_path->at(idx).orientation != 100)
            creature.SetOrientation(i_path->at(idx).orientation);

        if (WaypointBehavior *behavior = i_path->at(idx).behavior)
        {
            if (behavior->emote != 0)
                creature.HandleEmote(behavior->emote);

            if (behavior->spell != 0)
            {
                creature.CastSpell(&creature, behavior->spell, false);

                if (!IsActive(creature))                // force stop processing (cast can change movegens list)
                    return true;                        // not expire now, but already lost
            }

            if (behavior->model1 != 0)
                creature.SetDisplayId(behavior->model1);

            if (behavior->textid[0])
            {
                // Not only one text is set
                if (behavior->textid[1])
                {
                    // Select one from max 5 texts (0 and 1 already checked)
                    int i = 2;
                    for(; i < MAX_WAYPOINT_TEXT; ++i)
                    {
                        if (!behavior->textid[i])
                            break;
                    }

                    creature.Say(behavior->textid[rand() % i], 0, 0);
                }
                else
                    creature.Say(behavior->textid[0], 0, 0);
            }
        } // behavior done

        i_hasDone = true;
        MovementInform(creature);

        if (!IsActive(creature))                        // force stop processing (movement can move out active zone with cleanup movegens list)
            return true;                                // not expire now, but already lost

        // prevent a crash at empty waypoint path.
        if (!i_path || i_path->empty() || i_currentNode >= i_path->size())
        {
            creature.clearUnitState(UNIT_STAT_ROAMING_MOVE);
            return true;
        }
    }                                                       // i_creature.IsStopped()

    // This is at the end of waypoint segment or has been stopped by player
    if (i_nextMoveTime.Passed())
    {
        // If stopped then begin a new move segment
        if (creature.IsStopped())
        {
            creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

            if (creature.canFly())
                creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7);

            const WaypointNode &node = i_path->at(i_currentNode);
            i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
            i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());

            uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1;

            if (i_path->at(idx).orientation != 100)
                creature.SetOrientation(i_path->at(idx).orientation);

            if (WaypointBehavior *behavior = i_path->at(idx).behavior)
            {
                if (behavior->model2 != 0)
                    creature.SetDisplayId(behavior->model2);

                creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
            }
        }
        else
        {
            // If not stopped then stop it and set the reset of TimeTracker to waittime
            creature.StopMoving();
            SetStoppedByPlayer(false);

            i_nextMoveTime.Reset(i_path->at(i_currentNode).delay);
            ++i_currentNode;

            i_hasDone = false;

            if (i_currentNode >= i_path->size())
                i_currentNode = 0;
        }
    }
    return true;
}