bool Mob::CalculateNewPosition(float x, float y, float z, int speed, bool checkZ, bool calcHeading) { if(GetID()==0) return true; float nx = m_Position.x; float ny = m_Position.y; float nz = m_Position.z; // if NPC is rooted if (speed == 0) { SetHeading(CalculateHeadingToTarget(x, y)); if(moved){ SetCurrentSpeed(0); moved=false; } Log.Out(Logs::Detail, Logs::AI, "Rooted while calculating new position to (%.3f, %.3f, %.3f)", x, y, z); return true; } float old_test_vector=test_vector; m_TargetV.x = x - nx; m_TargetV.y = y - ny; m_TargetV.z = z - nz; if (m_TargetV.x == 0 && m_TargetV.y == 0) return false; SetCurrentSpeed((int8)(speed)); //*NPC_RUNANIM_RATIO); //speed *= NPC_SPEED_MULTIPLIER; Log.Out(Logs::Detail, Logs::AI, "Calculating new position to (%.3f, %.3f, %.3f) vector (%.3f, %.3f, %.3f) rate %.3f RAS %d", x, y, z, m_TargetV.x, m_TargetV.y, m_TargetV.z, speed, pRunAnimSpeed); // -------------------------------------------------------------------------- // 2: get unit vector // -------------------------------------------------------------------------- test_vector=sqrtf (x*x + y*y + z*z); tar_vector = speed / sqrtf (m_TargetV.x*m_TargetV.x + m_TargetV.y*m_TargetV.y + m_TargetV.z*m_TargetV.z); m_Position.w = CalculateHeadingToTarget(x, y); if (tar_vector >= 1.0) { if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), x, y, z); } m_Position.x = x; m_Position.y = y; m_Position.z = z; Log.Out(Logs::Detail, Logs::AI, "Close enough, jumping to waypoint"); } else { float new_x = m_Position.x + m_TargetV.x*tar_vector; float new_y = m_Position.y + m_TargetV.y*tar_vector; float new_z = m_Position.z + m_TargetV.z*tar_vector; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } m_Position.x = new_x; m_Position.y = new_y; m_Position.z = new_z; Log.Out(Logs::Detail, Logs::AI, "Next position (%.3f, %.3f, %.3f)", m_Position.x, m_Position.y, m_Position.z); } uint8 NPCFlyMode = 0; if(IsNPC()) { if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2) NPCFlyMode = 1; } //fix up pathing Z if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) { if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || (zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position)))) { glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z); float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f; Log.Out(Logs::Detail, Logs::AI, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.x,m_Position.y,m_Position.z); if ((newz > -2000) && std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check. { if (std::abs(x - m_Position.x) < 0.5 && std::abs(y - m_Position.y) < 0.5) { if (std::abs(z - m_Position.z) <= RuleR(Map, FixPathingZMaxDeltaMoving)) m_Position.z = z; else m_Position.z = newz + 1; } else m_Position.z = newz+1; } } } //OP_MobUpdate if((old_test_vector!=test_vector) || tar_ndx>20){ //send update tar_ndx=0; this->SetMoving(true); moved=true; m_Delta = glm::vec4(m_Position.x - nx, m_Position.y - ny, m_Position.z - nz, 0.0f); SendPosUpdate(); } tar_ndx++; // now get new heading SetAppearance(eaStanding, false); // make sure they're standing pLastChange = Timer::GetCurrentTime(); return true; }
bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool checkZ) { if(GetID()==0) return true; float nx = x_pos; float ny = y_pos; float nz = z_pos; // if NPC is rooted if (speed == 0.0) { SetHeading(CalculateHeadingToTarget(x, y)); if(moved){ SendPosition(); SetMoving(false); moved=false; } SetRunAnimSpeed(0); mlog(AI__WAYPOINTS, "Rooted while calculating new position to (%.3f, %.3f, %.3f)", x, y, z); return true; } float old_test_vector=test_vector; tar_vx = x - nx; tar_vy = y - ny; tar_vz = z - nz; if (tar_vx == 0 && tar_vy == 0) return false; pRunAnimSpeed = (uint8)(speed*NPC_RUNANIM_RATIO); speed *= NPC_SPEED_MULTIPLIER; mlog(AI__WAYPOINTS, "Calculating new position to (%.3f, %.3f, %.3f) vector (%.3f, %.3f, %.3f) rate %.3f RAS %d", x, y, z, tar_vx, tar_vy, tar_vz, speed, pRunAnimSpeed); // -------------------------------------------------------------------------- // 2: get unit vector // -------------------------------------------------------------------------- test_vector=sqrtf (x*x + y*y + z*z); tar_vector = speed / sqrtf (tar_vx*tar_vx + tar_vy*tar_vy + tar_vz*tar_vz); heading = CalculateHeadingToTarget(x, y); if (tar_vector >= 1.0) { if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), x, y, z); } x_pos = x; y_pos = y; z_pos = z; mlog(AI__WAYPOINTS, "Close enough, jumping to waypoint"); } else { float new_x = x_pos + tar_vx*tar_vector; float new_y = y_pos + tar_vy*tar_vector; float new_z = z_pos + tar_vz*tar_vector; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } x_pos = new_x; y_pos = new_y; z_pos = new_z; mlog(AI__WAYPOINTS, "Next position (%.3f, %.3f, %.3f)", x_pos, y_pos, z_pos); } uint8 NPCFlyMode = 0; if(IsNPC()) { if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2) NPCFlyMode = 1; } //fix up pathing Z if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) { if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) { Map::Vertex dest(x_pos, y_pos, z_pos); float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f; mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check. { if(ABS(x - x_pos) < 0.5 && ABS(y - y_pos) < 0.5) { if(ABS(z - z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving)) z_pos = z; else z_pos = newz + 1; } else z_pos = newz+1; } } } //OP_MobUpdate if((old_test_vector!=test_vector) || tar_ndx>20){ //send update tar_ndx=0; this->SetMoving(true); moved=true; delta_x=(x_pos-nx); delta_y=(y_pos-ny); delta_z=(z_pos-nz); delta_heading=0;//(heading-nh)*8; SendPosUpdate(); } tar_ndx++; // now get new heading SetAppearance(eaStanding, false); // make sure they're standing pLastChange = Timer::GetCurrentTime(); return true; }
bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, bool checkZ) { if(GetID()==0) return true; if(speed <= 0) { SetCurrentSpeed(0); return true; } if ((m_Position.x-x == 0) && (m_Position.y-y == 0)) {//spawn is at target coords if(m_Position.z-z != 0) { m_Position.z = z; Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z); return true; } Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater); return false; } else if ((std::abs(m_Position.x - x) < 0.1) && (std::abs(m_Position.y - y) < 0.1)) { Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): X/Y difference <0.1, Jumping to target.", x, y, z); if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), x, y, z); } m_Position.x = x; m_Position.y = y; m_Position.z = z; return true; } bool send_update = false; int compare_steps = 20; if(tar_ndx < compare_steps && m_TargetLocation.x==x && m_TargetLocation.y==y) { float new_x = m_Position.x + m_TargetV.x*tar_vector; float new_y = m_Position.y + m_TargetV.y*tar_vector; float new_z = m_Position.z + m_TargetV.z*tar_vector; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } m_Position.x = new_x; m_Position.y = new_y; m_Position.z = new_z; Log.Out(Logs::Detail, Logs::AI, "Calculating new position2 to (%.3f, %.3f, %.3f), old vector (%.3f, %.3f, %.3f)", x, y, z, m_TargetV.x, m_TargetV.y, m_TargetV.z); uint8 NPCFlyMode = 0; if(IsNPC()) { if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2) NPCFlyMode = 1; } //fix up pathing Z if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) { if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || (zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position)))) { glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z); float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f; Log.Out(Logs::Detail, Logs::AI, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.x,m_Position.y,m_Position.z); if ((newz > -2000) && std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check. { if ((std::abs(x - m_Position.x) < 0.5) && (std::abs(y - m_Position.y) < 0.5)) { if (std::abs(z - m_Position.z) <= RuleR(Map, FixPathingZMaxDeltaMoving)) m_Position.z = z; else m_Position.z = newz + 1; } else m_Position.z = newz + 1; } } } tar_ndx++; return true; } if (tar_ndx>50) { tar_ndx--; } else { tar_ndx=0; } m_TargetLocation = glm::vec3(x, y, z); float nx = this->m_Position.x; float ny = this->m_Position.y; float nz = this->m_Position.z; // float nh = this->heading; m_TargetV.x = x - nx; m_TargetV.y = y - ny; m_TargetV.z = z - nz; SetCurrentSpeed((int8)speed); pRunAnimSpeed = speed; if(IsClient()) { animation = speed / 2; } //pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO); //speed *= NPC_SPEED_MULTIPLIER; Log.Out(Logs::Detail, Logs::AI, "Calculating new position2 to (%.3f, %.3f, %.3f), new vector (%.3f, %.3f, %.3f) rate %.3f, RAS %d", x, y, z, m_TargetV.x, m_TargetV.y, m_TargetV.z, speed, pRunAnimSpeed); // -------------------------------------------------------------------------- // 2: get unit vector // -------------------------------------------------------------------------- float mag = sqrtf (m_TargetV.x*m_TargetV.x + m_TargetV.y*m_TargetV.y + m_TargetV.z*m_TargetV.z); tar_vector = (float)speed / mag; // mob move fix int numsteps = (int) ( mag * 16.0f / (float)speed + 0.5f); // mob move fix if (numsteps<20) { if (numsteps>1) { tar_vector=1.0f ; m_TargetV.x = m_TargetV.x/(float)numsteps; m_TargetV.y = m_TargetV.y/(float)numsteps; m_TargetV.z = m_TargetV.z/(float)numsteps; float new_x = m_Position.x + m_TargetV.x; float new_y = m_Position.y + m_TargetV.y; float new_z = m_Position.z + m_TargetV.z; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } m_Position.x = new_x; m_Position.y = new_y; m_Position.z = new_z; m_Position.w = CalculateHeadingToTarget(x, y); tar_ndx = 20 - numsteps; Log.Out(Logs::Detail, Logs::AI, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.x, m_Position.y, m_Position.z, numsteps); } else { if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), x, y, z); } m_Position.x = x; m_Position.y = y; m_Position.z = z; Log.Out(Logs::Detail, Logs::AI, "Only a single step to get there... jumping."); } } else { tar_vector/=16.0f; float dur = Timer::GetCurrentTime() - pLastChange; if(dur < 1.0f) { dur = 1.0f; } tar_vector = (tar_vector * AImovement_duration) / 100.0f; float new_x = m_Position.x + m_TargetV.x*tar_vector; float new_y = m_Position.y + m_TargetV.y*tar_vector; float new_z = m_Position.z + m_TargetV.z*tar_vector; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } m_Position.x = new_x; m_Position.y = new_y; m_Position.z = new_z; m_Position.w = CalculateHeadingToTarget(x, y); Log.Out(Logs::Detail, Logs::AI, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.x, m_Position.y, m_Position.z, numsteps); } uint8 NPCFlyMode = 0; if(IsNPC()) { if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2) NPCFlyMode = 1; } //fix up pathing Z if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) { if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || (zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position)))) { glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z); float newz = zone->zonemap->FindBestZ(dest, nullptr); Log.Out(Logs::Detail, Logs::AI, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.x, m_Position.y, m_Position.z); if ((newz > -2000) && std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check. { if (std::abs(x - m_Position.x) < 0.5 && std::abs(y - m_Position.y) < 0.5) { if (std::abs(z - m_Position.z) <= RuleR(Map, FixPathingZMaxDeltaMoving)) m_Position.z = z; else m_Position.z = newz + 1; } else m_Position.z = newz+1; } } } SetMoving(true); moved=true; m_Delta = glm::vec4(m_Position.x - nx, m_Position.y - ny, m_Position.z - nz, 0.0f); if (IsClient()) { SendPosUpdate(1); CastToClient()->ResetPositionTimer(); } else { SendPosUpdate(); SetAppearance(eaStanding, false); } pLastChange = Timer::GetCurrentTime(); return true; }
bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, bool checkZ) { if(GetID()==0) return true; if ((x_pos-x == 0) && (y_pos-y == 0)) {//spawn is at target coords if(z_pos-z != 0) { z_pos = z; mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z); return true; } mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater); return false; } else if ((ABS(x_pos - x) < 0.1) && (ABS(y_pos - y) < 0.1)) { mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f): X/Y difference <0.1, Jumping to target.", x, y, z); if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), x, y, z); } x_pos = x; y_pos = y; z_pos = z; return true; } int compare_steps = IsBoat() ? 1 : 20; if(tar_ndx < compare_steps && tarx==x && tary==y) { float new_x = x_pos + tar_vx*tar_vector; float new_y = y_pos + tar_vy*tar_vector; float new_z = z_pos + tar_vz*tar_vector; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } x_pos = new_x; y_pos = new_y; z_pos = new_z; mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), old vector (%.3f, %.3f, %.3f)", x, y, z, tar_vx, tar_vy, tar_vz); uint8 NPCFlyMode = 0; if(IsNPC()) { if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2) NPCFlyMode = 1; } //fix up pathing Z if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) { if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) { Map::Vertex dest(x_pos, y_pos, z_pos); float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f; mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check. { if((ABS(x - x_pos) < 0.5) && (ABS(y - y_pos) < 0.5)) { if(ABS(z-z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving)) z_pos = z; else z_pos = newz + 1; } else z_pos = newz + 1; } } } tar_ndx++; return true; } if (tar_ndx>50) { tar_ndx--; } else { tar_ndx=0; } tarx=x; tary=y; tarz=z; float nx = this->x_pos; float ny = this->y_pos; float nz = this->z_pos; // float nh = this->heading; tar_vx = x - nx; tar_vy = y - ny; tar_vz = z - nz; //pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO); //speed *= NPC_SPEED_MULTIPLIER; mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), new vector (%.3f, %.3f, %.3f) rate %.3f, RAS %d", x, y, z, tar_vx, tar_vy, tar_vz, speed, pRunAnimSpeed); // -------------------------------------------------------------------------- // 2: get unit vector // -------------------------------------------------------------------------- float mag = sqrtf (tar_vx*tar_vx + tar_vy*tar_vy + tar_vz*tar_vz); tar_vector = speed / mag; // mob move fix int numsteps = (int) ( mag * 20 / speed) + 1; // mob move fix if (numsteps<20) { if (numsteps>1) { tar_vector=1.0f ; tar_vx = tar_vx/numsteps; tar_vy = tar_vy/numsteps; tar_vz = tar_vz/numsteps; float new_x = x_pos + tar_vx; float new_y = y_pos + tar_vy; float new_z = z_pos + tar_vz; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } x_pos = new_x; y_pos = new_y; z_pos = new_z; tar_ndx=22-numsteps; heading = CalculateHeadingToTarget(x, y); mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", x_pos, y_pos, z_pos, numsteps); } else { if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), x, y, z); } x_pos = x; y_pos = y; z_pos = z; mlog(AI__WAYPOINTS, "Only a single step to get there... jumping."); } } else { tar_vector/=20; float new_x = x_pos + tar_vx*tar_vector; float new_y = y_pos + tar_vy*tar_vector; float new_z = z_pos + tar_vz*tar_vector; if(IsNPC()) { entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z); } x_pos = new_x; y_pos = new_y; z_pos = new_z; heading = CalculateHeadingToTarget(x, y); mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", x_pos, y_pos, z_pos, numsteps); } uint8 NPCFlyMode = 0; if(IsNPC()) { if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2) NPCFlyMode = 1; } //fix up pathing Z if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) { if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() || (zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos))) { Map::Vertex dest(x_pos, y_pos, z_pos); float newz = zone->zonemap->FindBestZ(dest, nullptr); + 2.0f; mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check. { if(ABS(x - x_pos) < 0.5 && ABS(y - y_pos) < 0.5) { if(ABS(z - z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving)) z_pos = z; else z_pos = newz + 1; } else z_pos = newz+1; } } } SetMoving(true); moved=true; delta_x=x_pos-nx; delta_y=y_pos-ny; delta_z=z_pos-nz; delta_heading=0; if (IsClient()) SendPosUpdate(1); else SendPosUpdate(); SetAppearance(eaStanding, false); pLastChange = Timer::GetCurrentTime(); return true; }