Skip to content

Commit 6b91a62

Browse files
authored
Properly set rotation data from LuaAI (#4406)
* Properly set rotation data from LuaAI * Update Variable Name
1 parent 8b9ac5f commit 6b91a62

File tree

3 files changed

+102
-43
lines changed

3 files changed

+102
-43
lines changed

code/ai/ai.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ extern void ai_do_default_behavior(object *obj);
586586
extern void ai_start_waypoints(object *objp, waypoint_list *wp_list, int wp_flags);
587587
extern void ai_ship_hit(object *objp_ship, object *hit_objp, vec3d *hit_normal);
588588
extern void ai_ship_destroy(int shipnum);
589+
extern vec3d ai_get_acc_limit(vec3d* vel_limit, const object* objp);
589590
extern void ai_turn_towards_vector(vec3d *dest, object *objp, vec3d *slide_vec, vec3d *rel_pos, float bank_override, int flags, vec3d *rvec = nullptr, vec3d* turnrate_mod = nullptr);
590591
extern void init_ai_object(int objnum);
591592
extern void ai_init(void); // Call this one to parse ai.tbl.

code/ai/aicode.cpp

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,43 +1261,7 @@ void ai_turn_towards_vector(vec3d* dest, object* objp, vec3d* slide_vec, vec3d*
12611261
}
12621262
}
12631263

1264-
// Set rate at which ship can accelerate to its rotational velocity.
1265-
// For now, weapons just go much faster.
1266-
acc_limit = vel_limit;
1267-
if (objp->type == OBJ_WEAPON)
1268-
acc_limit *= 8.0f;
1269-
1270-
// do _proper_ handling of acc_limit and vel_limit if this flag is set
1271-
if (Framerate_independent_turning) {
1272-
// handle modifications to rotdamp (that could affect acc_limit and vel_limit)
1273-
// handled in its entirety in physics_sim_rot
1274-
float rotdamp = pip->rotdamp;
1275-
float shock_fraction_time_left = 0.f;
1276-
if (pip->flags & PF_IN_SHOCKWAVE) {
1277-
shock_fraction_time_left = timestamp_until(pip->shockwave_decay) / (float)SW_BLAST_DURATION;
1278-
if (shock_fraction_time_left > 0)
1279-
rotdamp = pip->rotdamp + pip->rotdamp * (SW_ROT_FACTOR - 1) * shock_fraction_time_left;
1280-
}
1281-
1282-
if (Ai_respect_tabled_turntime_rotdamp) {
1283-
// We're assuming the turn rate here is accurate so leave it as is
1284-
// but we'll use the ship's rotdamp to modify acc_limit
1285-
// (this is the polynomial approximation of the exponential effect rotdamp has on players)
1286-
if (rotdamp == 0.f)
1287-
acc_limit *= 1000.f;
1288-
else
1289-
acc_limit = vel_limit * (0.5f / rotdamp);
1290-
}
1291-
else {
1292-
// else, calculate the retail-friendly vel and acc values
1293-
ai_compensate_for_retail_turning(&vel_limit, &acc_limit, rotdamp, objp->type == OBJ_WEAPON);
1294-
1295-
// handle missile turning accel (which is bundled into rotdamp)
1296-
if (objp->type == OBJ_WEAPON && rotdamp != 0.f) {
1297-
acc_limit = vel_limit * (0.5f / rotdamp);
1298-
}
1299-
}
1300-
}
1264+
acc_limit = ai_get_acc_limit(&vel_limit, objp);
13011265

13021266
// for formation flying
13031267
if ((flags & AITTV_SLOW_BANK_ACCEL)) {
@@ -1364,6 +1328,52 @@ void ai_turn_towards_vector(vec3d* dest, object* objp, vec3d* slide_vec, vec3d*
13641328

13651329
}
13661330

1331+
//vel_limit can be modified if the object is a weapon and retail behaviour is enabled
1332+
vec3d ai_get_acc_limit(vec3d* vel_limit, const object* objp) {
1333+
// Set rate at which ship can accelerate to its rotational velocity.
1334+
// For now, weapons just go much faster.
1335+
vec3d acc_limit = *vel_limit;
1336+
if (objp->type == OBJ_WEAPON)
1337+
acc_limit *= 8.0f;
1338+
1339+
const physics_info* pip = &objp->phys_info;
1340+
1341+
// do _proper_ handling of acc_limit and vel_limit if this flag is set
1342+
if (Framerate_independent_turning) {
1343+
// handle modifications to rotdamp (that could affect acc_limit and vel_limit)
1344+
// handled in its entirety in physics_sim_rot
1345+
float rotdamp = pip->rotdamp;
1346+
float shock_fraction_time_left = 0.f;
1347+
if (pip->flags & PF_IN_SHOCKWAVE) {
1348+
shock_fraction_time_left = timestamp_until(pip->shockwave_decay) / (float)SW_BLAST_DURATION;
1349+
if (shock_fraction_time_left > 0)
1350+
rotdamp = pip->rotdamp + pip->rotdamp * (SW_ROT_FACTOR - 1) * shock_fraction_time_left;
1351+
}
1352+
1353+
if (Ai_respect_tabled_turntime_rotdamp) {
1354+
// We're assuming the turn rate here is accurate so leave it as is
1355+
// but we'll use the ship's rotdamp to modify acc_limit
1356+
// (this is the polynomial approximation of the exponential effect rotdamp has on players)
1357+
if (rotdamp == 0.f)
1358+
acc_limit *= 1000.f;
1359+
else
1360+
acc_limit = *vel_limit * (0.5f / rotdamp);
1361+
}
1362+
else {
1363+
// else, calculate the retail-friendly vel and acc values
1364+
ai_compensate_for_retail_turning(vel_limit, &acc_limit, rotdamp, objp->type == OBJ_WEAPON);
1365+
1366+
// handle missile turning accel (which is bundled into rotdamp)
1367+
if (objp->type == OBJ_WEAPON && rotdamp != 0.f) {
1368+
acc_limit = *vel_limit * (0.5f / rotdamp);
1369+
}
1370+
}
1371+
}
1372+
1373+
return acc_limit;
1374+
}
1375+
1376+
13671377
// Set aip->target_objnum to objnum
13681378
// Update aip->previous_target_objnum.
13691379
// If new target (objnum) is different than old target, reset target_time.

code/scripting/api/objs/ai_helper.cpp

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "vecmath.h"
77

88
#include "ai/ai.h"
9+
#include "mission/missionparse.h"
10+
#include "ship/ship.h"
911

1012
namespace scripting {
1113
namespace api {
@@ -39,19 +41,65 @@ inline int aici_getset_helper(lua_State* L, float control_info::* value) {
3941
return ade_set_args(L, "f", AI_ci.*value);
4042
}
4143

42-
ADE_VIRTVAR(Pitch, l_AI_Helper, "number", "The pitch rate for the ship this frame, -1 to 1", "number", "The pitch rate, or 0 if the handle is invalid")
44+
inline int pi_rotation_getset_helper(lua_State* L, int axis) {
45+
//Use with care! This works only if, as expected, the l_AI_Helper object is the one supplied to the luaai scripts this very frame
46+
object_h ship;
47+
float f = 0.0f;
48+
if (!ade_get_args(L, "o|f", l_AI_Helper.Get(&ship), &f))
49+
return ade_set_error(L, "f", 0.0f);
50+
51+
if (!ship.IsValid())
52+
return ade_set_error(L, "f", 0.0f);
53+
54+
vec3d vel_limit;
55+
// get the turn rate if we have Use_axial_turnrate_differences
56+
if (The_mission.ai_profile->flags[AI::Profile_Flags::Use_axial_turnrate_differences]) {
57+
vel_limit = Ship_info[Ships[ship.objp->instance].ship_info_index].max_rotvel;
58+
}
59+
else { // else get the turn time
60+
float turn_time = Ship_info[Ships[ship.objp->instance].ship_info_index].srotation_time;
61+
62+
if (turn_time > 0.0f)
63+
{
64+
vel_limit.xyz.x = PI2 / turn_time;
65+
vel_limit.xyz.y = PI2 / turn_time;
66+
vel_limit.xyz.z = PI2 / turn_time;
67+
}
68+
}
69+
vec3d acc_limit = ai_get_acc_limit(&vel_limit, ship.objp);
70+
71+
float currentThrustRate = ((ship.objp->phys_info.desired_rotvel.a1d[axis] - ship.objp->phys_info.rotvel.a1d[axis]) / AI_frametime) / acc_limit.a1d[axis];
72+
73+
if (ADE_SETTING_VAR) {
74+
currentThrustRate = f;
75+
float targetVel = currentThrustRate * acc_limit.a1d[axis] * AI_frametime + ship.objp->phys_info.rotvel.a1d[axis];
76+
CLAMP(targetVel, -vel_limit.a1d[axis], vel_limit.a1d[axis]);
77+
ship.objp->phys_info.desired_rotvel.a1d[axis] = targetVel;
78+
79+
vec3d rotstep = ship.objp->phys_info.desired_rotvel * AI_frametime;
80+
81+
matrix rotmat;
82+
angles rotangles{ rotstep.xyz.x, rotstep.xyz.z, rotstep.xyz.y };
83+
vm_angles_2_matrix(&rotmat, &rotangles);
84+
vm_matrix_x_matrix(&ship.objp->phys_info.ai_desired_orient, &ship.objp->orient, &rotmat);
85+
}
86+
87+
return ade_set_args(L, "f", currentThrustRate);
88+
}
89+
90+
ADE_VIRTVAR(Pitch, l_AI_Helper, "number", "The pitch thrust rate for the ship this frame, -1 to 1", "number", "The pitch rate, or 0 if the handle is invalid")
4391
{
44-
return aici_getset_helper(L, &control_info::pitch);
92+
return pi_rotation_getset_helper(L, 0);
4593
}
4694

47-
ADE_VIRTVAR(Bank, l_AI_Helper, "number", "The bank rate for the ship this frame, -1 to 1", "number", "The bank rate, or 0 if the handle is invalid")
95+
ADE_VIRTVAR(Bank, l_AI_Helper, "number", "The bank thrust rate for the ship this frame, -1 to 1", "number", "The bank rate, or 0 if the handle is invalid")
4896
{
49-
return aici_getset_helper(L, &control_info::bank);
97+
return pi_rotation_getset_helper(L, 2);
5098
}
5199

52-
ADE_VIRTVAR(Heading, l_AI_Helper, "number", "The heading rate for the ship this frame, -1 to 1", "number", "The heading rate, or 0 if the handle is invalid")
100+
ADE_VIRTVAR(Heading, l_AI_Helper, "number", "The heading thrust rate for the ship this frame, -1 to 1", "number", "The heading rate, or 0 if the handle is invalid")
53101
{
54-
return aici_getset_helper(L, &control_info::heading);
102+
return pi_rotation_getset_helper(L, 1);
55103
}
56104

57105
ADE_VIRTVAR(ForwardThrust, l_AI_Helper, "number", "The forward thrust rate for the ship this frame, -1 to 1", "number", "The forward thrust rate, or 0 if the handle is invalid")

0 commit comments

Comments
 (0)