Skip to content

Commit 49cd8c3

Browse files
authored
Merge pull request scp-fs2open#6717 from Goober5000/improve_scripted_waypoints
improve scripting support for waypoint lists
2 parents 11b085c + a294559 commit 49cd8c3

5 files changed

Lines changed: 77 additions & 18 deletions

File tree

code/ai/aicode.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3534,6 +3534,13 @@ void ai_start_waypoints(object *objp, int wp_list_index, int wp_flags, int start
35343534
wp_list = find_waypoint_list_at_index(wp_list_index);
35353535
}
35363536

3537+
if (wp_list->get_waypoints().empty())
3538+
{
3539+
Warning(LOCATION, "Waypoint list '%s' is empty!", wp_list->get_name());
3540+
aip->mode = AIM_NONE;
3541+
return;
3542+
}
3543+
35373544
auto wp = find_waypoint_at_index(wp_list, start_index);
35383545
if (!wp)
35393546
{

code/object/waypoint.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ void waypoint_add_list(const char *name, const SCP_vector<vec3d> &vec_list)
411411
Assert(wp_list.get_waypoints().size() <= 0xffff);
412412
}
413413

414-
int waypoint_add(const vec3d *pos, int waypoint_instance)
414+
int waypoint_add(const vec3d *pos, int waypoint_instance, bool first_waypoint_in_list)
415415
{
416416
Assert(pos != NULL);
417417
waypoint_list *wp_list;
@@ -426,22 +426,28 @@ int waypoint_add(const vec3d *pos, int waypoint_instance)
426426
waypoint_find_unique_name(buf, static_cast<int>(Waypoint_lists.size()) + 1);
427427

428428
// add new list with that name
429-
waypoint_list new_list(buf);
430-
Waypoint_lists.push_back(new_list);
429+
Waypoint_lists.emplace_back(buf);
431430
wp_list = &Waypoint_lists.back();
432431

433432
// set up references
434433
wp_list_index = static_cast<int>(Waypoint_lists.size()) - 1;
435434
wp_index = static_cast<int>(wp_list->get_waypoints().size());
436435
}
437-
// create the waypoint on the same list as, and immediately after, waypoint_instance
436+
// create the waypoint on the same list as, and immediately after, waypoint_instance (unless it's the first waypoint)
438437
else
439438
{
440439
calc_waypoint_indexes(waypoint_instance, wp_list_index, wp_index);
441440
wp_list = find_waypoint_list_at_index(wp_list_index);
442441

443-
// theoretically waypoint_instance points to a current waypoint, so advance past it
444-
wp_index++;
442+
if (first_waypoint_in_list)
443+
{
444+
wp_index = 0;
445+
}
446+
else
447+
{
448+
// theoretically waypoint_instance points to a current waypoint, so advance past it
449+
wp_index++;
450+
}
445451

446452
// it has to be on, or at the end of, an existing list
447453
Assert(wp_list != NULL);

code/object/waypoint.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void waypoint_add_list(const char *name, const SCP_vector<vec3d> &vec_list);
9797

9898
// Attempts to create a waypoint with the specified instance (used to calculate list and index).
9999
// Returns the object number, or -1 on failure. Used by scripting and FRED.
100-
int waypoint_add(const vec3d *pos, int waypoint_instance);
100+
int waypoint_add(const vec3d *pos, int waypoint_instance, bool first_waypoint_in_list = false);
101101

102102
// Removes a waypoint, including its entire list if it's the last waypoint remaining.
103103
void waypoint_remove(const waypoint *wpt);

code/parse/sexp.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25208,16 +25208,16 @@ void sexp_set_training_context_fly_path(int node)
2520825208
{
2520925209
bool is_nan, is_nan_forever;
2521025210

25211-
waypoint_list *wp_list = find_matching_waypoint_list(CTEXT(node));
25212-
if (wp_list == nullptr)
25211+
int wp_list = find_matching_waypoint_list_index(CTEXT(node));
25212+
if (wp_list < 0)
2521325213
return;
2521425214

2521525215
int distance = eval_num(CDR(node), is_nan, is_nan_forever);
2521625216
if (is_nan || is_nan_forever)
2521725217
return;
2521825218

2521925219
Training_context |= TRAINING_CONTEXT_FLY_PATH;
25220-
Training_context_waypoint_path = find_index_of_waypoint_list(wp_list);
25220+
Training_context_waypoint_path = wp_list;
2522125221
Training_context_distance = static_cast<float>(distance);
2522225222
Training_context_goal_waypoint = 0;
2522325223
Training_context_at_waypoint = -1;

code/scripting/api/libs/mission.cpp

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,28 +1472,74 @@ ADE_FUNC(createDebris,
14721472
return ade_set_args(L, "o", l_Debris.Set(object_h(obj)));
14731473
}
14741474

1475+
ADE_FUNC(createWaypointList, l_Mission, "[string name]",
1476+
"Creates a waypoint list. If a name is not specified, the list will have a default name. Be sure to populate the list with at least one waypoint before using it!",
1477+
"waypointlist",
1478+
"Waypoint list handle, or invalid handle if waypoint list couldn't be created")
1479+
{
1480+
char buf[NAME_LENGTH];
1481+
const char* name = nullptr;
1482+
if (!ade_get_args(L, "|s", &name))
1483+
return ade_set_error(L, "o", l_WaypointList.Set(waypointlist_h()));
1484+
1485+
// use either a specified name...
1486+
if (name)
1487+
{
1488+
auto list = find_matching_waypoint_list(name);
1489+
if (list)
1490+
{
1491+
Warning(LOCATION, "Waypoint list '%s' already exists!", name);
1492+
return ade_set_error(L, "o", l_WaypointList.Set(waypointlist_h()));
1493+
}
1494+
if (strlen(name) > NAME_LENGTH - 1)
1495+
{
1496+
Warning(LOCATION, "Waypoint list name '%s' must be at most %d characters!", name, NAME_LENGTH - 1);
1497+
return ade_set_error(L, "o", l_WaypointList.Set(waypointlist_h()));
1498+
}
1499+
strcpy_s(buf, name);
1500+
}
1501+
// ...or a generated name
1502+
else
1503+
{
1504+
waypoint_find_unique_name(buf, static_cast<int>(Waypoint_lists.size()) + 1);
1505+
}
1506+
1507+
// add new list with that name
1508+
Waypoint_lists.emplace_back(buf);
1509+
return ade_set_args(L, "o", l_WaypointList.Set(waypointlist_h(static_cast<int>(Waypoint_lists.size()) - 1)));
1510+
}
1511+
14751512
ADE_FUNC(createWaypoint, l_Mission, "[vector Position, waypointlist List]",
1476-
"Creates a waypoint",
1513+
"Creates a waypoint. If Position is not specified, the waypoint will be at (0,0,0). If List is not specified, a new list will be created and the waypoint will be added to it.",
14771514
"waypoint",
14781515
"Waypoint handle, or invalid waypoint handle if waypoint couldn't be created")
14791516
{
1480-
vec3d *v3 = NULL;
1481-
waypointlist_h *wlh = NULL;
1517+
vec3d *v3 = nullptr;
1518+
waypointlist_h *wlh = nullptr;
14821519
if(!ade_get_args(L, "|oo", l_Vector.GetPtr(&v3), l_WaypointList.GetPtr(&wlh)))
14831520
return ade_set_error(L, "o", l_Waypoint.Set(object_h()));
14841521

1485-
// determine where we need to create it - it looks like we were given a waypoint list but not a waypoint itself
1522+
// determine where we need to create it - if we were given a waypoint list, put it at the end
1523+
// (unless the list is empty, in which case put it at the beginning)
14861524
int waypoint_instance = -1;
1525+
bool first_waypoint_in_list = false;
14871526
if (wlh && wlh->isValid())
14881527
{
1489-
int wp_list_index = find_index_of_waypoint_list(wlh->getList());
1490-
int wp_index = static_cast<int>(wlh->getList()->get_waypoints().size()) - 1;
1528+
int wp_list_index = wlh->wl_index;
1529+
int wp_index;
1530+
if (wlh->getList()->get_waypoints().empty())
1531+
{
1532+
wp_index = 0;
1533+
first_waypoint_in_list = true;
1534+
}
1535+
else
1536+
wp_index = static_cast<int>(wlh->getList()->get_waypoints().size()) - 1;
14911537
waypoint_instance = calc_waypoint_instance(wp_list_index, wp_index);
14921538
}
1493-
int obj_idx = waypoint_add(v3 != NULL ? v3 : &vmd_zero_vector, waypoint_instance);
1539+
int obj_idx = waypoint_add(v3 != nullptr ? v3 : &vmd_zero_vector, waypoint_instance, first_waypoint_in_list);
14941540

14951541
if(obj_idx >= 0)
1496-
return ade_set_args(L, "o", l_Waypoint.Set(object_h(&Objects[obj_idx])));
1542+
return ade_set_args(L, "o", l_Waypoint.Set(object_h(obj_idx)));
14971543
else
14981544
return ade_set_args(L, "o", l_Waypoint.Set(object_h()));
14991545
}

0 commit comments

Comments
 (0)