diff --git a/scripts/ai/include/attack_generic.lua b/scripts/ai/include/attack_generic.lua index 51129b1..6a65f60 100644 --- a/scripts/ai/include/attack_generic.lua +++ b/scripts/ai/include/attack_generic.lua @@ -2,6 +2,10 @@ -- Generic attack functions. --]] +atk_changetarget = 1.8 +atk_approach = 1.4 +atk_aim = 1.0 + --[[ -- Mainly manages targetting nearest enemy. --]] @@ -15,7 +19,7 @@ function atk_g_think() range = ai.getweaprange() -- Shouldn't switch targets if close. - if dist > range * 1.6 then + if dist > range * atk_changetarget then ai.poptask() ai.pushtask(0, "attack", enemy) end @@ -41,43 +45,72 @@ function atk_g() range = ai.getweaprange() -- We first bias towards range. - if dist > range*1.3 then - dir = ai.face(target) -- Normal face the target. + if dist > range * atk_approach then + atk_g_ranged(target, dist) - secondary, special, ammo = ai.secondary("Launcher") - - -- Shoot missiles if in range. - if secondary == "Launcher" and - dist < ai.getweaprange(1) then - -- More lenient with aiming. - if special == "Smart" and dir < 30 then - ai.shoot(2) - -- Non-smart miss more. - elseif dir < 10 then - ai.shoot(2) - end + elseif dist > range * atk_aim then + if ai.relvel(target) < 0 then + atk_g_ranged(target, dist) + else + atk_g_aim(target, dist) end - -- Approach for melee. - if dir < 10 then - ai.accel() - end - -- Close enough to melee. + -- Close enough to melee. else - secondary, special = ai.secondary("Beam Weapon") - dir = ai.aim(target) -- We aim instead of face. - - -- Fire non-smart secondary weapons. - if(secondary == "Launcher" and special ~= "Smart") or - secondary == "Beam Weapon" then - if dir < 10 or special == "Turret" then -- Need good accuracy. - ai.shoot(2) - end - end - - if(dir < 10 and dist < range) or ai.hasturrets() then - ai.shoot() - end + atk_g_melee(target, dist) + end +end + +-- ]] +-- Enter ranged combat with the target. +-- ]] +function atk_g_ranged(target, dist) + dir = ai.face(target) -- Normal face the target. + secondary, special, ammo = ai.secondary("Launcher") + + -- Shoot missiles if in range. + if secondary == "Launcher" and + dist < ai.getweaprange(1) then + -- More lenient with aiming. + if special == "Smart" and dir < 30 then + ai.shoot(2) + + -- Non-smart miss more. + elseif dir < 10 then + ai.shoot(2) + end + end + + -- Approach for melee. + if dir < 10 then + ai.accel() + end +end + +--[[ +-- Aim at the target. +--]] +function atk_g_aim(target, dist) + dir = ai.aim(target) +end + +--[[ +-- Melee the target. +--]] +function atk_g_melee(target, dist) + secondary, special = ai.secondary("Beam Weapon") + dir = ai.aim(target) -- We aim instead of face. + + -- Fire non-smart secondary weapons. + if(secondary == "Launcher" and special ~= "Smart") or + secondary == "Beam Weapon" then + if dir < 10 or special == "Turret" then -- Need good acuracy. + ai.shoot(2) + end + end + + if(dir < 10 and dist < range) or ai.hasturrets() then + ai.shoot() end end diff --git a/src/ai.c b/src/ai.c index e142b12..d3ebca7 100644 --- a/src/ai.c +++ b/src/ai.c @@ -150,6 +150,7 @@ static int ai_getrndplanet(lua_State* L); /* Vec2 getrndplanet() */ static int ai_getlandplanet(lua_State* L); /* Vec2 getlandplanet() */ static int ai_hyperspace(lua_State* L); /* [number] hyperspace() */ static int ai_stop(lua_State* L); /* stop() */ +static int ai_relvel(lua_State* L); /* relvel(number) */ /* Escorts. */ static int ai_e_attack(lua_State* L); /* bool e_attack() */ static int ai_e_hold(lua_State* L); /* bool e_hold() */ @@ -212,6 +213,7 @@ static const luaL_Reg ai_methods[] = { { "brake", ai_brake }, { "stop", ai_stop }, { "hyperspace", ai_hyperspace }, + { "relvel", ai_relvel }, /* Escorts. */ { "e_attack", ai_e_attack }, { "e_hold", ai_e_hold }, @@ -1108,6 +1110,26 @@ static int ai_hyperspace(lua_State* L) { return 1; } +/* Get the relative velocity of a pilot. */ +static int ai_relvel(lua_State* L) { + unsigned int id; + Pilot* p; + + LLUA_MIN_ARGS(1); + + if(lua_isnumber(L, 1)) id = (unsigned int)lua_tonumber(L, 1); + else LLUA_INVALID_PARAMETER(); + + p = pilot_get(id); + if(p == NULL) { + LLUA_DEBUG("Invalid pilot identifier."); + return 0; + } + + lua_pushnumber(L, vect_dist(&cur_pilot->solid->vel, &p->solid->vel)); + return 1; +} + /* Completely stop the pilot if it is below minimum vel error. (No instant stops.) */ static int ai_stop(lua_State* L) { (void)L; /* Just avoid a gcc warning. */