From 8a4124370ad7c91308b3847f8504e56d2a5721a1 Mon Sep 17 00:00:00 2001 From: MillhioreBT Date: Wed, 6 Sep 2023 20:03:30 -0400 Subject: [PATCH 1/6] Decay time random --- data/items/items.xml | 12 ++++++------ src/item.cpp | 7 ++++++- src/item.h | 5 +++++ src/items.cpp | 15 ++++++++++++++- src/items.h | 1 + src/luascript.cpp | 13 +++++++++++++ src/luascript.h | 1 + 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/data/items/items.xml b/data/items/items.xml index 6eed1612a2..d5ca543ac2 100644 --- a/data/items/items.xml +++ b/data/items/items.xml @@ -729,7 +729,7 @@ - + @@ -737,7 +737,7 @@ - + @@ -19687,12 +19687,12 @@ - + - + @@ -30117,12 +30117,12 @@ - + - + diff --git a/src/item.cpp b/src/item.cpp index a0611db458..006edb32a0 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -238,7 +238,12 @@ void Item::setID(uint16_t newid) id = newid; const ItemType& it = Item::items[newid]; - uint32_t newDuration = it.decayTime * 1000; + uint32_t newDuration; + if (it.decayTimeMax != 0) { + newDuration = normal_random(it.decayTime, it.decayTimeMax) * 1000; + } else { + newDuration = it.decayTime * 1000; + } if (newDuration == 0 && !it.stopTime && it.decayTo < 0) { removeAttribute(ITEM_ATTRIBUTE_DECAYSTATE); diff --git a/src/item.h b/src/item.h index 54577fb39a..cfdbcff361 100644 --- a/src/item.h +++ b/src/item.h @@ -871,11 +871,16 @@ class Item : virtual public Thing void setDefaultDuration() { uint32_t duration = getDefaultDuration(); + if (uint32_t durationMax = getDefaultDurationMax()) { + duration = normal_random(duration, durationMax); + } + if (duration != 0) { setDuration(duration); } } uint32_t getDefaultDuration() const { return items[id].decayTime * 1000; } + uint32_t getDefaultDurationMax() const { return items[id].decayTimeMax * 1000; } bool canDecay() const; virtual bool canRemove() const { return true; } diff --git a/src/items.cpp b/src/items.cpp index 92c3cb1ac4..34f01c9e90 100644 --- a/src/items.cpp +++ b/src/items.cpp @@ -611,8 +611,17 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id) } pugi::xml_attribute valueAttribute = attributeNode.attribute("value"); + pugi::xml_attribute maxValueAttr; if (!valueAttribute) { - continue; + valueAttribute = attributeNode.attribute("minvalue"); + if (!valueAttribute) { + continue; + } + + maxValueAttr = attributeNode.attribute("maxvalue"); + if (!maxValueAttr) { + continue; + } } std::string tmpStrValue = boost::algorithm::to_lower_copy(keyAttribute.as_string()); @@ -882,6 +891,10 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id) case ITEM_PARSE_DURATION: { it.decayTime = pugi::cast(valueAttribute.value()); + + if (maxValueAttr) { + it.decayTimeMax = pugi::cast(maxValueAttr.value()); + } break; } diff --git a/src/items.h b/src/items.h index 3a89980c5b..7daf62cdf1 100644 --- a/src/items.h +++ b/src/items.h @@ -338,6 +338,7 @@ class ItemType uint32_t weight = 0; uint32_t levelDoor = 0; uint32_t decayTime = 0; + uint32_t decayTimeMax = 0; uint32_t wieldInfo = 0; uint32_t minReqLevel = 0; uint32_t minReqMagicLevel = 0; diff --git a/src/luascript.cpp b/src/luascript.cpp index 45e4a2a0ee..c355d7cdce 100644 --- a/src/luascript.cpp +++ b/src/luascript.cpp @@ -2981,6 +2981,7 @@ void LuaScriptInterface::registerFunctions() registerMethod("ItemType", "hasAllowDistRead", LuaScriptInterface::luaItemTypeHasAllowDistRead); registerMethod("ItemType", "getWieldInfo", LuaScriptInterface::luaItemTypeGetWieldInfo); registerMethod("ItemType", "getDuration", LuaScriptInterface::luaItemTypeGetDuration); + registerMethod("ItemType", "getDurationMax", LuaScriptInterface::luaItemTypeGetDurationMax); registerMethod("ItemType", "getLevelDoor", LuaScriptInterface::luaItemTypeGetLevelDoor); registerMethod("ItemType", "getRuneSpellName", LuaScriptInterface::luaItemTypeGetRuneSpellName); registerMethod("ItemType", "getVocationString", LuaScriptInterface::luaItemTypeGetVocationString); @@ -13223,6 +13224,18 @@ int LuaScriptInterface::luaItemTypeGetDuration(lua_State* L) return 1; } +int LuaScriptInterface::luaItemTypeGetDurationMax(lua_State* L) +{ + // itemType:getDurationMax() + const ItemType* itemType = getUserdata(L, 1); + if (itemType) { + lua_pushinteger(L, itemType->decayTimeMax); + } else { + lua_pushnil(L); + } + return 1; +} + int LuaScriptInterface::luaItemTypeGetLevelDoor(lua_State* L) { // itemType:getLevelDoor() diff --git a/src/luascript.h b/src/luascript.h index 2b9f1047e2..997b211e78 100644 --- a/src/luascript.h +++ b/src/luascript.h @@ -1248,6 +1248,7 @@ class LuaScriptInterface static int luaItemTypeHasAllowDistRead(lua_State* L); static int luaItemTypeGetWieldInfo(lua_State* L); static int luaItemTypeGetDuration(lua_State* L); + static int luaItemTypeGetDurationMax(lua_State* L); static int luaItemTypeGetLevelDoor(lua_State* L); static int luaItemTypeGetRuneSpellName(lua_State* L); static int luaItemTypeGetVocationString(lua_State* L); From c8e07d5c25b388a78cfc9aec6a08a5b2f5ada75f Mon Sep 17 00:00:00 2001 From: MillhioreBT Date: Wed, 6 Sep 2023 20:11:27 -0400 Subject: [PATCH 2/6] method getDefaultDuration moved to cpp --- src/item.cpp | 12 ++++++++++++ src/item.h | 12 +----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 006edb32a0..a0350177f6 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -1055,6 +1055,18 @@ void Item::setUniqueId(uint16_t n) } } +void Item::setDefaultDuration() +{ + uint32_t duration = getDefaultDuration(); + if (uint32_t durationMax = getDefaultDurationMax()) { + duration = normal_random(duration, durationMax); + } + + if (duration != 0) { + setDuration(duration); + } +} + bool Item::canDecay() const { if (isRemoved()) { diff --git a/src/item.h b/src/item.h index cfdbcff361..ed8ba54df3 100644 --- a/src/item.h +++ b/src/item.h @@ -868,17 +868,7 @@ class Item : virtual public Thing void setUniqueId(uint16_t n); - void setDefaultDuration() - { - uint32_t duration = getDefaultDuration(); - if (uint32_t durationMax = getDefaultDurationMax()) { - duration = normal_random(duration, durationMax); - } - - if (duration != 0) { - setDuration(duration); - } - } + void setDefaultDuration(); uint32_t getDefaultDuration() const { return items[id].decayTime * 1000; } uint32_t getDefaultDurationMax() const { return items[id].decayTimeMax * 1000; } bool canDecay() const; From 4a56bcfdceb1c669ff6713b842247292bb686281 Mon Sep 17 00:00:00 2001 From: MillhioreBT Date: Wed, 20 Sep 2023 21:27:20 -0400 Subject: [PATCH 3/6] applying changes --- data/lib/compat/compat.lua | 2 ++ src/enums.h | 2 ++ src/item.cpp | 12 ++++++------ src/item.h | 17 ++++++++++++----- src/items.cpp | 2 +- src/items.h | 2 +- src/luascript.cpp | 16 +++++++++++----- src/luascript.h | 2 +- 8 files changed, 36 insertions(+), 19 deletions(-) diff --git a/data/lib/compat/compat.lua b/data/lib/compat/compat.lua index 2fded53faa..6dcd149657 100644 --- a/data/lib/compat/compat.lua +++ b/data/lib/compat/compat.lua @@ -1619,3 +1619,5 @@ function table.maxn(t) end return max end + +ItemType.getDuration = ItemType.getDurationMin diff --git a/src/enums.h b/src/enums.h index 3a05d77553..6a243ef525 100644 --- a/src/enums.h +++ b/src/enums.h @@ -83,6 +83,8 @@ enum itemAttrTypes : uint32_t ITEM_ATTRIBUTE_STOREITEM = 1 << 25, ITEM_ATTRIBUTE_ATTACK_SPEED = 1 << 26, ITEM_ATTRIBUTE_OPENCONTAINER = 1 << 27, + ITEM_ATTRIBUTE_DURATION_MIN = ITEM_ATTRIBUTE_DURATION, + ITEM_ATTRIBUTE_DURATION_MAX = 1 << 28, ITEM_ATTRIBUTE_CUSTOM = 1U << 31 }; diff --git a/src/item.cpp b/src/item.cpp index a0350177f6..cc84d7a1b4 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -239,10 +239,10 @@ void Item::setID(uint16_t newid) const ItemType& it = Item::items[newid]; uint32_t newDuration; - if (it.decayTimeMax != 0) { - newDuration = normal_random(it.decayTime, it.decayTimeMax) * 1000; + if (it.decayTimeMin != 0 && it.decayTimeMax != 0) { + newDuration = normal_random(it.decayTimeMin, it.decayTimeMax) * 1000; } else { - newDuration = it.decayTime * 1000; + newDuration = it.decayTimeMin * 1000; } if (newDuration == 0 && !it.stopTime && it.decayTo < 0) { @@ -1057,7 +1057,7 @@ void Item::setUniqueId(uint16_t n) void Item::setDefaultDuration() { - uint32_t duration = getDefaultDuration(); + uint32_t duration = getDefaultDurationMin(); if (uint32_t durationMax = getDefaultDurationMax()) { duration = normal_random(duration, durationMax); } @@ -1073,7 +1073,7 @@ bool Item::canDecay() const return false; } - if (getDecayTo() < 0 || getDecayTime() == 0) { + if (getDecayTo() < 0 || (getDecayTimeMin() == 0 && getDecayTimeMax() == 0)) { return false; } @@ -1264,7 +1264,7 @@ bool Item::hasMarketAttributes() const } } else if (attr.type == ITEM_ATTRIBUTE_DURATION) { uint32_t duration = static_cast(attr.value.integer); - if (duration != getDefaultDuration()) { + if (duration <= getDefaultDurationMin()) { return false; } } else { diff --git a/src/item.h b/src/item.h index ed8ba54df3..27a846fd6c 100644 --- a/src/item.h +++ b/src/item.h @@ -687,12 +687,19 @@ class Item : virtual public Thing return static_cast(getIntAttr(ITEM_ATTRIBUTE_DECAYSTATE)); } - int32_t getDecayTime() const + int32_t getDecayTimeMin() const { - if (hasAttribute(ITEM_ATTRIBUTE_DURATION)) { - return getIntAttr(ITEM_ATTRIBUTE_DURATION); + if (hasAttribute(ITEM_ATTRIBUTE_DURATION_MIN)) { + return getIntAttr(ITEM_ATTRIBUTE_DURATION_MIN); } - return items[id].decayTime; + return items[id].decayTimeMin; + } + int32_t getDecayTimeMax() const + { + if (hasAttribute(ITEM_ATTRIBUTE_DURATION_MAX)) { + return getIntAttr(ITEM_ATTRIBUTE_DURATION_MAX); + } + return items[id].decayTimeMax; } void setDecayTo(int32_t decayTo) { setIntAttr(ITEM_ATTRIBUTE_DECAYTO, decayTo); } @@ -869,7 +876,7 @@ class Item : virtual public Thing void setUniqueId(uint16_t n); void setDefaultDuration(); - uint32_t getDefaultDuration() const { return items[id].decayTime * 1000; } + uint32_t getDefaultDurationMin() const { return items[id].decayTimeMin * 1000; } uint32_t getDefaultDurationMax() const { return items[id].decayTimeMax * 1000; } bool canDecay() const; diff --git a/src/items.cpp b/src/items.cpp index 34f01c9e90..953b954bf0 100644 --- a/src/items.cpp +++ b/src/items.cpp @@ -890,7 +890,7 @@ void Items::parseItemNode(const pugi::xml_node& itemNode, uint16_t id) } case ITEM_PARSE_DURATION: { - it.decayTime = pugi::cast(valueAttribute.value()); + it.decayTimeMin = pugi::cast(valueAttribute.value()); if (maxValueAttr) { it.decayTimeMax = pugi::cast(maxValueAttr.value()); diff --git a/src/items.h b/src/items.h index 7daf62cdf1..a9bb6e1fa9 100644 --- a/src/items.h +++ b/src/items.h @@ -337,7 +337,7 @@ class ItemType uint32_t attackSpeed = 0; uint32_t weight = 0; uint32_t levelDoor = 0; - uint32_t decayTime = 0; + uint32_t decayTimeMin = 0; uint32_t decayTimeMax = 0; uint32_t wieldInfo = 0; uint32_t minReqLevel = 0; diff --git a/src/luascript.cpp b/src/luascript.cpp index c355d7cdce..1e73555403 100644 --- a/src/luascript.cpp +++ b/src/luascript.cpp @@ -2980,7 +2980,7 @@ void LuaScriptInterface::registerFunctions() registerMethod("ItemType", "hasShowDuration", LuaScriptInterface::luaItemTypeHasShowDuration); registerMethod("ItemType", "hasAllowDistRead", LuaScriptInterface::luaItemTypeHasAllowDistRead); registerMethod("ItemType", "getWieldInfo", LuaScriptInterface::luaItemTypeGetWieldInfo); - registerMethod("ItemType", "getDuration", LuaScriptInterface::luaItemTypeGetDuration); + registerMethod("ItemType", "getDurationMin", LuaScriptInterface::luaItemTypeGetDurationMin); registerMethod("ItemType", "getDurationMax", LuaScriptInterface::luaItemTypeGetDurationMax); registerMethod("ItemType", "getLevelDoor", LuaScriptInterface::luaItemTypeGetLevelDoor); registerMethod("ItemType", "getRuneSpellName", LuaScriptInterface::luaItemTypeGetRuneSpellName); @@ -13212,12 +13212,12 @@ int LuaScriptInterface::luaItemTypeGetWieldInfo(lua_State* L) return 1; } -int LuaScriptInterface::luaItemTypeGetDuration(lua_State* L) +int LuaScriptInterface::luaItemTypeGetDurationMin(lua_State* L) { - // itemType:getDuration() + // itemType:getDurationMin() const ItemType* itemType = getUserdata(L, 1); if (itemType) { - lua_pushinteger(L, itemType->decayTime); + lua_pushinteger(L, itemType->decayTimeMin); } else { lua_pushnil(L); } @@ -17959,7 +17959,13 @@ int LuaScriptInterface::luaWeaponDuration(lua_State* L) uint16_t id = weapon->getID(); ItemType& it = Item::items.getItemType(id); - it.decayTime = getNumber(L, 2); + if (isTable(L, 2)) { + it.decayTimeMin = getField(L, 2, "min"); + it.decayTimeMax = getField(L, 2, "max"); + } else { + it.decayTimeMin = getNumber(L, 2); + } + it.showDuration = showDuration; pushBoolean(L, true); } else { diff --git a/src/luascript.h b/src/luascript.h index 997b211e78..e37dfd5715 100644 --- a/src/luascript.h +++ b/src/luascript.h @@ -1247,7 +1247,7 @@ class LuaScriptInterface static int luaItemTypeHasShowDuration(lua_State* L); static int luaItemTypeHasAllowDistRead(lua_State* L); static int luaItemTypeGetWieldInfo(lua_State* L); - static int luaItemTypeGetDuration(lua_State* L); + static int luaItemTypeGetDurationMin(lua_State* L); static int luaItemTypeGetDurationMax(lua_State* L); static int luaItemTypeGetLevelDoor(lua_State* L); static int luaItemTypeGetRuneSpellName(lua_State* L); From b3669322fd87db72164c30ced96d45649db12132 Mon Sep 17 00:00:00 2001 From: MillhioreBT Date: Wed, 20 Sep 2023 21:28:33 -0400 Subject: [PATCH 4/6] missing enums --- src/luascript.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/luascript.cpp b/src/luascript.cpp index 1e73555403..37cb70bf28 100644 --- a/src/luascript.cpp +++ b/src/luascript.cpp @@ -1656,6 +1656,8 @@ void LuaScriptInterface::registerFunctions() registerEnum(ITEM_ATTRIBUTE_STOREITEM); registerEnum(ITEM_ATTRIBUTE_ATTACK_SPEED); registerEnum(ITEM_ATTRIBUTE_OPENCONTAINER); + registerEnum(ITEM_ATTRIBUTE_DURATION_MIN); + registerEnum(ITEM_ATTRIBUTE_DURATION_MAX); registerEnum(ITEM_TYPE_DEPOT); registerEnum(ITEM_TYPE_MAILBOX); From 74e969a3857824a8f4f98a61237e6570928fa945 Mon Sep 17 00:00:00 2001 From: Sarah Wesker Date: Thu, 14 Mar 2024 12:47:25 -0400 Subject: [PATCH 5/6] suggestion of @ranisalt --- src/item.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index cc84d7a1b4..c28d4dac1c 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -238,12 +238,7 @@ void Item::setID(uint16_t newid) id = newid; const ItemType& it = Item::items[newid]; - uint32_t newDuration; - if (it.decayTimeMin != 0 && it.decayTimeMax != 0) { - newDuration = normal_random(it.decayTimeMin, it.decayTimeMax) * 1000; - } else { - newDuration = it.decayTimeMin * 1000; - } + uint32_t newDuration = normal_random(it.decayTimeMin, it.decayTimeMax) * 1000; if (newDuration == 0 && !it.stopTime && it.decayTo < 0) { removeAttribute(ITEM_ATTRIBUTE_DECAYSTATE); From 74afa01ce90cbffbb457e40a420a0122c80f1821 Mon Sep 17 00:00:00 2001 From: Sarah Wesker Date: Thu, 14 Mar 2024 12:52:42 -0400 Subject: [PATCH 6/6] fix small thing --- src/networkmessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/networkmessage.cpp b/src/networkmessage.cpp index b176947911..319e1dd394 100644 --- a/src/networkmessage.cpp +++ b/src/networkmessage.cpp @@ -106,7 +106,7 @@ void NetworkMessage::addItem(uint16_t id, uint8_t count) add(it.charges); addByte(0x00); // boolean (is brand new) } else if (it.showClientDuration) { - add(it.decayTime); + add(it.decayTimeMin); addByte(0x00); // boolean (is brand new) }