Skip to content

Commit

Permalink
when killing bosses / semibosses for the first time, guaranteed loot …
Browse files Browse the repository at this point in the history
…is given from their equipped items

closes #841

Still need to do a pass on items for all bosses. It sucks that killing a boss sometimes only gives a trash loot for your guaranteed
  • Loading branch information
b5635 committed Nov 4, 2024
1 parent fd6c222 commit fc1eb83
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 16 deletions.
11 changes: 11 additions & 0 deletions src/itp/itempalcus.itp.json
Original file line number Diff line number Diff line change
Expand Up @@ -5494,6 +5494,17 @@
"value": "cre_baxep1"
}
},
{
"__struct_id": 0,
"NAME": {
"type": "cexostring",
"value": "High Quality Dagger"
},
"RESREF": {
"type": "resref",
"value": "cre_daggerp1"
}
},
{
"__struct_id": 0,
"NAME": {
Expand Down
44 changes: 31 additions & 13 deletions src/nss/inc_loot.nss
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ object GenerateTierItem(int iCR, int iAreaCR, object oContainer, string sType =
// Open a personal loot. Called from a containing object.
void OpenPersonalLoot(object oContainer, object oPC);

// Gets a random equipped item that is lootable
object SelectEquippedItemToDropAsLoot(object oCreature);


// ===========================================================
Expand Down Expand Up @@ -661,37 +663,37 @@ object CopyTierItemToObjectOrLocation(object oItem, object oContainer = OBJECT_I
{
return OBJECT_INVALID;
}

// i know we do some checks below, but the local needs to be set before it goes any further
// adds a new UUID to make sure the item does not stack
int nBaseType = GetBaseItemType(oItem);

if (IsAmmoInfinite(oItem) && (nBaseType == BASE_ITEM_THROWINGAXE ||
nBaseType == BASE_ITEM_DART ||
nBaseType == BASE_ITEM_SHURIKEN ||
nBaseType == BASE_ITEM_ARROW ||
nBaseType == BASE_ITEM_BULLET ||
if (IsAmmoInfinite(oItem) && (nBaseType == BASE_ITEM_THROWINGAXE ||
nBaseType == BASE_ITEM_DART ||
nBaseType == BASE_ITEM_SHURIKEN ||
nBaseType == BASE_ITEM_ARROW ||
nBaseType == BASE_ITEM_BULLET ||
nBaseType == BASE_ITEM_BOLT))
{
SetLocalString(oItem, "new_uuid", GetRandomUUID());
}

object oNewItem;
if (GetIsObjectValid(oContainer))
{
oNewItem = CopyItem(oItem, oContainer, TRUE);
}
else
{
oNewItem = CopyObject(oItem, lLocation, OBJECT_INVALID, "", TRUE);
oNewItem = CopyObject(oItem, lLocation, OBJECT_INVALID, "", TRUE);
}

if (!GetIsObjectValid(oItem))
{
return OBJECT_INVALID;
}

if (nBaseType == BASE_ITEM_THROWINGAXE || nBaseType == BASE_ITEM_DART || nBaseType == BASE_ITEM_SHURIKEN || nBaseType == BASE_ITEM_ARROW || nBaseType == BASE_ITEM_BULLET || nBaseType == BASE_ITEM_BOLT)
if (nBaseType == BASE_ITEM_THROWINGAXE || nBaseType == BASE_ITEM_DART || nBaseType == BASE_ITEM_SHURIKEN || nBaseType == BASE_ITEM_ARROW || nBaseType == BASE_ITEM_BULLET || nBaseType == BASE_ITEM_BOLT)
{
if (IsAmmoInfinite(oNewItem))
{ // If the ammo has ANY item properties at all, it is considered magical and infinite. Make sure it only has a stack size of 1.
Expand Down Expand Up @@ -868,6 +870,22 @@ object SelectItemToDropAsLoot(int iCR, int iAreaCR, string sType, int nTier, obj
return SelectTierItem(iCR, iAreaCR, sType, nTier, oDestinationContainer, bNonUnique, fQualityExponentModifier);
}

object SelectEquippedItemToDropAsLoot(object oCreature)
{
// We can get any tier
json jItems = _BuildListOfOwnDroppableLoot(oCreature, 0, TRUE);
int nNumItems = JsonGetLength(jItems);


if (nNumItems > 0)
{
int nIndex = Random(JsonGetLength(jItems));
object oReturn = StringToObject(JsonGetString(JsonArrayGet(jItems, nIndex)));

return oReturn;
}
return OBJECT_INVALID;
}


// ---------------------------------------------------------
Expand Down Expand Up @@ -1281,7 +1299,7 @@ int ShouldDebugLoot()
if (!GetLocalInt(GetModule(), "init_complete"))
{
return TRUE;
}
}
}
return FALSE;
}
Expand Down Expand Up @@ -1554,7 +1572,7 @@ int LootDebugOutput()
float fRawGold = GetLocalFloat(GetModule(), LOOT_DEBUG_GOLD);
SendDebugMessage("Expected raw gold: " + FloatToString(fRawGold), TRUE);
SendDebugMessage("Total item value: " + FloatToString(fGoldTotal), TRUE);

return FloatToInt(fGoldTotal + fRawGold);
}

Expand All @@ -1566,7 +1584,7 @@ void CalculatePlaceableLootValues()
string sPlaceable;
// This is in _BASE.
location lSpawn = GetLocation(GetWaypointByTag("_calc_plc_values"));

SetLocalInt(oModule, LOOT_DEBUG_ENABLED, 1);
for (nPlaceableTier=0; nPlaceableTier<3; nPlaceableTier++)
{
Expand All @@ -1582,7 +1600,7 @@ void CalculatePlaceableLootValues()
SetLocalInt(oPlaceable, "cr", nACR);
SetLocalInt(oPlaceable, "area_cr", nACR);
ExecuteScript("party_credit", oPlaceable);
DeleteLocalInt(oPlaceable, "no_credit");
DeleteLocalInt(oPlaceable, "no_credit");
int nGold = LootDebugOutput();
WriteTimestampedLogEntry("Value of placeable loot " + sTreasureTier + " at ACR " + IntToString(nACR) + " = " + IntToString(nGold));
SetLocalInt(oModule, "placeable_value_" + sTreasureTier + "_" + IntToString(nACR), nGold);
Expand Down
15 changes: 15 additions & 0 deletions src/nss/party_credit.nss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "inc_henchman"
#include "inc_key"
#include "inc_party"
#include "inc_sql"

// The max distance in meters a player can be from
// a target killed by a trap, and still get xp.
Expand Down Expand Up @@ -796,6 +797,20 @@ void main()

if (bNoTreasure == FALSE)
{
// If this is the very first time the player has looted this boss/semiboss,
// a single piece of loot will be guaranteed from their equipped item (if present)
if ((bBoss || bSemiBoss) && GetObjectType(OBJECT_SELF) == OBJECT_TYPE_CREATURE)
{
object oEquippedItem = SelectEquippedItemToDropAsLoot(OBJECT_SELF);
string sLootKey = "looted_"+GetResRef(OBJECT_SELF);

if (GetIsObjectValid(oEquippedItem) && SQLocalsPlayer_GetInt(oPC, sLootKey) != 1)
{
CopyItem(oEquippedItem, oPersonalLoot, TRUE);
SQLocalsPlayer_SetInt(oPC, sLootKey, 1);
}
}

SetLocalInt(oPersonalLoot, "cr", GetLocalInt(oContainer, "cr"));
SetLocalInt(oPersonalLoot, "area_cr", GetLocalInt(oContainer, "area_cr"));
json jItemArray = JsonArrayGet(jAssignments, nNth);
Expand Down
7 changes: 7 additions & 0 deletions src/utc/likler.utc.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@
"Equip_ItemList": {
"type": "list",
"value": [
{
"__struct_id": 2,
"EquippedRes": {
"type": "resref",
"value": "armor120"
}
},
{
"__struct_id": 16,
"EquippedRes": {
Expand Down
2 changes: 1 addition & 1 deletion src/utc/torin.utc.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@
"__struct_id": 16,
"EquippedRes": {
"type": "resref",
"value": "nw_wswdg001"
"value": "cre_daggerp1"
}
}
]
Expand Down
4 changes: 2 additions & 2 deletions src/utc/zor.utc.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
"__struct_id": 2,
"EquippedRes": {
"type": "resref",
"value": "nw_aarcl008"
"value": "nw_maarcl047"
}
},
{
Expand Down Expand Up @@ -316,7 +316,7 @@
},
"NaturalAC": {
"type": "byte",
"value": 6
"value": 5
},
"NoPermDeath": {
"type": "byte",
Expand Down
130 changes: 130 additions & 0 deletions src/uti/cre_daggerp1.uti.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
{
"__data_type": "UTI ",
"AddCost": {
"type": "dword",
"value": 0
},
"BaseItem": {
"type": "int",
"value": 22
},
"Charges": {
"type": "byte",
"value": 0
},
"Comment": {
"type": "cexostring",
"value": "1"
},
"Cost": {
"type": "dword",
"value": 251
},
"Cursed": {
"type": "byte",
"value": 0
},
"DescIdentified": {
"type": "cexolocstring",
"value": {}
},
"Description": {
"type": "cexolocstring",
"value": {}
},
"Identified": {
"type": "byte",
"value": 0
},
"LocalizedName": {
"id": 191,
"type": "cexolocstring",
"value": {
"0": "High Quality Dagger"
}
},
"ModelPart1": {
"type": "byte",
"value": 21
},
"ModelPart2": {
"type": "byte",
"value": 31
},
"ModelPart3": {
"type": "byte",
"value": 21
},
"PaletteID": {
"type": "byte",
"value": 59
},
"Plot": {
"type": "byte",
"value": 0
},
"PropertiesList": {
"type": "list",
"value": [
{
"__struct_id": 0,
"ChanceAppear": {
"type": "byte",
"value": 100
},
"CostTable": {
"type": "byte",
"value": 4
},
"CostValue": {
"type": "word",
"value": 1
},
"Param1": {
"type": "byte",
"value": 255
},
"Param1Value": {
"type": "byte",
"value": 0
},
"PropertyName": {
"type": "word",
"value": 16
},
"Subtype": {
"type": "word",
"value": 1
}
}
]
},
"StackSize": {
"type": "word",
"value": 1
},
"Stolen": {
"type": "byte",
"value": 0
},
"Tag": {
"type": "cexostring",
"value": "NW_WSWDG001"
},
"TemplateResRef": {
"type": "resref",
"value": "cre_daggerp1"
},
"xModelPart1": {
"type": "word",
"value": 21
},
"xModelPart2": {
"type": "word",
"value": 31
},
"xModelPart3": {
"type": "word",
"value": 21
}
}

0 comments on commit fc1eb83

Please sign in to comment.