-void havocbot_bunnyhop(entity this, vector dir)
-{
- // Don't jump when attacking
- if(this.aistatus & AI_STATUS_ATTACKING)
- return;
-
- if (!this.goalcurrent || IS_PLAYER(this.goalcurrent))
- return;
-
- if((this.aistatus & AI_STATUS_RUNNING) && vdist(this.velocity, <, autocvar_sv_maxspeed * 0.75)
- || (this.aistatus & AI_STATUS_DANGER_AHEAD))
- {
- this.aistatus &= ~AI_STATUS_RUNNING;
- PHYS_INPUT_BUTTON_JUMP(this) = false;
- this.bot_canruntogoal = 0;
- this.bot_timelastseengoal = 0;
- return;
- }
-
- if(this.waterlevel > WATERLEVEL_WETFEET || IS_DUCKED(this))
- {
- this.aistatus &= ~AI_STATUS_RUNNING;
- return;
- }
-
- if(this.bot_lastseengoal != this.goalcurrent && !(this.aistatus & AI_STATUS_RUNNING))
- {
- this.bot_canruntogoal = 0;
- this.bot_timelastseengoal = 0;
- }
-
- // Run only to visible goals
- if(IS_ONGROUND(this))
- if(vdist(vec2(this.velocity), >=, autocvar_sv_maxspeed))
- if(checkpvs(this.origin + this.view_ofs, this.goalcurrent))
- {
- this.bot_lastseengoal = this.goalcurrent;
-
- // seen it before
- if(this.bot_timelastseengoal)
- {
- vector gco = get_closer_dest(this.goalcurrent, this.origin);
- // for a period of time
- if(time - this.bot_timelastseengoal > autocvar_bot_ai_bunnyhop_firstjumpdelay)
- {
- bool checkdistance = true;
-
- // don't run if it is too close
- if(this.bot_canruntogoal==0)
- {
- if(vdist(this.origin - gco, >, autocvar_bot_ai_bunnyhop_startdistance))
- this.bot_canruntogoal = 1;
- else
- this.bot_canruntogoal = -1;
- }
-
- if(this.bot_canruntogoal != 1)
- return;
-
- if(this.aistatus & AI_STATUS_ROAMING)
- if(this.goalcurrent.classname == "waypoint")
- if (!(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL))
- if(fabs(gco.z - this.origin.z) < this.maxs.z - this.mins.z)
- if (this.goalstack01 && !wasfreed(this.goalstack01))
- if (!(this.goalstack01.wpflags & WAYPOINTFLAG_JUMP))
- {
- vector gno = (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5;
- vector deviation = vectoangles(gno - this.origin) - vectoangles(gco - this.origin);
- while (deviation.y < -180) deviation.y = deviation.y + 360;
- while (deviation.y > 180) deviation.y = deviation.y - 360;
-
- if(fabs(deviation.y) < 20)
- if(vlen2(this.origin - gco) < vlen2(this.origin - gno))
- if(fabs(gno.z - gco.z) < this.maxs.z - this.mins.z)
- {
- if(vdist(gco - gno, >, autocvar_bot_ai_bunnyhop_startdistance))
- if(checkpvs(this.origin + this.view_ofs, this.goalstack01))
- {
- checkdistance = false;
- }
- }
- }
-
- if(checkdistance)
- {
- this.aistatus &= ~AI_STATUS_RUNNING;
- // increase stop distance in case the goal is on a slope or a lower platform
- if(vdist(this.origin - gco, >, autocvar_bot_ai_bunnyhop_stopdistance + (this.origin.z - gco.z)))
- PHYS_INPUT_BUTTON_JUMP(this) = true;
- }
- else
- {
- this.aistatus |= AI_STATUS_RUNNING;
- PHYS_INPUT_BUTTON_JUMP(this) = true;
- }
- }
- }
- else
- {
- this.bot_timelastseengoal = time;
- }
- }
- else
- {
- this.bot_timelastseengoal = 0;
- }
-}
-