1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
|
#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 <= (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 (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;
} else {
LuaError(L, "Cannot put a primary in a secondary bank or a secondary in a primary bank!");
}
current.getBank()->wep_count[bank] = 0;
}
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_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
|