diff --git a/sources/Commands/ACommandDB.uc b/sources/Commands/ACommandDB.uc index b300717..dfd7687 100644 --- a/sources/Commands/ACommandDB.uc +++ b/sources/Commands/ACommandDB.uc @@ -54,7 +54,7 @@ class ACommandDB extends Command // Arrays should be kept same length, elements with the same index // correspond to the same pair. var protected array queueWaitingListDatabases; -var protected array queueWaitingListPlayers; +var protected array queueWaitingListPlayers; // Auxiliary structure that corresponds to database + JSON path from resolved // database link. @@ -141,16 +141,17 @@ protected function BuildData(CommandDataBuilder builder) @ "data to the old one, instead of rewriting it.")); } -protected function PushPlayer(APlayer nextPlayer, Database callDatabase) +protected function PushPlayer(EPlayer nextPlayer, Database callDatabase) { - queueWaitingListPlayers[queueWaitingListPlayers.length] = nextPlayer; + queueWaitingListPlayers[queueWaitingListPlayers.length] = + EPlayer(nextPlayer.Copy()); queueWaitingListDatabases[queueWaitingListDatabases.length] = callDatabase; } -protected function APlayer PopPlayer(Database relevantDatabase) +protected function EPlayer PopPlayer(Database relevantDatabase) { local int i; - local APlayer result; + local EPlayer result; if (queueWaitingListPlayers.length <= 0) return none; if (queueWaitingListDatabases.length <= 0) return none; @@ -165,36 +166,37 @@ protected function APlayer PopPlayer(Database relevantDatabase) } i += 1; } - if (result != none && result.IsConnected()) { + if (result != none && result.IsExistent()) { return result; } + _.memory.Free(result); return none; } -protected function Executed(CommandCall result) +protected function Executed(CallData result, EPlayer callerPlayer) { - local AcediaObject valueToWrite; - local DBPointerPair pair; - local Text subCommand; - subCommand = result.GetSubCommand(); + local AcediaObject valueToWrite; + local DBPointerPair pair; + local Text subCommand; + subCommand = result.subCommandName; // Try executing on of the operation that manage multiple databases - if (TryAPICallCommands(subCommand, result)) { + if (TryAPICallCommands(subCommand, callerPlayer, result.parameters)) { return; } // If we have failed - it has got to be one of the operations on // a single database - pair = TryLoadingDB(result.GetParameters().GetText(T(TDATABASE_LINK))); + pair = TryLoadingDB(result.parameters.GetText(T(TDATABASE_LINK))); if (pair.database == none) { - result.GetCallerPlayer().Console().WriteLine(T(TBAD_DBLINK)); + callerPlayer.BorrowConsole().WriteLine(T(TBAD_DBLINK)); return; } // Remember the last player we are making a query to and make that query - PushPlayer(result.GetCallerPlayer(), pair.database); + PushPlayer(callerPlayer, pair.database); if (subCommand.StartsWith(T(TWRITE))) { - valueToWrite = result.GetParameters().GetItem(T(TJSON_VALUE)); - if (result.GetOptions().HasKey(T(TINCREMENT))) + valueToWrite = result.parameters.GetItem(T(TJSON_VALUE)); + if (result.options.HasKey(T(TINCREMENT))) { pair.database.IncrementData(pair.pointer, valueToWrite) .connect = DisplayResponse; @@ -222,16 +224,13 @@ protected function Executed(CommandCall result) // Simple API calls private function bool TryAPICallCommands( - Text subCommand, - CommandCall result) + Text subCommand, + EPlayer callerPlayer, + AssociativeArray commandParameters) { - local APlayer callerPlayer; - local AssociativeArray commandParameters; - callerPlayer = result.GetCallerPlayer(); - commandParameters = result.GetParameters(); if (subCommand.IsEmpty()) { - callerPlayer.Console().WriteLine(T(TNO_DEFAULT_COMMAND)); + callerPlayer.BorrowConsole().WriteLine(T(TNO_DEFAULT_COMMAND)); return true; } else if (subCommand.Compare(T(TLIST))) @@ -269,38 +268,38 @@ private function DBPointerPair TryLoadingDB(Text databaseLink) return result; } -protected function CreateDatabase(APlayer callerPlayer, Text databaseName) +protected function CreateDatabase(EPlayer callerPlayer, Text databaseName) { if (callerPlayer == none) { return; } if (_.db.ExistsLocal(databaseName)) { - callerPlayer.Console().WriteLine(T(TDB_ALREADY_EXISTS)); + callerPlayer.BorrowConsole().WriteLine(T(TDB_ALREADY_EXISTS)); return; } if (_.db.NewLocal(databaseName) != none) { - callerPlayer.Console().WriteLine(T(TDB_CREATED)); + callerPlayer.BorrowConsole().WriteLine(T(TDB_CREATED)); } else { - callerPlayer.Console().WriteLine(T(TDB_CANNOT_BE_CREATED)); + callerPlayer.BorrowConsole().WriteLine(T(TDB_CANNOT_BE_CREATED)); } } -protected function DeleteDatabase(APlayer callerPlayer, Text databaseName) +protected function DeleteDatabase(EPlayer callerPlayer, Text databaseName) { if (callerPlayer == none) { return; } if (_.db.DeleteLocal(databaseName)) { - callerPlayer.Console().WriteLine(T(TDA_DELETED)); + callerPlayer.BorrowConsole().WriteLine(T(TDA_DELETED)); } else { - callerPlayer.Console().WriteLine(T(TDB_DOESNT_EXIST)); + callerPlayer.BorrowConsole().WriteLine(T(TDB_DOESNT_EXIST)); } } -protected function ListDatabases(APlayer callerPlayer) +protected function ListDatabases(EPlayer callerPlayer) { local int i; local array availableDatabases; @@ -309,7 +308,7 @@ protected function ListDatabases(APlayer callerPlayer) return; } availableDatabases = _.db.ListLocal(); - console = callerPlayer.Console(); + console = callerPlayer.BorrowConsole(); console.Write(T(TAVAILABLE_DATABASES)); for (i = 0; i < availableDatabases.length; i += 1) { @@ -323,23 +322,23 @@ protected function ListDatabases(APlayer callerPlayer) } protected function OutputStatus( - APlayer callerPlayer, + EPlayer callerPlayer, Database.DBQueryResult error) { if (callerPlayer == none) { return; } if (error == DBR_Success) { - callerPlayer.Console().WriteLine(T(TQUERY_COMPLETED)); + callerPlayer.BorrowConsole().WriteLine(T(TQUERY_COMPLETED)); } if (error == DBR_InvalidPointer) { - callerPlayer.Console().WriteLine(T(TQUERY_INVALID_POINTER)); + callerPlayer.BorrowConsole().WriteLine(T(TQUERY_INVALID_POINTER)); } if (error == DBR_InvalidDatabase) { - callerPlayer.Console().WriteLine(T(TQUERY_INVALID_DB)); + callerPlayer.BorrowConsole().WriteLine(T(TQUERY_INVALID_DB)); } if (error == DBR_InvalidData) { - callerPlayer.Console().WriteLine(T(TQUERY_INVALID_DATA)); + callerPlayer.BorrowConsole().WriteLine(T(TQUERY_INVALID_DATA)); } } @@ -349,15 +348,17 @@ protected function DisplayData( Database source) { local Text printedJSON; - local APlayer callerPlayer; + local EPlayer callerPlayer; local Collection dataAsCollection; callerPlayer = PopPlayer(source); OutputStatus(callerPlayer, result); if (callerPlayer != none && result == DBR_Success) { printedJSON = _.json.PrettyPrint(data); - callerPlayer.Console().Write(printedJSON).Flush(); + callerPlayer.BorrowConsole().Write(printedJSON).Flush(); _.memory.Free(printedJSON); + _.memory.Free(callerPlayer); + callerPlayer = none; } dataAsCollection = Collection(data); if (dataAsCollection != none) { @@ -372,17 +373,19 @@ protected function DisplaySize( Database source) { local Text sizeAsText; - local APlayer callerPlayer; + local EPlayer callerPlayer; callerPlayer = PopPlayer(source); OutputStatus(callerPlayer, result); if (callerPlayer != none && result == DBR_Success) { sizeAsText = _.text.FromInt(size); - callerPlayer.Console() + callerPlayer.BorrowConsole() .Write(T(TOBJECT_SIZE_IS)) .Write(sizeAsText) .Flush(); _.memory.Free(sizeAsText); + _.memory.Free(callerPlayer); + callerPlayer = none; } } @@ -392,7 +395,7 @@ protected function DisplayKeys( Database source) { local int i; - local APlayer callerPlayer; + local EPlayer callerPlayer; local ConsoleWriter console; callerPlayer = PopPlayer(source); OutputStatus(callerPlayer, result); @@ -401,7 +404,7 @@ protected function DisplayKeys( } if (callerPlayer != none && result == DBR_Success) { - console = callerPlayer.Console(); + console = callerPlayer.BorrowConsole(); console.Write(T(TOBJECT_KEYS_ARE)); for (i = 0; i < keys.GetLength(); i += 1) { @@ -411,6 +414,8 @@ protected function DisplayKeys( console.UseColor(_.color.jPropertyName).Write(keys.GetText(i)); } console.Flush(); + _.memory.Free(callerPlayer); + callerPlayer = none; } _.memory.Free(keys); } @@ -419,7 +424,10 @@ protected function DisplayResponse( Database.DBQueryResult result, Database source) { - OutputStatus(PopPlayer(source), result); + local EPlayer callerPlayer; + callerPlayer = PopPlayer(source); + OutputStatus(callerPlayer, result); + _.memory.Free(callerPlayer); } defaultproperties diff --git a/sources/Commands/ACommandDosh.uc b/sources/Commands/ACommandDosh.uc index 8c0fb8f..5317fd2 100644 --- a/sources/Commands/ACommandDosh.uc +++ b/sources/Commands/ACommandDosh.uc @@ -46,22 +46,23 @@ protected function BuildData(CommandDataBuilder builder) @ "by '{$TextEmphasis --min}' option.")); } -protected function ExecutedFor(APlayer player, CommandCall result) +protected function ExecutedFor( + EPlayer player, + CallData result, + EPlayer callerPlayer) { - local int oldAmount, newAmount; - local int amount, minValue, maxValue; - local AssociativeArray commandOptions; + local int oldAmount, newAmount; + local int amount, minValue, maxValue; // Find min and max value boundaries - commandOptions = result.GetOptions(); - minValue = commandOptions.GetIntBy(P("/min/minValue"), 0); - maxValue = commandOptions.GetIntBy(P("/max/maxValue"), MaxInt); + minValue = result.options.GetIntBy(P("/min/minValue"), 0); + maxValue = result.options.GetIntBy(P("/max/maxValue"), MaxInt); if (minValue > maxValue) { maxValue = minValue; } // Change dosh oldAmount = player.GetDosh(); - amount = result.GetParameters().GetInt(P("amount")); - if (result.GetSubCommand().IsEmpty()) { + amount = result.parameters.GetInt(P("amount")); + if (result.subCommandName.IsEmpty()) { newAmount = oldAmount + amount; } else { @@ -70,10 +71,10 @@ protected function ExecutedFor(APlayer player, CommandCall result) } newAmount = Clamp(newAmount, minValue, maxValue); // Announce dosh change, if necessary - if (!commandOptions.HasKey(P("silent"))) { - AnnounceDoshChange(player.Console(), oldAmount, newAmount); + if (!result.options.HasKey(P("silent"))) { + AnnounceDoshChange(player.BorrowConsole(), oldAmount, newAmount); } - player.SetDosh(newAmount); + player.SetDosh(newAmount); } protected function AnnounceDoshChange( diff --git a/sources/Commands/ACommandGive.uc b/sources/Commands/ACommandGive.uc index cf5912e..5b30cdc 100644 --- a/sources/Commands/ACommandGive.uc +++ b/sources/Commands/ACommandGive.uc @@ -39,24 +39,23 @@ protected function BuildData(CommandDataBuilder builder) .ParamBoolean(P("keep-items")); } -protected function ExecutedFor(APlayer player, CommandCall result) +protected function ExecutedFor( + EPlayer player, + CallData result, + EPlayer callerPlayer) { local int i; local bool doForce; local Text itemTemplate, itemName; local array addedItems, rejectedItems; - local APlayer callerPlayer; local EInventory inventory; local EItemTemplateInfo templateInfo; - local AssociativeArray options; local DynamicArray itemsToAdd; - callerPlayer = result.GetCallerPlayer(); inventory = player.GetInventory(); - itemsToAdd = result.GetParameters().GetDynamicArray(P("items")); - options = result.GetOptions(); - doForce = options.HasKey(P("force")); - if (options.HasKey(P("clear"))) { - inventory.RemoveAll(options.GetBoolBy(P("/clear/keep-items"))); + itemsToAdd = result.parameters.GetDynamicArray(P("items")); + doForce = result.options.HasKey(P("force")); + if (result.options.HasKey(P("clear"))) { + inventory.RemoveAll(result.options.GetBoolBy(P("/clear/keep-items"))); } for (i = 0; i < itemsToAdd.GetLength(); i += 1) { @@ -118,8 +117,8 @@ protected function bool GiveItemTo( } protected function ReportResultsToCaller( - APlayer caller, - APlayer target, + EPlayer caller, + EPlayer target, array addedItems, array rejectedItems) { @@ -129,7 +128,7 @@ protected function ReportResultsToCaller( if (addedItems.length <= 0 && rejectedItems.length <= 0) { return; } - console = caller.Console(); + console = caller.BorrowConsole(); targetName = target.GetName(); console.Write(F("{$TextEmphasis Giving} weapons to ")) .Write(targetName).Write(P(": ")); @@ -175,8 +174,8 @@ protected function ReportResultsToCaller( } protected function AnnounceGivingItems( - APlayer caller, - Aplayer target, + EPlayer caller, + EPlayer target, array addedItems) { local int i; diff --git a/sources/Commands/ACommandNick.uc b/sources/Commands/ACommandNick.uc index 7ddf8d4..7bcd31e 100644 --- a/sources/Commands/ACommandNick.uc +++ b/sources/Commands/ACommandNick.uc @@ -27,9 +27,12 @@ protected function BuildData(CommandDataBuilder builder) .Describe(P("Changes nickname of targeted players to .")); } -protected function ExecutedFor(APlayer player, CommandCall result) +protected function ExecutedFor( + EPlayer player, + CallData result, + EPlayer callerPlayer) { - player.SetName(result.GetParameters().GetText(P("nick"))); + player.SetName(result.parameters.GetText(P("nick"))); } defaultproperties diff --git a/sources/Commands/ACommandTrader.uc b/sources/Commands/ACommandTrader.uc index 2604dfb..e2c4ce2 100644 --- a/sources/Commands/ACommandTrader.uc +++ b/sources/Commands/ACommandTrader.uc @@ -90,57 +90,51 @@ protected function BuildData(CommandDataBuilder builder) @ "disable the trader and not boot players inside it.")); } -protected function Executed(CommandCall result) +protected function Executed(CallData result, EPlayer callerPlayer) { - local Text subCommand; - local AssociativeArray commandParameters, commandOptions; - subCommand = result.GetSubCommand(); - commandParameters = result.GetParameters(); - commandOptions = result.GetOptions(); - if (subCommand.IsEmpty()) { - _.kf.trading.SetTradingStatus(commandParameters.GetBool(T(TENABLE))); + if (result.subCommandName.IsEmpty()) { + _.kf.trading.SetTradingStatus(result.parameters.GetBool(T(TENABLE))); } - else if (subCommand.Compare(T(TLIST))) { - ListTradersFor(result.GetCallerPlayer()); + else if (result.subCommandName.Compare(T(TLIST))) { + ListTradersFor(callerPlayer); } - else if (subCommand.Compare(T(TTIME), SCASE_INSENSITIVE)) { - HandleTraderTime(result); + else if (result.subCommandName.Compare(T(TTIME), SCASE_INSENSITIVE)) { + HandleTraderTime(result, callerPlayer); } - else if (subCommand.Compare(T(TOPEN), SCASE_INSENSITIVE)) { - SetTradersOpen(true, result); + else if (result.subCommandName.Compare(T(TOPEN), SCASE_INSENSITIVE)) { + SetTradersOpen(true, result, callerPlayer); } - else if (subCommand.Compare(T(TCLOSE), SCASE_INSENSITIVE)) { - SetTradersOpen(false, result); + else if (result.subCommandName.Compare(T(TCLOSE), SCASE_INSENSITIVE)) { + SetTradersOpen(false, result, callerPlayer); } - else if (subCommand.Compare(T(TSELECT), SCASE_INSENSITIVE)) { - SelectTrader(result); + else if (result.subCommandName.Compare(T(TSELECT), SCASE_INSENSITIVE)) { + SelectTrader(result, callerPlayer); } - else if (subCommand.Compare(T(TBOOT), SCASE_INSENSITIVE)) { - BootFromTraders(result); + else if (result.subCommandName.Compare(T(TBOOT), SCASE_INSENSITIVE)) { + BootFromTraders(result, callerPlayer); } - else if (subCommand.Compare(T(TENABLE), SCASE_INSENSITIVE)) { - SetTradersEnabled(true, result); + else if (result.subCommandName.Compare(T(TENABLE), SCASE_INSENSITIVE)) { + SetTradersEnabled(true, result, callerPlayer); } - else if (subCommand.Compare(T(TDISABLE), SCASE_INSENSITIVE)) { - SetTradersEnabled(false, result); + else if (result.subCommandName.Compare(T(TDISABLE), SCASE_INSENSITIVE)) { + SetTradersEnabled(false, result, callerPlayer); } - else if (subCommand.Compare(T(TAUTO_OPEN), SCASE_INSENSITIVE)) { - SetTradersAutoOpen(result); + else if (result.subCommandName.Compare(T(TAUTO_OPEN), SCASE_INSENSITIVE)) { + SetTradersAutoOpen(result, callerPlayer); } - subCommand.FreeSelf(); } -protected function ListTradersFor(APlayer target) +protected function ListTradersFor(EPlayer target) { local int i; - local ATrader closestTrader; + local ETrader closestTrader; local ConsoleWriter console; - local array availableTraders; + local array availableTraders; if (target == none) { return; } availableTraders = _.kf.trading.GetTraders(); - console = target.Console(); + console = target.BorrowConsole(); console.Flush() .UseColor(_.color.TextEmphasis) .Write(T(TLIST_TRADERS)) @@ -148,22 +142,23 @@ protected function ListTradersFor(APlayer target) closestTrader = FindClosestTrader(target); for (i = 0; i < availableTraders.length; i += 1) { - WriteTrader(availableTraders[i], availableTraders[i] == closestTrader, - console); + WriteTrader(availableTraders[i], + availableTraders[i].SameAs(closestTrader), console); if (i != availableTraders.length - 1) { console.Write(T(TCOMMA_SPACE)); } } + _.memory.Free(closestTrader); + _.memory.FreeMany(availableTraders); console.Flush(); } -protected function HandleTraderTime(CommandCall result) +protected function HandleTraderTime(CallData result, EPlayer callerPlayer) { local int countDownValue; local Text parameter; local Parser parser; - local APlayer callerPlayer; - parameter = result.GetParameters().GetText(T(TTRADER_TIME)); + parameter = result.parameters.GetText(T(TTRADER_TIME)); if (parameter.Compare(T(TPAUSE), SCASE_INSENSITIVE)) { _.kf.trading.SetCountDownPause(true); @@ -180,10 +175,9 @@ protected function HandleTraderTime(CommandCall result) } else { - callerPlayer = result.GetCallerPlayer(); if (callerPlayer != none) { - callerPlayer.Console() + callerPlayer.BorrowConsole() .UseColor(_.color.TextFailure) .Write(T(TCANNOT_PARSE_PARAM)) .WriteLine(parameter) @@ -194,14 +188,17 @@ protected function HandleTraderTime(CommandCall result) } -protected function SetTradersOpen(bool doOpen, CommandCall result) +protected function SetTradersOpen( + bool doOpen, + CallData result, + EPlayer callerPlayer) { local int i; local bool needToBootPlayers; - local array selectedTraders; - selectedTraders = GetTradersArray(result); + local array selectedTraders; + selectedTraders = GetTradersArray(result, callerPlayer); needToBootPlayers = !doOpen - && !result.GetOptions().HasKey(T(TIGNORE_PLAYERS)); + && !result.options.HasKey(T(TIGNORE_PLAYERS)); for (i = 0; i < selectedTraders.length; i += 1) { selectedTraders[i].SetOpen(doOpen); @@ -209,23 +206,24 @@ protected function SetTradersOpen(bool doOpen, CommandCall result) selectedTraders[i].BootPlayers(); } } + _.memory.FreeMany(selectedTraders); } -protected function SelectTrader(CommandCall result) +protected function SelectTrader(CallData result, EPlayer callerPlayer) { local int i; - local APlayer callerPlayer; local ConsoleWriter console; local Text selectedTraderName, nextTraderName; - local ATrader previouslySelectedTrader; - local array availableTraders; - selectedTraderName = result.GetParameters().GetText(T(TTRADER)); + local ETrader previouslySelectedTrader; + local array availableTraders; + selectedTraderName = result.parameters.GetText(T(TTRADER)); previouslySelectedTrader = _.kf.trading.GetSelectedTrader(); // Corner case: no new trader if (selectedTraderName == none) { _.kf.trading.SelectTrader(none); - HandleTraderSwap(result, none, availableTraders[i]); + HandleTraderSwap(result, previouslySelectedTrader, none); + _.memory.Free(previouslySelectedTrader); return; } // Find new trader among available ones @@ -239,14 +237,15 @@ protected function SelectTrader(CommandCall result) HandleTraderSwap( result, previouslySelectedTrader, availableTraders[i]); nextTraderName.FreeSelf(); + _.memory.Free(previouslySelectedTrader); + _.memory.FreeMany(availableTraders); return; } nextTraderName.FreeSelf(); } // If we have reached here: given trader name was invalid. - callerPlayer = result.GetCallerPlayer(); if (callerPlayer != none) { - console = callerPlayer.Console(); + console = callerPlayer.BorrowConsole(); } if (console != none) { @@ -254,20 +253,22 @@ protected function SelectTrader(CommandCall result) .UseColor(_.color.TextNegative).Write(T(TUNKNOWN_TRADERS)) .ResetColor().WriteLine(selectedTraderName); } + _.memory.Free(previouslySelectedTrader); + _.memory.FreeMany(availableTraders); } // Boot players from the old trader iff -// 1. It's different from the new one (otherwise swapping means nothing); +// 1. It is different from the new one (otherwise swapping means nothing); // 2. Option "ignore-players" was not specified. protected function HandleTraderSwap( - CommandCall result, - ATrader oldTrader, - ATrader newTrader) + CallData result, + ETrader oldTrader, + ETrader newTrader) { - if (oldTrader == none) return; - if (oldTrader == newTrader) return; - if (result.GetOptions().HasKey(T(TIGNORE_DOORS))) return; - if (result.GetOptions().HasKey(T(TIGNORE_PLAYERS))) return; + if (oldTrader == none) return; + if (oldTrader.SameAs(newTrader)) return; + if (result.options.HasKey(T(TIGNORE_DOORS))) return; + if (result.options.HasKey(T(TIGNORE_PLAYERS))) return; oldTrader.Close().BootPlayers(); if (newTrader != none) { @@ -275,69 +276,75 @@ protected function HandleTraderSwap( } } -protected function BootFromTraders(CommandCall result) +protected function BootFromTraders(CallData result, EPlayer callerPlayer) { local int i; - local array selectedTraders; - selectedTraders = GetTradersArray(result); + local array selectedTraders; + selectedTraders = GetTradersArray(result, callerPlayer); if (selectedTraders.length <= 0) { selectedTraders = _.kf.trading.GetTraders(); } for (i = 0; i < selectedTraders.length; i += 1) { selectedTraders[i].BootPlayers(); } + _.memory.FreeMany(selectedTraders); } -protected function SetTradersEnabled(bool doEnable, CommandCall result) +protected function SetTradersEnabled( + bool doEnable, + CallData result, + EPlayer callerPlayer) { local int i; - local array selectedTraders; - selectedTraders = GetTradersArray(result); + local array selectedTraders; + selectedTraders = GetTradersArray(result, callerPlayer); for (i = 0; i < selectedTraders.length; i += 1) { selectedTraders[i].SetEnabled(doEnable); } + _.memory.FreeMany(selectedTraders); } -protected function SetTradersAutoOpen(CommandCall result) +protected function SetTradersAutoOpen(CallData result, EPlayer callerPlayer) { local int i; local bool doAutoOpen; - local array selectedTraders; - doAutoOpen = result.GetParameters().GetBool(T(TAUTO_OPEN_QUESTION)); - selectedTraders = GetTradersArray(result); + local array selectedTraders; + doAutoOpen = result.parameters.GetBool(T(TAUTO_OPEN_QUESTION)); + selectedTraders = GetTradersArray(result, callerPlayer); for (i = 0; i < selectedTraders.length; i += 1) { selectedTraders[i].SetAutoOpen(doAutoOpen); } + _.memory.FreeMany(selectedTraders); } // Reads traders specified for the command (if any). // Assumes `result != none`. -protected function array GetTradersArray(CommandCall result) +protected function array GetTradersArray( + CallData result, + EPlayer callerPlayer) { local int i, j; - local APLayer callerPlayer; local Text nextTraderName; local DynamicArray specifiedTrades; - local array resultTraders; - local array availableTraders; + local array resultTraders; + local array availableTraders; // Boundary cases: all traders and no traders at all availableTraders = _.kf.trading.GetTraders(); - if (result.GetOptions().HasKey(T(TALL))) { + if (result.options.HasKey(T(TALL))) { return availableTraders; } // Add closest one, if flag tells us to - callerPlayer = result.GetCallerPlayer(); - if (result.GetOptions().HasKey(T(TCLOSEST))) + if (result.options.HasKey(T(TCLOSEST))) { resultTraders = InsertTrader(resultTraders, FindClosestTrader(callerPlayer)); } - specifiedTrades = result.GetParameters().GetDynamicArray(T(TTRADERS)); + specifiedTrades = result.parameters.GetDynamicArray(T(TTRADERS)); if (specifiedTrades == none) { return resultTraders; } // We iterate over `availableTraders` in the outer loop because: - // 1. Each `ATrader` from `availableTraders` will be matched only once, + // 1. Each `ETrader` from `availableTraders` will be matched only once, // ensuring that result will not contain duplicate instances; // 2. `availableTraders.GetName()` creates a new `Text` copy and // `specifiedTrades.GetText()` does not. @@ -350,6 +357,7 @@ protected function array GetTradersArray(CommandCall result) { resultTraders = InsertTrader(resultTraders, availableTraders[i]); + availableTraders[i] = none; specifiedTrades.Remove(j, 1); break; } @@ -362,16 +370,17 @@ protected function array GetTradersArray(CommandCall result) // Some of the remaining trader names inside `specifiedTrades` do not // match any actual traders. Report it. if (callerPlayer != none && specifiedTrades.GetLength() > 0) { - ReportUnknowTraders(specifiedTrades, callerPlayer.Console()); + ReportUnknowTraders(specifiedTrades, callerPlayer.BorrowConsole()); } + _.memory.FreeMany(availableTraders); return resultTraders; } // Auxiliary method that adds `newTrader` into existing array of traders // if it is still missing. -protected function array InsertTrader( - array traders, - ATrader newTrader) +protected function array InsertTrader( + /* take */ array traders, + /* take */ ETrader newTrader) { local int i; if (newTrader == none) { @@ -379,7 +388,9 @@ protected function array InsertTrader( } for (i = 0; i < traders.length; i += 1) { - if (traders[i] == newTrader) { + if (traders[i].SameAs(newTrader)) + { + _.memory.Free(newTrader); return traders; } } @@ -410,12 +421,12 @@ protected function ReportUnknowTraders( } // Find closest trader to the `target` player -protected function ATrader FindClosestTrader(APlayer target) +protected function ETrader FindClosestTrader(EPlayer target) { local int i; local float newDistance, bestDistance; - local ATrader bestTrader; - local array availableTraders; + local ETrader bestTrader; + local array availableTraders; local Vector targetLocation; if (target == none) { return none; @@ -428,17 +439,20 @@ protected function ATrader FindClosestTrader(APlayer target) VSizeSquared(availableTraders[i].GetLocation() - targetLocation); if (bestTrader == none || newDistance < bestDistance) { - bestTrader = availableTraders[i]; bestDistance = newDistance; + _.memory.Free(bestTrader); + bestTrader = availableTraders[i]; + availableTraders[i] = none; } } + _.memory.FreeMany(availableTraders); return bestTrader; } // Writes a trader name along with information on whether it's // disabled / auto-open protected function WriteTrader( - ATrader traderToWrite, + ETrader traderToWrite, bool isClosestTrader, ConsoleWriter console) { @@ -462,7 +476,7 @@ protected function WriteTrader( } protected function WriteTraderTags( - ATrader traderToWrite, + ETrader traderToWrite, bool isClosest, ConsoleWriter console) {