diff --git a/client.lua b/client.lua index 7d47ad3..5215bb9 100644 --- a/client.lua +++ b/client.lua @@ -124,6 +124,7 @@ function client.connect(ip, port) slimeBalls.reset() items.client.reset() damageText.reset() + quests.refresh() collectgarbage() end client.currentState = client.newState() @@ -237,7 +238,8 @@ function client.sendMessage(msg) end end -for _, v in ipairs{'spawnProjectile', 'moveItem', 'dropItem', 'useItem', 'usePortal'} do +for _, v in ipairs{'spawnProjectile', 'moveItem', 'dropItem', 'useItem', 'usePortal', +'setInventorySlot', 'newItem'} do client[v] = function(data) client.nutClient:sendRPC(v, bitser.dumps(data)) end diff --git a/entityDefs/player.lua b/entityDefs/player.lua index 5393456..4838842 100644 --- a/entityDefs/player.lua +++ b/entityDefs/player.lua @@ -251,16 +251,17 @@ function player.client:swing() local attackItem = items.client.getItem(self.inventory.items[2]) if attackItem and attackItem.atk then playerDamage = attackItem.atk + self.stats.atk.total - end - if self.isLocalPlayer then - client.spawnProjectile{ - x = px, y = py - 14, - angle = a, - speed = 2e2, - life = 3, - pierce = 2, - damage = playerDamage - } + if self.isLocalPlayer then + client.spawnProjectile{ + x = px, y = py - 14, + angle = a, + speed = 2e2, + life = 3, + pierce = 2, + damage = playerDamage, + color = sword2color[attackItem.imageId] + } + end end end @@ -284,6 +285,12 @@ function player.client:mousepressed(x, y, btn) end end +function player.client:drawFrame(anim, frame, x, y, ox) + local quad = anim.quads[frame] + local _, _, w, h = quad:getViewport() + love.graphics.draw(anim.sheet, quad, x, y, 0, self.direction, 1, ox, h) +end + function player.client:draw() local _canvas = love.graphics.getCanvas() local _shader = love.graphics.getShader() @@ -322,24 +329,36 @@ function player.client:draw() love.graphics.setColor(1, 1, 1) local attackItem = items.client.getItem(self.inventory.items[2]) + local helmetItem = items.client.getItem(self.inventory.items[1]) + local chestItem = items.client.getItem(self.inventory.items[3]) + local pantsItem = items.client.getItem(self.inventory.items[6]) if self.swinging then local swingFrameIdx = math.floor(self.swingTimer*12) + 1 swingFrameIdx = lume.clamp(swingFrameIdx, 1, 5) if vd < 10 then -- swinging and standing still - local quad = anims.player.swing.body.quads[swingFrameIdx] - local _, _, w, h = quad:getViewport() - love.graphics.draw(anims.player.swing.body.sheet, quad, - lume.round(px), lume.round(py), - 0, self.direction, 1, - 23, h) + -- body + self:drawFrame(anims.player.swing.body, swingFrameIdx, + lume.round(px), lume.round(py), 23) + -- pants + if pantsItem then + self:drawFrame(anims.player.armor.armor0.pants.swing, swingFrameIdx, + lume.round(px), lume.round(py), 23) + end + -- chest + if chestItem then + self:drawFrame(anims.player.armor.armor0.chest.swing, swingFrameIdx, + lume.round(px), lume.round(py), 23) + end + -- helmet + if helmetItem then + self:drawFrame(anims.player.armor.armor0.helmet.swing, swingFrameIdx, + lume.round(px), lume.round(py), 23) + end + -- sword if attackItem and isSword[attackItem.imageId] then - local quad = anims.player.swords[attackItem.imageId].swing.quads[swingFrameIdx] - local _, _, w, h = quad:getViewport() - love.graphics.draw(anims.player.swords[attackItem.imageId].swing.sheet, quad, - lume.round(px), lume.round(py), - 0, self.direction, 1, - 23, h) + self:drawFrame(anims.player.swords[attackItem.imageId].swing, swingFrameIdx, + lume.round(px), lume.round(py), 23) end else -- swinging and walking @@ -348,65 +367,86 @@ function player.client:draw() or xv < -10 and self.direction == 1 then walkFrameIdx = math.floor(-self.walkTimer*12) % #anims.player.walk.body.quads + 1 end - local quad = anims.player.walkAndSwing.lowerBody.quads[walkFrameIdx] - local _, _, w, h = quad:getViewport() - love.graphics.draw(anims.player.walkAndSwing.lowerBody.sheet, quad, - lume.round(px), lume.round(py), - 0, self.direction, 1, - 23, h) + self:drawFrame(anims.player.walkAndSwing.lowerBody, walkFrameIdx, + lume.round(px), lume.round(py), 23) + -- pants + if pantsItem then + self:drawFrame(anims.player.armor.armor0.pants.walkAndSwing, walkFrameIdx, + lume.round(px), lume.round(py), 23) + end -- upper body love.graphics.push() if swingFrameIdx == 4 then love.graphics.translate(0, 1) end if walkFrameIdx == 4 then love.graphics.translate(0, -1) end - local quad = anims.player.walkAndSwing.upperBody.quads[swingFrameIdx] - local _, _, w, h = quad:getViewport() - love.graphics.draw(anims.player.walkAndSwing.upperBody.sheet, quad, - lume.round(px), lume.round(py), - 0, self.direction, 1, - 23, h) + self:drawFrame(anims.player.walkAndSwing.upperBody, swingFrameIdx, + lume.round(px), lume.round(py), 23) + -- chest + if chestItem then + self:drawFrame(anims.player.armor.armor0.chest.walkAndSwing, swingFrameIdx, + lume.round(px), lume.round(py), 23) + end + -- helmet + if helmetItem then + self:drawFrame(anims.player.armor.armor0.helmet.walkAndSwing, swingFrameIdx, + lume.round(px), lume.round(py), 23) + end love.graphics.pop() -- sword if attackItem and isSword[attackItem.imageId] then - local quad = anims.player.swords[attackItem.imageId].swing.quads[swingFrameIdx] - local _, _, w, h = quad:getViewport() - love.graphics.draw(anims.player.swords[attackItem.imageId].swing.sheet, quad, - lume.round(px), lume.round(py), - 0, self.direction, 1, - 23, h) + self:drawFrame(anims.player.swords[attackItem.imageId].swing, swingFrameIdx, + lume.round(px), lume.round(py), 23) end end else if vd < 10 then -- standing still - local quad = anims.player.swing.body.quads[1] - local _, _, w, h = quad:getViewport() - love.graphics.draw(anims.player.swing.body.sheet, quad, - lume.round(px), lume.round(py), - 0, self.direction, 1, - 23, h) + -- body + self:drawFrame(anims.player.swing.body, 1, + lume.round(px), lume.round(py), 23) + -- pants + if pantsItem then + self:drawFrame(anims.player.armor.armor0.pants.swing, 1, + lume.round(px), lume.round(py), 23) + end + -- chest + if chestItem then + self:drawFrame(anims.player.armor.armor0.chest.swing, 1, + lume.round(px), lume.round(py), 23) + end + -- helmet + if helmetItem then + self:drawFrame(anims.player.armor.armor0.helmet.swing, 1, + lume.round(px), lume.round(py), 23) + end + -- sword if attackItem and isSword[attackItem.imageId] then - local quad = anims.player.swords[attackItem.imageId].swing.quads[1] - local _, _, w, h = quad:getViewport() - love.graphics.draw(anims.player.swords[attackItem.imageId].swing.sheet, quad, - lume.round(px), lume.round(py), - 0, self.direction, 1, - 23, h) + self:drawFrame(anims.player.swords[attackItem.imageId].swing, 1, + lume.round(px), lume.round(py), 23) end else -- walking - local quad = anims.player.walk.body.quads[walkFrameIdx] - local _, _, w, h = quad:getViewport() - love.graphics.draw(anims.player.walk.body.sheet, quad, - lume.round(px), lume.round(py), - 0, self.direction, 1, - 8, h) + -- body + self:drawFrame(anims.player.walk.body, walkFrameIdx, + lume.round(px), lume.round(py), 8) + -- pants + if pantsItem then + self:drawFrame(anims.player.armor.armor0.pants.walk, walkFrameIdx, + lume.round(px), lume.round(py), 8) + end + -- chest + if chestItem then + self:drawFrame(anims.player.armor.armor0.chest.walk, walkFrameIdx, + lume.round(px), lume.round(py), 8) + end + -- helmet + if helmetItem then + self:drawFrame(anims.player.armor.armor0.helmet.walk, walkFrameIdx, + lume.round(px), lume.round(py), 8) + end + -- sword if attackItem and isSword[attackItem.imageId] then - local quad = anims.player.swords[attackItem.imageId].walk.quads[walkFrameIdx] - local _, _, w, h = quad:getViewport() - love.graphics.draw(anims.player.swords[attackItem.imageId].walk.sheet, quad, - lume.round(px), lume.round(py), - 0, self.direction, 1, - 8, h) + self:drawFrame(anims.player.swords[attackItem.imageId].walk, walkFrameIdx, + lume.round(px), lume.round(py), 8) end end end diff --git a/gfx/items/chest.png b/gfx/items/chest.png new file mode 100644 index 0000000..6858dd8 Binary files /dev/null and b/gfx/items/chest.png differ diff --git a/gfx/items/helmet.png b/gfx/items/helmet.png new file mode 100644 index 0000000..8366560 Binary files /dev/null and b/gfx/items/helmet.png differ diff --git a/gfx/items/pants.png b/gfx/items/pants.png new file mode 100644 index 0000000..1e27581 Binary files /dev/null and b/gfx/items/pants.png differ diff --git a/gfx/player/armor/armor0/chest/swing.png b/gfx/player/armor/armor0/chest/swing.png new file mode 100644 index 0000000..6385e9c Binary files /dev/null and b/gfx/player/armor/armor0/chest/swing.png differ diff --git a/gfx/player/armor/armor0/chest/walk.png b/gfx/player/armor/armor0/chest/walk.png new file mode 100644 index 0000000..92a2e83 Binary files /dev/null and b/gfx/player/armor/armor0/chest/walk.png differ diff --git a/gfx/player/armor/armor0/chest/walk_and_swing.png b/gfx/player/armor/armor0/chest/walk_and_swing.png new file mode 100644 index 0000000..18eb249 Binary files /dev/null and b/gfx/player/armor/armor0/chest/walk_and_swing.png differ diff --git a/gfx/player/armor/armor0/helmet/swing.png b/gfx/player/armor/armor0/helmet/swing.png new file mode 100644 index 0000000..37d42c6 Binary files /dev/null and b/gfx/player/armor/armor0/helmet/swing.png differ diff --git a/gfx/player/armor/armor0/helmet/walk.png b/gfx/player/armor/armor0/helmet/walk.png new file mode 100644 index 0000000..b9e18a8 Binary files /dev/null and b/gfx/player/armor/armor0/helmet/walk.png differ diff --git a/gfx/player/armor/armor0/helmet/walk_and_swing.png b/gfx/player/armor/armor0/helmet/walk_and_swing.png new file mode 100644 index 0000000..65b2301 Binary files /dev/null and b/gfx/player/armor/armor0/helmet/walk_and_swing.png differ diff --git a/gfx/player/armor/armor0/pants/swing.png b/gfx/player/armor/armor0/pants/swing.png new file mode 100644 index 0000000..4e5ced8 Binary files /dev/null and b/gfx/player/armor/armor0/pants/swing.png differ diff --git a/gfx/player/armor/armor0/pants/walk.png b/gfx/player/armor/armor0/pants/walk.png new file mode 100644 index 0000000..54508c2 Binary files /dev/null and b/gfx/player/armor/armor0/pants/walk.png differ diff --git a/gfx/player/armor/armor0/pants/walk_and_swing.png b/gfx/player/armor/armor0/pants/walk_and_swing.png new file mode 100644 index 0000000..7a85adb Binary files /dev/null and b/gfx/player/armor/armor0/pants/walk_and_swing.png differ diff --git a/gfx/ui/questui.png b/gfx/ui/questui.png new file mode 100644 index 0000000..6222455 Binary files /dev/null and b/gfx/ui/questui.png differ diff --git a/hud.lua b/hud.lua index 8640c59..5231739 100644 --- a/hud.lua +++ b/hud.lua @@ -168,7 +168,7 @@ function hud.update(dt) end function hud.mousepressed(x, y, btn, isTouch, presses) - mx, my = window2game(x, y) + local mx, my = window2game(x, y) mx, my = lume.round(mx), lume.round(my) -- deactivate chat if click outside field @@ -183,120 +183,11 @@ function hud.mousepressed(x, y, btn, isTouch, presses) if chat.active and not chatFieldPressed then chat.active = false end - - -- inventory management - local bag = playerController.player.inventory - local panel = hud.inventoryPanel - local pmx = mx - lume.round(panel.x) - local pmy = my - lume.round(panel.y) - for slotId, slot in ipairs(hud.inventorySlots) do - if pmx >= slot.x and pmx <= slot.x + slot.w - and pmy >= slot.y and pmy <= slot.y + slot.h and panel.open then - uiMouseDown = true - if bag.items[slotId] then - -- use item - if btn == 1 and (love.keyboard.isScancodeDown('lshift') or presses > 1) then - client.useItem{ - bagId = bag.id, - slotId = slotId - } - end - -- move items - if btn == 1 then - local heldItem = playerController.heldItem - heldItem.bagId = bag.id - heldItem.slotId = slotId - heldItem.offset.x = slot.x - pmx - heldItem.offset.y = slot.y - pmy - elseif btn == 2 then - local closestBag = playerController.closestBag - if closestBag.id and closestBag.open then - local bagTo = client.currentState.lootBags[closestBag.id] - for bagSlotId, _ in ipairs(lootBagSlots) do - if bagTo.items[bagSlotId] == nil then - client.moveItem{ - from = { - bagId = bag.id, - slotId = slotId - }, - to = { - bagId = bagTo.id, - slotId = bagSlotId - } - } - break - end - end - end - end - end - end - end end function hud.mousereleased(x, y, btn, isTouch, presses) local mx, my = window2game(x, y) mx, my = lume.round(mx), lume.round(my) - local heldItem = playerController.heldItem - if heldItem.bagId then - local bagFrom = client.currentState.lootBags[heldItem.bagId] - if heldItem.bagId == 'inventory' then - bagFrom = playerController.player.inventory - end - local bagTo = playerController.player.inventory - local panel = hud.inventoryPanel - local pmx = mx - lume.round(panel.x) - local pmy = my - lume.round(panel.y) - local itemHeld = true - if pmx > 0 and pmx < panel.img:getWidth() - and pmy > 0 and pmy < panel.img:getHeight() then - for slotId, slot in ipairs(hud.inventorySlots) do - if pmx >= slot.x and pmx <= slot.x + slot.w - and pmy >= slot.y and pmy <= slot.y + slot.h then - client.moveItem{ - from = { - bagId = bagFrom.id, - slotId = heldItem.slotId - }, - to = { - bagId = bagTo.id, - slotId = slotId - } - } - itemHeld = false - -- move clientside before response (will be corrected/affirmed) - local temp = bagTo.items[slotId] - bagTo.items[slotId] = bagFrom.items[heldItem.slotId] - bagFrom.items[heldItem.slotId] = temp - break - end - end - -- move to open slot if dropped in inventory panel - if itemHeld then - for invSlotId, _ in ipairs(hud.inventorySlots) do - if bagTo.items[invSlotId] == nil then - client.moveItem{ - from = { - bagId = bagFrom.id, - slotId = heldItem.slotId - }, - to = { - bagId = bagTo.id, - slotId = invSlotId - } - } - itemHeld = false - break - end - end - end - elseif bagFrom.id == 'inventory' then - client.dropItem{ - slotId = heldItem.slotId - } - itemHeld = false - end - end end function hud.keypressed(k, scancode, isrepeat) @@ -468,18 +359,12 @@ function hud.draw() -- held item local heldItem = playerController.heldItem - if heldItem.bagId then - local bag = client.currentState.lootBags[heldItem.bagId] - if heldItem.bagId == 'inventory' then - bag = p.inventory - end - if bag then - local item = items.client.getItem(bag.items[heldItem.slotId]) - if item then - cursor.cursor = cursor.hand - love.graphics.setColor(1, 1, 1) - love.graphics.draw(gfx.items[item.imageId], mx + heldItem.offset.x, my + heldItem.offset.y) - end + if heldItem.itemId then + local item = items.client.getItem(heldItem.itemId) + if item then + cursor.cursor = cursor.hand + love.graphics.setColor(1, 1, 1) + love.graphics.draw(gfx.items[item.imageId], mx + heldItem.offset.x, my + heldItem.offset.y) end end end diff --git a/items.lua b/items.lua index 28ac63d..af99c62 100644 --- a/items.lua +++ b/items.lua @@ -10,9 +10,14 @@ items = { } function items.server.newItem(data) - local id = lume.uuid() - items.server.container[id] = data - return id + data.id = lume.uuid() + if isSword[data.imageId] then + data.type = 'sword' + else + data.type = data.imageId + end + items.server.container[data.id] = data + return data.id end function items.server.reset() @@ -44,3 +49,403 @@ function items.client.getItem(id) return nil end end + +-- todo: refactor + +function items.client.mousepressed(x, y, btn, isTouch, presses) + local mx, my = window2game(x, y) + mx, my = lume.round(mx), lume.round(my) + local wmx, wmy = camera:screen2world(mx, my) + + -- hud + local bag = playerController.player.inventory + local panel = hud.inventoryPanel + local pmx = mx - lume.round(panel.x) + local pmy = my - lume.round(panel.y) + for slotId, slot in ipairs(hud.inventorySlots) do + if pmx >= slot.x and pmx <= slot.x + slot.w + and pmy >= slot.y and pmy <= slot.y + slot.h and panel.open then + uiMouseDown = true + if bag.items[slotId] then + -- use item + if btn == 1 and (love.keyboard.isScancodeDown('lshift') or presses > 1) then + client.useItem{ + bagId = bag.id, + slotId = slotId + } + end + -- move items + if btn == 1 then + local heldItem = playerController.heldItem + heldItem.itemId = bag.items[slotId] + heldItem.bagId = bag.id + heldItem.slotId = slotId + heldItem.offset.x = slot.x - pmx + heldItem.offset.y = slot.y - pmy + elseif btn == 2 then + local closestBag = playerController.closestBag + if closestBag.id and closestBag.open then + local bagTo = client.currentState.lootBags[closestBag.id] + for bagSlotId, _ in ipairs(lootBagSlots) do + if bagTo.items[bagSlotId] == nil then + client.moveItem{ + from = { + bagId = bag.id, + slotId = slotId + }, + to = { + bagId = bagTo.id, + slotId = bagSlotId + } + } + break + end + end + end + end + end + end + end + + -- lootBags + local closestBag = playerController.closestBag + if closestBag.id and closestBag.open then + local bag = client.currentState.lootBags[closestBag.id] + local img = gfx.ui.bag + local bmx = wmx - (lume.round(bag.x) - lume.round(img:getWidth()/2)) + local bmy = wmy - (lume.round(bag.y) - img:getHeight() - 20) + for slotId, slot in ipairs(lootBagSlots) do + if bmx >= slot.x and bmx <= slot.x + slot.w + and bmy >= slot.y and bmy <= slot.y + slot.h then + uiMouseDown = true + if bag.items[slotId] then + if btn == 1 then + local heldItem = playerController.heldItem + heldItem.itemId = bag.items[slotId] + heldItem.bagId = bag.id + heldItem.slotId = slotId + heldItem.offset.x = slot.x - bmx + heldItem.offset.y = slot.y - bmy + elseif btn == 2 then + local p = playerController.player + local item = items.client.getItem(bag.items[slotId]) + if not item then break end + for invSlotId, _ in ipairs(hud.inventorySlots) do + local slotType = slot2type[invSlotId] + if p.inventory.items[invSlotId] == nil + and (slotType == nil or slotType == item.type) then + client.moveItem{ + from = { + bagId = bag.id, + slotId = slotId + }, + to = { + bagId = p.inventory.id, + slotId = invSlotId + } + } + break + end + end + end + end + break + end + end + end + + -- quest + if btn == 1 then + local cqb = playerController.closestQuestBlock + if cqb.id and cqb.open then + local qb = client.currentState.entities[cqb.id] + if qb then + local img = gfx.ui.quest + local bmx = wmx - (lume.round(qb.x + 8) - lume.round(img:getWidth()/2)) + local bmy = wmy - (lume.round(qb.y + 8) - img:getHeight() - 20) + for slotId, slot in ipairs(questBlockSlots) do + local exists = true + local item = items.client.getItem(quests.current.heldItems[slotId]) + if not item then + exists = false + if slotId <= 4 then + item = items.client.getItem(quests.current.cost[slotId]) + else + item = items.client.getItem(quests.current.reward[slotId - 4]) + end + end + if slotId >= 5 then + local allExist = true + for i, item in ipairs(quests.current.cost) do + if not quests.current.heldItems[i] then + allExist = false + break + end + end + exists = allExist + end + if bmx >= slot.x and bmx <= slot.x + slot.w + and bmy >= slot.y and bmy <= slot.y + slot.h then + uiMouseDown = true + if item and exists then + local heldItem = playerController.heldItem + heldItem.itemId = item.id + heldItem.bagId = 'quest' + heldItem.slotId = slotId + heldItem.offset.x = slot.x - bmx + heldItem.offset.y = slot.y - bmy + end + end + end + end + end + elseif btn == 2 then + local cqb = playerController.closestQuestBlock + if cqb.id and cqb.open then + local qb = client.currentState.entities[cqb.id] + if qb then + -- give items + local bag = playerController.player.inventory + local panel = hud.inventoryPanel + local pmx = mx - lume.round(panel.x) + local pmy = my - lume.round(panel.y) + for slotId, slot in ipairs(hud.inventorySlots) do + if pmx >= slot.x and pmx <= slot.x + slot.w + and pmy >= slot.y and pmy <= slot.y + slot.h and panel.open then + uiMouseDown = true + if bag.items[slotId] then + local item = items.client.getItem(bag.items[slotId]) + if not item then break end + for questSlotId, questItemId in pairs(quests.current.cost) do + local questItem = items.client.getItem(questItemId) + if not questItem then break end + if quests.current.heldItems[questSlotId] == nil + and item.imageId == questItem.imageId then + quests.current.heldItems[questSlotId] = bag.items[slotId] + client.setInventorySlot{ + slotId = slotId, + itemId = nil + } + break + end + end + end + end + end + + -- take reward + local allExist = true + for i, item in ipairs(quests.current.cost) do + if not quests.current.heldItems[i] then + allExist = false + break + end + end + if allExist then + local img = gfx.ui.quest + local bmx = wmx - (lume.round(qb.x + 8) - lume.round(img:getWidth()/2)) + local bmy = wmy - (lume.round(qb.y + 8) - img:getHeight() - 20) + local slot = questBlockSlots[5] + if bmx >= slot.x and bmx <= slot.x + slot.w + and bmy >= slot.y and bmy <= slot.y + slot.h then + uiMouseDown = true + local itemId = quests.current.reward[1] + local item = items.client.getItem(itemId) + if item then + for invSlotId, _ in ipairs(hud.inventorySlots) do + local slotType = slot2type[invSlotId] + -- bag = player inventory + if bag.items[invSlotId] == nil + and (slotType == nil or slotType == item.type) then + client.setInventorySlot{ + slotId = invSlotId, + itemId = itemId + } + quests.refresh() + break + end + end + end + end + end + end + end + end +end + +function items.client.mousereleased(x, y, btn, isTouch, presses) + local mx, my = window2game(x, y) + mx, my = lume.round(mx), lume.round(my) + local wmx, wmy = camera:screen2world(mx, my) + + if btn == 1 then + -- hud + local heldItem = playerController.heldItem + local itemIsHeld = true + if heldItem.bagId then + local bagFrom = client.currentState.lootBags[heldItem.bagId] + if heldItem.bagId == 'inventory' then + bagFrom = playerController.player.inventory + end + local bagTo = playerController.player.inventory + local panel = hud.inventoryPanel + local pmx = mx - lume.round(panel.x) + local pmy = my - lume.round(panel.y) + if pmx > 0 and pmx < panel.img:getWidth() + and pmy > 0 and pmy < panel.img:getHeight() then + for slotId, slot in ipairs(hud.inventorySlots) do + if pmx >= slot.x and pmx <= slot.x + slot.w + and pmy >= slot.y and pmy <= slot.y + slot.h then + local item = items.client.getItem(heldItem.itemId) + if not item then break end + local slotType = slot2type[slotId] + if (slotType == nil or slotType == item.type) then + if heldItem.bagId == 'quest' then + client.setInventorySlot{ + slotId = slotId, + itemId = heldItem.itemId + } + if heldItem.slotId <= 4 then + quests.current.heldItems[heldItem.slotId] = nil + elseif heldItem.slotId == 5 then + quests.refresh() + end + itemIsHeld = false + break + end + client.moveItem{ + from = { + bagId = bagFrom.id, + slotId = heldItem.slotId + }, + to = { + bagId = bagTo.id, + slotId = slotId + } + } + itemIsHeld = false + -- move clientside before response (will be corrected/affirmed) + local temp = bagTo.items[slotId] + bagTo.items[slotId] = bagFrom.items[heldItem.slotId] + bagFrom.items[heldItem.slotId] = temp + break + end + end + end + -- move to open slot if dropped in inventory panel + if itemIsHeld then + for invSlotId, _ in ipairs(hud.inventorySlots) do + local item = items.client.getItem(heldItem.itemId) + if not item then break end + local slotType = slot2type[invSlotId] + if bagTo.items[invSlotId] == nil + and (slotType == nil or slotType == item.type) then + if heldItem.bagId == 'quest' then + client.setInventorySlot{ + slotId = invSlotId, + itemId = heldItem.itemId + } + if heldItem.slotId <= 4 then + quests.current.heldItems[heldItem.slotId] = nil + elseif heldItem.slotId == 5 then + quests.refresh() + end + itemIsHeld = false + break + end + client.moveItem{ + from = { + bagId = bagFrom.id, + slotId = heldItem.slotId + }, + to = { + bagId = bagTo.id, + slotId = invSlotId + } + } + itemIsHeld = false + break + end + end + end + end + end + + -- lootBags + local closestBag = playerController.closestBag + local heldItem = playerController.heldItem + if closestBag.id and closestBag.open and heldItem.bagId then + local bagFrom = client.currentState.lootBags[heldItem.bagId] + if heldItem.bagId == 'inventory' then + bagFrom = playerController.player.inventory + end + local bagTo = client.currentState.lootBags[closestBag.id] + local img = gfx.ui.bag + local bmx = wmx - (lume.round(bagTo.x) - lume.round(img:getWidth()/2)) + local bmy = wmy - (lume.round(bagTo.y) - img:getHeight() - 20) + for slotId, slot in ipairs(lootBagSlots) do + if bmx >= slot.x and bmx <= slot.x + slot.w + and bmy >= slot.y and bmy <= slot.y + slot.h then + if heldItem.bagId == 'quest' then + break + end + client.moveItem{ + from = { + bagId = bagFrom.id, + slotId = heldItem.slotId + }, + to = { + bagId = bagTo.id, + slotId = slotId + } + } + itemIsHeld = false + -- move clientside before response (will be corrected/affirmed) + local temp = bagTo.items[slotId] + bagTo.items[slotId] = bagFrom.items[heldItem.slotId] + bagFrom.items[heldItem.slotId] = temp + break + end + end + end + + -- quest + local cqb = playerController.closestQuestBlock + if cqb.id and cqb.open and heldItem.bagId == 'inventory' then + local qb = client.currentState.entities[cqb.id] + if qb then + local p = playerController.player + local img = gfx.ui.quest + local bmx = wmx - (lume.round(qb.x + 8) - lume.round(img:getWidth()/2)) + local bmy = wmy - (lume.round(qb.y + 8) - img:getHeight() - 20) + for slotId=1, 4 do + local slot = questBlockSlots[slotId] + if bmx >= slot.x and bmx <= slot.x + slot.w + and bmy >= slot.y and bmy <= slot.y + slot.h then + local item = items.client.getItem(heldItem.itemId) + if not item then break end + local questItemId = quests.current.cost[slotId] + local questItem = items.client.getItem(questItemId) + if not questItem then break end + if quests.current.heldItems[slotId] == nil + and item.imageId == questItem.imageId then + quests.current.heldItems[slotId] = p.inventory.items[heldItem.slotId] + itemIsHeld = false + client.setInventorySlot{ + slotId = heldItem.slotId, + itemId = nil + } + break + end + end + end + end + end + if heldItem.bagId == 'inventory' and itemIsHeld then + client.dropItem{ + slotId = heldItem.slotId + } + itemIsHeld = false + end + end +end diff --git a/loadassets.lua b/loadassets.lua index fb3b732..4ce0abb 100644 --- a/loadassets.lua +++ b/loadassets.lua @@ -28,7 +28,8 @@ gfx = { right = love.graphics.newImage('gfx/ui/buttons/right.png') }, bag = love.graphics.newImage('gfx/ui/bagui.png'), - itemInfo = love.graphics.newImage('gfx/ui/item_info.png') + itemInfo = love.graphics.newImage('gfx/ui/item_info.png'), + quest = love.graphics.newImage('gfx/ui/questui.png') }, hud = { frame = love.graphics.newImage('gfx/ui/hud/frame.png'), @@ -70,6 +71,25 @@ gfx = { upperBody = love.graphics.newImage('gfx/player/walk_and_swing/upper_body.png'), lowerBody = love.graphics.newImage('gfx/player/walk_and_swing/lower_body.png') }, + armor = { + armor0 = { + chest = { + walk = love.graphics.newImage('gfx/player/armor/armor0/chest/walk.png'), + swing = love.graphics.newImage('gfx/player/armor/armor0/chest/swing.png'), + walkAndSwing = love.graphics.newImage('gfx/player/armor/armor0/chest/walk_and_swing.png') + }, + helmet = { + walk = love.graphics.newImage('gfx/player/armor/armor0/helmet/walk.png'), + swing = love.graphics.newImage('gfx/player/armor/armor0/helmet/swing.png'), + walkAndSwing = love.graphics.newImage('gfx/player/armor/armor0/helmet/walk_and_swing.png') + }, + pants = { + walk = love.graphics.newImage('gfx/player/armor/armor0/pants/walk.png'), + swing = love.graphics.newImage('gfx/player/armor/armor0/pants/swing.png'), + walkAndSwing = love.graphics.newImage('gfx/player/armor/armor0/pants/walk_and_swing.png') + } + } + }, swords = { sword0 = { walk = love.graphics.newImage('gfx/player/swords/sword0/walk.png'), @@ -122,7 +142,10 @@ gfx = { sword3 = love.graphics.newImage('gfx/items/sword3.png'), sword4 = love.graphics.newImage('gfx/items/sword4.png'), shield = love.graphics.newImage('gfx/items/shield.png'), - apple = love.graphics.newImage('gfx/items/apple.png') + apple = love.graphics.newImage('gfx/items/apple.png'), + helmet = love.graphics.newImage('gfx/items/helmet.png'), + chest = love.graphics.newImage('gfx/items/chest.png'), + pants = love.graphics.newImage('gfx/items/pants.png') }, slimeBall = love.graphics.newImage('gfx/slime_ball.png') } @@ -156,6 +179,25 @@ anims.player = { upperBody = newAnim(gfx.player.walkAndSwing.upperBody, 43, 34, 1, 5), lowerBody = newAnim(gfx.player.walkAndSwing.lowerBody, 43, 34, 1, 5) }, + armor = { + armor0 = { + chest = { + walk = newAnim(gfx.player.armor.armor0.chest.walk, 20, 31, 1, 5), + swing = newAnim(gfx.player.armor.armor0.chest.swing, 43, 34, 1, 5), + walkAndSwing = newAnim(gfx.player.armor.armor0.chest.walkAndSwing, 43, 34, 1, 5) + }, + helmet = { + walk = newAnim(gfx.player.armor.armor0.helmet.walk, 20, 31, 1, 5), + swing = newAnim(gfx.player.armor.armor0.helmet.swing, 43, 34, 1, 5), + walkAndSwing = newAnim(gfx.player.armor.armor0.helmet.walkAndSwing, 43, 34, 1, 5) + }, + pants = { + walk = newAnim(gfx.player.armor.armor0.pants.walk, 20, 31, 1, 5), + swing = newAnim(gfx.player.armor.armor0.pants.swing, 43, 34, 1, 5), + walkAndSwing = newAnim(gfx.player.armor.armor0.pants.walkAndSwing, 43, 34, 1, 5) + } + } + }, swords = { sword0 = { walk = newAnim(gfx.player.swords.sword0.walk, 20, 29, 1, 5), diff --git a/main.lua b/main.lua index 902b129..688ce7a 100644 --- a/main.lua +++ b/main.lua @@ -9,6 +9,7 @@ json = require 'lib.json' bitser = require 'lib.bitser' Camera = require 'lib.camera' +require 'tempCommon' require 'utils' require 'loadassets' require 'sound' @@ -18,6 +19,7 @@ require 'cursor' require 'text' require 'menu' require 'hud' +require 'chat' require 'physics' require 'scene' require 'world' @@ -30,62 +32,7 @@ require 'lootBag' require 'portals' require 'damageText' require 'realm' -require 'chat' - --- todo: better sword check -isSword = {['sword0']=true, ['sword1']=true, ['sword2']=true, ['sword3']=true, ['sword4']=true} -tile2id = {} -for i, v in ipairs{'water', 'sand', 'grass', 'rock', 'path', 'floor', 'wall', 'platform', 'platform2'} do - tile2id[v] = i -end - --- todo: enemy inheritance -function serverEnemyDamage(self, d, clientId) - self.hp = self.hp - d - if self.hp <= 0 and not self.destroyed then - sound.play('scream') - server.addXP(clientId, math.random(3, 5)) - local bagItems = {} - local choices = { - none=50, shield=15, apple=20, - sword0=3, sword1=3, sword2=3, sword3=3, sword4=3 - } - for _=1, 3 do - choice = lume.weightedchoice(choices) - if choice ~= 'none' then - local itemData = {imageId=choice} - if choice == 'sword0' then - itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+10)) - elseif choice =='sword1' then - itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+12)) - elseif choice =='sword2' then - itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+14)) - elseif choice =='sword3' then - itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+16)) - elseif choice =='sword4' then - itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+18)) - end - local itemId = items.server.newItem(itemData) - table.insert(bagItems, itemId) - end - end - local numItems = #bagItems - if numItems ~= 0 then - local type = lume.randomchoice{'lootBag', 'lootBag1', 'lootBagFuse'} - lootBag.server:new{ - realm = serverRealm, - x = self.x, y = self.y, - items = bagItems, - type = type, - life = 30 - }:spawn() - end - --if math.random() < 0.5 then portals.server.spawn{x=self.x, y=self.y, life=10} end - self:destroy() - else - sound.play('spider') - end -end +require 'quests' function love.load() camera = Camera{ssx=gsx, ssy=gsy} @@ -109,34 +56,6 @@ function love.resize(w, h) gameScale = math.min(ssx/gsx, ssy/gsy) end --- window to game canvas -function window2game(x, y) - x = x - (ssx-gameScale*gsx)/2 - x = x / gameScale - y = y - (ssy-gameScale*gsy)/2 - y = y / gameScale - return x, y -end - -function setGameCanvas2x() - local _shader = love.graphics.getShader() - local _color = {love.graphics.getColor()} - love.graphics.setShader() - love.graphics.setCanvas(canvases.game2x) - love.graphics.setBlendMode('alpha', 'premultiplied') - love.graphics.setColor(1, 1, 1) - love.graphics.push() - love.graphics.origin() - love.graphics.draw(canvases.game, 0, 0, 0, 2, 2) - love.graphics.pop() - love.graphics.setCanvas(canvases.game) - love.graphics.setBlendMode('alpha') - love.graphics.clear() - love.graphics.setCanvas(canvases.game2x) - love.graphics.setShader(_shader) - love.graphics.setColor(_color) -end - function love.update(dt) prof.push('frame') prof.push('update') @@ -169,6 +88,7 @@ function love.mousepressed(x, y, btn, isTouch, presses) if gameState == 'playing' then hud.mousepressed(x, y, btn, isTouch, presses) playerController.mousepressed(x, y, btn, isTouch, presses) + items.client.mousepressed(x, y, btn, isTouch, presses) end end @@ -177,12 +97,16 @@ function love.mousereleased(x, y, btn, isTouch, presses) if gameState == 'playing' then hud.mousereleased(x, y, btn, isTouch, presses) playerController.mousereleased(x, y, btn, isTouch, presses) + items.client.mousereleased(x, y, btn, isTouch, presses) end - uiMouseDown = false - local heldItem = playerController.heldItem - heldItem.bagId = nil - heldItem.slotId = nil + if not love.mouse.isDown(1) and not love.mouse.isDown(2) then + uiMouseDown = false + local heldItem = playerController.heldItem + heldItem.itemId = nil + heldItem.bagId = nil + heldItem.slotId = nil + end end function love.textinput(t) @@ -213,6 +137,27 @@ function love.keypressed(k, scancode, isrepeat) hud.keypressed(k, scancode, isrepeat) playerController.keypressed(k, scancode, isrepeat) portals.client.keypressed(k, scancode, isrepeat) + if k == 'q' then + local p = playerController.player + for _, costItemId in ipairs(quests.current.cost) do + local costItem = items.client.getItem(costItemId) + if costItem then + -- duplicates costItem + for invSlotId, _ in ipairs(hud.inventorySlots) do + local slotType = slot2type[invSlotId] + if p.inventory.items[invSlotId] == nil + and (slotType == nil or slotType == costItem.type) then + client.setInventorySlot{ + slotId = invSlotId, + itemId = costItemId + } + p.inventory.items[invSlotId] = costItemId + break + end + end + end + end + end end if not isrepeat then if k == 'escape' and not chatPanelOpen then diff --git a/menu.lua b/menu.lua index 8741527..8f052f8 100644 --- a/menu.lua +++ b/menu.lua @@ -365,7 +365,7 @@ function menu.load() end} menu.masterVolumeSlider = menu.addSlider{state='options_audio', text='Master Volume', w=120, value=menu.defaults.masterVolume, action=function(v) - sound.play('select') + --sound.play('select') love.audio.setVolume(v) end} menu.addButton{state='options_audio', text='Back', y=exitY, action=function() diff --git a/playerController.lua b/playerController.lua index 0269e70..bc235b0 100644 --- a/playerController.lua +++ b/playerController.lua @@ -3,7 +3,8 @@ playerController = { interactRange = 30, closestBag = {id=nil, dist=nil, open=false}, hoveredItem = nil, - heldItem = {bagId=nil, slotId=nil, offset={x=0, y=0}} + heldItem = {itemId=nil, bagId=nil, slotId=nil, offset={x=0, y=0}}, + closestQuestBlock = {id=nil, dist=nil, open=false} } function playerController.load() @@ -42,7 +43,7 @@ function playerController.update(dt) closestBag.id = nil closestBag.dist = nil for _, bag in pairs(client.currentState.lootBags) do - local dist = math.sqrt((bag.x - px)^2 + (bag.y - py)^2) + local dist = lume.distance(bag.x, bag.y, px, py) if not closestBag.dist or dist < closestBag.dist then closestBag.id = bag.id closestBag.dist = dist @@ -53,12 +54,31 @@ function playerController.update(dt) closestBag.open = false end local heldItem = playerController.heldItem - if heldItem.bagId ~= 'inventory' and (not closestBag.id + if heldItem.bagId ~= 'inventory' and heldItem.bagId ~= 'quest' and (not closestBag.id or closestBag.id ~= heldItem.bagId or closestBag.dist > playerController.interactRange) then + heldItem.itemId = nil heldItem.bagId = nil heldItem.slotId = nil end playerController.hoveredItem = nil + + -- update closest questBlock + local cqb = playerController.closestQuestBlock + local lastId = cqb.id + cqb.id = nil + cqb.dist = nil + for _, v in pairs(client.currentState.entities) do + if not v.destroyed and v.type == 'questBlock' then + local dist = math.max(math.abs(v.x + 8 - px), math.abs(v.y + 8 - py)) + if not cqb.dist or dist < cqb.dist then + cqb.id = v.id + cqb.dist = dist + end + end + end + if not cqb.id or cqb.id ~= lastId or cqb.dist > playerController.interactRange then + cqb.open = false + end end function playerController.mousepressed(x, y, btn) @@ -66,48 +86,6 @@ function playerController.mousepressed(x, y, btn) mx, my = lume.round(mx), lume.round(my) local wmx, wmy = camera:screen2world(mx, my) - -- lootBags - local closestBag = playerController.closestBag - if closestBag.id and closestBag.open then - local bag = client.currentState.lootBags[closestBag.id] - local img = gfx.ui.bag - local bmx = wmx - (lume.round(bag.x) - lume.round(img:getWidth()/2)) - local bmy = wmy - (lume.round(bag.y) - img:getHeight() - 20) - for slotId, slot in ipairs(lootBagSlots) do - if bmx >= slot.x and bmx <= slot.x + slot.w - and bmy >= slot.y and bmy <= slot.y + slot.h then - uiMouseDown = true - if bag.items[slotId] then - if btn == 1 then - local heldItem = playerController.heldItem - heldItem.bagId = bag.id - heldItem.slotId = slotId - heldItem.offset.x = slot.x - bmx - heldItem.offset.y = slot.y - bmy - elseif btn == 2 then - local p = playerController.player - for invSlotId, _ in ipairs(hud.inventorySlots) do - if p.inventory.items[invSlotId] == nil then - client.moveItem{ - from = { - bagId = bag.id, - slotId = slotId - }, - to = { - bagId = p.inventory.id, - slotId = invSlotId - } - } - break - end - end - end - end - break - end - end - end - -- player attack if not uiMouseDown then playerController.player:mousepressed(x, y, btn) @@ -118,40 +96,6 @@ function playerController.mousereleased(x, y, btn) local mx, my = window2game(x, y) mx, my = lume.round(mx), lume.round(my) local wmx, wmy = camera:screen2world(mx, my) - - -- lootBags - local closestBag = playerController.closestBag - local heldItem = playerController.heldItem - if closestBag.id and closestBag.open and heldItem.bagId then - local bagFrom = client.currentState.lootBags[heldItem.bagId] - if heldItem.bagId == 'inventory' then - bagFrom = playerController.player.inventory - end - local bagTo = client.currentState.lootBags[closestBag.id] - local img = gfx.ui.bag - local bmx = wmx - (lume.round(bagTo.x) - lume.round(img:getWidth()/2)) - local bmy = wmy - (lume.round(bagTo.y) - img:getHeight() - 20) - for slotId, slot in ipairs(lootBagSlots) do - if bmx >= slot.x and bmx <= slot.x + slot.w - and bmy >= slot.y and bmy <= slot.y + slot.h then - client.moveItem{ - from = { - bagId = bagFrom.id, - slotId = heldItem.slotId - }, - to = { - bagId = bagTo.id, - slotId = slotId - } - } - -- move clientside before response (will be corrected/affirmed) - local temp = bagTo.items[slotId] - bagTo.items[slotId] = bagFrom.items[heldItem.slotId] - bagFrom.items[heldItem.slotId] = temp - break - end - end - end end function playerController.keypressed(k, scancode, isrepeat) @@ -160,5 +104,9 @@ function playerController.keypressed(k, scancode, isrepeat) if closestBag.id and closestBag.dist < playerController.interactRange then closestBag.open = not closestBag.open end + local cqb = playerController.closestQuestBlock + if cqb.id and cqb.dist < playerController.interactRange then + cqb.open = not cqb.open + end end end diff --git a/projectiles.lua b/projectiles.lua index 0409f66..dfafc06 100644 --- a/projectiles.lua +++ b/projectiles.lua @@ -14,7 +14,8 @@ function projectiles.server.spawn(data) speed = 2e2, life = 3, pierce = 2, - damage = 5 + damage = 5, + color = {192/255, 192/255, 192/255} } for k, v in pairs(defaults) do if data[k] == nil then data[k] = v end @@ -69,7 +70,8 @@ function projectiles.server.spawn(data) id = data.id, x = data.x, y = data.y, angle = data.angle, - polys = data.polys + polys = data.polys, + color = data.color } server.currentState.projectiles[data.id] = state server.added.projectiles[data.id] = state @@ -118,7 +120,7 @@ function projectiles.client.draw() love.graphics.setCanvas(canvases.tempGame) love.graphics.setShader() love.graphics.clear() - love.graphics.setColor(192/255, 192/255, 192/255) + love.graphics.setColor(v.color) love.graphics.push() love.graphics.translate(lume.round(v.x), lume.round(v.y)) love.graphics.rotate(-v.angle) diff --git a/quests.lua b/quests.lua new file mode 100644 index 0000000..fd5c0a6 --- /dev/null +++ b/quests.lua @@ -0,0 +1,49 @@ + +quests = {} + +questBlockSlots = {} +for k, v in ipairs{'cost', 'reward'} do + for j=1, 2 do + for i=1, 2 do + table.insert(questBlockSlots, { + x = 7 + (i-1)*18 + (k-1)*54, + y = 22 + (j-1)*18, + w = 15, + h = 15, + type = v + }) + end + end +end + +function quests.refresh() + quests.current = {cost={}, reward={}, heldItems={}} + local choices = { + shield=40, apple=40, + sword0=10, sword1=10 + } + for _=1, 2 do + choice = lume.weightedchoice(choices) + local itemData = {imageId=choice} + if choice == 'sword0' then + itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+10)) + elseif choice =='sword1' then + itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+12)) + end + local itemId = items.server.newItem(itemData) + table.insert(quests.current.cost, itemId) + end + local choices = {sword2=40, sword3=40, sword4=20} + choice = lume.weightedchoice(choices) + local itemData = {imageId=choice} + if choice =='sword2' then + itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+14)) + elseif choice =='sword3' then + itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+16)) + elseif choice =='sword4' then + itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+18)) + end + local itemId = items.server.newItem(itemData) + table.insert(quests.current.reward, itemId) +end +quests.refresh() diff --git a/realm.lua b/realm.lua index d1c7ed9..dd1a0c0 100644 --- a/realm.lua +++ b/realm.lua @@ -79,7 +79,7 @@ end function realm.client:draw() local mx, my = window2game(love.mouse.getPosition()) mx, my = lume.round(mx), lume.round(my) - wmx, wmy = camera:screen2world(mx, my) + local wmx, wmy = camera:screen2world(mx, my) self.world:draw() @@ -142,4 +142,69 @@ function realm.client:draw() y = bag.y } end + + local cqb = playerController.closestQuestBlock + if cqb.id and cqb.open then + local qb = client.currentState.entities[cqb.id] + if qb then + scene.add{ + draw = function() + local img = gfx.ui.quest + love.graphics.push() + love.graphics.translate( + lume.round(qb.x + 8) - lume.round(img:getWidth()/2), + lume.round(qb.y + 8) - img:getHeight() - 20) + love.graphics.setColor(1, 1, 1) + love.graphics.draw(img, 0, 0) + local bmx = wmx - (lume.round(qb.x + 8) - lume.round(img:getWidth()/2)) + local bmy = wmy - (lume.round(qb.y + 8) - img:getHeight() - 20) + + for slotId, slot in ipairs(questBlockSlots) do + local exists = true + local item = items.client.getItem(quests.current.heldItems[slotId]) + if not item then + exists = false + if slotId <= 4 then + item = items.client.getItem(quests.current.cost[slotId]) + else + item = items.client.getItem(quests.current.reward[slotId - 4]) + end + end + if slotId >= 5 then + local allExist = true + for i, item in ipairs(quests.current.cost) do + if not quests.current.heldItems[i] then + allExist = false + break + end + end + exists = allExist + end + if bmx >= slot.x and bmx <= slot.x + slot.w + and bmy >= slot.y and bmy <= slot.y + slot.h then + if item then + cursor.cursor = cursor.hand + playerController.hoveredItem = item + end + love.graphics.setColor(1, 1, 1, 0.4) + love.graphics.rectangle('fill', slot.x, slot.y, slot.w, slot.h) + end + local heldItem = playerController.heldItem + if not (heldItem.bagId == 'quest' and heldItem.slotId == slotId) then + if item then + if exists then + love.graphics.setColor(1, 1, 1) + else + love.graphics.setColor(1, 1, 1, 0.4) + end + love.graphics.draw(gfx.items[item.imageId], slot.x, slot.y) + end + end + end + love.graphics.pop() + end, + y = qb.y + } + end + end end diff --git a/server.lua b/server.lua index e1c74a8..c014c80 100644 --- a/server.lua +++ b/server.lua @@ -165,6 +165,10 @@ function server.start(port, singleplayer) local ty = portal.y + lume.random(-128, 128) server.nutServer:sendRPC('teleportPlayer', bitser.dumps{x=tx, y=ty}, clientId) end + end, + setInventorySlot = function(self, data, clientId) + local p = server.currentState.players[clientId] + p.inventory.items[data.slotId] = data.itemId end } for k, v in pairs(bitserRPCs) do diff --git a/tempCommon.lua b/tempCommon.lua new file mode 100644 index 0000000..3e12f1a --- /dev/null +++ b/tempCommon.lua @@ -0,0 +1,94 @@ + +-- todo: better sword check +isSword = {} +for _, v in ipairs{'sword0', 'sword1', 'sword2', 'sword3', 'sword4'} do + isSword[v] = true +end +sword2color = { + sword0 = {192/255, 192/255, 192/255}, + sword1 = {114/255, 114/255, 114/255}, + sword2 = {166/255, 97/255, 56/255}, + sword3 = {238/255, 50/255, 255/255}, + sword4 = {255/255, 255/255, 50/255} +} +slot2type = {'helmet', 'sword', 'chest', 'shield', 'accessory', 'pants', 'accessory'} +tile2id = {} +for i, v in ipairs{'water', 'sand', 'grass', 'rock', 'path', 'floor', 'wall', 'platform', 'platform2'} do + tile2id[v] = i +end + +-- todo: enemy inheritance +function serverEnemyDamage(self, d, clientId) + self.hp = self.hp - d + if self.hp <= 0 and not self.destroyed then + sound.play('scream') + server.addXP(clientId, math.random(3, 5)) + local bagItems = {} + local choices = { + none=20, apple=10, helmet=16, chest=16, pants=16, shield=5, + sword0=4, sword1=4, sword2=3, sword3=3, sword4=3 + } + for _=1, 3 do + choice = lume.weightedchoice(choices) + if choice ~= 'none' then + local itemData = {imageId=choice} + if choice == 'sword0' then + itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+10)) + elseif choice =='sword1' then + itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+12)) + elseif choice =='sword2' then + itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+14)) + elseif choice =='sword3' then + itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+16)) + elseif choice =='sword4' then + itemData.atk = math.max(5, math.floor(love.math.randomNormal()*2+18)) + end + local itemId = items.server.newItem(itemData) + table.insert(bagItems, itemId) + end + end + local numItems = #bagItems + if numItems ~= 0 then + local type = lume.randomchoice{'lootBag', 'lootBag1', 'lootBagFuse'} + lootBag.server:new{ + realm = serverRealm, + x = self.x, y = self.y, + items = bagItems, + type = type, + life = 30 + }:spawn() + end + --if math.random() < 0.5 then portals.server.spawn{x=self.x, y=self.y, life=10} end + self:destroy() + else + sound.play('spider') + end +end + +-- window to game canvas +function window2game(x, y) + x = x - (ssx-gameScale*gsx)/2 + x = x / gameScale + y = y - (ssy-gameScale*gsy)/2 + y = y / gameScale + return x, y +end + +function setGameCanvas2x() + local _shader = love.graphics.getShader() + local _color = {love.graphics.getColor()} + love.graphics.setShader() + love.graphics.setCanvas(canvases.game2x) + love.graphics.setBlendMode('alpha', 'premultiplied') + love.graphics.setColor(1, 1, 1) + love.graphics.push() + love.graphics.origin() + love.graphics.draw(canvases.game, 0, 0, 0, 2, 2) + love.graphics.pop() + love.graphics.setCanvas(canvases.game) + love.graphics.setBlendMode('alpha') + love.graphics.clear() + love.graphics.setCanvas(canvases.game2x) + love.graphics.setShader(_shader) + love.graphics.setColor(_color) +end