void PathFinderMovementGenerator::createFilter() { uint16 includeFlags = 0; uint16 excludeFlags = 0; if (m_sourceUnit->GetTypeId() == TYPEID_UNIT) { Creature* creature = (Creature*)m_sourceUnit; if (creature->canWalk()) includeFlags |= NAV_GROUND; // walk // creatures don't take environmental damage if (creature->canSwim()) includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim } else if (m_sourceUnit->GetTypeId() == TYPEID_PLAYER) { // perfect support not possible, just stay 'safe' includeFlags |= (NAV_GROUND | NAV_WATER); } m_filter.setIncludeFlags(includeFlags); m_filter.setExcludeFlags(excludeFlags); updateFilter(); }
dtQueryFilter PathInfo::createFilter() { dtQueryFilter filter; if (m_sourceUnit->GetTypeId() != TYPEID_UNIT) return filter; Creature* creature = (Creature*)m_sourceUnit; unsigned short includeFlags = 0; unsigned short excludeFlags = 0; if (creature->canWalk()) includeFlags |= NAV_GROUND; // walk // creatures don't take environmental damage if (creature->canSwim() || creature->isPet()) includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim // allow creatures to cheat and use different movement types if they are moved // forcefully into terrain they can't normally move in if (creature->IsInWater() || creature->IsUnderWater()) includeFlags |= getNavTerrain(creature->GetPositionX(),creature->GetPositionY(),creature->GetPositionZ()); filter.setIncludeFlags(includeFlags); filter.setExcludeFlags(excludeFlags); return filter; }
void FleeingMovementGenerator<Creature>::_Init(Creature &owner) { if (!&owner) return; is_water_ok = owner.canSwim(); is_land_ok = owner.canWalk(); }
void ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok) { creature.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); is_water_ok = creature.canSwim(); is_land_ok = creature.canWalk(); }
void FleeingMovementGenerator<Creature>::_Init(Creature &owner) { owner.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); owner.SetTargetGUID(0); is_water_ok = owner.canSwim(); is_land_ok = owner.canWalk(); }
void ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok) { creature.RemoveSplineFlag(SPLINEFLAG_WALKMODE); is_water_ok = creature.canSwim(); is_land_ok = creature.canWalk(); }
void FleeingMovementGenerator<Creature>::_Init(Creature &owner) { owner.RemoveSplineFlag(SPLINEFLAG_WALKMODE); owner.SetTargetGUID(0); is_water_ok = owner.canSwim(); is_land_ok = owner.canWalk(); }
void FleeingMovementGenerator<Creature>::_Init(Creature &owner) { if (!&owner) return; //owner.SetTargetGuid(ObjectGuid()); is_water_ok = owner.canSwim(); is_land_ok = owner.canWalk(); }
void FleeingMovementGenerator<Creature>::_Init(Creature &owner) { if(!&owner) return; owner.SetUInt64Value(UNIT_FIELD_TARGET, 0); is_water_ok = owner.canSwim(); is_land_ok = owner.canWalk(); }
void FleeingMovementGenerator<Creature>::_Init(Creature &owner) { if(!&owner) return; owner.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); owner.SetUInt64Value(UNIT_FIELD_TARGET, 0); is_water_ok = owner.canSwim(); is_land_ok = owner.canWalk(); }
void RandomMovementGenerator<Creature>::Initialize(Creature &creature) { if (!creature.isAlive()) return; if (creature.canFly() && !(creature.canWalk() && creature.IsAtGroundLevel(creature.GetPositionX(), creature.GetPositionY(), creature.GetPositionZ()))) creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); else creature.AddSplineFlag(SPLINEFLAG_WALKMODE); creature.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); _setRandomLocation(creature); }
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; }
void RandomCircleMovementGenerator<Creature>::Initialize(Creature &creature) { if (!creature.isAlive()) return; if (creature.canFly() && !(creature.canWalk() && creature.IsAtGroundLevel(creature.GetPositionX(), creature.GetPositionY(), creature.GetPositionZ()))) creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); else creature.AddSplineFlag(SPLINEFLAG_WALKMODE); creature.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); m_bClockWise = urand(0, 1) ? true : false; i_wpId = 0; fillSplineWayPoints(creature); SplineFlags flags = SplineFlags(SPLINEFLAG_FORWARD | SPLINEFLAG_UNKNOWN7 | SPLINEFLAG_FLYING | creature.GetSplineFlags()); creature.SendSplineMove(&m_splineMap, SPLINETYPE_NORMAL, flags, 500, NULL); }
dtQueryFilter PathInfo::createFilter() { dtQueryFilter filter; if(m_sourceObject->GetTypeId() != TYPEID_UNIT) return filter; Creature* creature = (Creature*)m_sourceObject; filter.includeFlags = 0; filter.excludeFlags = 0; if(creature->canWalk()) { filter.includeFlags |= NAV_GROUND; // walk filter.includeFlags |= NAV_SHALLOW_WATER; // any creature can walk through shallow water } if(creature->canSwim()) filter.includeFlags |= NAV_WATER; // swim else { // TODO: check size of creature to determine NAV_AVERAGE_WATER and NAV_DEEP_WATER } // TODO: check for NAV_MAGMA //if(creature->IsImmunedToDamage(SPELL_SCHOOL_MASK_FIRE)) // immune to fire damage - valid? // TODO: check for NAV_SLIME // allow creatures to cheat and use different movement types if they are moved // forcefully into terrain they can't normally move in if(creature->IsInWater() || creature->IsUnderWater()) filter.includeFlags |= getNavTerrain(creature->GetPositionX(),creature->GetPositionY(),creature->GetPositionZ()); return filter; }
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) { float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist; creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance); z = creature.GetPositionZ(); Map const* map = creature.GetBaseMap(); // For 2D/3D system selection //bool is_land_ok = creature.canWalk(); // not used? //bool is_water_ok = creature.canSwim(); // not used? bool is_air_ok = creature.canFly(); const float angle = rand_norm_f()*(M_PI_F*2.0f); const float range = rand_norm_f()*wander_distance; const float distanceX = range * cos(angle); const float distanceY = range * sin(angle); nx = X + distanceX; ny = Y + distanceY; // prevent invalid coordinates generation MaNGOS::NormalizeMapCoord(nx); MaNGOS::NormalizeMapCoord(ny); dist = distanceX*distanceX + distanceY*distanceY; if (is_air_ok) // 3D system above ground and above water (flying mode) { // Limit height change const float distanceZ = rand_norm_f() * sqrtf(dist)/2.0f; nz = Z + distanceZ; float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height. float wz = map->GetWaterLevel(nx, ny); // Problem here, we must fly above the ground and water, not under. Let's try on next tick if (tz >= nz || wz >= nz) return; } //else if (is_water_ok) // 3D system under water and above ground (swimming mode) else // 2D only { nz = Z; if (!map->IsNextZcoordOK(nx, ny, nz, dist)) return; // let's forget this bad coords where a z cannot be find and retry at next tick creature.UpdateGroundPositionZ(nx, ny, nz, dist); } Traveller<Creature> traveller(creature); creature.SetOrientation(creature.GetAngle(nx, ny)); i_destinationHolder.SetDestination(traveller, nx, ny, nz); creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (is_air_ok && !(creature.canWalk() && creature.IsAtGroundLevel(nx, ny, nz))) { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); } //else if (is_water_ok) // Swimming mode to be done with more than this check else { i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(), 10000+i_destinationHolder.GetTotalTravelTime())); creature.AddSplineFlag(SPLINEFLAG_WALKMODE); } }
void ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok) { is_water_ok = creature.canSwim(); is_land_ok = creature.canWalk(); }
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) { float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist; creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance); z = creature.GetPositionZ(); uint32 mapid=creature.GetMapId(); Map const* map = MapManager::Instance().GetBaseMap(mapid); // For 2D/3D system selection bool is_land_ok = creature.canWalk(); bool is_water_ok = creature.canSwim(); bool is_air_ok = creature.canFly(); const float angle = rand_norm()*(M_PI*2); const float range = rand_norm()*wander_distance; const float distanceX = range * cos(angle); const float distanceY = range * sin(angle); nx = X + distanceX; ny = Y + distanceY; // prevent invalid coordinates generation Trinity::NormalizeMapCoord(nx); Trinity::NormalizeMapCoord(ny); dist = (nx - X)*(nx - X) + (ny - Y)*(ny - Y); if (is_air_ok) // 3D system above ground and above water (flying mode) { const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change nz = Z + distanceZ; float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height. float wz = map->GetWaterLevel(nx, ny); if (tz >= nz || wz >= nz) return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick } //else if (is_water_ok) // 3D system under water and above ground (swimming mode) else // 2D only { dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE) // The fastest way to get an accurate result 90% of the time. // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long. nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check if (fabs(nz-Z)>dist) { nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above if (fabs(nz-Z)>dist) { nz = map->GetHeight(nx,ny,Z+dist-2.0f,true); // Vmap Higher if (fabs(nz-Z)>dist) return; // let's forget this bad coords where a z cannot be find and retry at next tick } } } Traveller<Creature> traveller(creature); creature.SetOrientation(creature.GetAngle(nx,ny)); i_destinationHolder.SetDestination(traveller, nx, ny, nz); creature.addUnitState(UNIT_STAT_ROAMING); if (is_air_ok) { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); } //else if (is_water_ok) // Swimming mode to be done with more than this check else { i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime())); creature.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE); } }