From ccff30e0db2dd1a837fac247931eacaf041173a4 Mon Sep 17 00:00:00 2001 From: DarkGod <darkgod@net-core.org> Date: Fri, 25 Jul 2014 01:23:30 +0200 Subject: [PATCH] shhh super secret! --- game/engines/default/engine/ui/EquipDoll.lua | 23 +++++- .../default/engine/ui/EquipDollFrame.lua | 7 +- game/modules/tome/class/Actor.lua | 73 +++++++++++++++++++ game/modules/tome/class/Object.lua | 12 +++ game/modules/tome/dialogs/ShowEquipInven.lua | 56 +++++++++++--- game/modules/tome/load.lua | 20 ++--- 6 files changed, 168 insertions(+), 23 deletions(-) diff --git a/game/engines/default/engine/ui/EquipDoll.lua b/game/engines/default/engine/ui/EquipDoll.lua index 0fbca59dd1..f1fb7b6873 100644 --- a/game/engines/default/engine/ui/EquipDoll.lua +++ b/game/engines/default/engine/ui/EquipDoll.lua @@ -123,13 +123,34 @@ function _M:generateEquipDollFrames() if inven then for item, def in ipairs(v) do if item > inven.max then break end - local frame = EquipDollFrame.new{actor=self.actor, inven=inven, name_pos=def.text, item=item, w=doll.w, h=doll.h, iw=doll.iw, ih=doll.ih, ix=doll.ix, iy=doll.iy, bg=doll.itemframe, bg_sel=doll.itemframe_sel, bg_empty=self.actor.inven_def[inven.name].infos and self.actor.inven_def[inven.name].infos.equipdoll_back, drag_enable=self.drag_enable, subobject=self.subobject} + + local frame = EquipDollFrame.new{actor=self.actor, inven=inven, name_pos=def.text, item=item, w=doll.w, h=doll.h, iw=doll.iw, ih=doll.ih, ix=doll.ix, iy=doll.iy, bg=doll.itemframe, bg_sel=doll.itemframe_sel, bg_empty=self.actor.inven_def[inven.name].infos and self.actor.inven_def[inven.name].infos.equipdoll_back, drag_enable=self.drag_enable} frame.doll_select = true frame.actorWear = function(_, ...) if self.actorWear then self.actorWear(frame, ...) end end frame.fct=function(button, event) if frame:getItem() and self.fct then self.fct({inven=inven, item=item, object=frame:getItem()}, button, event) end end frame.filter = self.filter frame.on_focus_change=function(status) local ui = self.focus_ui if self.on_select and ui then self.on_select(ui, ui.ui.inven, ui.ui.item, ui.ui:getItem()) end end uis[#uis+1] = {x=def.x, y=def.y, ui=frame, _weight=def.weight} + + if self.subobject then + local frame = EquipDollFrame.new{actor=self.actor, inven=inven, name_pos=def.text, item=item, w=math.ceil(doll.w/2), h=math.ceil(doll.h/2), iw=math.ceil(doll.iw/2), ih=math.ceil(doll.ih/2), ix=math.floor(doll.ix/2), iy=math.floor(doll.iy/2), bg=doll.itemframe, bg_sel=doll.itemframe_sel, bg_empty=self.actor.inven_def[inven.name].infos and self.actor.inven_def[inven.name].infos.equipdoll_back, drag_enable=self.drag_enable, subobject=self.subobject} + frame.doll_select = true + frame.secondary = true + frame.no_name = true + frame.actorWear = function(_, ...) if self.actorWear then self.actorWear(frame, ...) end end + frame.fct=function(button, event) if frame:getItem() and self.fct then self.fct({inven=inven, item=item, object=frame:getItem()}, button, event) end end + frame.filter = self.filter + frame.on_focus_change=function(status) local ui = self.focus_ui if self.on_select and ui then self.on_select(ui, ui.ui.inven, ui.ui.item, ui.ui:getItem()) end end + + local dsx, dsy = doll.w + 3, 0 + if def.subshift == "up" then dsx, dsy = 0, -math.ceil(doll.h/2) - 3 + elseif def.subshift == "bottom" then dsx, dsy = 0, doll.h + 3 + elseif def.subshift == "left" then dsx, dsy = -math.ceil(doll.w/2) - 3, 0 + end + + uis[#uis+1] = {x=def.x + dsx, y=def.y + dsy, ui=frame, _weight=def.weight} + end + max_w = math.max(def.x, max_w) max_h = math.max(def.y, max_h) end diff --git a/game/engines/default/engine/ui/EquipDollFrame.lua b/game/engines/default/engine/ui/EquipDollFrame.lua index 144a8023a3..d23de2f9ad 100644 --- a/game/engines/default/engine/ui/EquipDollFrame.lua +++ b/game/engines/default/engine/ui/EquipDollFrame.lua @@ -105,6 +105,7 @@ end function _M:drawItemShortName(o, x, y) if not o then return end + if self.no_name then return end local t = nil if self.last_o == o then @@ -137,16 +138,16 @@ end function _M:display(x, y, nb_keyframes, ox, oy) if self.focused then - self.bg_sel.t:toScreenFull(x, y, self.w, self.h, self.bg_sel.tw, self.bg_sel.th) + self.bg_sel.t:toScreenPrecise(x, y, self.w, self.h, 0, self.bg_sel.w/self.bg_sel.tw, 0, self.bg_sel.h/self.bg_sel.th) else - self.bg.t:toScreenFull(x, y, self.w, self.h, self.bg.tw, self.bg.th) + self.bg.t:toScreenPrecise(x, y, self.w, self.h, 0, self.bg.w/self.bg.tw, 0, self.bg.h/self.bg.th) end local o = self:getItem() if o and o.toScreen then o:toScreen(nil, x + self.f_ix, y + self.f_iy, self.f_iw, self.f_ih) elseif self.bg_empty then - self.bg_empty.t:toScreenFull(x + self.f_ix, y + self.f_iy, self.f_iw, self.f_ih, self.bg_empty.tw, self.bg_empty.th) + self.bg_empty.t:toScreenPrecise(x + self.f_ix, y + self.f_iy, self.f_iw, self.f_ih, 0, self.bg_empty.w/self.bg_empty.tw, 0, self.bg_empty.h/self.bg_empty.th) end self:drawItemShortName(o, x, y) diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index d3b24df6fd..c45fa9efae 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -6078,3 +6078,76 @@ end function _M:transmoGetWord() return "transmogrify" end + +function _M:doTakeoffTinker(base_o, oldo) + if base_o.tinker ~= oldo then return end + + local mustwear = base_o.wielded + if mustwear then self:onTakeoff(base_o, true) end + base_o.tinker = nil + local forbid = oldo:check("on_untinker", base_o, self) + if oldo.tinkered then + for k, id in pairs(oldo.tinkered) do + if type(id) == "table" then base_o:removeTemporaryValue(id[1], id[2]) + else base_o:removeTemporaryValue(k, id) + end + end + end + oldo.tinkered = nil + if mustwear then self:onWear(base_o, true) end + + self:addObject(self.INVEN_INVEN, oldo) + game.logPlayer(self, "You detach %s from your %s.", oldo:getName{do_color=true}, base_o:getName{do_color=true}) + + return true +end + +function _M:doWearTinker(wear_inven, wear_item, wear_o, base_inven, base_item, base_o, can_remove) + if not base_o then + game.logPlayer(self, "You can not use a tinker without the corresponding item.") + return + end + if not wear_o.is_tinker then + game.logPlayer(self, "This item is not a tinker.") + return + end + if wear_o.on_type and wear_o.on_type ~= rawget(base_o, "type") then + game.logPlayer(self, "This tinker can not be applied to this item.") + return + end + if wear_o.on_slot and wear_o.on_slot ~= base_o.slot then + game.logPlayer(self, "This tinker can not be applied to this item.") + return + end + if base_o.tinker then + if not can_remove then + game.logPlayer(self, "You already have a tinker on this item.") + return + else + self:doTakeoffTinker(base_o, base_o.tinker) + end + end + + local mustwear = base_o.wielded + if mustwear then self:onTakeoff(base_o, true) end + + wear_o.tinkered = {} + local forbid = wear_o:check("on_tinker", base_o, self) + if wear_o.object_tinker then + for k, e in pairs(wear_o.object_tinker) do + table.print(e) + wear_o.tinkered[k] = base_o:addTemporaryValue(k, e) + end + end + + if mustwear then self:onWear(base_o, true) end + + if not forbid then + base_o.tinker = wear_o + game.logPlayer(self, "You attach %s to your %s.", wear_o:getName{do_color=true}, base_o:getName{do_color=true}) + + self:removeObject(wear_inven, wear_item) + else + game.logPlayer(self, "You fail to attach %s to %s.", wear_o:getName{do_color=true}, base_o:getName{do_color=true}) + end +end diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua index 9a6b3edd7a..ecef6c607d 100644 --- a/game/modules/tome/class/Object.lua +++ b/game/modules/tome/class/Object.lua @@ -1921,3 +1921,15 @@ function _M:addedToLevel(level, x, y) self.__price_level_mod = util.getval(level.data.objects_cost_modifier, self) end end + +function _M:getTinker() + return self.tinker +end + +function _M:canAttachTinker(tinker, override) + if not tinker.is_tinker then return end + if tinker.on_type and tinker.on_type ~= rawget(self, "type") then return end + if tinker.on_slot and tinker.on_slot ~= self.slot then return end + if self.tinker and not override then return end + return true +end diff --git a/game/modules/tome/dialogs/ShowEquipInven.lua b/game/modules/tome/dialogs/ShowEquipInven.lua index 3452c73470..b1511703c3 100644 --- a/game/modules/tome/dialogs/ShowEquipInven.lua +++ b/game/modules/tome/dialogs/ShowEquipInven.lua @@ -52,19 +52,31 @@ function _M:init(title, equip_actor, filter, action, on_select, inven_actor) end end - self.c_doll = EquipDoll.new{actor=equip_actor, drag_enable=true, filter=filter, + self.c_doll = EquipDoll.new{subobject=equip_actor:attr("can_tinker") and "getTinker" or nil, actor=equip_actor, drag_enable=true, filter=filter, fct = function(item, button, event) self:use(item, button, event) end, on_select = function(ui, inven, item, o) if ui.ui.last_display_x then self:select{last_display_x=ui.ui.last_display_x+ui.ui.w, last_display_y=ui.ui.last_display_y, object=o} end end, actorWear = function(ui, wear_inven, wear_item, wear_o) - if ui:getItem() then - local bi = self.equip_actor:getInven(ui.inven) - local ws = self.equip_actor:getInven(wear_o:wornInven()) - local os = self.equip_actor:getObjectOffslot(wear_o) - if bi and ((ws and ws.id == bi.id) or (os and self.equip_actor:getInven(os).id == bi.id)) then - self.equip_actor:doTakeoff(ui.inven, ui.item, ui:getItem(), true, self.inven_actor) + if wear_o.is_tinker then + local base_inven, base_item = ui.inven, ui.item + -- Find appropriate slot + if not base_inven or not base_item then + base_inven, base_item = self:findTinkerSpot(wear_o) end + if base_inven and base_item then + local base_o = base_inven[base_item] + self.equip_actor:doWearTinker(wear_inven, wear_item, wear_o, base_inven, base_item, base_o, true) + end + else + if ui:getItem() then + local bi = self.equip_actor:getInven(ui.inven) + local ws = self.equip_actor:getInven(wear_o:wornInven()) + local os = self.equip_actor:getObjectOffslot(wear_o) + if bi and ((ws and ws.id == bi.id) or (os and self.equip_actor:getInven(os).id == bi.id)) then + self.equip_actor:doTakeoff(ui.inven, ui.item, ui:getItem(), true, self.inven_actor) + end + end + self.equip_actor:doWear(wear_inven, wear_item, wear_o, self.inven_actor) end - self.equip_actor:doWear(wear_inven, wear_item, wear_o, self.inven_actor) self.c_inven:generateList() end } @@ -261,7 +273,12 @@ end function _M:onDragTakeoff() local drag = game.mouse.dragged.payload - if drag.kind == "inventory" and drag.inven and self.equip_actor:getInven(drag.inven) and self.equip_actor:getInven(drag.inven).worn then + + if drag.kind == "inventory" and drag.inven and self.equip_actor:getInven(drag.inven) and self.equip_actor:getInven(drag.inven).worn and drag.object.is_tinker then + self.equip_actor:doTakeoffTinker(self.equip_actor:getInven(drag.inven)[drag.item_idx], drag.object) + self.c_inven:generateList() + game.mouse:usedDrag() + elseif drag.kind == "inventory" and drag.inven and self.equip_actor:getInven(drag.inven) and self.equip_actor:getInven(drag.inven).worn then self.equip_actor:doTakeoff(drag.inven, drag.item_idx, drag.object, nil, self.inven_actor) self.c_inven:generateList() game.mouse:usedDrag() @@ -280,3 +297,24 @@ end function _M:generateList() self.c_inven:generateList() end + +function _M:findTinkerSpot(tinker) + local possible = {} + self.equip_actor:inventoryApplyAll(function(inven, item, o) + if not inven.worn then return end + if o:canAttachTinker(tinker, true) then + possible[#possible+1] = {inven=inven, item=item, free=o.tinker and 1 or 0} + end + end) + if #possible == 0 then return end + + -- Find one that has no atatchement if possible, if not replace one + table.sort(possible, function(a, b) + if a.free ~= b.free then return a.free < b.free + elseif a.inven.id ~= b.inven.id then return a.inven.id < b.inven.id + else return a.item < b.item + end + end) + table.print(possible) + return possible[1].inven, possible[1].item +end diff --git a/game/modules/tome/load.lua b/game/modules/tome/load.lua index 9e79676c20..8dacb8096e 100644 --- a/game/modules/tome/load.lua +++ b/game/modules/tome/load.lua @@ -183,20 +183,20 @@ ActorInventory:defineInventory("QS_PSIONIC_FOCUS", "Second weapon set: psionic f ActorInventory:defineInventory("QS_QUIVER", "Second weapon set: Quiver", false, "Weapon Set 2: Your readied ammo.", true) ActorInventory.equipdolls = { default = { w=48, h=48, itemframe="ui/equipdoll/itemframe48.png", itemframe_sel="ui/equipdoll/itemframe-sel48.png", ix=3, iy=3, iw=42, ih=42, doll_x=116, doll_y=168+64, list={ - PSIONIC_FOCUS = {{weight=1, x=48, y=48}}, - MAINHAND = {{weight=2, x=48, y=120}}, - OFFHAND = {{weight=3, x=48, y=192}}, - BODY = {{weight=4, x=48, y=264}}, - QUIVER = {{weight=5, x=48, y=336}}, - FINGER = {{weight=6, x=48, y=408}, {weight=7, x=120, y=408, text="bottom"}}, - LITE = {{weight=8, x=192, y=408}}, - TOOL = {{weight=9, x=264, y=408, text="bottom"}}, + PSIONIC_FOCUS = {{weight=1, x=48, y=48, subshift="left"}}, + MAINHAND = {{weight=2, x=48, y=120, subshift="left"}}, + OFFHAND = {{weight=3, x=48, y=192, subshift="left"}}, + BODY = {{weight=4, x=48, y=264, subshift="left"}}, + QUIVER = {{weight=5, x=48, y=336, subshift="left"}}, + FINGER = {{weight=6, x=48, y=408, subshift="bottom"}, {weight=7, x=120, y=408, text="bottom", subshift="bottom"}}, + LITE = {{weight=8, x=192, y=408, subshift="bottom"}}, + TOOL = {{weight=9, x=264, y=408, subshift="bottom", text="bottom"}}, FEET = {{weight=10, x=264, y=336}}, BELT = {{weight=11, x=264, y=264}}, HANDS = {{weight=12, x=264, y=192}}, CLOAK = {{weight=13, x=264, y=120}}, - NECK = {{weight=14, x=192, y=48, text="topright"}}, - HEAD = {{weight=15, x=120, y=48, text="topleft"}}, + NECK = {{weight=14, x=192, y=48, subshift="bottom", text="topright"}}, + HEAD = {{weight=15, x=120, y=48, subshift="bottom", text="topleft"}}, }}, alchemist_golem = { w=48, h=48, itemframe="ui/equipdoll/itemframe48.png", itemframe_sel="ui/equipdoll/itemframe-sel48.png", ix=3, iy=3, iw=42, ih=42, doll_x=116, doll_y=168+64, list={ MAINHAND = {{weight=1, x=48, y=120}}, -- GitLab