Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/game/Object/Unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,11 @@ class MovementInfo
};

JumpInfo const& GetJumpInfo() const { return jump; }
void SetJumpInfo(float vel, float sinA, float cosA, float xyspd)
{
jump.velocity = vel; jump.sinAngle = sinA; jump.cosAngle = cosA; jump.xyspeed = xyspd;
Comment on lines +674 to +676
}
void SetFallTime(uint32 t) { fallTime = t; }
private:
// common
uint32 moveFlags; // see enum MovementFlags
Expand Down
143 changes: 141 additions & 2 deletions src/modules/Bots/playerbot/PlayerbotAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,12 @@ void PacketHandlingHelper::AddPacket(const WorldPacket& packet)
*/
PlayerbotAI::PlayerbotAI() : PlayerbotAIBase(), bot(NULL), aiObjectContext(NULL),
currentEngine(NULL), chatHelper(this), chatFilter(this), accountId(0), security(NULL), master(NULL), currentState(BOT_STATE_NON_COMBAT),
m_eatingUntil(0), m_drinkingUntil(0)
m_eatingUntil(0), m_drinkingUntil(0),
m_isJumping(false), m_jumpStartTime(0),
m_jumpStartX(0.f), m_jumpStartY(0.f), m_jumpStartZ(0.f),
m_jumpSinAngle(0.f), m_jumpCosAngle(1.f), m_jumpXYSpeed(0.f),
m_pendingJump(false), m_jumpRequestTime(0),
m_jumpTargetX(0.f), m_jumpTargetY(0.f), m_jumpTargetZ(0.f), m_jumpTargetO(0.f)
{
for (int i = 0 ; i < BOT_STATE_MAX; i++)
{
Expand All @@ -92,7 +97,12 @@ PlayerbotAI::PlayerbotAI() : PlayerbotAIBase(), bot(NULL), aiObjectContext(NULL)
*/
PlayerbotAI::PlayerbotAI(Player* bot) :
PlayerbotAIBase(), chatHelper(this), chatFilter(this), security(bot), master(NULL),
m_eatingUntil(0), m_drinkingUntil(0)
m_eatingUntil(0), m_drinkingUntil(0),
m_isJumping(false), m_jumpStartTime(0),
m_jumpStartX(0.f), m_jumpStartY(0.f), m_jumpStartZ(0.f),
m_jumpSinAngle(0.f), m_jumpCosAngle(1.f), m_jumpXYSpeed(0.f),
m_pendingJump(false), m_jumpRequestTime(0),
m_jumpTargetX(0.f), m_jumpTargetY(0.f), m_jumpTargetZ(0.f), m_jumpTargetO(0.f)
{
this->bot = bot;

Expand Down Expand Up @@ -162,6 +172,132 @@ PlayerbotAI::~PlayerbotAI()
}
}

static const float BOT_JUMP_VELOCITY = 7.9557f;
static const float BOT_JUMP_GRAVITY = 19.2911f;

void PlayerbotAI::RequestJump()
{
if (m_pendingJump || m_isJumping)
return;

Player* master = GetMaster();
if (!master)
return;

m_jumpTargetX = master->GetPositionX();
m_jumpTargetY = master->GetPositionY();
m_jumpTargetZ = master->GetPositionZ();
m_jumpTargetO = master->GetOrientation();
m_pendingJump = true;
m_jumpRequestTime = getMSTime();
}

void PlayerbotAI::StartJump(bool forward, float orientation)
{
if (m_isJumping || bot->IsDead())
return;

bot->GetMotionMaster()->Clear();
bot->GetMotionMaster()->MoveIdle();

m_jumpStartTime = getMSTime();
m_jumpStartX = bot->GetPositionX();
m_jumpStartY = bot->GetPositionY();
m_jumpStartZ = bot->GetPositionZ();

float o = (orientation >= 0.f) ? orientation : bot->GetOrientation();
m_jumpCosAngle = cosf(o);
m_jumpSinAngle = sinf(o);
m_jumpXYSpeed = forward ? bot->GetSpeed(MOVE_RUN) : 0.f;
m_isJumping = true;

bot->SetFallInformation(0, m_jumpStartZ);

bot->m_movementInfo.SetMovementFlags(MOVEFLAG_FALLING);
if (forward)
bot->m_movementInfo.AddMovementFlag(MOVEFLAG_FORWARD);
bot->m_movementInfo.SetFallTime(0);
bot->m_movementInfo.SetJumpInfo(-BOT_JUMP_VELOCITY, m_jumpCosAngle, m_jumpSinAngle, m_jumpXYSpeed);
bot->m_movementInfo.ChangePosition(m_jumpStartX, m_jumpStartY, m_jumpStartZ, o);
bot->m_movementInfo.UpdateTime(m_jumpStartTime);

WorldPacket data(MSG_MOVE_JUMP, 64);
data << bot->GetPackGUID();
bot->m_movementInfo.Write(data);
bot->SendMessageToSet(&data, false);
}

void PlayerbotAI::UpdateJump()
{
if (m_pendingJump && !m_isJumping)
{
if (getMSTime() - m_jumpRequestTime > 10000)
{
m_pendingJump = false;
}
else
{
float dx = m_jumpTargetX - bot->GetPositionX();
float dy = m_jumpTargetY - bot->GetPositionY();
float dist2d = sqrtf(dx * dx + dy * dy);
if (dist2d <= 0.5f)
{
m_pendingJump = false;
StartJump(true, m_jumpTargetO);
}
else
{
bot->GetMotionMaster()->MovePoint(0, m_jumpTargetX, m_jumpTargetY, m_jumpTargetZ);
}
}
return;
}

if (!m_isJumping)
return;

uint32 now = getMSTime();
uint32 fallTimeMs = now - m_jumpStartTime;
float t = fallTimeMs / 1000.f;

float z = m_jumpStartZ + BOT_JUMP_VELOCITY * t - 0.5f * BOT_JUMP_GRAVITY * t * t;
float x = m_jumpStartX + m_jumpCosAngle * m_jumpXYSpeed * t;
float y = m_jumpStartY + m_jumpSinAngle * m_jumpXYSpeed * t;

float maxDuration = 2.f * BOT_JUMP_VELOCITY / BOT_JUMP_GRAVITY * 1000.f + 100.f;
bool landed = fallTimeMs > 200 && ((z <= m_jumpStartZ + 0.05f) || (float(fallTimeMs) >= maxDuration));

bot->m_movementInfo.UpdateTime(now);
bot->m_movementInfo.SetFallTime(fallTimeMs);
bot->m_movementInfo.ChangePosition(x, y, z, bot->GetOrientation());

if (landed)
{
m_isJumping = false;

float landZ = m_jumpStartZ;
if (Map* map = bot->GetMap())
{
float terrainZ = map->GetHeight(x, y, z > m_jumpStartZ ? z : m_jumpStartZ);
if (terrainZ > INVALID_HEIGHT)
landZ = terrainZ;
}

bot->m_movementInfo.RemoveMovementFlag(MovementFlags(MOVEFLAG_FALLING | MOVEFLAG_FORWARD));
bot->m_movementInfo.ChangePosition(x, y, landZ, bot->GetOrientation());

WorldPacket data(MSG_MOVE_FALL_LAND, 64);
data << bot->GetPackGUID();
bot->m_movementInfo.Write(data);
bot->SendMessageToSet(&data, false);

bot->SetFallInformation(fallTimeMs, landZ);
bot->GetMotionMaster()->Clear();
bot->GetMotionMaster()->MoveIdle();
bot->GetMap()->PlayerRelocation(bot, x, y, landZ, bot->GetOrientation());
}
}

void PlayerbotAI::UpdateAI(uint32 elapsed)
{
if (bot->IsBeingTeleported())
Expand Down Expand Up @@ -206,6 +342,9 @@ void PlayerbotAI::UpdateAI(uint32 elapsed)
}
}

if (m_isJumping || m_pendingJump)
UpdateJump();

PlayerbotAIBase::UpdateAI(elapsed);
}

Expand Down
15 changes: 15 additions & 0 deletions src/modules/Bots/playerbot/PlayerbotAI.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ class PlayerbotAI : public PlayerbotAIBase
static bool IsOpposing(uint8 race1, uint8 race2);
PlayerbotSecurity* GetSecurity() { return &security; }

void StartJump(bool forward, float orientation = -1.f);
void RequestJump();
bool IsJumping() const { return m_isJumping; }
bool IsPendingJump() const { return m_pendingJump; }

bool IsEating() const
{
return m_eatingUntil && time(0) <= m_eatingUntil
Expand Down Expand Up @@ -213,5 +218,15 @@ class PlayerbotAI : public PlayerbotAIBase
PlayerbotSecurity security;
time_t m_eatingUntil;
time_t m_drinkingUntil;

bool m_isJumping;
uint32 m_jumpStartTime;
float m_jumpStartX, m_jumpStartY, m_jumpStartZ;
float m_jumpSinAngle, m_jumpCosAngle, m_jumpXYSpeed;
bool m_pendingJump;
uint32 m_jumpRequestTime;
float m_jumpTargetX, m_jumpTargetY, m_jumpTargetZ, m_jumpTargetO;

void UpdateJump();
};

4 changes: 4 additions & 0 deletions src/modules/Bots/playerbot/strategy/actions/ActionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ namespace ai
creators["set facing"] = &ActionContext::set_facing;
creators["attack duel opponent"] = &ActionContext::attack_duel_opponent;
creators["drop target"] = &ActionContext::drop_target;
creators["jump"] = &ActionContext::jump;
creators["jump up"] = &ActionContext::jump_up;
}

private:
Expand Down Expand Up @@ -112,5 +114,7 @@ namespace ai
static Action* healthstone(PlayerbotAI* ai) { return new UseItemAction(ai, "healthstone"); }
static Action* move_out_of_enemy_contact(PlayerbotAI* ai) { return new MoveOutOfEnemyContactAction(ai); }
static Action* set_facing(PlayerbotAI* ai) { return new SetFacingTargetAction(ai); }
static Action* jump(PlayerbotAI* ai) { return new JumpAction(ai); }
static Action* jump_up(PlayerbotAI* ai) { return new JumpInPlaceAction(ai); }
};
};
18 changes: 18 additions & 0 deletions src/modules/Bots/playerbot/strategy/actions/MovementActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,3 +626,21 @@ bool SetFacingTargetAction::isUseful()
{
return !AI_VALUE2(bool, "facing", "current target");
}

bool JumpAction::Execute(Event event)
{
if (ai->IsJumping() || ai->IsPendingJump())
return false;

ai->RequestJump();
return ai->IsPendingJump();
}

bool JumpInPlaceAction::Execute(Event event)
{
if (ai->IsJumping())
return false;

ai->StartJump(false);
return true;
Comment on lines +641 to +645
}
14 changes: 14 additions & 0 deletions src/modules/Bots/playerbot/strategy/actions/MovementActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,18 @@ namespace ai
virtual bool isUseful();
};

class JumpAction : public MovementAction
{
public:
JumpAction(PlayerbotAI* ai) : MovementAction(ai, "jump") {}
virtual bool Execute(Event event);
};

class JumpInPlaceAction : public MovementAction
{
public:
JumpInPlaceAction(PlayerbotAI* ai) : MovementAction(ai, "jump up") {}
virtual bool Execute(Event event);
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ void ChatCommandHandlerStrategy::InitTriggers(std::list<TriggerNode*> &triggers)
triggers.push_back(new TriggerNode(
"attackers",
NextAction::array(0, new NextAction("tell attackers", relevance), NULL)));

triggers.push_back(new TriggerNode(
"jump",
NextAction::array(0, new NextAction("jump", relevance), NULL)));

triggers.push_back(new TriggerNode(
"jump up",
NextAction::array(0, new NextAction("jump up", relevance), NULL)));
}


Expand Down Expand Up @@ -173,4 +181,6 @@ ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* ai) : PassTr
supported.push_back("summon");
supported.push_back("who");
supported.push_back("save mana");
supported.push_back("jump");
supported.push_back("jump up");
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,14 @@ namespace ai
creators["save mana"] = &ChatTriggerContext::save_mana;
creators["max dps"] = &ChatTriggerContext::max_dps;
creators["attackers"] = &ChatTriggerContext::attackers;
creators["jump"] = &ChatTriggerContext::jump;
creators["jump up"] = &ChatTriggerContext::jump_up;
}

private:
static Trigger* attackers(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "attackers"); }
static Trigger* jump(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "jump"); }
static Trigger* jump_up(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "jump up"); }
static Trigger* max_dps(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "max dps"); }
static Trigger* save_mana(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "save mana"); }
static Trigger* who(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "who"); }
Expand Down
Loading