Skip to content

Commit

Permalink
Merged PR 837: 854_added_ammunition
Browse files Browse the repository at this point in the history
Added ammunition

Related Work Items: #732

Related work items: #854
  • Loading branch information
Allen B. Cummings committed Jan 19, 2021
1 parent 414a6e7 commit 2e8217d
Show file tree
Hide file tree
Showing 6 changed files with 301 additions and 12 deletions.
18 changes: 18 additions & 0 deletions lib/instances/items/weapons/ammunition/quiver-of-arrows.c
@@ -0,0 +1,18 @@
//*****************************************************************************
// Copyright (c) 2021 - Allen Cummings, RealmsMUD, All rights reserved. See
// the accompanying LICENSE file for details.
//*****************************************************************************
virtual inherit "/lib/items/ammunition.c";

/////////////////////////////////////////////////////////////////////////////
public void reset(int arg)
{
if (!arg)
{
set("name", "quiver");
set("short", "A quiver");
set("ammunition type", "arrow");
set("max capacity", 24);
set("quantity", 24);
}
}
150 changes: 150 additions & 0 deletions lib/items/ammunition.c
@@ -0,0 +1,150 @@
//*****************************************************************************
// Copyright (c) 2021 - Allen Cummings, RealmsMUD, All rights reserved. See
// the accompanying LICENSE file for details.
//*****************************************************************************
virtual inherit "/lib/items/item.c";

/////////////////////////////////////////////////////////////////////////////
public nomask mixed query(string element)
{
mixed ret = 0;
switch(element)
{
case "type":
{
ret = "ammunition";
break;
}
case "remaining capacity":
{
ret = itemData["max capacity"] - itemData["quantity"];
break;
}
case "short":
{
ret = "item"::query("short");
if ((isIlluminated() > 8) && itemData["ammunition type"])
{
if (itemData["quantity"])
{
ret += sprintf(" containing %d %s%s (%d max)",
itemData["quantity"],
itemData["ammunition type"],
(itemData["quantity"] == 1) ? "" : "s",
itemData["max capacity"]);
}
else
{
ret += sprintf(" that is empty (%d max)",
itemData["max capacity"]);
}
}
break;
}
case "low light description":
{
ret = "The silhouette of a small, rectangular object";
break;
}
case "dim light description":
{
ret = "Something that appears to be an ammunition container";
break;
}
default:
{
ret = "item"::query(element);
}
}

return ret;
}

/////////////////////////////////////////////////////////////////////////////
public nomask int addAmmunition(int amount)
{
int ret = 0;

if (amount > 0)
{
if (!member(itemData, "quantity"))
{
itemData["quantity"] = 0;
}

int remainingCapacity = query("remaining capacity");
if (amount > remainingCapacity)
{
itemData["quantity"] += remainingCapacity;
ret = amount - remainingCapacity;
}
else
{
itemData["quantity"] += amount;
}
}
return ret;
}

/////////////////////////////////////////////////////////////////////////////
public nomask varargs int set(string element, mixed data)
{
int ret = 0;

if (element && stringp(element))
{
switch (element)
{
case "ammunition type":
{
if (stringp(data))
{
ret = 1;
itemData["ammunition type"] = data;
}
break;
}
case "max capacity":
{
if (intp(data))
{
ret = 1;
itemData["max capacity"] = data;
}
break;
}
case "quantity":
{
if (intp(data) && member(itemData, "max capacity"))
{
ret = 1;
addAmmunition(data);
}
else
{
raise_error("ammunition.c: 'max capacity' must be set before "
"quantity");
}
break;
}
default:
{
ret = "item"::set(element, data);
}
}
}
return ret;
}

/////////////////////////////////////////////////////////////////////////////
public nomask int doNotDestroyWhenConsumed()
{
return 1;
}

/////////////////////////////////////////////////////////////////////////////
public int id(string item)
{
return (item == itemData["ammunition type"]) ||
"item"::id(item);
}
6 changes: 4 additions & 2 deletions lib/modules/inventory.c
Expand Up @@ -1131,12 +1131,14 @@ private nomask string displayUnequippedItems(object banner, int verbose,

if (member(otherItems, key))
{
otherItems[key]++;
otherItems[key] += equipment->query("quantity") ?
equipment->query("quantity") : 1;
allItems -= ({ equipment });
}
else
{
otherItems[key] = 1;
otherItems[key] = equipment->query("quantity") ?
equipment->query("quantity") : 1;
}
}

Expand Down
2 changes: 0 additions & 2 deletions lib/modules/research/instantaneousRitualResearchItem.c
Expand Up @@ -134,5 +134,3 @@ protected nomask int applyEffect(object initiator, object target)
ret ||= applyBeneficialEffect(initiator, target);
return ret;
}


75 changes: 67 additions & 8 deletions lib/modules/research/ritualResearchItem.c
Expand Up @@ -87,6 +87,22 @@ protected int addSpecification(string type, mixed value)
}
break;
}
case "consumables":
{
if (mappingp(value) && (sizeof(value) == sizeof(filter(value,
(: (stringp($1) && intp($2)) :)))))
{
specificationData[type] = value;
ret = 1;
}
else
{
raise_error(sprintf("ERROR - ritualResearchItem: the '%s'"
" specification must be a valid mapping.\n",
type));
}
break;
}
default:
{
ret = "researchItem"::addSpecification(type, value);
Expand Down Expand Up @@ -208,6 +224,47 @@ protected int performRitual(object initiator)
return 0;
}

/////////////////////////////////////////////////////////////////////////////
private nomask int useConsumables(object initiator)
{
int ret = 1;
if (member(specificationData, "comsumables"))
{
object *potentialConsumables = all_inventory(initiator) +
all_inventory(environment(initiator));

foreach(string item in m_indices(specificationData["comsumables"]))
{
for (int i = 0; i < specificationData["comsumables"][item]; i++)
{
object *consumables = filter(potentialConsumables,
(: ($1->id($2) && !(($1->query("quantity") == 0) &&
$1->doNotDestroyWhenConsumed())) :), item);

if (sizeof(consumables))
{
object itemObj = consumables[0];
if (itemObj->query("quantity") > 0)
{
itemObj->set("quantity", itemObj->query("quantity") - 1);
}
if (!itemObj->query("quantity") &&
!itemObj->doNotDestroyWhenConsumed())
{
destruct(itemObj);
}
}
else
{
ret = 0;
break;
}
}
}
}
return ret;
}

/////////////////////////////////////////////////////////////////////////////
public nomask int execute(string command, object initiator)
{
Expand All @@ -233,19 +290,21 @@ public nomask int execute(string command, object initiator)
displayMessage(coolDownMessage, initiator, initiator);
ret = 0;
}
ret &&= performRitual(initiator);

if(ret && !initiator->spellAction())
if (!initiator->spellAction())
{
ret = applyToScope(command, initiator, researchName);
if(!ret && member(specificationData, "use ability fail message"))
ret &&= useConsumables(initiator) && performRitual(initiator) &&
applyToScope(command, initiator, researchName);

if (!ret && member(specificationData, "use ability fail message"))
{
displayMessage(specificationData["use ability fail message"],
displayMessage(specificationData["use ability fail message"],
initiator, initiator);
}
initiator->spellAction(1);
else
{
initiator->spellAction(1);
}
}
}
return ret;
}

62 changes: 62 additions & 0 deletions lib/tests/items/ammunitionTest.c
@@ -0,0 +1,62 @@
//*****************************************************************************
// Copyright (c) 2021 - Allen Cummings, RealmsMUD, All rights reserved. See
// the accompanying LICENSE file for details.
//*****************************************************************************
inherit "/lib/tests/framework/testFixture.c";

object Ammo;

/////////////////////////////////////////////////////////////////////////////
void Setup()
{
Ammo = clone_object("/lib/items/ammunition.c");
Ammo->set("name", "quiver");
Ammo->set("short", "A quiver");
Ammo->set("ammunition type", "arrow");
Ammo->set("max capacity", 24);
}

/////////////////////////////////////////////////////////////////////////////
void CleanUp()
{
destruct(Ammo);
}

/////////////////////////////////////////////////////////////////////////////
void IdReturnsTrueForAmmunitionType()
{
ExpectTrue(Ammo->id("arrow"));
}

/////////////////////////////////////////////////////////////////////////////
void ShortReturnsCorrectMessageWhenEmpty()
{
ExpectEq("A quiver that is empty (24 max)",
Ammo->short(), "short() returns correct value");
}

/////////////////////////////////////////////////////////////////////////////
void ShortReturnsCorrectMessageWhenOneItemInContainer()
{
Ammo->set("quantity", 1);

ExpectEq("A quiver containing 1 arrow (24 max)", Ammo->short());
}

/////////////////////////////////////////////////////////////////////////////
void AddAmmunitionAddsTheDesiredQuantityToTheContainer()
{
Ammo->set("quantity", 1);

ExpectEq(0, Ammo->addAmmunition(4));
ExpectEq("A quiver containing 5 arrows (24 max)", Ammo->short());
}

/////////////////////////////////////////////////////////////////////////////
void AddingAmmunitionAboveCapacityReturnsLeftOverAmmo()
{
Ammo->set("quantity", 10);

ExpectEq(6, Ammo->addAmmunition(20));
ExpectEq("A quiver containing 24 arrows (24 max)", Ammo->short());
}

0 comments on commit 2e8217d

Please sign in to comment.