diff --git a/game/engines/default/data/gfx/metal-ui/equipdoll/itemframe-sel48.png b/game/engines/default/data/gfx/metal-ui/equipdoll/itemframe-sel48.png new file mode 100644 index 0000000000000000000000000000000000000000..d5a5a849ee9003acaf551878201f1e902aefbeec Binary files /dev/null and b/game/engines/default/data/gfx/metal-ui/equipdoll/itemframe-sel48.png differ diff --git a/game/engines/default/data/gfx/metal-ui/equipdoll/itemframe48.png b/game/engines/default/data/gfx/metal-ui/equipdoll/itemframe48.png new file mode 100644 index 0000000000000000000000000000000000000000..954804eb655ef18861655b3606a9166bf7c65f0c Binary files /dev/null and b/game/engines/default/data/gfx/metal-ui/equipdoll/itemframe48.png differ diff --git a/game/engines/default/engine/KeyBind.lua b/game/engines/default/engine/KeyBind.lua index 764be6d0c24b06f74dec479cbd323aa80b91fac5..ad91fa21db71f94f29bd2ea2f8308081a5084ed6 100644 --- a/game/engines/default/engine/KeyBind.lua +++ b/game/engines/default/engine/KeyBind.lua @@ -214,7 +214,7 @@ function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode, isup, key, ismouse) if self.any_key then self.any_key(sym, ctrl, shift, alt, meta, unicode, isup, key) end - local ks, us + local ks, kks, us if not ismouse then ks, kks, us = self:makeKeyString(sym, ctrl, shift, alt, meta, unicode, key) else ks = self:makeMouseString(sym, ctrl, shift, alt, meta) end -- print(self, "[BIND]", sym, ctrl, shift, alt, meta, unicode, " :=: ", ks, kks, us, " ?=? ", self.binds[ks], kks and self.binds[kks], us and self.binds[us]) diff --git a/game/engines/default/engine/interface/ActorInventory.lua b/game/engines/default/engine/interface/ActorInventory.lua index 0cd774e26e32f29d212ebe37a74edce1c1d22963..f53228efa6be0a91ee864485fde6c06d80c76d4e 100644 --- a/game/engines/default/engine/interface/ActorInventory.lua +++ b/game/engines/default/engine/interface/ActorInventory.lua @@ -31,7 +31,7 @@ _M.inven_def = {} --- Defines stats -- Static! -function _M:defineInventory(short_name, name, is_worn, desc, show_equip) +function _M:defineInventory(short_name, name, is_worn, desc, show_equip, infos) assert(name, "no inventory slot name") assert(short_name, "no inventory slot short_name") assert(desc, "no inventory slot desc") @@ -41,6 +41,7 @@ function _M:defineInventory(short_name, name, is_worn, desc, show_equip) description = desc, is_worn = is_worn, is_shown_equip = show_equip, + infos = infos, }) self.inven_def[#self.inven_def].id = #self.inven_def self.inven_def[short_name] = self.inven_def[#self.inven_def] @@ -60,7 +61,7 @@ end function _M:initBody() if self.body then for inven, max in pairs(self.body) do - self.inven[self["INVEN_"..inven]] = {max=max, worn=self.inven_def[self["INVEN_"..inven]].is_worn, id=self["INVEN_"..inven]} + self.inven[self["INVEN_"..inven]] = {max=max, worn=self.inven_def[self["INVEN_"..inven]].is_worn, id=self["INVEN_"..inven], name=inven} end self.body = nil end diff --git a/game/engines/default/engine/ui/Dialog.lua b/game/engines/default/engine/ui/Dialog.lua index fbf3f6adafbb9e50474e1ffab7fa7a27b5ca66b8..80ea2226b8f987221e69ba03affc668f312c5a8e 100644 --- a/game/engines/default/engine/ui/Dialog.lua +++ b/game/engines/default/engine/ui/Dialog.lua @@ -446,11 +446,11 @@ function _M:setFocus(id) for i = 1, #self.uis do if self.uis[i].ui == id then id = i break end end - if type(id) == "table" then return end + if type(id) == "table" then self:no_focus() return end end local ui = self.uis[id] - if not ui.ui.can_focus then return end + if not ui.ui.can_focus then self:no_focus() return end self.focus_ui = ui self.focus_ui_id = id ui.ui:setFocus(true) @@ -504,6 +504,8 @@ end function _M:on_focus(id, ui) end +function _M:no_focus() +end function _M:mouseEvent(button, x, y, xrel, yrel, bx, by, event) -- Look for focus @@ -514,9 +516,10 @@ function _M:mouseEvent(button, x, y, xrel, yrel, bx, by, event) -- Pass the event ui.ui.mouse:delegate(button, bx, by, xrel, yrel, bx, by, event) - break + return end end + self:no_focus() end function _M:keyEvent(...) @@ -570,6 +573,8 @@ function _M:drawFrame(x, y, r, g, b, a) end end +function _M:innerDisplayBack(x, y, nb_keyframes) +end function _M:innerDisplay(x, y, nb_keyframes) end @@ -617,6 +622,8 @@ function _M:toScreen(x, y, nb_keyframes) self.title_tex[1]:toScreenFull(x + (self.w - self.title_tex.w) / 2 + self.frame.title_x, y + self.frame.title_y, self.title_tex.w, self.title_tex.h, self.title_tex[2], self.title_tex[3]) end + self:innerDisplayBack(x, y, nb_keyframes, tx, ty) + -- UI elements for i = 1, #self.uis do local ui = self.uis[i] diff --git a/game/engines/default/engine/ui/EquipDollFrame.lua b/game/engines/default/engine/ui/EquipDollFrame.lua new file mode 100644 index 0000000000000000000000000000000000000000..f27e97b9e0258dc88aab2800ade040a82ac30e5b --- /dev/null +++ b/game/engines/default/engine/ui/EquipDollFrame.lua @@ -0,0 +1,108 @@ +-- TE4 - T-Engine 4 +-- Copyright (C) 2009, 2010, 2011 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +require "engine.class" +local Base = require "engine.ui.Base" +local Focusable = require "engine.ui.Focusable" + +module(..., package.seeall, class.inherit(Base, Focusable)) + +function _M:init(t) + self.actor = assert(t.actor, "no equipdollframe actor") + self.inven = assert(t.inven, "no equipdollframe inven") + self.item = assert(t.item, "no equipdollframe item") + self.w = assert(t.w, "no equipdollframe w") + self.h = assert(t.h, "no equipdollframe h") + self.f_iw = assert(t.iw, "no equipdollframe iw") + self.f_ih = assert(t.ih, "no equipdollframe ih") + self.f_ix = assert(t.ix, "no equipdollframe ix") + self.f_iy = assert(t.iy, "no equipdollframe iy") + self.bg = assert(t.bg, "no equipdollframe bg") + self.bg_sel = assert(t.bg_sel, "no equipdollframe bg_sel") + self.bg_empty = t.bg_empty + self.drag_enable = t.drag_enable + self.fct = t.fct + + Base.init(self, t) +end + +function _M:generate() + self.mouse:reset() + self.key:reset() + + self.bg = self:getUITexture(self.bg) + self.bg_sel = self:getUITexture(self.bg_sel) + if self.bg_empty then self.bg_empty = self:getUITexture(self.bg_empty) end + + self.mouse:registerZone(0, 0, self.w, self.h, function(button, x, y, xrel, yrel, bx, by, event) + if button == "left" and event == "button" then self:onUse(button, event) end + if event == "motion" and button == "left" and self.inven[self.item] then self:onDrag(self.inven, self.item, self.inven[self.item]) + elseif button == "drag-end" and self.drag_enable then + local drag = game.mouse.dragged.payload + print(table.serialize(drag,nil,true)) + if drag.kind == "inventory" and drag.inven and self.actor:getInven(drag.inven) and not self.actor:getInven(drag.inven).worn then + self:actorWear(drag.inven, drag.item_idx, drag.object) + game.mouse:usedDrag() + end + end + end) + self.key:addBinds{ + ACCEPT = function() self:onUse("left", "key") end, + } +end + +function _M:onUse(...) + if not self.fct then return end + self:sound("button") + self.fct(...) +end + +-- Overload to do as you need +function _M:actorWear(inven, item, o) +end + +function _M:onDrag(inven, item, o) + if not self.drag_enable then return end + if o then + local s = o:getEntityFinalSurface(nil, 64, 64) + local x, y = core.mouse.get() + game.mouse:startDrag(x, y, s, {kind="inventory", item_idx=item, inven=inven, object=o, id=o:getName{no_add_name=true, force_id=true, no_count=true}}, function(drag, used) + local x, y = core.mouse.get() + game.mouse:receiveMouse("drag-end", x, y, true, nil, {drag=drag}) + end) + end +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) + else + self.bg.t:toScreenFull(x, y, self.w, self.h, self.bg.tw, self.bg.th) + end + + local o = self.inven[self.item] + 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) + end + + self.last_display_x = ox + self.last_display_y = oy +end diff --git a/game/engines/default/engine/ui/ListColumns.lua b/game/engines/default/engine/ui/ListColumns.lua index a922192a0f632a8ef8e6749b19e1ada33fc07ec2..b5a1000b3d97ebe3a1520235c486afbdaf5afa29 100644 --- a/game/engines/default/engine/ui/ListColumns.lua +++ b/game/engines/default/engine/ui/ListColumns.lua @@ -37,6 +37,7 @@ function _M:init(t) self.fct = t.fct self.select = t.select self.on_drag = t.on_drag + self.on_drag_end = t.on_drag_end self.all_clicks = t.all_clicks self.hide_columns = t.hide_columns @@ -186,6 +187,7 @@ function _M:generate() self:onSelect() if (self.all_clicks or button == "left") and event == "button" then self:onUse(button, event) end if event == "motion" and button == "left" and self.on_drag then self.on_drag(self.list[self.sel], self.sel) end + if button == "drag-end" and self.on_drag_end then self.on_drag_end(self.list[self.sel], self.sel) end end) self.key:addBinds{ ACCEPT = function() self:onUse("left", "key") end, diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 7a9a4cfe76fcbc3e87000ebbe657080fe254673b..b13317b9b7badc76c2e6091cb40fead18b8c6231 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -1177,17 +1177,6 @@ function _M:onTakeHit(value, src) value = t.do_onTakeHit(self, t, self:isTalentActive(self.T_DEFLECTION), value) end - -- Mount takes some damage ? - local mount = self:hasMount() - if mount and mount.mount.share_damage then - mount.mount.actor:takeHit(value * mount.mount.share_damage / 100, src) - value = value * (100 - mount.mount.share_damage) / 100 - -- Remove the dead mount - if mount.mount.actor.dead and mount.mount.effect then - self:removeEffect(mount.mount.effect) - end - end - -- Achievements if not self.no_take_hit_achievements and src and src.resolveSource and src:resolveSource().player and value >= 600 then local rsrc = src:resolveSource() diff --git a/game/modules/tome/class/GameState.lua b/game/modules/tome/class/GameState.lua index 6506c2a4efaa1386fbd9e086914006a04defbfb5..eac86b7b8f6786e196882df15efd0c950759074f 100644 --- a/game/modules/tome/class/GameState.lua +++ b/game/modules/tome/class/GameState.lua @@ -1341,7 +1341,7 @@ function _M:createRandomBoss(base, data) -- All bosses have alll body parts .. yes snake bosses can use archery and so on .. -- This is to prevent them from having unusable talents b.inven = {} - b.body = { INVEN = 1000, QS_MAINHAND = 1, QS_OFFHAND = 1, MAINHAND = 1, OFFHAND = 1, FINGER = 2, NECK = 1, LITE = 1, BODY = 1, HEAD = 1, CLOAK = 1, HANDS = 1, BELT = 1, FEET = 1, TOOL = 1, QUIVER = 1, MOUNT = 1 } + b.body = { INVEN = 1000, QS_MAINHAND = 1, QS_OFFHAND = 1, MAINHAND = 1, OFFHAND = 1, FINGER = 2, NECK = 1, LITE = 1, BODY = 1, HEAD = 1, CLOAK = 1, HANDS = 1, BELT = 1, FEET = 1, TOOL = 1, QUIVER = 1 } b:initBody() b:resolve() diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 233469fea306b2c92ba713966206d2cd379a5eeb..b4c23acbb6536c03a0eb6f8887f46f4744de3699 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -150,12 +150,6 @@ function _M:attackTarget(target, damtype, mult, noenergy) if not self.combat.no_stealth_break then break_stealth = true end end - -- Mount attack ? - local mount = self:hasMount() - if mount and mount.mount.attack_with_rider and core.fov.distance(self.x, self.y, target.x, target.y) <= 1 then - mount.mount.actor:attackTarget(target, nil, nil, nil) - end - -- We use up our own energy if speed and not noenergy then self:useEnergy(game.energy_to_act * speed) @@ -214,7 +208,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) -- Does the blow connect? yes .. complex :/ local atk, def = self:combatAttack(weapon), target:combatDefense() - + -- add stalker damage and attack bonus local effStalker = self:hasEffect(self.EFF_STALKER) if effStalker and effStalker.target == target then @@ -222,7 +216,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) atk = atk + t.getAttackChange(self, t, effStalker.bonus) mult = mult * t.getStalkedDamageMultiplier(self, t, effStalker.bonus) end - + if not self:canSee(target) then atk = atk / 3 end local dam, apr, armor = force_dam or self:combatDamage(weapon), self:combatAPR(weapon), target:combatArmor() print("[ATTACK] to ", target.name, " :: ", dam, apr, armor, def, "::", mult) @@ -238,7 +232,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) local t = target:getTalentFromId(target.T_REPEL) repelled = t.isRepelled(target, t) end - + -- If hit is over 0 it connects, if it is 0 we still have 50% chance local hitted = false local crit = false @@ -276,7 +270,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) local srcname = game.level.map.seens(self.x, self.y) and self.name:capitalize() or "Something" game.logSeen(target, "%s misses %s.", srcname, target.name) end - + -- handle stalk targeting for hits (also handled in Actor for turn end effects) if hitted and target ~= self then if effStalker then @@ -284,7 +278,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) effStalker.hit = effStalker.hit or effStalker.target == target elseif self:isTalentActive(self.T_STALK) then local stalk = self:isTalentActive(self.T_STALK) - + if not stalk.hit then -- mark a new target stalk.hit = true @@ -348,7 +342,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) local dam = t.getDamage(self, t) DamageType:get(DamageType.DRAINLIFE).projector(self, target.x, target.y, DamageType.DRAINLIFE, dam) end - + -- Autospell cast if hitted and not target.dead and self:knowTalent(self.T_ARCANE_COMBAT) and self:isTalentActive(self.T_ARCANE_COMBAT) then local t = self:getTalentFromId(self.T_ARCANE_COMBAT) @@ -750,7 +744,7 @@ function _M:getOffHandMult(mult) elseif self:knowTalent(Talents.T_CORRUPTED_STRENGTH) then offmult = (mult or 1) / (2 - (math.min(self:getTalentLevel(Talents.T_CORRUPTED_STRENGTH), 8) / 9)) end - + return offmult end @@ -1078,20 +1072,9 @@ function _M:hasMassiveArmor() return armor end ---- Check if the actor has a mount -function _M:hasMount() - if not self:getInven("MOUNT") then return end - local mount = self:getInven("MOUNT")[1] - if not mount or mount.type ~= "mount" then - return nil - end - return mount -end - -- Unarmed Combat; this handles grapple checks and building combo points -- Builds Comob; reduces the cooldown on all unarmed abilities on cooldown by one function _M:buildCombo() - local duration = 3 local power = 1 -- Combo String bonuses diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/ammo_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/ammo_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..6ff9ec401357e965a3b8a6e044299a4417e32ce4 Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/ammo_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/amulet_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/amulet_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..67bb5c82556ed019e384b73e1a077731f2e8120b Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/amulet_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/belt_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/belt_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..7b5864f57067fc878d8d48af96b693e96369ab6e Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/belt_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/body_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/body_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..b192aeba995410536add30d4436df6e3f9ee7cab Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/body_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/boots_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/boots_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..4cdf184834ecabb79be8b5c2879e038c19477e86 Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/boots_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/cloak_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/cloak_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..11e3ea1e331b383cc964f81d48f55905f9f36d65 Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/cloak_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/gem_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/gem_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd548d3acff6c94504cb00e3f1e9639bef89f66 Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/gem_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/hands_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/hands_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..96cb98e610f469428bee5f128da0a949de3fafcb Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/hands_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/head_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/head_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..5286fd69010dd38cc566cbadc3cc973a8f287da7 Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/head_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/light_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/light_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..11942c6c3295fa49397f503bcde8fe3b3ba56f92 Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/light_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/mainhand_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/mainhand_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..f8c75a34a171177123094d56239b30e605fafcae Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/mainhand_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/offhand_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/offhand_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..66cd06fa8718e62c0b6deaccbea3d9b72e69eaf4 Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/offhand_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/psionic_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/psionic_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..a7a00d1f047789797e9f3f28948eb3ef29c80d5a Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/psionic_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/ring_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/ring_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..5605da377c9ebf0d07d964aa494298c0bc17ebbb Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/ring_inv.png differ diff --git a/game/modules/tome/data/gfx/metal-ui/equipdoll/tool_inv.png b/game/modules/tome/data/gfx/metal-ui/equipdoll/tool_inv.png new file mode 100644 index 0000000000000000000000000000000000000000..b79291ef0c5321ae284e41ac0a9026f6f200ecb1 Binary files /dev/null and b/game/modules/tome/data/gfx/metal-ui/equipdoll/tool_inv.png differ diff --git a/game/modules/tome/dialogs/Birther.lua b/game/modules/tome/dialogs/Birther.lua index 9749e651f70b5a58425b8aa6ddf4a7e724e87435..a009352a221033844b8e195e86238c503d52bd58 100644 --- a/game/modules/tome/dialogs/Birther.lua +++ b/game/modules/tome/dialogs/Birther.lua @@ -864,7 +864,7 @@ function _M:fakeEquip(v) self.actor.inven = {} else self.actor.inven = {} - local fake_body = { INVEN = 1000, QS_MAINHAND = 1, QS_OFFHAND = 1, MAINHAND = 1, OFFHAND = 1, FINGER = 2, NECK = 1, LITE = 1, BODY = 1, HEAD = 1, CLOAK = 1, HANDS = 1, BELT = 1, FEET = 1, TOOL = 1, QUIVER = 1, MOUNT = 1 } + local fake_body = { INVEN = 1000, QS_MAINHAND = 1, QS_OFFHAND = 1, MAINHAND = 1, OFFHAND = 1, FINGER = 2, NECK = 1, LITE = 1, BODY = 1, HEAD = 1, CLOAK = 1, HANDS = 1, BELT = 1, FEET = 1, TOOL = 1, QUIVER = 1 } self.actor.body = fake_body self.actor:initBody() diff --git a/game/modules/tome/dialogs/ShowEquipInven.lua b/game/modules/tome/dialogs/ShowEquipInven.lua index 4ae362577ab511eee20da056f473ea36aea958a5..5e2d2f3ea40e8118f7ca543a189b3b75ce3ea3c3 100644 --- a/game/modules/tome/dialogs/ShowEquipInven.lua +++ b/game/modules/tome/dialogs/ShowEquipInven.lua @@ -18,12 +18,110 @@ -- darkgod@te4.org require "engine.class" -local Base = require "engine.dialogs.ShowEquipInven" +local Dialog = require "engine.ui.Dialog" +local ListColumns = require "engine.ui.ListColumns" +local Textzone = require "engine.ui.Textzone" +local TextzoneList = require "engine.ui.TextzoneList" +local Separator = require "engine.ui.Separator" +local EquipDollFrame = require "engine.ui.EquipDollFrame" -module(..., package.seeall, class.inherit(Base)) +module(..., package.seeall, class.inherit(Dialog)) -function _M:init(...) - Base.init(self, ...) +function _M:init(title, actor, filter, action, on_select) + self.action = action + self.filter = filter + self.actor = actor + self.on_select = on_select + + Dialog.init(self, title or "Inventory", math.max(800, game.w * 0.8), math.max(600, game.h * 0.8)) + + self.max_h = 0 + + self.c_inven = ListColumns.new{width=math.floor(self.iw / 2 - 10), height=self.ih - self.max_h*self.font_h - 10, sortable=true, scrollbar=true, columns={ + {name="", width={20,"fixed"}, display_prop="char", sort="id"}, + {name="", width={24,"fixed"}, display_prop="object", sort="sortname", direct_draw=function(item, x, y) if item.object then item.object:toScreen(nil, x+4, y, 16, 16) end end}, + {name="Inventory", width=72, display_prop="name", sort="sortname"}, + {name="Category", width=20, display_prop="cat", sort="cat"}, + {name="Enc.", width=8, display_prop="encumberance", sort="encumberance"}, + }, list={}, fct=function(item, sel, button, event) self:use(item, button, event) end, select=function(item, sel) self:select(item) end, on_drag=function(item) self:onDrag(item) end, on_drag_end=function() self:onDragTakeoff() end} + + local uis = self:generateEquipDollFrames() + self:generateList() + + uis[#uis+1] = {right=0, top=0, ui=self.c_inven} + uis[#uis+1] = {hcenter=0, top=5, ui=Separator.new{dir="horizontal", size=self.ih - 10}} + + self:loadUI(uis) + self:setFocus(self.c_inven) + self:setupUI() + + self.key:addCommands{ + __TEXTINPUT = function(c) + local list + if self.focus_ui and self.focus_ui.ui == self.c_inven then list = self.c_inven.list + elseif self.focus_ui and self.focus_ui.ui == self.c_equip then list = self.c_equip.list + end + if list and list.chars[c] then + self:use(list[list.chars[c]]) + end + end, + } + self.key:addBinds{ + HOTKEY_1 = function() self:defineHotkey(1) end, + HOTKEY_2 = function() self:defineHotkey(2) end, + HOTKEY_3 = function() self:defineHotkey(3) end, + HOTKEY_4 = function() self:defineHotkey(4) end, + HOTKEY_5 = function() self:defineHotkey(5) end, + HOTKEY_6 = function() self:defineHotkey(6) end, + HOTKEY_7 = function() self:defineHotkey(7) end, + HOTKEY_8 = function() self:defineHotkey(8) end, + HOTKEY_9 = function() self:defineHotkey(9) end, + HOTKEY_10 = function() self:defineHotkey(10) end, + HOTKEY_11 = function() self:defineHotkey(11) end, + HOTKEY_12 = function() self:defineHotkey(12) end, + HOTKEY_SECOND_1 = function() self:defineHotkey(13) end, + HOTKEY_SECOND_2 = function() self:defineHotkey(14) end, + HOTKEY_SECOND_3 = function() self:defineHotkey(15) end, + HOTKEY_SECOND_4 = function() self:defineHotkey(16) end, + HOTKEY_SECOND_5 = function() self:defineHotkey(17) end, + HOTKEY_SECOND_6 = function() self:defineHotkey(18) end, + HOTKEY_SECOND_7 = function() self:defineHotkey(19) end, + HOTKEY_SECOND_8 = function() self:defineHotkey(20) end, + HOTKEY_SECOND_9 = function() self:defineHotkey(21) end, + HOTKEY_SECOND_10 = function() self:defineHotkey(22) end, + HOTKEY_SECOND_11 = function() self:defineHotkey(23) end, + HOTKEY_SECOND_12 = function() self:defineHotkey(24) end, + HOTKEY_THIRD_1 = function() self:defineHotkey(25) end, + HOTKEY_THIRD_2 = function() self:defineHotkey(26) end, + HOTKEY_THIRD_3 = function() self:defineHotkey(27) end, + HOTKEY_THIRD_4 = function() self:defineHotkey(28) end, + HOTKEY_THIRD_5 = function() self:defineHotkey(29) end, + HOTKEY_THIRD_6 = function() self:defineHotkey(30) end, + HOTKEY_THIRD_7 = function() self:defineHotkey(31) end, + HOTKEY_THIRD_8 = function() self:defineHotkey(32) end, + HOTKEY_THIRD_9 = function() self:defineHotkey(33) end, + HOTKEY_THIRD_10 = function() self:defineHotkey(34) end, + HOTKEY_THIRD_11 = function() self:defineHotkey(35) end, + HOTKEY_THIRD_12 = function() self:defineHotkey(36) end, + HOTKEY_FOURTH_1 = function() self:defineHotkey(37) end, + HOTKEY_FOURTH_2 = function() self:defineHotkey(38) end, + HOTKEY_FOURTH_3 = function() self:defineHotkey(39) end, + HOTKEY_FOURTH_4 = function() self:defineHotkey(40) end, + HOTKEY_FOURTH_5 = function() self:defineHotkey(41) end, + HOTKEY_FOURTH_6 = function() self:defineHotkey(42) end, + HOTKEY_FOURTH_7 = function() self:defineHotkey(43) end, + HOTKEY_FOURTH_8 = function() self:defineHotkey(44) end, + HOTKEY_FOURTH_9 = function() self:defineHotkey(45) end, + HOTKEY_FOURTH_10 = function() self:defineHotkey(46) end, + HOTKEY_FOURTH_11 = function() self:defineHotkey(47) end, + HOTKEY_FOURTH_12 = function() self:defineHotkey(48) end, + ACCEPT = function() + if self.focus_ui and self.focus_ui.ui == self.c_inven then self:use(self.c_inven.list[self.c_inven.sel]) + elseif self.focus_ui and self.focus_ui.ui == self.c_equip then self:use(self.c_equip.list[self.c_equip.sel]) + end + end, + EXIT = function() game:unregisterDialog(self) end, + } -- Add tooltips self.on_select = function(item) @@ -31,44 +129,125 @@ function _M:init(...) game:tooltipDisplayAtMap(item.last_display_x, item.last_display_y, item.object:getDesc({do_color=true}, self.actor:getInven(item.object:wornInven()))) end end - self.on_drag = function(item) self:onDrag(item) end self.key.any_key = function(sym) -- Control resets the tooltip if sym == self.key._LCTRL or sym == self.key._RCTRL then local i = self.cur_item self.cur_item = nil self:select(i) end end end -function _M:unload() - for i, item in ipairs(self.equip_list or {}) do if item.object then item.object.__new_pickup = nil end end - for i, item in ipairs(self.inven_list or {}) do if item.object then item.object.__new_pickup = nil end end +function _M:on_register() + game:onTickEnd(function() self.key:unicodeInput(true) end) end -function _M:onDrag(item) - if item and item.object then - local s = item.object:getEntityFinalSurface(nil, 64, 64) - local x, y = core.mouse.get() - game.mouse:startDrag(x, y, s, {kind="inventory", id=item.object:getName{no_add_name=true, force_id=true, no_count=true}}, function(drag, used) - local x, y = core.mouse.get() - game.mouse:receiveMouse("drag-end", x, y, true, nil, {drag=drag}) - end) +function _M:defineHotkey(id) + if not self.actor or not self.actor.hotkey then return end + + local item = nil + if self.focus_ui and self.focus_ui.ui == self.c_inven then item = self.c_inven.list[self.c_inven.sel] + elseif self.focus_ui and self.focus_ui.ui == self.c_equip then item = self.c_equip.list[self.c_equip.sel] + end + if not item or not item.object then return end + + self.actor.hotkey[id] = {"inventory", item.object:getName{no_add_name=true, no_count=true}} + self:simplePopup("Hotkey "..id.." assigned", item.object:getName{no_add_name=true, no_count=true}:capitalize().." assigned to hotkey "..id) + self.actor.changed = true +end + +function _M:select(item) + if self.cur_item == item then return end + if item then + if self.on_select then self.on_select(item) end + end + self.cur_item = item +end + +function _M:on_focus(id, ui) + if self.focus_ui and self.focus_ui.ui == self.c_inven then self:select(self.c_inven.list[self.c_inven.sel]) + elseif self.focus_ui and self.focus_ui.ui and self.focus_ui.ui.doll_select and self.focus_ui.ui.inven[self.focus_ui.ui.item] then + self:select{last_display_x=self.focus_ui.ui.last_display_x+self.focus_ui.ui.w, last_display_y=self.focus_ui.ui.last_display_y, object=self.focus_ui.ui.inven[self.focus_ui.ui.item]} + else + game.tooltip_x = nil + end +end +function _M:no_focus() + game.tooltip_x = nil +end + +function _M:use(item, button, event) + if item then + if self.action(item.object, item.inven, item.item, button, event) then + game:unregisterDialog(self) + end + end +end + +function _M:generateEquipDollFrames() + local doll = self.actor.equipdolls[self.actor.equipdoll or "default"] + if not doll then return end + + local uis = {} + + for k, v in pairs(doll.list) do + local inven = self.actor:getInven(k) + if inven then + for item, def in ipairs(v) do + local frame = EquipDollFrame.new{actor=self.actor, inven=inven, 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=true} + frame.doll_select = true + frame.actorWear = function(_, ...) + if inven[item] then self.actor:doTakeoff(inven, item, inven[item]) end + self.actor:doWear(...) + self:generateList() + end + frame.fct=function(button, event) if inven[item] then self:use({inven=inven, item=item, object=inven[item]}, button, event) end end + uis[#uis+1] = {left=def.x, top=def.y, ui=frame} + end + end end + return uis +end + +function _M:innerDisplayBack(x, y, nb_keyframes) + local doll = self.actor.equipdolls[self.actor.equipdoll or "default"] + if not doll then return end + + self.actor:toScreen(nil, x + doll.doll_x, y + doll.doll_y, 128, 128) end -function _M:generateList() - Base.generateList(self, true) - for i, item in ipairs(self.inven_list or {}) do if item.object and item.object.__new_pickup then - item.name = ("#{bold}#"..item.name.."#{normal}#"):toTString() - end end - for i, item in ipairs(self.equip_list or {}) do if item.object and item.object.__new_pickup then - item.name = ("#{bold}#"..item.name.."#{normal}#"):toTString() - end end +function _M:generateList(no_update) + -- Makes up the list + self.inven_list = {} + local list = self.inven_list + local chars = {} + local i = 1 + for item, o in ipairs(self.actor:getInven("INVEN") or {}) do + if not self.filter or self.filter(o) then + local char = self:makeKeyChar(i) + + local enc = 0 + o:forAllStack(function(o) enc=enc+o.encumber end) + + list[#list+1] = { id=#list+1, char=char, name=o:getName(), sortname=o:getName():toString():removeColorCodes(), color=o:getDisplayColor(), object=o, inven=self.actor.INVEN_INVEN, item=item, cat=o.subtype, encumberance=enc, desc=o:getDesc() } + chars[char] = #list + i = i + 1 + end + end + list.chars = chars + + if not no_update then + self.c_inven:setList(self.inven_list) + end +end - self.c_inven:setList(self.inven_list) - self.c_equip:setList(self.equip_list) +function _M:on_recover_focus() + self:generateList() +end + +function _M:unload() + for inven_id = 1, #self.actor.inven_def do if self.actor.inven[inven_id] then for item, o in ipairs(self.actor.inven[inven_id]) do o.__new_pickup = nil end end end end function _M:updateTitle(title) - Base.updateTitle(self, title) + Dialog.updateTitle(self, title) local green = colors.LIGHT_GREEN local red = colors.LIGHT_RED @@ -83,8 +262,31 @@ function _M:updateTitle(title) } end +function _M:onDrag(item) + if item and item.object then + local s = item.object:getEntityFinalSurface(nil, 64, 64) + local x, y = core.mouse.get() + game.mouse:startDrag(x, y, s, {kind="inventory", item_idx=item.item, inven=item.inven, object=item.object, id=item.object:getName{no_add_name=true, force_id=true, no_count=true}}, function(drag, used) + if not used then + local x, y = core.mouse.get() + game.mouse:receiveMouse("drag-end", x, y, true, nil, {drag=drag}) + end + end) + end +end + +function _M:onDragTakeoff() + local drag = game.mouse.dragged.payload + print(table.serialize(drag,nil,true)) + if drag.kind == "inventory" and drag.inven and self.actor:getInven(drag.inven) and self.actor:getInven(drag.inven).worn then + self.actor:doTakeoff(drag.inven, drag.item_idx, drag.object) + self:generateList() + game.mouse:usedDrag() + end +end + function _M:drawFrame(x, y, r, g, b, a) - Base.drawFrame(self, x, y, r, g, b, a) + Dialog.drawFrame(self, x, y, r, g, b, a) if r == 0 then return end -- Drawing the shadow if self.ui ~= "metal" then return end if not self.title_fill then return end diff --git a/game/modules/tome/load.lua b/game/modules/tome/load.lua index b325ccfbf97bd3c532796cae6685bb295dac0df6..85e403daabc460205ed3548365ab56a16829f63a 100644 --- a/game/modules/tome/load.lua +++ b/game/modules/tome/load.lua @@ -119,26 +119,42 @@ KeyBind:load("move,hotkeys,inventory,actions,interface,tome,debug") dofile("/mod/resolvers.lua") -- Body parts -ActorInventory:defineInventory("MAINHAND", "In main hand", true, "Most weapons are wielded in the main hand.") -ActorInventory:defineInventory("OFFHAND", "In off hand", true, "You can use shields or a second weapon in your off-hand, if you have the talents for it.") -ActorInventory:defineInventory("PSIONIC_FOCUS", "Psionic focus", true, "Object held in your telekinetic grasp. It can be a weapon or some other item to provide a benefit to your psionic powers.") -ActorInventory:defineInventory("FINGER", "On fingers", true, "Rings are worn on fingers.") -ActorInventory:defineInventory("NECK", "Around neck", true, "Amulets are worn around the neck.") -ActorInventory:defineInventory("LITE", "Light source", true, "A light source allows you to see in the dark places of the world.") -ActorInventory:defineInventory("BODY", "Main armor", true, "Armor protects you from physical attacks. The heavier the armor the more it hinders the use of talents and spells.") -ActorInventory:defineInventory("CLOAK", "Cloak", true, "A cloak can simply keep you warm or grant you wondrous powers should you find a magical one.") -ActorInventory:defineInventory("HEAD", "On head", true, "You can wear helmets or crowns on your head.") -ActorInventory:defineInventory("BELT", "Around waist", true, "Belts are worn around your waist.") -ActorInventory:defineInventory("INBELT", "In your belt", true, "Put small objects in your belt. Using them from the belt only uses 60% of the normal time.") -ActorInventory:defineInventory("HANDS", "On hands", true, "Various gloves can be worn on your hands.") -ActorInventory:defineInventory("FEET", "On feet", true, "Sandals or boots can be worn on your feet.") -ActorInventory:defineInventory("TOOL", "Tool", true, "This is your readied tool, always available immediately.") -ActorInventory:defineInventory("QUIVER", "Quiver", true, "Your readied ammo.") -ActorInventory:defineInventory("GEM", "Socketed Gems", true, "Socketed gems.") -ActorInventory:defineInventory("MOUNT", "Mount", false, "Your mount.") +ActorInventory:defineInventory("MAINHAND", "In main hand", true, "Most weapons are wielded in the main hand.", nil, {equipdoll_back="ui/equipdoll/mainhand_inv.png"}) +ActorInventory:defineInventory("OFFHAND", "In off hand", true, "You can use shields or a second weapon in your off-hand, if you have the talents for it.", nil, {equipdoll_back="ui/equipdoll/offhand_inv.png"}) +ActorInventory:defineInventory("PSIONIC_FOCUS", "Psionic focus", true, "Object held in your telekinetic grasp. It can be a weapon or some other item to provide a benefit to your psionic powers.", nil, {equipdoll_back="ui/equipdoll/psionic_inv.png"}) +ActorInventory:defineInventory("FINGER", "On fingers", true, "Rings are worn on fingers.", nil, {equipdoll_back="ui/equipdoll/ring_inv.png"}) +ActorInventory:defineInventory("NECK", "Around neck", true, "Amulets are worn around the neck.", nil, {equipdoll_back="ui/equipdoll/amulet_inv.png"}) +ActorInventory:defineInventory("LITE", "Light source", true, "A light source allows you to see in the dark places of the world.", nil, {equipdoll_back="ui/equipdoll/light_inv.png"}) +ActorInventory:defineInventory("BODY", "Main armor", true, "Armor protects you from physical attacks. The heavier the armor the more it hinders the use of talents and spells.", nil, {equipdoll_back="ui/equipdoll/body_inv.png"}) +ActorInventory:defineInventory("CLOAK", "Cloak", true, "A cloak can simply keep you warm or grant you wondrous powers should you find a magical one.", nil, {equipdoll_back="ui/equipdoll/cloak_inv.png"}) +ActorInventory:defineInventory("HEAD", "On head", true, "You can wear helmets or crowns on your head.", nil, {equipdoll_back="ui/equipdoll/head_inv.png"}) +ActorInventory:defineInventory("BELT", "Around waist", true, "Belts are worn around your waist.", nil, {equipdoll_back="ui/equipdoll/belt_inv.png"}) +ActorInventory:defineInventory("HANDS", "On hands", true, "Various gloves can be worn on your hands.", nil, {equipdoll_back="ui/equipdoll/hands_inv.png"}) +ActorInventory:defineInventory("FEET", "On feet", true, "Sandals or boots can be worn on your feet.", nil, {equipdoll_back="ui/equipdoll/boots_inv.png"}) +ActorInventory:defineInventory("TOOL", "Tool", true, "This is your readied tool, always available immediately.", nil, {equipdoll_back="ui/equipdoll/tool_inv.png"}) +ActorInventory:defineInventory("QUIVER", "Quiver", true, "Your readied ammo.", nil, {equipdoll_back="ui/equipdoll/ammo_inv.png"}) +ActorInventory:defineInventory("GEM", "Socketed Gems", true, "Socketed gems.", nil, {equipdoll_back="ui/equipdoll/gem_inv.png"}) ActorInventory:defineInventory("QS_MAINHAND", "Second weapon set: In main hand", false, "Weapon Set 2: Most weapons are wielded in the main hand. Press 'x' to switch weapon sets.", true) ActorInventory:defineInventory("QS_OFFHAND", "Second weapon set: In off hand", false, "Weapon Set 2: You can use shields or a second weapon in your off-hand, if you have the talents for it. Press 'x' to switch weapon sets.", true) ActorInventory:defineInventory("QS_PSIONIC_FOCUS", "Second weapon set: psionic focus", false, "Weapon Set 2: Object held in your telekinetic grasp. It can be a weapon or some other item to provide a benefit to your psionic powers. Press 'x' to switch weapon sets.", 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={ + MAINHAND = {{x=48, y=120}}, + OFFHAND = {{x=48, y=192}}, + PSIONIC_FOCUS = {{x=48, y=48}}, + FINGER = {{x=48, y=408}, {x=120, y=408}}, + NECK = {{x=192, y=48}}, + LITE = {{x=192, y=408}}, + BODY = {{x=48, y=264}}, + CLOAK = {{x=264, y=120}}, + HEAD = {{x=120, y=48}}, + BELT = {{x=264, y=264}}, + HANDS = {{x=264, y=192}}, + FEET = {{x=264, y=336}}, + TOOL = {{x=264, y=408}}, + QUIVER = {{x=48, y=336}}, + }}, +} -- Damage types DamageType:loadDefinition("/data/damage_types.lua")