diff --git a/sources/AcediaAdmin_Feature.uc b/sources/AcediaAdmin_Feature.uc
index 258967f..475da83 100644
--- a/sources/AcediaAdmin_Feature.uc
+++ b/sources/AcediaAdmin_Feature.uc
@@ -33,6 +33,7 @@ protected function OnEnabled()
return;
}
commandsFeature.RegisterCommand(class'ACommandDosh');
+ commandsFeature.RegisterCommand(class'ACommandGive');
commandsFeature.RegisterCommand(class'ACommandNick');
commandsFeature.RegisterCommand(class'ACommandTrader');
commandsFeature.RegisterCommand(class'ACommandDB');
@@ -46,6 +47,7 @@ protected function OnDisabled()
if (commandsFeature != none)
{
commandsFeature.RemoveCommand(class'ACommandDosh');
+ commandsFeature.RemoveCommand(class'ACommandGive');
commandsFeature.RemoveCommand(class'ACommandNick');
commandsFeature.RemoveCommand(class'ACommandTrader');
commandsFeature.RemoveCommand(class'ACommandDB');
diff --git a/sources/Commands/ACommandGive.uc b/sources/Commands/ACommandGive.uc
new file mode 100644
index 0000000..cf5912e
--- /dev/null
+++ b/sources/Commands/ACommandGive.uc
@@ -0,0 +1,219 @@
+/**
+ * Command for giving players weapons or other items.
+ * Copyright 2021 Anton Tarasenko
+ *------------------------------------------------------------------------------
+ * This file is part of Acedia.
+ *
+ * Acedia is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Acedia is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Acedia. If not, see .
+ */
+class ACommandGive extends Command;
+
+protected function BuildData(CommandDataBuilder builder)
+{
+ builder.Name(P("give")).Summary(P("Gives player specified weapon / item."));
+ builder.RequireTarget();
+ builder.ParamTextList(P("items"))
+ .Describe(P("Gives players a specified item."));
+ builder.Option(P("force"))
+ .Describe(P("Due to inventory limitations, this command might refuse to"
+ @ "add specified weapons. Using this flag makes it try to resolve"
+ @ "situation and allow adding specified weapon. But results are"
+ @ "still not guaranteed."));
+ builder.Option(P("clear"))
+ .Describe(F("Clears target's inventory before adding new weapons."
+ @ "By default destroys inventory. Setting optional parameter to"
+ @ "{$TypeBoolean 'true'} will make game try to keep items,"
+ @ "e.g. by just dropping them on the floor."))
+ .OptionalParams()
+ .ParamBoolean(P("keep-items"));
+}
+
+protected function ExecutedFor(APlayer player, CommandCall result)
+{
+ 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")));
+ }
+ for (i = 0; i < itemsToAdd.GetLength(); i += 1)
+ {
+ itemTemplate = GetTemplate(itemsToAdd.GetText(i));
+ templateInfo = _.kf.GetItemTemplateInfo(itemTemplate);
+ if (templateInfo != none) {
+ itemName = templateInfo.GetName();
+ }
+ else {
+ itemName = itemTemplate.Copy();
+ }
+ if (inventory.AddTemplate(itemTemplate, doForce)) {
+ addedItems[addedItems.length] = itemName;
+ }
+ else {
+ rejectedItems[rejectedItems.length] = itemName;
+ }
+ _.memory.Free(itemTemplate);
+ itemTemplate = none;
+ itemName = none;
+ }
+ ReportResultsToCaller(callerPlayer, player, addedItems, rejectedItems);
+ AnnounceGivingItems(callerPlayer, player, addedItems);
+ _.memory.Free(inventory);
+ _.memory.FreeMany(addedItems);
+ _.memory.FreeMany(rejectedItems);
+}
+
+protected function Text GetTemplate(Text userItemName)
+{
+ if (userItemName == none) {
+ return none;
+ }
+ if (userItemName.StartsWith(P("$"))) {
+ return _.alias.ResolveWeapon(userItemName, true);
+ }
+ return userItemName.Copy();
+}
+
+protected function bool GiveItemTo(
+ Text itemTemplate,
+ EInventory inventory,
+ bool doForce)
+{
+ local bool addedSuccessfully;
+ if (itemTemplate == none) {
+ return false;
+ }
+ if (!itemTemplate.StartsWith(P("$"))) {
+ addedSuccessfully = inventory.AddTemplate(itemTemplate);
+ }
+ else
+ {
+ itemTemplate = _.alias.ResolveWeapon(itemTemplate, true);
+ addedSuccessfully = inventory.AddTemplate(itemTemplate, doForce);
+ _.memory.Free(itemTemplate);
+ }
+ return addedSuccessfully;
+}
+
+protected function ReportResultsToCaller(
+ APlayer caller,
+ APlayer target,
+ array addedItems,
+ array rejectedItems)
+{
+ local int i;
+ local Text targetName;
+ local ConsoleWriter console;
+ if (addedItems.length <= 0 && rejectedItems.length <= 0) {
+ return;
+ }
+ console = caller.Console();
+ targetName = target.GetName();
+ console.Write(F("{$TextEmphasis Giving} weapons to "))
+ .Write(targetName).Write(P(": "));
+ targetName.FreeSelf();
+ if (addedItems.length > 0)
+ {
+ console.Write(F("{$TextPositive successfully} gave "));
+ for (i = 0; i < addedItems.length; i += 1)
+ {
+ if (i > 0)
+ {
+ if (i == addedItems.length - 1) {
+ console.Write(P(" and "));
+ }
+ else {
+ console.Write(P(", "));
+ }
+ }
+ console.UseColorOnce(_.color.TextSubtle).Write(addedItems[i]);
+ }
+ }
+ if (rejectedItems.length > 0)
+ {
+ if (addedItems.length > 0) {
+ console.Write(F(", {$TextNegative but} "));
+ }
+ console.Write(F("{$TextNegative failed} to give "));
+ for (i = 0; i < rejectedItems.length; i += 1)
+ {
+ if (i > 0)
+ {
+ if (i == rejectedItems.length - 1) {
+ console.Write(P(" and "));
+ }
+ else {
+ console.Write(P(", "));
+ }
+ }
+ console.UseColorOnce(_.color.TextSubtle).Write(rejectedItems[i]);
+ }
+ }
+ console.Flush();
+}
+
+protected function AnnounceGivingItems(
+ APlayer caller,
+ Aplayer target,
+ array addedItems)
+{
+ local int i;
+ local Text targetName;
+ local MutableText message;
+ local ConsoleWriter console;
+ local Text.Formatting itemNameFormatting;
+ if (addedItems.length <= 0) {
+ return;
+ }
+ message = _.text.Empty();
+ itemNameFormatting = _.text.FormattingFromColor(_.color.TextSubtle);
+ message.Append(F("{$TextPositive given}: "));
+ for (i = 0; i < addedItems.length; i += 1)
+ {
+ if (i > 0)
+ {
+ if (i == addedItems.length - 1) {
+ message.Append(P(" and "));
+ }
+ else {
+ message.Append(P(", "));
+ }
+ }
+ message.Append(addedItems[i], itemNameFormatting);
+ }
+ targetName = target.GetName();
+ console = _.console.ForAll().ButPlayer(caller).ButPlayer(target)
+ .Write(targetName).Write(P(" was ")).Say(message);
+ if (caller != target) {
+ console.ForPlayer(target).Write(P("You were ")).Say(message);
+ }
+ console.FreeSelf();
+ message.FreeSelf();
+ targetName.FreeSelf();
+}
+
+defaultproperties
+{
+}
\ No newline at end of file