Skip to content

Commit 2e6b38e

Browse files
authored
Merge pull request #7204 from Goober5000/asteroid_debris_iterators
add getAsteroidList and getDebrisList script API iterators
2 parents b341e85 + 73dd6c0 commit 2e6b38e

1 file changed

Lines changed: 68 additions & 8 deletions

File tree

code/scripting/api/libs/mission.cpp

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ ADE_INDEXER(l_Mission_Debris, "number Index", "Array of debris in the current mi
294294
if( idx >= 0 && idx < (int)Debris.size() ) {
295295
if (Debris[idx].objnum == -1) //Somehow accessed an invalid debris piece
296296
return ade_set_error(L, "o", l_Debris.Set(object_h()));
297-
return ade_set_args(L, "o", l_Debris.Set(object_h(&Objects[Debris[idx].objnum])));
297+
return ade_set_args(L, "o", l_Debris.Set(object_h(Debris[idx].objnum)));
298298
}
299299

300300
return ade_set_error(L, "o", l_Debris.Set(object_h()));
@@ -329,7 +329,7 @@ ADE_INDEXER(l_Mission_EscortShips, "number Index", "Gets escort ship at specifie
329329
if(idx < 0)
330330
return ade_set_error(L, "o", l_Ship.Set(object_h()));
331331

332-
return ade_set_args(L, "o", l_Ship.Set(object_h(&Objects[idx])));
332+
return ade_set_args(L, "o", l_Ship.Set(object_h(idx)));
333333
}
334334

335335
ADE_FUNC(__len, l_Mission_EscortShips, NULL, "Current number of escort ships", "number", "Current number of escort ships")
@@ -1334,7 +1334,7 @@ ADE_FUNC(createShip,
13341334
));
13351335
}
13361336

1337-
return ade_set_args(L, "o", l_Ship.Set(object_h(&Objects[obj_idx])));
1337+
return ade_set_args(L, "o", l_Ship.Set(object_h(obj_idx)));
13381338
} else
13391339
return ade_set_error(L, "o", l_Ship.Set(object_h()));
13401340
}
@@ -1571,7 +1571,7 @@ ADE_FUNC(createWeapon,
15711571
int obj_idx = weapon_create(&pos, real_orient, wclass, parent_idx, group);
15721572

15731573
if(obj_idx > -1)
1574-
return ade_set_args(L, "o", l_Weapon.Set(object_h(&Objects[obj_idx])));
1574+
return ade_set_args(L, "o", l_Weapon.Set(object_h(obj_idx)));
15751575
else
15761576
return ade_set_error(L, "o", l_Weapon.Set(object_h()));
15771577
}
@@ -1647,7 +1647,7 @@ ADE_FUNC(createWarpeffect,
16471647
int obj_idx = fireball_create(&pos, fireballclass, FIREBALL_WARP_EFFECT, -1, radius, false, &velocity, duration, -1, &m_orient, 0, flags, opensound->idx, closesound->idx, opentime, closetime);
16481648

16491649
if (obj_idx > -1)
1650-
return ade_set_args(L, "o", l_Fireball.Set(object_h(&Objects[obj_idx])));
1650+
return ade_set_args(L, "o", l_Fireball.Set(object_h(obj_idx)));
16511651
else
16521652
return ade_set_error(L, "o", l_Fireball.Set(object_h()));
16531653
}
@@ -1679,7 +1679,7 @@ ADE_FUNC(createExplosion,
16791679
int obj_idx = fireball_create(&pos, fireballclass, type, parent_idx, radius, false, &velocity);
16801680

16811681
if (obj_idx > -1)
1682-
return ade_set_args(L, "o", l_Fireball.Set(object_h(&Objects[obj_idx])));
1682+
return ade_set_args(L, "o", l_Fireball.Set(object_h(obj_idx)));
16831683
else
16841684
return ade_set_error(L, "o", l_Fireball.Set(object_h()));
16851685
}
@@ -2908,7 +2908,7 @@ ADE_FUNC(getShipList,
29082908
return luacpp::LuaValueList{ luacpp::LuaValue::createNil(LInner) };
29092909
}
29102910

2911-
return luacpp::LuaValueList{ luacpp::LuaValue::createValue(LInner, l_Ship.Set(object_h(&Objects[so->objnum]))) };
2911+
return luacpp::LuaValueList{ luacpp::LuaValue::createValue(LInner, l_Ship.Set(object_h(so->objnum))) };
29122912
}));
29132913
}
29142914

@@ -2940,7 +2940,67 @@ ADE_FUNC(getMissileList,
29402940
return luacpp::LuaValueList{ luacpp::LuaValue::createNil(LInner) };
29412941
}
29422942

2943-
return luacpp::LuaValueList{ luacpp::LuaValue::createValue(LInner, l_Weapon.Set(object_h(&Objects[mo->objnum]))) };
2943+
return luacpp::LuaValueList{ luacpp::LuaValue::createValue(LInner, l_Weapon.Set(object_h(mo->objnum))) };
2944+
}));
2945+
}
2946+
2947+
ADE_FUNC(getAsteroidList,
2948+
l_Mission,
2949+
nullptr,
2950+
"Get an iterator to the list of asteroids in this mission",
2951+
"iterator<asteroid>",
2952+
"An iterator across all asteroids in the mission. Can be used in a for .. in loop. Is not valid for more than one frame.")
2953+
{
2954+
asteroid_obj* ao = &Asteroid_obj_list;
2955+
2956+
return ade_set_args(L, "u", luacpp::LuaFunction::createFromStdFunction(L, [ao](lua_State* LInner, const luacpp::LuaValueList& /*params*/) mutable -> luacpp::LuaValueList {
2957+
//Since the first element of a list is the next element from the head, and we start this function with the the captured "ao" object being the head, this GET_NEXT will return the first element on first call of this lambda.
2958+
//Similarly, an empty list is defined by the head's next element being itself, hence an empty list will immediately return nil just fine
2959+
ao = GET_NEXT(ao);
2960+
2961+
// skip should-be-dead asteroids
2962+
if (ao != nullptr) {
2963+
while (ao != END_OF_LIST(&Asteroid_obj_list)) {
2964+
if (!Objects[ao->objnum].flags[Object::Object_Flags::Should_be_dead]) {
2965+
break;
2966+
}
2967+
ao = GET_NEXT(ao);
2968+
}
2969+
}
2970+
2971+
if (ao == END_OF_LIST(&Asteroid_obj_list) || ao == nullptr) {
2972+
return luacpp::LuaValueList{ luacpp::LuaValue::createNil(LInner) };
2973+
}
2974+
2975+
return luacpp::LuaValueList{ luacpp::LuaValue::createValue(LInner, l_Asteroid.Set(object_h(ao->objnum))) };
2976+
}));
2977+
}
2978+
2979+
ADE_FUNC(getDebrisList,
2980+
l_Mission,
2981+
nullptr,
2982+
"Get an iterator to the list of debris in this mission",
2983+
"iterator<debris>",
2984+
"An iterator across all debris in the mission. Can be used in a for .. in loop. Is not valid for more than one frame.")
2985+
{
2986+
size_t idx = 0;
2987+
2988+
return ade_set_args(L, "u", luacpp::LuaFunction::createFromStdFunction(L, [idx](lua_State* LInner, const luacpp::LuaValueList& /*params*/) mutable -> luacpp::LuaValueList {
2989+
// iterate through the Debris vector to find the next valid debris piece
2990+
while (idx < Debris.size()) {
2991+
const debris& db = Debris[idx];
2992+
idx++;
2993+
2994+
// debris must be Used, must have a valid objnum, and must not be should-be-dead
2995+
if (db.flags[Debris_Flags::Used] && db.objnum != -1) {
2996+
if (!Objects[db.objnum].flags[Object::Object_Flags::Should_be_dead]) {
2997+
return luacpp::LuaValueList{ luacpp::LuaValue::createValue(LInner, l_Debris.Set(object_h(db.objnum))) };
2998+
}
2999+
}
3000+
}
3001+
3002+
// end of list or no more valid debris found
3003+
return luacpp::LuaValueList{ luacpp::LuaValue::createNil(LInner) };
29443004
}));
29453005
}
29463006

0 commit comments

Comments
 (0)