diff --git a/game/engines/default/engine/interface/ActorInventory.lua b/game/engines/default/engine/interface/ActorInventory.lua index f53228efa6be0a91ee864485fde6c06d80c76d4e..49b92a5a0838fdeaf6a5c65eb0e623a68e1536cf 100644 --- a/game/engines/default/engine/interface/ActorInventory.lua +++ b/game/engines/default/engine/interface/ActorInventory.lua @@ -219,6 +219,10 @@ function _M:onRemoveObject(o) o.carried = nil end +--- Called upon dropping an object +function _M:onDropObject(o) +end + --- Drop an object on the floor -- @param inven the inventory to drop from -- @param item the item id to drop @@ -232,6 +236,9 @@ function _M:dropFloor(inven, item, vocal, all) if o:check("on_drop", self) then return false end o = self:removeObject(inven, item, all) + + self:onDropObject(o) + local ok, idx = game.level.map:addObject(self.x, self.y, o) if vocal then game.logSeen(self, "%s drops on the floor: %s.", self.name:capitalize(), o:getName{do_color=true}) end diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index ce38ef4bc03c87b16c4cc63cf230aa7cad447e65..aeac5345240266ef3a97a11e991b195cfbfe18f1 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -252,7 +252,7 @@ function _M:useEnergy(val) stalk.hit_turns = 0 end end - + -- Curse of Shrouds: turn shroud of passing on or off local eff = self:hasEffect(self.EFF_CURSE_OF_SHROUDS) if eff then self.tempeffect_def[self.EFF_CURSE_OF_SHROUDS].doShroudOfPassing(self, eff) end @@ -631,7 +631,7 @@ function _M:move(x, y, force) if not force and moved and (self.x ~= ox or self.y ~= oy) and not self.did_energy then local eff = self:hasEffect(self.EFF_CURSE_OF_SHROUDS) if eff then eff.moved = true end - + self:useEnergy(game.energy_to_act * self:combatMovementSpeed()) end end @@ -659,7 +659,7 @@ function _M:move(x, y, force) t.chooseCursedAuraTree(self, t) end end - + if moved and self:knowTalent(self.T_DEFILING_TOUCH) then local t = self:getTalentFromId(self.T_DEFILING_TOUCH) t.curseFloor(self, t, x, y) @@ -1662,7 +1662,7 @@ function _M:die(src, death_note) end end) end - + -- Curse of Corpses: Corpselight -- Curse of Corpses: Reprieve from Death if src and src.hasEffect and src:hasEffect(src.EFF_CURSE_OF_CORPSES) then @@ -1672,7 +1672,7 @@ function _M:die(src, death_note) def.doCorpselight(src, eff, self) end end - + -- Curse of Shrouds: Shroud of Death if src and src.hasEffect and src:hasEffect(src.EFF_CURSE_OF_SHROUDS) then local eff = src:hasEffect(src.EFF_CURSE_OF_SHROUDS) @@ -1917,7 +1917,9 @@ function _M:getEncumbrance() -- Compute encumbrance for inven_id, inven in pairs(self.inven) do for item, o in ipairs(inven) do - o:forAllStack(fct) + if not o.__transmo then + o:forAllStack(fct) + end end end -- print("Total encumbrance", enc) @@ -3182,3 +3184,30 @@ function _M:addedToLevel(level, x, y) self:check("on_added_to_level", level, x, y) end +--- Called upon dropping an object +function _M:onDropObject(o) + if self:attr("has_transmo") then o.__transmo = false end +end + +function _M:transmoPricemod(o) if o.type == "gem" then return 0.40 else return 0.05 end end +function _M:transmoFilter(o) if o:getPrice() <= 0 or o.quest then return false end return true end +function _M:transmoInven(inven, idx, o) + local price = math.min(o:getPrice() * self:transmoPricemod(o), 25) * o:getNumber() + local price = math.min(o:getPrice() * self:transmoPricemod(o), 25) * o:getNumber() + price = math.floor(price * 100) / 100 -- Make sure we get at most 2 digit precision + if price ~= price or not tostring(price):find("^[0-9]") then price = 1 end -- NaN is the only value that does not equals itself, this is the way to check it since we do not have a math.isnan method + self:removeObject(self:getInven("INVEN"), idx, true) + self:sortInven() + self:incMoney(price) + if self.hasQuest and self:hasQuest("shertul-fortress") then self:hasQuest("shertul-fortress"):gain_energy(price/10) end + game.log("You gain %0.2f gold from the transmogrification of %s.", price, o:getName{do_count=true, do_color=true}) +end + +function _M:transmo() + local d = require("mod.dialogs.ShowInventory").new("Transmogrify", self:getInven("INVEN"), function(o) return self:transmoFilter(o) end, function(o, idx) + self:transmoInven(self, inven, idx, o) + end, self) + game:registerDialog(d) + + return {id=true, used=true} +end diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 83172ce54c5235479d9f63c57741ae39e97d6aa1..7f86b28b2dc6babcf2a49093828521218632cc5b 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -563,6 +563,18 @@ function _M:changeLevel(lev, zone, keep_old_lev, force_down, auto_zone_stair) return end + -- Transmo! + local p = self:getPlayer(true) + if p:attr("has_transmo") then + local inven = p:getInven("INVEN") + for i = #inven, 1, -1 do + local o = inven[i] + if o.__transmo then + p:transmoInven(inven, i, o) + end + end + end + -- Finish stuff registered for the previous level self:onTickEndExecute() @@ -1392,7 +1404,7 @@ function _M:setupCommands() USERCHAT_SHOW_TALK = function() self.show_userchat = not self.show_userchat end, - + TOGGLE_BUMP_ATTACK = function() if (self.bump_attack_disabled) then self.log("Movement Mode: #LIGHT_GREEN#Default#LAST#.") @@ -1401,7 +1413,7 @@ function _M:setupCommands() self.log("Movement Mode: #LIGHT_RED#Passive#LAST#.") self.bump_attack_disabled = true end - + -- Update tooltip display if we're hovering over the icon. local mx, my = core.mouse.get() if (mx < self.icons.w and my > self.icons.display_y) then diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua index b6718e9a0a8d2a1877b307674e682c0452653e47..66cabae4ad8990dc46f7a34320a366bb87628448 100644 --- a/game/modules/tome/class/Object.lua +++ b/game/modules/tome/class/Object.lua @@ -957,6 +957,9 @@ function _M:getDesc(name_param, compare_with, never_compare) if self.__new_pickup then desc:add({"font","bold"},{"color","LIGHT_BLUE"},"Newly picked up",{"font","normal"},{"color","LAST"},true) end + if self.__transmo then + desc:add({"font","bold"},{"color","YELLOW"},"This item will automatically be transmogrified when you leave the level.",{"font","normal"},{"color","LAST"},true) + end name_param = name_param or {} name_param.do_color = true diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index a4c6bdad4367c24d45656a93d0060b9722a287ac..19a499a92be853b550eb7cb899600188d96838a3 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -159,7 +159,15 @@ function _M:describeFloor(x, y) local i, nb = 1, 0 local obj = game.level.map:getObject(x, y, i) while obj do - if not ((obj.auto_pickup and not obj.unique) and self:pickupFloor(i, true)) then + local desc = true + if (obj.auto_pickup and not obj.unique) and self:pickupFloor(i, true) then desc = false end + if self:attr("has_transmo") and obj.__transmo == nil then + if self:pickupFloor(i, true) then + desc = false + obj.__transmo = true + end + end + if desc then if self:attr("auto_id") and obj:getPowerRank() <= self.auto_id then obj:identify(true) end nb = nb + 1 i = i + 1 @@ -1048,7 +1056,7 @@ end function _M:attackOrMoveDir(dir) local tmp = game.bump_attack_disabled - + game.bump_attack_disabled = false self:moveDir(dir) game.bump_attack_disabled = tmp diff --git a/game/modules/tome/data/general/objects/quest-artifacts.lua b/game/modules/tome/data/general/objects/quest-artifacts.lua index fe8e8808ad3d69725eaaebd05fd849abf1cd136f..1afa38af9fb356769fec56de65d5085492b84457 100644 --- a/game/modules/tome/data/general/objects/quest-artifacts.lua +++ b/game/modules/tome/data/general/objects/quest-artifacts.lua @@ -339,4 +339,11 @@ You have heard of such items before. They are very useful to adventurers, allowi return {id=true, used=true} end }, + + on_drop = function(self, who) + if who == game.player then + game.logPlayer(who, "You cannot bring yourself to drop the %s", self:getName()) + return true + end + end, } diff --git a/game/modules/tome/data/gfx/metal-ui/inven_tabs/chest.png b/game/modules/tome/data/gfx/metal-ui/inven_tabs/chest.png new file mode 100644 index 0000000000000000000000000000000000000000..570a71d7cfe771049aae7d0a4a8b222110933bb6 Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/inven_tabs/chest.png differ diff --git a/game/modules/tome/data/zones/shertul-fortress/objects.lua b/game/modules/tome/data/zones/shertul-fortress/objects.lua index 737e801a7bd7011adecf968676394b6a8eb481ae..1133bc9bdfc19ac29bc5cb9518ef68eff003aa7b 100644 --- a/game/modules/tome/data/zones/shertul-fortress/objects.lua +++ b/game/modules/tome/data/zones/shertul-fortress/objects.lua @@ -29,45 +29,30 @@ newEntity{ base = "BASE_WAND", desc = [[This chest is an extension of Yiilkgur, any items dropped inside is transported to the Fortress, processed by the core and destroyed to extract energy. The byproduct of this effect is the creation of gold, which is useless to the Fortress, so it is sent back to you. -When activated it will prompt to destroy items on the floor, if there are none it prompts for your inventory.]], +When you possess the chest all items you walk upon will automatically be put inside and transmogrified when you leave the level. +Simply go to your inventory to move them out of the chest if you wish to keep them. +Items in the chest will not encumber you.]], cost = 0, quest=true, + carrier = { + has_transmo = 1, + }, +--[[ max_power = 1000, power_regen = 1, - pricemod = function(o) if o.type == "gem" then return 0.40 else return 0.05 end end, - transmo_filter = function(o) if o:getPrice() <= 0 or o.quest then return false end return true end, - transmo_inven = function(self, who, inven, idx, o) - local price = math.min(o:getPrice() * self.pricemod(o), 25) * o:getNumber() - local price = math.min(o:getPrice() * self.pricemod(o), 25) * o:getNumber() - price = math.floor(price * 100) / 100 -- Make sure we get at most 2 digit precision - if price ~= price or not tostring(price):find("^[0-9]") then price = 1 end -- NaN is the only value that does not equals itself, this is the way to check it since we do not have a math.isnan method - who:removeObject(who:getInven("INVEN"), idx, true) - who:sortInven() - who:incMoney(price) - who:hasQuest("shertul-fortress"):gain_energy(price/10) - game.log("You gain %0.2f gold from the transmogrification of %s.", price, o:getName{do_count=true, do_color=true}) - end, use_power = { name = "open a portal to send items to the Fortress core, extracting energies from it for the Fortress and sending back useless gold.", power = 0, use = function(self, who) - -- On the floor or inventory - if game.level.map:getObjectTotal(who.x, who.y) > 0 then - local x, y = who.x, who.y - local d = require("mod.dialogs.ShowPickupFloor").new("Transmogrify", x, y, self.transmo_filter, function(o, idx) - local price = math.min(o:getPrice() * self.pricemod(o), 25) * o:getNumber() - game.level.map:removeObject(x, y, idx) - who:incMoney(price) - who:hasQuest("shertul-fortress"):gain_energy(price/10) - game.log("You gain %0.2f gold from the transmogrification of %s.", price, o:getName{do_count=true, do_color=true}) - end, "Transmogrify all", who) - game:registerDialog(d) - else - local d = require("mod.dialogs.ShowInventory").new("Transmogrify", who:getInven("INVEN"), self.transmo_filter, function(o, idx) - self:transmo_inven(who, inven, idx, o) - end, who) - game:registerDialog(d) - end + who:transmo() return {id=true, used=true} end }, +]] + + on_drop = function(self, who) + if who == game.player then + game.logPlayer(who, "You cannot bring yourself to drop the %s", self:getName()) + return true + end + end, } newEntity{ base = "BASE_CLOTH_ARMOR", diff --git a/game/modules/tome/dialogs/ShowEquipInven.lua b/game/modules/tome/dialogs/ShowEquipInven.lua index bee368ee98e07cf9aa40136cb1f8b9c35979eb9e..6514e0632670d870f44956c7f63e83ab75299313 100644 --- a/game/modules/tome/dialogs/ShowEquipInven.lua +++ b/game/modules/tome/dialogs/ShowEquipInven.lua @@ -50,7 +50,7 @@ function _M:init(title, actor, filter, action, on_select) end } - self.c_tabs = ImageList.new{width=self.iw - 20 - self.c_doll.w, height=36, tile_w=32, tile_h=32, padding=5, force_size=true, selection="ctrl-multiple", list={ + local tabslist = { {image="metal-ui/inven_tabs/weapons.png", kind="weapons", desc="All kinds of weapons"}, {image="metal-ui/inven_tabs/armors.png", kind="armors", desc="All kinds of armours"}, {image="metal-ui/inven_tabs/jewelry.png", kind="jewelry", desc="Rings and Amulets"}, @@ -58,7 +58,10 @@ function _M:init(title, actor, filter, action, on_select) {image="metal-ui/inven_tabs/inscriptions.png", kind="inscriptions", desc="Infusions, Runes, ..."}, {image="metal-ui/inven_tabs/misc.png", kind="misc", desc="Miscellaneous"}, {image="metal-ui/inven_tabs/quests.png", kind="quests", desc="Quest and plot related items"}, - }, fct=function() self:generateList() end, on_select=function(item) self:select(item) end} + } + if actor:attr("has_transmo") then tabslist[#tabslist+1] = {image="metal-ui/inven_tabs/chest.png", kind="transmo", desc="Transmogrification Chest"} end + + self.c_tabs = ImageList.new{width=self.iw - 20 - self.c_doll.w, height=36, tile_w=32, tile_h=32, padding=5, force_size=true, selection="ctrl-multiple", list=tabslist, fct=function() self:generateList() end, on_select=function(item) self:select(item) end} self.c_tabs.dlist[1][1].selected = true self.c_tabs.no_keyboard_focus = true @@ -91,8 +94,8 @@ function _M:init(title, actor, filter, action, on_select) self:use(list[list.chars[c]]) end end, - _TAB = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = util.boundWrap(self.c_tabs.sel_i+1, 1, 7) self.c_tabs:onUse("left") end, - [{"_TAB","ctrl"}] = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = util.boundWrap(self.c_tabs.sel_i-1, 1, 7) self.c_tabs:onUse("left", false) end, + _TAB = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = util.boundWrap(self.c_tabs.sel_i+1, 1, 8) self.c_tabs:onUse("left") end, + [{"_TAB","ctrl"}] = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = util.boundWrap(self.c_tabs.sel_i-1, 1, 8) self.c_tabs:onUse("left", false) end, } self.key:addBinds{ HOTKEY_1 = function() self:defineHotkey(1) end, @@ -157,6 +160,7 @@ function _M:init(title, actor, filter, action, on_select) SWITCH_PARTY_5 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 5 self.c_tabs:onUse("left") end, SWITCH_PARTY_6 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 6 self.c_tabs:onUse("left") end, SWITCH_PARTY_7 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 7 self.c_tabs:onUse("left") end, + SWITCH_PARTY_8 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 8 self.c_tabs:onUse("left") end, ORDER_PARTY_1 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 1 self.c_tabs:onUse("left", true) end, ORDER_PARTY_2 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 2 self.c_tabs:onUse("left", true) end, ORDER_PARTY_3 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 3 self.c_tabs:onUse("left", true) end, @@ -164,6 +168,7 @@ function _M:init(title, actor, filter, action, on_select) ORDER_PARTY_5 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 5 self.c_tabs:onUse("left", true) end, ORDER_PARTY_6 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 6 self.c_tabs:onUse("left", true) end, ORDER_PARTY_7 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 7 self.c_tabs:onUse("left", true) end, + ORDER_PARTY_8 = function() self.c_tabs.sel_j = 1 self.c_tabs.sel_i = 87 self.c_tabs:onUse("left", true) end, } -- Add tooltips @@ -226,12 +231,13 @@ function _M:use(item, button, event) end local tab_filters = { - weapons = function(o) return o.type == "weapon" end, - armors = function(o) return o.type == "armor" end, - gems = function(o) return o.type == "gem" or o.type == "alchemist-gem" end, - jewelry = function(o) return o.type == "jewelry" end, - inscriptions = function(o) return o.type == "scroll" end, - quests = function(o) return o.plot or o.quest end, + weapons = function(o) return not o.__transmo and (o.type == "weapon") end, + armors = function(o) return not o.__transmo and (o.type == "armor") end, + gems = function(o) return not o.__transmo and (o.type == "gem" or o.type == "alchemist-gem") end, + jewelry = function(o) return not o.__transmo and (o.type == "jewelry") end, + inscriptions = function(o) return not o.__transmo and (o.type == "scroll") end, + quests = function(o) return not o.__transmo and (o.plot or o.quest) end, + transmo = function(o) return o.__transmo end, } function _M:updateTabFilter() @@ -245,6 +251,7 @@ function _M:updateTabFilter() elseif item.data.kind == "jewelry" then checks[#checks+1] = tab_filters.jewelry elseif item.data.kind == "inscriptions" then checks[#checks+1] = tab_filters.inscriptions elseif item.data.kind == "quests" then checks[#checks+1] = tab_filters.quests + elseif item.data.kind == "transmo" then checks[#checks+1] = tab_filters.transmo elseif item.data.kind == "misc" then local misc misc = function(o) diff --git a/game/modules/tome/dialogs/UseItemDialog.lua b/game/modules/tome/dialogs/UseItemDialog.lua index b2de7bea0aebfb649257953da88d792ad62f83f4..f5e8041c5cf1991908a01afe206b7c0085857ce6 100644 --- a/game/modules/tome/dialogs/UseItemDialog.lua +++ b/game/modules/tome/dialogs/UseItemDialog.lua @@ -77,9 +77,12 @@ function _M:use(item) elseif act == "transmo" then self:yesnoPopup("Transmogrify", "Really transmogrify "..self.object:getName{}, function(ret) if not ret then return end - item.transmo:transmo_inven(self.actor, self.inven, self.item, self.object) + self.actor:transmoInven(self.inven, self.item, self.object) self.onuse(self.inven, self.item, self.object, false) end) + elseif act == "toinven" then + self.object.__transmo = false + self.onuse(self.inven, self.item, self.object, false) elseif act == "chat-link" then profile.chat.uc_ext:sendObjectLink(self.object) end @@ -88,13 +91,17 @@ end function _M:generateList() local list = {} - local transmo_chest = self.actor:findInAllInventoriesBy("define_as", "TRANSMO_CHEST") + local transmo_chest = self.actor:attr("has_transmo") - if self.object:canUseObject() then list[#list+1] = {name="Use", action="use"} end - if self.inven == self.actor.INVEN_INVEN and self.object:wornInven() and self.actor:getInven(self.object:wornInven()) then list[#list+1] = {name="Wield/Wear", action="wear"} end - if self.inven ~= self.actor.INVEN_INVEN and self.object:wornInven() then list[#list+1] = {name="Take off", action="takeoff"} end + if not self.object.__transmo then + if self.object:canUseObject() then list[#list+1] = {name="Use", action="use"} end + if self.inven == self.actor.INVEN_INVEN and self.object:wornInven() and self.actor:getInven(self.object:wornInven()) then list[#list+1] = {name="Wield/Wear", action="wear"} end + if self.inven ~= self.actor.INVEN_INVEN and self.object:wornInven() then list[#list+1] = {name="Take off", action="takeoff"} end + else + list[#list+1] = {name="Move to normal inventory", action="toinven"} + end if self.inven == self.actor.INVEN_INVEN then list[#list+1] = {name="Drop", action="drop"} end - if self.inven == self.actor.INVEN_INVEN and transmo_chest and transmo_chest.transmo_filter(self.object) then list[#list+1] = {name="Transmogrify", action="transmo", transmo=transmo_chest} end + if self.inven == self.actor.INVEN_INVEN and transmo_chest and self.actor:transmoFilter(self.object) then list[#list+1] = {name="Transmogrify now", action="transmo"} end if profile.auth and profile.hash_valid then list[#list+1] = {name="Link item in chat", action="chat-link"} end self.max = 0