mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-12 19:06:09 -10:00
* Fix isWeaponAllowedOnShip bank lookup for secondary banks isWeaponAllowedOnShip numbers banks per ship class, with the secondaries right after the primaries, but the bank restriction lists keep secondary bank n at MAX_SHIP_PRIMARY_BANKS + n. On a ship with fewer than three primary banks, the secondary banks were checked against the wrong list. Map the bank before the lookup. The restriction lists are only allocated for ship classes that have $Allowed PBanks/SBanks, so both this function and the loadout weapon setter read past the end of an empty vector for any other class. Skip the bank check when there are no lists. The loadout weapon setter also treated a primary slot the ship does not have (bank 3 on a two-primary ship) as a secondary bank. Fixes #7985 * Cover more bank layouts and the loadout setter in the shipclass tests Add classes with one and three primary banks, a restricted primary bank, the bank-omitted case, and tests for the loadout weapon setter's bank range and restriction checks. * Fall back to the class weapon list in loadout bank checks The weapon loadout's slot and pool moves read a ship class's per-bank restriction lists without checking they exist. Those lists are only allocated for classes with $Allowed PBanks/SBanks, so a move request for any other class (from a script through sendWeaponRequestPacket, or a multiplayer client) read past the end of an empty vector and crashed. When a class has no per-bank lists, check the weapon against the class-wide allowed weapons instead. Classes with lists behave as before. * Simplify the loadout bank checks and tidy the loadout setter wl_bank_allows_weapon already allows a bank with no restriction, so the four loadout checks call it directly. The comment now says what the empty case means: a class without bank lists allows no weapons. The Loadout_Weapon setter rejects a weapon index one past the end, and only resets the amount when it actually stored the weapon. * Check the class weapon list in the loadout bank check A bank without its own list accepted any weapon of the right type, so a move request from a script or a multiplayer client could load a weapon the ship class can't carry. Check the class-wide list first, as the rearm code does. An empty slot coming back from a swap has nothing to check, which also stops it adding a -1 entry to the weapon pool. --------- Co-authored-by: Dustinspace217 <[email protected]>
507 lines
15 KiB
C++
507 lines
15 KiB
C++
#include "shipwepselect.h"
|
|
#include "ship/ship.h"
|
|
#include "weapon/weapon.h"
|
|
#include "missionui/missionweaponchoice.h"
|
|
#include "network/multiteamselect.h"
|
|
|
|
namespace scripting {
|
|
namespace api {
|
|
|
|
ss_wing_info_h::ss_wing_info_h() : ss_wing(-1) {}
|
|
ss_wing_info_h::ss_wing_info_h(int l_wing) : ss_wing(l_wing) {}
|
|
bool ss_wing_info_h::isValid() const
|
|
{
|
|
return ss_wing >= 0;
|
|
}
|
|
ss_wing_info* ss_wing_info_h::getWing() const
|
|
{
|
|
return &Ss_wings[ss_wing];
|
|
}
|
|
|
|
int ss_wing_info_h::getWingIndex() const
|
|
{
|
|
return ss_wing;
|
|
}
|
|
|
|
ss_slot_info_h::ss_slot_info_h() {}
|
|
ss_slot_info_h::ss_slot_info_h(ss_slot_info* l_slots, int l_idx, int l_wing) : ss_slots(l_slots), ss_idx(l_idx), ss_wing(l_wing) {}
|
|
bool ss_slot_info_h::isValid() const
|
|
{
|
|
return ss_slots != nullptr;
|
|
}
|
|
ss_slot_info* ss_slot_info_h::getSlot() const
|
|
{
|
|
return &ss_slots[ss_idx];
|
|
}
|
|
|
|
int ss_slot_info_h::getSlotIndex() const
|
|
{
|
|
return ss_idx;
|
|
}
|
|
|
|
int ss_slot_info_h::getWingIndex() const
|
|
{
|
|
return ss_wing;
|
|
}
|
|
|
|
wss_unit_wep_h::wss_unit_wep_h() : ss_unit(-1) {}
|
|
wss_unit_wep_h::wss_unit_wep_h(int l_unit) : ss_unit(l_unit) {}
|
|
bool wss_unit_wep_h::isValid() const
|
|
{
|
|
return ss_unit >= 0;
|
|
// return ((ss_unit >= 0) && ((ss_bank >= 0) && (ss_bank <= 6)));
|
|
}
|
|
wss_unit* wss_unit_wep_h::getBank() const
|
|
{
|
|
return &Wss_slots[ss_unit];
|
|
}
|
|
|
|
wss_unit_count_h::wss_unit_count_h() : ss_unit(-1) {}
|
|
wss_unit_count_h::wss_unit_count_h(int l_unit) : ss_unit(l_unit) {}
|
|
bool wss_unit_count_h::isValid() const
|
|
{
|
|
return ss_unit >= 0;
|
|
// return ((ss_unit >= 0) && ((ss_bank >= 0) && (ss_bank <= 6)));
|
|
}
|
|
wss_unit* wss_unit_count_h::getBank() const
|
|
{
|
|
return &Wss_slots[ss_unit];
|
|
}
|
|
|
|
//**********HANDLE: loadout wing
|
|
ADE_OBJ(l_Loadout_Wing_Slot, ss_slot_info_h, "loadout_wing_slot", "Loadout wing slot handle");
|
|
|
|
ADE_VIRTVAR(isShipLocked, l_Loadout_Wing_Slot, nullptr, "If the slot's ship is locked", "boolean", "The slot ship status")
|
|
{
|
|
ss_slot_info_h current;
|
|
if (!ade_get_args(L, "o", l_Loadout_Wing_Slot.Get(¤t))) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "b", (current.getSlot()->status & WING_SLOT_SHIPS_DISABLED) != 0);
|
|
}
|
|
|
|
ADE_VIRTVAR(isWeaponLocked,
|
|
l_Loadout_Wing_Slot,
|
|
nullptr,
|
|
"If the slot's weapons are locked",
|
|
"boolean",
|
|
"The slot weapon status")
|
|
{
|
|
ss_slot_info_h current;
|
|
if (!ade_get_args(L, "o", l_Loadout_Wing_Slot.Get(¤t))) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "b", (current.getSlot()->status & WING_SLOT_WEAPONS_DISABLED) != 0);
|
|
}
|
|
|
|
ADE_VIRTVAR(isDisabled, l_Loadout_Wing_Slot, nullptr, "If the slot is not used in the current mission or disabled for the current player in multi", "boolean", "The slot disabled status")
|
|
{
|
|
ss_slot_info_h current;
|
|
if (!ade_get_args(L, "o", l_Loadout_Wing_Slot.Get(¤t))) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
bool result = !current.getSlot()->in_mission;
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
int index = (current.getWingIndex() * MAX_WING_SLOTS) + current.getSlotIndex();
|
|
result = multi_ts_disabled_slot(index);
|
|
}
|
|
|
|
return ade_set_args(L, "b", result);
|
|
}
|
|
|
|
ADE_VIRTVAR(isFilled, l_Loadout_Wing_Slot, "boolean", "If the slot is empty or filled. true if filled, false if empty", "boolean", "The slot filled status")
|
|
{
|
|
ss_slot_info_h current;
|
|
bool setv;
|
|
if (!ade_get_args(L, "o|b", l_Loadout_Wing_Slot.Get(¤t), &setv)) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
LuaError(L, "This property may not be modified in multiplayer.");
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
if (!(current.getSlot()->status & WING_SLOT_DISABLED)) {
|
|
if (setv) {
|
|
current.getSlot()->status &= ~WING_SLOT_EMPTY;
|
|
current.getSlot()->status |= WING_SLOT_FILLED;
|
|
} else {
|
|
current.getSlot()->status &= ~WING_SLOT_FILLED;
|
|
current.getSlot()->status |= WING_SLOT_EMPTY;
|
|
}
|
|
} else {
|
|
LuaError(L, "You cannot empty a slot that is ship or weapon locked!");
|
|
}
|
|
}
|
|
|
|
return ade_set_args(L, "b", (current.getSlot()->status & WING_SLOT_EMPTY) == 0);
|
|
}
|
|
|
|
ADE_VIRTVAR(isPlayer, l_Loadout_Wing_Slot, nullptr, "If the slot is a player ship", "boolean", "The slot player status")
|
|
{
|
|
ss_slot_info_h current;
|
|
if (!ade_get_args(L, "o", l_Loadout_Wing_Slot.Get(¤t))) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
bool result = (current.getSlot()->status & WING_SLOT_IS_PLAYER) != 0;
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
int index = (current.getWingIndex() * MAX_WING_SLOTS) + current.getSlotIndex();
|
|
result = multi_ts_is_player_in_slot(index);
|
|
}
|
|
|
|
return ade_set_args(L, "b", result);
|
|
}
|
|
|
|
ADE_VIRTVAR(isPlayerAllowed, l_Loadout_Wing_Slot, nullptr, "If the slot is allowed to have player ship. In single player this is functionally the same as isPlayer.", "boolean", "The slot player allowed status")
|
|
{
|
|
ss_slot_info_h current;
|
|
if (!ade_get_args(L, "o", l_Loadout_Wing_Slot.Get(¤t))) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
bool result = (current.getSlot()->status & WING_SLOT_IS_PLAYER) != 0;
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
int index = (current.getWingIndex() * MAX_WING_SLOTS) + current.getSlotIndex();
|
|
result = multi_ts_is_player_allowed_in_slot(index);
|
|
}
|
|
|
|
return ade_set_args(L, "b", result);
|
|
}
|
|
|
|
// Probably don't need this one!
|
|
ADE_VIRTVAR(ShipClassIndex,
|
|
l_Loadout_Wing_Slot,
|
|
nullptr,
|
|
"The index of the ship class assigned to the slot",
|
|
"number",
|
|
"The ship class index")
|
|
{
|
|
ss_slot_info_h current;
|
|
if (!ade_get_args(L, "o", l_Loadout_Wing_Slot.Get(¤t))) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "i", (current.getSlot()->original_ship_class + 1));
|
|
}
|
|
|
|
ADE_VIRTVAR(Callsign,
|
|
l_Loadout_Wing_Slot,
|
|
nullptr,
|
|
"The callsign of the ship slot. In multiplayer this may be the player's callsign.",
|
|
"string",
|
|
"the callsign")
|
|
{
|
|
ss_slot_info_h current;
|
|
if (!ade_get_args(L, "o", l_Loadout_Wing_Slot.Get(¤t))) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
char name[NAME_LENGTH];
|
|
ss_return_name(current.getWingIndex(), current.getSlotIndex(), name);
|
|
|
|
return ade_set_args(L, "s", name);
|
|
}
|
|
|
|
//**********HANDLE: loadout amount
|
|
ADE_OBJ(l_Loadout_Amount, wss_unit_count_h, "loadout_amount", "Loadout handle");
|
|
|
|
ADE_INDEXER(l_Loadout_Amount,
|
|
"number bank, number amount",
|
|
"Array of ship bank weapons. 1-3 are Primary weapons. 4-7 are Secondary weapons. Note that banks "
|
|
"that do not exist on the ship class are still valid here as a loadout slot. Also note that "
|
|
"primary banks will hold the value of 1 even if it is ballistic. If the amount to set is greater than "
|
|
"the bank's capacity then it will be set to capacity. Set to -1 to empty the slot. Amounts less than -1 will be set to -1.",
|
|
"number",
|
|
"Amount of the currently loaded weapon, -1 if bank has no weapon, or nil if the ship or index is invalid")
|
|
{
|
|
wss_unit_count_h current;
|
|
int idx = -1;
|
|
int amount;
|
|
if (!ade_get_args(L, "oi|i", l_Loadout_Amount.Get(¤t), &idx, &amount))
|
|
return ADE_RETURN_NIL;
|
|
|
|
if (idx < 1 || idx > MAX_SHIP_WEAPONS) {
|
|
return ADE_RETURN_NIL;
|
|
};
|
|
|
|
idx--; // Convert from Lua
|
|
if (ADE_SETTING_VAR) {
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
LuaError(L, "This property may not be modified in multiplayer.");
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
ship_info* sip = &Ship_info[current.getBank()->ship_class];
|
|
int widx = current.getBank()->wep[idx];
|
|
if (widx >= 0 && widx < (int)Weapon_info.size()) {
|
|
weapon_info* wip = &Weapon_info[widx];
|
|
int capacity = 0;
|
|
// Calculate max capacity of the weapon in the current bank
|
|
if (wip->subtype == WP_LASER) {
|
|
capacity = 1;
|
|
} else {
|
|
capacity = wl_calc_missile_fit(widx, sip->secondary_bank_ammo_capacity[idx - MAX_SHIP_PRIMARY_BANKS]);
|
|
}
|
|
if (amount > capacity) {
|
|
amount = capacity;
|
|
}
|
|
if (amount < -1) {
|
|
amount = -1;
|
|
}
|
|
} else {
|
|
Warning(LOCATION, "Could not set amount for loadout weapon slot %i because the loaded weapon is invalid!", idx);
|
|
amount = -1;
|
|
}
|
|
current.getBank()->wep_count[idx] = amount;
|
|
}
|
|
|
|
return ade_set_args(L, "i", current.getBank()->wep_count[idx]);
|
|
}
|
|
|
|
ADE_FUNC(__len, l_Loadout_Amount, nullptr, "The number of weapon banks in the slot", "number", "The number of banks.")
|
|
{
|
|
return ade_set_args(L, "i", MAX_SHIP_WEAPONS);
|
|
}
|
|
|
|
//**********HANDLE: loadout weapon
|
|
ADE_OBJ(l_Loadout_Weapon, wss_unit_wep_h, "loadout_weapon", "Loadout handle");
|
|
|
|
ADE_INDEXER(l_Loadout_Weapon,
|
|
"number bank, number WeaponIndex",
|
|
"Array of ship bank weapons. 1-3 are Primary weapons. 4-7 are Secondary weapons. Note that banks "
|
|
"that do not exist on the ship class are still valid here as a loadout slot. When setting the weapon "
|
|
"it will be checked if it is valid for the ship and bank. If it is not then it will be set to -1 and the "
|
|
"amount will be set to -1. If it is valid for the ship then the amount is set to 0. Use .Amounts to set "
|
|
"the amount afterwards. Set to -1 to empty the slot.",
|
|
"number",
|
|
"index into Weapon Classes, 0 if bank is empty, -1 if the ship cannot carry the weapon, or nil if the ship or index is invalid")
|
|
{
|
|
wss_unit_wep_h current;
|
|
int bank = -1;
|
|
int wepIndex;
|
|
if (!ade_get_args(L, "oi|i", l_Loadout_Weapon.Get(¤t), &bank, &wepIndex))
|
|
return ADE_RETURN_NIL;
|
|
|
|
if (bank < 1 || bank > MAX_SHIP_WEAPONS) {
|
|
return ADE_RETURN_NIL;
|
|
};
|
|
|
|
ship_info* sip = &Ship_info[current.getBank()->ship_class];
|
|
int bankType = -1;
|
|
// Decide if we're setting a valid primary or secondary bank on the current ship class
|
|
if (bank <= sip->num_primary_banks) {
|
|
bankType = WP_LASER;
|
|
} else if (bank > MAX_SHIP_PRIMARY_BANKS && bank <= (sip->num_secondary_banks + MAX_SHIP_PRIMARY_BANKS)) {
|
|
bankType = WP_MISSILE;
|
|
}
|
|
|
|
wepIndex--; // Convert from Lua
|
|
bank--; //Convert from Lua
|
|
if (ADE_SETTING_VAR) {
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
LuaError(L, "This property may not be modified in multiplayer.");
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
if (bankType == -1 || wepIndex >= weapon_info_size()) {
|
|
LuaError(L, "The provided bank or weapon index is invalid!");
|
|
} else {
|
|
bool valid = false;
|
|
//First we check that this is a valid bank for the ship and that the script is not trying to empty the bank
|
|
if (wepIndex > -1) {
|
|
// Next we check that this is a weapon the ship can carry
|
|
if (!sip->restricted_loadout_flag.empty() &&
|
|
eval_weapon_flag_for_game_type(sip->restricted_loadout_flag[bank])) {
|
|
if (eval_weapon_flag_for_game_type(sip->allowed_bank_restricted_weapons[bank][wepIndex])) {
|
|
valid = true;
|
|
}
|
|
} else {
|
|
if (eval_weapon_flag_for_game_type(sip->allowed_weapons[wepIndex])) {
|
|
valid = true;
|
|
}
|
|
}
|
|
}
|
|
if (valid) {
|
|
//Now we double check that we're putting a primary in a primary slot or secondary in a secondary slot
|
|
weapon_info* wip = &Weapon_info[wepIndex];
|
|
if (wip->subtype == bankType) {
|
|
current.getBank()->wep[bank] = wepIndex;
|
|
current.getBank()->wep_count[bank] = 0;
|
|
} else {
|
|
LuaError(L, "Cannot put a primary in a secondary bank or a secondary in a primary bank!");
|
|
}
|
|
}
|
|
else {
|
|
//If the ship cannot carry this weapon in this bank then we set it to -1 and the amount to -1
|
|
current.getBank()->wep[bank] = -1;
|
|
current.getBank()->wep_count[bank] = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ade_set_args(L, "i", current.getBank()->wep[bank] + 1);
|
|
}
|
|
|
|
ADE_FUNC(__len, l_Loadout_Weapon, nullptr, "The number of weapon banks in the slot", "number", "The number of banks.")
|
|
{
|
|
return ade_set_args(L, "i", MAX_SHIP_WEAPONS);
|
|
}
|
|
|
|
//**********HANDLE: loadout ship
|
|
ADE_OBJ_NO_MULTI(l_Loadout_Ship, int, "loadout_ship", "Loadout handle");
|
|
ADE_OBJ_VALIDATOR_RANGE(l_Loadout_Ship, MAX_WSS_SLOTS);
|
|
|
|
ADE_VIRTVAR(ShipClassIndex,
|
|
l_Loadout_Ship,
|
|
"number",
|
|
"The index of the Ship Class. When setting the ship class this will also set the weapons to empty slots. Use "
|
|
".Weapons and .Amounts to set those afterwards. Set to -1 to empty the slot and be sure to set the slot to empty "
|
|
"using Loadout_Wings[slot].isFilled.",
|
|
"number",
|
|
"The index or nil if handle is invalid")
|
|
{
|
|
int current;
|
|
int shipIndex;
|
|
if (!ade_get_args(L, "o|i", l_Loadout_Ship.Get(¤t), &shipIndex)) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
shipIndex--; //Convert from Lua
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
if (Game_mode & GM_MULTIPLAYER) {
|
|
LuaError(L, "This property may not be modified in multiplayer.");
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
if (shipIndex > -1) {
|
|
// If we're not trying to empty the slot then make sure it's a valid ship index
|
|
if (shipIndex > ship_info_size()) {
|
|
LuaError(L, "The provided ship index is invalid!");
|
|
} else {
|
|
Wss_slots[current].ship_class = shipIndex;
|
|
//Reset all currently loaded weapons here
|
|
for (int i = 0; i < MAX_SHIP_WEAPONS; i++) {
|
|
Wss_slots[current].wep[i] = -1;
|
|
Wss_slots[current].wep_count[i] = -1;
|
|
}
|
|
}
|
|
} else {
|
|
Wss_slots[current].ship_class = -1;
|
|
}
|
|
}
|
|
|
|
return ade_set_args(L, "i", (Wss_slots[current].ship_class + 1));
|
|
}
|
|
|
|
ADE_VIRTVAR(Weapons,
|
|
l_Loadout_Ship,
|
|
nullptr,
|
|
"Array of weapons in the loadout slot",
|
|
"loadout_weapon",
|
|
"The weapons array or nil if handle is invalid")
|
|
{
|
|
int current;
|
|
if (!ade_get_args(L, "o", l_Loadout_Ship.Get(¤t))) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "o", l_Loadout_Weapon.Set(wss_unit_wep_h(current)));
|
|
}
|
|
|
|
ADE_VIRTVAR(Amounts,
|
|
l_Loadout_Ship,
|
|
nullptr,
|
|
"Array of weapon amounts in the loadout slot",
|
|
"loadout_amount",
|
|
"The weapon amounts array or nil if handle is invalid")
|
|
{
|
|
int current;
|
|
if (!ade_get_args(L, "o", l_Loadout_Ship.Get(¤t))) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
return ade_set_args(L, "o", l_Loadout_Amount.Set(wss_unit_count_h(current)));
|
|
}
|
|
|
|
//**********HANDLE: loadout wing
|
|
ADE_OBJ(l_Loadout_Wing, ss_wing_info_h, "loadout_wing", "Loadout handle");
|
|
|
|
ADE_INDEXER(l_Loadout_Wing,
|
|
"number idx",
|
|
"Array of loadout wing slot data",
|
|
"loadout_wing_slot",
|
|
"loadout slot handle, or invalid handle if index is invalid")
|
|
{
|
|
ss_wing_info_h current;
|
|
int idx;
|
|
if (!ade_get_args(L, "oi", l_Loadout_Wing.Get(¤t), &idx))
|
|
return ade_set_error(L, "s", "");
|
|
idx--; // Convert to Lua's 1 based index system
|
|
return ade_set_args(L, "o", l_Loadout_Wing_Slot.Set(ss_slot_info_h(current.getWing()->ss_slots, idx, current.getWingIndex())));
|
|
}
|
|
|
|
//This seems superfluous because the loadout wing slots is always max but not only is it something scripters may expect,
|
|
//but also if max wings is ever expanded this will automatically reflect that
|
|
ADE_FUNC(__len, l_Loadout_Wing, nullptr, "The number of slots in the wing", "number", "The number of slots.")
|
|
{
|
|
return ade_set_args(L, "i", MAX_WING_SLOTS);
|
|
}
|
|
|
|
ADE_VIRTVAR(Name, l_Loadout_Wing, nullptr, "The name of the wing", "string", "The wing")
|
|
{
|
|
ss_wing_info_h current;
|
|
if (!ade_get_args(L, "o", l_Loadout_Wing.Get(¤t))) {
|
|
return ADE_RETURN_NIL;
|
|
}
|
|
|
|
if (ADE_SETTING_VAR) {
|
|
LuaError(L, "This property is read only.");
|
|
}
|
|
|
|
wing* wp;
|
|
wp = &Wings[current.getWing()->wingnum];
|
|
|
|
return ade_set_args(L, "s", wp->name);
|
|
}
|
|
|
|
} // namespace api
|
|
} // namespace scripting
|