diff --git a/game/engine/Chat.lua b/game/engine/Chat.lua new file mode 100644 index 0000000000000000000000000000000000000000..4779d2ac6789117e8bab5ba0c788f6fb3f610ac8 --- /dev/null +++ b/game/engine/Chat.lua @@ -0,0 +1,44 @@ +require "engine.class" +require "engine.dialogs.Chat" + +--- Handle chats between the player and NPCs +module(..., package.seeall, class.make) + +function _M:init(name, npc, player) + self.chats = {} + self.npc = npc + self.player = player + + local f = loadfile("/data/chats/"..name..".lua") + setfenv(f, setmetatable({ + newChat = function(c) self:addChat(c) end, + }, {__index=_G})) + self.default_id = f() +end + +--- Adds a chat to the list of possible chats +function _M:addChat(c) + assert(c.id, "no chat id") + assert(c.text, "no chat text") + assert(c.answers, "no chat answers") + self.chats[c.id] = c + print("[CHAT] loaded", c.id, c) +end + +--- Invokes a chat +-- @param id the id of the first chat to run, if nil it will use the default one +function _M:invoke(id) + local d = engine.dialogs.Chat.new(self, id or self.default_id) + game:registerDialog(d) +end + +--- Gets the chat with the given id +function _M:get(id) + print("[CHAT] get", id) + return self.chats[id] +end + +--- Replace some keywords in the given text +function _M:replace(text) + return text:gsub("@playername@", self.player.name):gsub("@npcname@", self.npc.name) +end diff --git a/game/engine/Dialog.lua b/game/engine/Dialog.lua index c2d315d8fb6d91560a6487aac541499214753fbf..c34461298f266afe405ee6d216b224a3b9c9406d 100644 --- a/game/engine/Dialog.lua +++ b/game/engine/Dialog.lua @@ -125,7 +125,7 @@ function _M:drawHBorder(s, x, y, h) end end -function _M:drawSelectionList(s, x, y, hskip, list, sel, prop, scroll, max, color, selcolor) +function _M:drawSelectionList(s, x, y, hskip, list, sel, prop, scroll, max, color, selcolor, max_size) selcolor = selcolor or {0,255,255} color = color or {255,255,255} max = max or 99999 @@ -139,12 +139,17 @@ function _M:drawSelectionList(s, x, y, hskip, list, sel, prop, scroll, max, colo if prop and type(v[prop]) == "string" then v = tostring(v[prop]) elseif prop and type(v[prop]) == "function" then v = tostring(v[prop](v)) else v = tostring(v) end - if sel == i then - s:drawColorString(self.font, v, x, y + (i-scroll) * hskip, selcolor[1], selcolor[2], selcolor[3]) - else - local r, g, b = color[1], color[2], color[3] - if vc then r, g, b = vc[1], vc[2], vc[3] end - s:drawColorString(self.font, v, x, y + (i-scroll) * hskip, r, g, b) + + local lines = v:splitLines(max_size or 100000, self.font) + for j = 1, #lines do + if sel == i then + s:drawColorString(self.font, lines[j], x, y, selcolor[1], selcolor[2], selcolor[3]) + else + local r, g, b = color[1], color[2], color[3] + if vc then r, g, b = vc[1], vc[2], vc[3] end + s:drawColorString(self.font, lines[j], x, y, r, g, b) + end + y = y + hskip end end end diff --git a/game/engine/Quest.lua b/game/engine/Quest.lua index 9dddb8117af7d862c551b08ff7060910e7ff9ebd..e05e859559e6bd554ec1a5a5ed25e97592bd9559 100644 --- a/game/engine/Quest.lua +++ b/game/engine/Quest.lua @@ -1,5 +1,6 @@ require "engine.class" +--- Handle quests module(..., package.seeall, class.make) PENDING = 0 @@ -13,6 +14,7 @@ function _M:init(q) end self.status = PENDING self.objectives = {} + self:check("on_grant", who) end --- Checks if the quest (or sub-objective) is complete diff --git a/game/engine/dialogs/Chat.lua b/game/engine/dialogs/Chat.lua new file mode 100644 index 0000000000000000000000000000000000000000..465160e221ea90af0e5da4e7a2272185bc6a1a67 --- /dev/null +++ b/game/engine/dialogs/Chat.lua @@ -0,0 +1,93 @@ +require "engine.class" +require "engine.Dialog" + +module(..., package.seeall, class.inherit(engine.Dialog)) + +function _M:init(chat, id) + self.cur_id = id + self.chat = chat + self.npc = chat.npc + self.player = chat.player + engine.Dialog.init(self, self.npc.name, 500, 400) + + self:generateList() + + self.sel = 1 + self.scroll = 1 + self.max = math.floor((self.ih - 5) / self.font_h) - 1 + + self:keyCommands({ + __TEXTINPUT = function(c) + if c:find("^[a-z]$") then + self.sel = util.bound(1 + string.byte(c) - string.byte('a'), 1, #self.list) + self:use() + end + end, + },{ + MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, + MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list) self.scroll = util.scroll(self.sel, self.scroll, self.max) self.changed = true end, + ACCEPT = function() self:use() end, + }) + self:mouseZones{ + { x=2, y=5, w=350, h=self.font_h*self.max, fct=function(button, x, y, xrel, yrel, tx, ty) + self.sel = util.bound(self.scroll + math.floor(ty / self.font_h), 1, #self.list) + if button == "left" then self:use() + elseif button == "right" then + end + end }, + } +end + +function _M:use() + local a = self.chat:get(self.cur_id).answers[self.list[self.sel].answer] + if not a then return end + + self.changed = true + + print("[CHAT] selected", a[1], a.action, a.jump) + if a.action then + local id = a.action(self.npc, self.player) + if id then + self.cur_id = id + self:generateList() + self.sel = 1 + self.scroll = 1 + return + end + end + if a.jump then + self.cur_id = a.jump + self:generateList() + self.sel = 1 + self.scroll = 1 + else + game:unregisterDialog(self) + end +end + +function _M:generateList() + -- Makes up the list + local list = {} + for i, a in ipairs(self.chat:get(self.cur_id).answers) do + if not a.cond or a.cond(self.npc, self.player) then + list[#list+1] = { name=string.char(string.byte('a')+i-1)..") "..a[1], answer=i, color=a.color} + end + end + self.list = list +end + +function _M:drawDialog(s) + local h = 5 + local lines = self.chat:replace(self.chat:get(self.cur_id).text):splitLines(self.iw - 10, self.font) + local r, g, b + for i = 1, #lines do + r, g, b = s:drawColorString(self.font, lines[i], 5, 2 + h, r, g, b) + h = h + self.font:lineSkip() + end + + self:drawWBorder(s, 5, h + 0.5 * self.font:lineSkip(), self.iw - 10) + + -- Answers + self:drawSelectionList(s, 5, h + 1.5 * self.font:lineSkip(), self.font_h, self.list, self.sel, "name", self.scroll, self.max, nil, nil, self.iw - 10) + self.changed = false +end diff --git a/game/engine/generator/map/Static.lua b/game/engine/generator/map/Static.lua index d18136be332edf404ccba1f6ecac7b8e2dc59b3e..548a9369f68ab92b30cf7d2210e1ce0755d0b99c 100644 --- a/game/engine/generator/map/Static.lua +++ b/game/engine/generator/map/Static.lua @@ -1,6 +1,5 @@ require "engine.class" local Map = require "engine.Map" -local Grid = require "engine.Grid" require "engine.Generator" module(..., package.seeall, class.inherit(engine.Generator)) @@ -34,7 +33,7 @@ function _M:loadMap(file) t[char] = {grid=grid, obj=obj, actor=actor, trap=trap} end, quickEntity = function(char, e) - local e = Grid.new(e) + local e = self.zone.grid_class.new(e) e:resolve() e:resolve(nil, true) t[char] = {grid=e} diff --git a/game/engine/interface/ActorQuest.lua b/game/engine/interface/ActorQuest.lua index 12a6eaa6ed44473450fbd4cd7356a29cc4e429e8..27fb2dc031d7daf12369bc56128988ce848b3358 100644 --- a/game/engine/interface/ActorQuest.lua +++ b/game/engine/interface/ActorQuest.lua @@ -22,7 +22,7 @@ function _M:grantQuest(quest) assert(quest.desc, "no quest desc") self.quests = self.quests or {} - self.quests[quest.id] = require(_M.quest_class).new(quest) + self.quests[quest.id] = require(_M.quest_class).new(quest, self) self.quests[quest.id].gained_turn = game.turn print("[QUEST] given to", self, quest.id) self:check("on_quest_grant", quest) diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 211958f3745981ba854b91bda1051488a43fcd83..078093616f489e88885ccb2ef570e243a4ecc205 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -267,7 +267,10 @@ function _M:display() -- Display a tooltip if available local mx, my = core.mouse.get() local tmx, tmy = self.level.map:getMouseTile(mx, my) - local tt = self.level.map:checkEntity(tmx, tmy, Map.ACTOR, "tooltip") or self.level.map:checkEntity(tmx, tmy, Map.OBJECT, "tooltip") or self.level.map:checkEntity(tmx, tmy, Map.TRAP, "tooltip") or self.level.map:checkEntity(tmx, tmy, Map.TERRAIN, "tooltip") + local tt = self.level.map:checkEntity(tmx, tmy, Map.ACTOR, "tooltip") or + self.level.map:checkEntity(tmx, tmy, Map.OBJECT, "tooltip") or + self.level.map:checkEntity(tmx, tmy, Map.TRAP, "tooltip") or + self.level.map:checkEntity(tmx, tmy, Map.TERRAIN, "tooltip") if tt and self.level.map.seens(tmx, tmy) then self.tooltip:set("%s", tt) local t = self.tooltip:display() @@ -367,7 +370,7 @@ function _M:setupCommands() self.key:addCommands{ [{"_d","ctrl"}] = function() - self:changeLevel(2, "illusory-castle") + self:changeLevel(1, "town-minas-tirith") end, } self.key:addBinds diff --git a/game/modules/tome/class/Grid.lua b/game/modules/tome/class/Grid.lua index 60a37e36ef014ad5105b37fc29b8ee9135777432..f42ec9164bff64a39b9574f8b05ee8629aa1a075 100644 --- a/game/modules/tome/class/Grid.lua +++ b/game/modules/tome/class/Grid.lua @@ -20,6 +20,11 @@ end function _M:tooltip() if self.show_tooltip then - return (self.show_tooltip == true) and self.name or self.show_tooltip + local name = ((self.show_tooltip == true) and self.name or self.show_tooltip) + if self.desc then + return name.."\n"..self.desc + else + return name + end end end diff --git a/game/modules/tome/data/chats/minas-tirith-elder.lua b/game/modules/tome/data/chats/minas-tirith-elder.lua new file mode 100644 index 0000000000000000000000000000000000000000..31c78b4a431e05ab025356af27f233d0ef6e53a4 --- /dev/null +++ b/game/modules/tome/data/chats/minas-tirith-elder.lua @@ -0,0 +1,27 @@ +newChat{ id="welcome", + text = [[Welcome @playername@ to Minas Tirith traveler, please be quick my time is precious.]], + answers = { + {"Nothing, excuse me. Bye!"}, + {"I have found this staff in my travels, it looks really old and powerful. I dare not use it.", jump="found_staff"}, + } +} + +newChat{ id="found_staff", + text = [[*He examines the staff* Indeed you were right in bringing it here. While I cannot sense its true purpose I feel this could be used to cause many wrongs. +Please surrender the staff to the protection of the King while we work to learn its power. +This could be related to the rumours we hear from the far east...]], + answers = { + {"Take it Sir.", action=function(npc, player) + player:setQuestStatus("staff-absorption", engine.Quest.DONE) + player.winner = true + local D = require "engine.Dialog" + D:simplePopup("Winner!", "#VIOLET#Congratulations you have won the game! At least for now... The quest has only started!") + + config.settings.tome = config.settings.tome or {} + config.settings.tome.allow_evil = true + game:saveSettings("tome.allow_evil", ("tome.allow_evil = %s\n"):format(tostring(config.settings.tome.allow_evil))) + end}, + } +} + +return "welcome" diff --git a/game/modules/tome/data/general/objects/quest-artifacts.lua b/game/modules/tome/data/general/objects/quest-artifacts.lua index 7b3023368d1814b4c3549aaaf4857bb145299897..4158a938782bc636e6d27e2672c56a608d5fb145 100644 --- a/game/modules/tome/data/general/objects/quest-artifacts.lua +++ b/game/modules/tome/data/general/objects/quest-artifacts.lua @@ -33,13 +33,7 @@ newEntity{ define_as = "STAFF_ABSORPTION", on_pickup = function(self, who) if who == game.player then - game.logPlayer(who, "#00FFFF#You can feel the power of this staff just by carrying it. This is both ancient and dangerous.") - game.logPlayer(who, "#00FFFF#It should be shown to the wise elders in Minas Tirith!") - who.winner = true who:grantQuest("staff-absorption") - - local D = require "engine.Dialog" - D:simplePopup("Winner!", "#VIOLET#Congratulations you have won the game! At least for now... The quest has only started!") end end, } diff --git a/game/modules/tome/data/gfx/object/potion-0x0.png b/game/modules/tome/data/gfx/object/potion-0x0.png index 1bcca0deb1d89075958c11801a6354f0cfc17faa..d609174e3b05a15ffe00a6498afff8bba0ca2efe 100644 Binary files a/game/modules/tome/data/gfx/object/potion-0x0.png and b/game/modules/tome/data/gfx/object/potion-0x0.png differ diff --git a/game/modules/tome/data/gfx/object/potion-0x1.png b/game/modules/tome/data/gfx/object/potion-0x1.png new file mode 100644 index 0000000000000000000000000000000000000000..2c922a600a69378289b897a43ea6536e8ba94824 Binary files /dev/null and b/game/modules/tome/data/gfx/object/potion-0x1.png differ diff --git a/game/modules/tome/data/gfx/object/potion-2x1.png b/game/modules/tome/data/gfx/object/potion-2x1.png new file mode 100644 index 0000000000000000000000000000000000000000..fa95b9cae664cc7989fcd2fb774cef4667d60705 Binary files /dev/null and b/game/modules/tome/data/gfx/object/potion-2x1.png differ diff --git a/game/modules/tome/data/maps/towns/bree.lua b/game/modules/tome/data/maps/towns/bree.lua index 6ea3c50e9bc3c655cf4228188b568aa6180e52e7..31f64a81151df277a78172b2159d75981b7df54d 100644 --- a/game/modules/tome/data/maps/towns/bree.lua +++ b/game/modules/tome/data/maps/towns/bree.lua @@ -1,4 +1,4 @@ -quickEntity('<', {name='into the wild', display='<', color=colors.WHITE, change_level=1, change_zone="wilderness"}) +quickEntity('<', {show_tooltip=true, name='into the wild', display='<', color=colors.WHITE, change_level=1, change_zone="wilderness"}) quickEntity('S', {name='brick roof top', display='#', color=colors.RED, block_move=true, block_sight=true, image="terrain/wood_wall1.png"}) quickEntity('s', {name='brick roof', display='#', color=colors.RED, block_move=true, block_sight=true, image="terrain/wood_wall1.png"}) quickEntity('t', {name='brick roof chimney', display='#', color=colors.LIGHT_RED, block_move=true, block_sight=true, image="terrain/wood_wall1.png"}) @@ -13,21 +13,21 @@ quickEntity(',', {name='dirt', display='.', color=colors.LIGHT_UMBER, image="ter quickEntity('-', {name='grass', display='.', color=colors.LIGHT_GREEN, image="terrain/grass.png"}) quickEntity('^', {name='hills', display='^', color=colors.SLATE, image="terrain/mountain.png", block_move=true, block_sight=true}) -quickEntity('1', {name="Closed store", display='1', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) -quickEntity('2', {name="Armour Smith", display='2', color=colors.UMBER, resolvers.store("ARMOR"), image="terrain/wood_store_armor.png"}) -quickEntity('3', {name="Weapon Smith", display='3', color=colors.UMBER, resolvers.store("WEAPON"), image="terrain/wood_store_weapon.png"}) -quickEntity('4', {name="Alchemist", display='4', color=colors.LIGHT_BLUE, resolvers.store("POTION"), image="terrain/wood_store_potion.png"}) -quickEntity('5', {name="Scribe", display='5', color=colors.WHITE, resolvers.store("SCROLL"), image="terrain/wood_store_book.png"}) -quickEntity('6', {name="Closed store", display='6', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) -quickEntity('7', {name="Closed store", display='7', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) -quickEntity('8', {name="Closed store", display='8', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) -quickEntity('9', {name="Closed store", display='9', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) -quickEntity('0', {name="Closed store", display='0', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) -quickEntity('a', {name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) -quickEntity('b', {name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) -quickEntity('c', {name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) -quickEntity('d', {name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) -quickEntity('e', {name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('1', {show_tooltip=true, name="Closed store", display='1', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('2', {show_tooltip=true, name="Armour Smith", display='2', color=colors.UMBER, resolvers.store("ARMOR"), image="terrain/wood_store_armor.png"}) +quickEntity('3', {show_tooltip=true, name="Weapon Smith", display='3', color=colors.UMBER, resolvers.store("WEAPON"), image="terrain/wood_store_weapon.png"}) +quickEntity('4', {show_tooltip=true, name="Alchemist", display='4', color=colors.LIGHT_BLUE, resolvers.store("POTION"), image="terrain/wood_store_potion.png"}) +quickEntity('5', {show_tooltip=true, name="Scribe", display='5', color=colors.WHITE, resolvers.store("SCROLL"), image="terrain/wood_store_book.png"}) +quickEntity('6', {show_tooltip=true, name="Closed store", display='6', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('7', {show_tooltip=true, name="Closed store", display='7', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('8', {show_tooltip=true, name="Closed store", display='8', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('9', {show_tooltip=true, name="Closed store", display='9', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('0', {show_tooltip=true, name="Closed store", display='0', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('a', {show_tooltip=true, name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('b', {show_tooltip=true, name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('c', {show_tooltip=true, name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('d', {show_tooltip=true, name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('e', {show_tooltip=true, name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) startx = 76 starty = 36 diff --git a/game/modules/tome/data/maps/towns/minas-tirith.lua b/game/modules/tome/data/maps/towns/minas-tirith.lua new file mode 100644 index 0000000000000000000000000000000000000000..ced381a08c1338730308250ee9e2e5cf6f96037a --- /dev/null +++ b/game/modules/tome/data/maps/towns/minas-tirith.lua @@ -0,0 +1,102 @@ +quickEntity('<', {show_tooltip=true, name='into the wild', display='<', color=colors.WHITE, change_level=1, change_zone="wilderness"}) +quickEntity('S', {name='brick roof top', display='#', color=colors.RED, block_move=true, block_sight=true, image="terrain/wood_wall1.png"}) +quickEntity('s', {name='brick roof', display='#', color=colors.RED, block_move=true, block_sight=true, image="terrain/wood_wall1.png"}) +quickEntity('t', {name='brick roof chimney', display='#', color=colors.LIGHT_RED, block_move=true, block_sight=true, image="terrain/wood_wall1.png"}) +quickEntity('#', {name='wall', display='#', color=colors.WHITE, block_move=true, block_sight=true, image="terrain/wood_wall1.png"}) +quickEntity('C', {name='dark pit', display='#', color=colors.LIGHT_DARK, block_move=true, block_sight=true}) +quickEntity('T', {name='tree', display='#', color=colors.LIGHT_GREEN, block_move=true, block_sight=true, image="terrain/tree.png"}) +quickEntity('V', {name='river', display='~', color=colors.BLUE, block_move=true, image="terrain/river.png"}) +quickEntity('O', {name='cooblestone road', display='.', color=colors.WHITE, image="terrain/stone_road1.png"}) +quickEntity(' ', {name='grass', display='.', color=colors.LIGHT_GREEN, image="terrain/grass.png"}) +quickEntity('-', {name='grass', display='.', color=colors.LIGHT_GREEN, image="terrain/grass.png"}) +quickEntity('^', {name='hills', display='^', color=colors.SLATE, image="terrain/mountain.png", block_move=true, block_sight=true}) + +quickEntity('1', {show_tooltip=true, name="Closed store", display='1', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('2', {show_tooltip=true, name="Armour Smith", display='2', color=colors.UMBER, resolvers.store("ARMOR"), image="terrain/wood_store_armor.png"}) +quickEntity('3', {show_tooltip=true, name="Weapon Smith", display='3', color=colors.UMBER, resolvers.store("WEAPON"), image="terrain/wood_store_weapon.png"}) +quickEntity('4', {show_tooltip=true, name="Alchemist", display='4', color=colors.LIGHT_BLUE, resolvers.store("POTION"), image="terrain/wood_store_potion.png"}) +quickEntity('5', {show_tooltip=true, name="Scribe", display='5', color=colors.WHITE, resolvers.store("SCROLL"), image="terrain/wood_store_book.png"}) +quickEntity('6', {show_tooltip=true, name="Closed store", display='6', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('7', {show_tooltip=true, name="Closed store", display='7', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('8', {show_tooltip=true, name="Closed store", display='8', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('9', {show_tooltip=true, name="Closed store", display='9', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('0', {show_tooltip=true, name="Closed store", display='0', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('a', {show_tooltip=true, name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('b', {show_tooltip=true, name="Hall of the King", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('c', {show_tooltip=true, name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('d', {show_tooltip=true, name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) +quickEntity('e', {show_tooltip=true, name="Closed store", display='*', color=colors.LIGHT_UMBER, block_move=true, block_sight=true, image="terrain/wood_store_closed.png"}) + +quickEntity('E', {show_tooltip=true, name="The Elder", display='*', color=colors.VIOLET, resolvers.chatfeature("minas-tirith-elder"), image="terrain/wood_store_closed.png"}) + +startx = 95 +starty = 45 + +return { +[[################################################################################################]], +[[#^^########------------------ ]], +[[#^^^------############---------- ^ ]], +[[#^^^----------###----#######------- ^^^^^ ]], +[[#^^----ssss-----###--------####------ ^^^^^^ ]], +[[#^^^---StSS-------###--#ssss--###------- ^^^^^^^^ ]], +[[#^^----ssss----OO---##--#StSS---####------ ^^^^^^^^ ]], +[[#^^----x#a#-----OOO--##--#sssss----###------ ^^^^^^^^ ]], +[[#^ ---------------OO--###-#m#7#------###----- ^^^^^^^^^^ ]], +[[#^ StSSSS-----ss---OO---##-----OOOOO---###---- ^^^^^^^^^^^ ]], +[[#^^ssssss----Ssss---OOO--##---OOOOOOOO---##---- ^l^^^^^^^ ]], +[[#^ ####9#---sstSss---OOO--##-OOOOOOOOOOO--##---- ^^^^^ ]], +[[#^^^-------##sssSss---OOO--#OOO--s--OOOOO--###--- ]], +[[#^^^######---##ssh--s--OOO-OOO--StS--OOOOO---##--- ]], +[[#^^^^----###---##--ssS--OOOOO#--ssss--OOOOOO--##--- ]], +[[#^^--------###----ssSs#--OOO-##-#####--OOOOOO--##--- ---- ]], +[[#^ ----------##--#stsi--OOOO--#---------OOOOOO--#------ -------- ]], +[[#^^-----------###-#s#--OOOOOO-##-#sssss--OOOOOO,#####--- ----------- ]], +[[#^^-------------##-#--OOO-OOO--#--ssssss--OOOOO,,,,,#---- ---ssssssss--- ]], +[[#^^--------------#---OOO-t-OOO-##-#SStSS--OOOOOO,##,#---------ssssssss---- ]], +[[#^^^--#----------##-OOO-sssOOO--#--ssssss-OOOOOO--#,#####-----SStSSSSS----- ]], +[[#^^^--#-----------#OOO-##4##OOO-##-ssssss--OOOOOO-#,,######---ssssssss--O--- ]], +[[#^^--###----------OOO-------OOO--#-####2#--OOOOOO-##,#k#,,##--ssssssss--O---- ]], +[[#^^^-###---------OOO#--SSStS-OOO-#---------OOOOO---#,,,,,,,#--ssssssss--O----- ]], +[[#^^-#####-------OOO-#--sssss-OOO-#--ssss--OOOOO--T-#,-----,#--#####d##--O------ ]], +[[#^^#######------OOO-##-###j#-OOO-##-ssss--OOOOO-TT-#------,#-------,,,,,O------ ]], +[[#^^^########----OOO--#-------OOO--#-StSS--OOOOO-TT-#-----,,#------------O------- ]], +[[#^^############-OOO--##-StSSS-OOO-#-ssss--OOOOO--T-#----,,##---ssssssss-O-------- ]], +[[#^^^#########---OOO---#-sssss-OOO-#-ssss--OOOOOO---#,,,,,##----SSSSStSS-O--------- ]], +[[#^^#####B###----OOO---#-###6#-OOO-#-##g#---OOOOOO--#######-----ssssssss-O---------- ]], +[[#^^^#######-----OOO---#-------OOO-#---------OOOOOOOOOOOOOOOOO--###e####-O----------- ]], +[[#^^#######bOOOOOOOO-^^^^^^^^^^MMM^^^^^^^^^^^^OOOOOOOOOOOOOOOOOOOOOOOOOOOO----------- ]], +[[#^^#######bOOOOOOO############III############^OOOOOOOOOOOOOOOOOOOOOOOOOOOOO--------- ]], +[[#^ #######bOOOOOOO############III############^OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO--------- ]], +[[#^ #######bOOOOOOOO-^^^^^^^^^^MMM^^^^^^^^^^^^OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO------- ]], +[[#^^^#######-----OOO---#-sSss--OOO-#---------OOOOOOOOOOOOOOOOO-----------OOOOOOO------ ]], +[[#^^#########----OOO---#-sSss--OOO-#-sssss--OOOOOO--#######--------sssss-O-OOOOO----- ]], +[[#^^#########E---OOO---#-stss--OOO-#-SStSS-OOOOOO---####,,##-------SStSS-O-OOOOO---- ]], +[[#^^############-OOO--##-sSss--OOO-#-sssss-OOOOO--T-##k#,,,##------sssss-O--OOOOO--- ]], +[[#^^#########----OOO--#--####-OOO--#-sssss-OOOOO-TT-#,,,,-,,#------sssss-O---OOOO--- ]], +[[#^^#######------OOO-##-------OOO-##-###3#-OOOOO-TT-#,-----,#------###0#-O---OOOOO--- ]], +[[#^^-#####-------OOO-#--Ssss--OOO-#--------OOOOO--T-#,-----,#------------O----OOOO---- ]], +[[#^^^-###---------OOO#-#stss--OOO-#-ssssss--OOOOO---#,----,,#----ssssss--O-----OOOO---- --]], +[[#^^--###----------OOO--#sSs-OOO--#-StSSSS--OOOOOO-##,-,,,,##----SStSSS--O------OOOO---- --O]], +[[#^^---#-----------#OOO--###-OOO-##-ssssss--OOOOOO-#,,,,####-----ssssss--O-------OOOO---- --OO]], +[[#^^^--#----------##-OOO----OOO--#--###5##-OOOOOO--#,#####-------ssssss-OO--------OOOO--------OO<]], +[[#^^^-------------#---OOO---OOO-##---------OOOOOO,##,#-----------####1#-O----------OOOO----OOOOOO]], +[[#^^-------------##----OOO-OOO--#--ss------OOOOO,,,,,#------------------O-----------OOOOOOOOOOO--]], +[[#^^^----------###--ss--OOOOOO-##-ssSs----OOOOOO,#####------------------O-------- ---OOOOOOOOO---]], +[[#^^^---------##---ssSs--OOOO--#--ssts#--OOOOOO--#------ ------ssssss--OO------ ---OOOOO----- ]], +[[#^^--------###---sstss#--OOO-##-ssSs#--OOOOOO--##----- ----StSSSS--O------ ----------- ]], +[[#^^------###-----#Sss#--OOOOO#--sSsf--OOOOOO--##----- ---ssssss--O----- ------- ]], +[[#^^^######---ss---#s#--OOO-OOO--Ss#--OOOOO---##----- --###w##-OO----- ]], +[[#^^^-------ssssS---#--OOO--#OOO--#--OOOOO--###----- --------O----- ]], +[[#^^-sssss-#ssstss----OOO--##-OOO---OOOOO--##------ ------OO---- ]], +[[#^^-SSStS--#sSsss#--OOO--##---OOOOOOOO---##------ ----O---- ]], +[[#^^-sssss---#ss##--OO---##--X--OOOOO---###------ ---O--- ]], +[[#^^^#####----##---OO--###--XXX-OOO---###------ --- ]], +[[#^^^------------OOO--##---XXX#-----###----- ]], +[[#^^--SStSS-----OO---##--XX###---####----- ]], +[[#^^^-sssss--------###--###----###------ ]], +[[#^^--#####------###--------####------ ]], +[[#^^^----------###----#######------ ]], +[[#^^^------############---------- ]], +[[#^^########----------------- ]], +[[################################################################################################]], +} \ No newline at end of file diff --git a/game/modules/tome/data/maps/wilderness/main.lua b/game/modules/tome/data/maps/wilderness/main.lua index e4243151757b85628d3df18c424a3b3312c060ac..87e4b219b4f64030c244608b39d044b7860bfee3 100644 --- a/game/modules/tome/data/maps/wilderness/main.lua +++ b/game/modules/tome/data/maps/wilderness/main.lua @@ -26,7 +26,8 @@ quickEntity('D', {show_tooltip=true, name="A path into the Old Forest", displa quickEntity('E', {show_tooltip=true, name="A mysterious hole in the beach", display='>', color={r=200, g=255, b=55}, change_level=1, change_zone="sandworm-lair"}) quickEntity('F', {show_tooltip=true, name="The entry to the old tower of Tol Falas",display='>', color={r=0, g=255, b=255}, change_level=1, change_zone="tol-falas"}) -quickEntity('1', {show_tooltip=true, name="Bree (Town)", display='*', color={r=255, g=255, b=255}, change_level=1, change_zone="town-bree"}) +quickEntity('1', {show_tooltip=true, name="Bree (Town)", desc="A quiet town at the crossroads of the north", display='*', color={r=255, g=255, b=255}, change_level=1, change_zone="town-bree"}) +quickEntity('2', {show_tooltip=true, name="Minas Tirith (Town)", desc="Captical city of the Reunited-Kingdom and Gondor ruled by High King Eldarion", display='*', color={r=255, g=255, b=255}, change_level=1, change_zone="town-minas-tirith"}) return { [[========q=qqqqqqqqqgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg]], @@ -44,26 +45,26 @@ return { [[======...._.bb._..._............................m....._._uuu................ii........ttttttttttttt]], [[=======.._..bb.._.._..hhhh................&....&mm~~~~.uu_uuuu..........i.....iii........tttttt^^^^]], [[======.._...bb..._._..hhh.......hhhhhh.....&&&&._mm..~.uuu_u_uu..^l......iiiiii..............ttt^^^]], -[[=====.._..ubbb...._._..h.=....hhh|hh..........__.mm__~.uuuu_h_uu.l8........_.....................^^]], -[[===...._....bb....._..hh.=_....h.|..........__...mm..~.uuuuuu_uu.=........_........................]], -[[====.._...bbbb...._....hhhh__....|.....A..._.....mm..~.uuuuuu____........._........................]], -[[=====.._..uubb..._........._.....|h......._Btt...mm..~6uuuuu&&&u._........._.......................]], -[[====...__..ubbb._......hh.._.....|.hh...._.t^^^._mm..~..uuu&f&&&u._........._......................]], -[[=====..._.....__......hho+-_.2---x1hh-------_L...mm---------------_........_.......................]], -[[======..==..=__....h....h|.._.hh.|ih....._..^^^._m...~..uuuuuuuuuu._........_......................]], -[[=============.....hhh....|.._.vvD|h......_.._.._mmm...~..uuuuuuuuu.._........_....................t]], -[[======........bb...h.....|..._vvv|hh...._.._...mm.....~..uuuuuuuu...._......_....................tt]], -[[=====E........bb.........[---_.v.|.h...._._..mmmmm.s._~..uuuuuuuu....._......_..................ttt]], -[[=====.........bb............._[--|....._.._..mmmm___s.~~.uuuuuuuu......_.._._..................tttt]], -[[======........bb...Cb......._....|....._._...mmmm.....~~.uuuuu.u........._.._.................ttttt]], -[[=======.....ubbb..bbbb....._.....|....._....mmmmm....~~...uuuu.............._...............ttttttt]], -[[==========..ubbbu........._......|...._.....mmmm.....~~...uuuu..............._...._.......ttttttttt]], -[[==========..uuubbubb....._.......|ss__.....hmmmm....~~....uuuuuuu............._.__._ ...ttttttttttt]], +[[=====.._..ubbb...._._..h.=....hhh.hh..........__.mm__~.uuuu_h_uu.l8........_.....................^^]], +[[===...._....bb....._..hh.=_....h............__...mm..~.uuuuuu_uu.=........_........................]], +[[====.._...bbbb...._....hhhh__..........A..._.....mm..~.uuuuuu____........._........................]], +[[=====.._..uubb..._........._......h......._Btt...mm..~6uuuuu&&&u._........._.......................]], +[[====...__..ubbb._......hh.._.......hh...._.t^^^._mm..~..uuu&f&&&u._........._......................]], +[[=====..._.....__......hho.-_.2....1hh......._L...mm..~..uuuuuuuuu._........_.......................]], +[[======..==..=__....h....h..._.hh..ih....._..^^^._m...~..uuuuuuuuuu._........_......................]], +[[=============.....hhh......._.vvD.h......_.._.._mmm...~..uuuuuuuuu.._........_....................t]], +[[======........bb...h........._vvv.hh...._.._...mm.....~..uuuuuuuu...._......_....................tt]], +[[=====E........bb............._.v...h...._._..mmmmm.s._~..uuuuuuuu....._......_..................ttt]], +[[=====.........bb............._........._.._..mmmm___s.~~.uuuuuuuu......_.._._..................tttt]], +[[======........bb...Cb......._.........._._...mmmm.....~~.uuuuu.u........._.._.................ttttt]], +[[=======.....ubbb..bbbb....._..........._....mmmmm....~~...uuuu.............._...............ttttttt]], +[[==========..ubbbu........._..........._.....mmmm.....~~...uuuu..............._...._.......ttttttttt]], +[[==========..uuubbubb....._........ss__.....hmmmm....~~....uuuuuuu............._.__._ ...ttttttttttt]], [[==========...uubuu......_........___ss_....mmmmm....~~..uuuuuuuuuu............._.... ...t ttttttt]], [[==========.....u.u....._........_.....______mm___...~~.uuuuuuuuuu................... ttttttt]], -[[===========.=........._........_...........mmmm_!.!~~..uu&uuuuuuu.................. ttttttt]], -[[================....__........_..ttt......mmmm._!4!~~..uuuuuuuuu................... ...tttt]], -[[=================.==t........_....tt.....ttmmm..!!!~.....uuuuu..................^^. ......tt]], +[[===========.=........._........_...........mmmm_!!!~~..uu&uuuuuuu.................. ttttttt]], +[[================....__........_..ttt......mmmm._!!!~~..uuuuuuuuu................... ...tttt]], +[[=================.==t........_....tt.....ttmmm.!!!!~.....uuuuu..................^^. ......tt]], [[===================tt........._.........ttmmm.......~~.........................^^^^. .......t]], [[===================t==......._..........ttmmmttttt._..~~~~~~....................^^^. ... .......t]], [[===================t==......_...........t&mmmmtttt_s_.....~~~..................^^^^^. ... ........t]], @@ -84,7 +85,7 @@ return { [[============================.^t_.__._........_&^^^.&&&&&......e.ddvaavaaavvv"""""_""""_""""""".....]], [[============================.t^_..._....hh.._&&&^^.._&&&&.&...~.ddd""a"a""""""""=="""_""""""""""...]], [[============================.t^._.hhhhhhhh...__...._^&^&&&&&.~..dd""""""""""""======_"""""""""""aaa]], -[[===========================.^^._...h.h........._.._.^&^^._^3.~..dd"""_"_"""""=====""""""""""""aaadd]], +[[===========================.^^._...h.h........._.._.^&^^._^2.~..dd"""_"_"""""=====""""""""""""aaadd]], [[==========================..^^.._.....===.=====_._&^...._...^.~.dd"__"_"__======"""""aa""""aaaadddd]], [[==========================.h...._...=====F=====_&&^...._._...~~.dd_""""""""""""_""a"aaaaaaaaddddddd]], [[========================.hhh=...=_.==========&^^^^.._._..._.~~..ddd""ddd""d"""dd_ddaadddddddddddddd]], diff --git a/game/modules/tome/data/quests/staff-absorption.lua b/game/modules/tome/data/quests/staff-absorption.lua index d1b2b8be31a97b7c26dbe77c556d19f5d0449926..fb699cfb8c15b7a90dd66ce9c19965c3ba7da7de 100644 --- a/game/modules/tome/data/quests/staff-absorption.lua +++ b/game/modules/tome/data/quests/staff-absorption.lua @@ -7,3 +7,9 @@ desc = function(self, who) desc[#desc+1] = "You should bring it to the elders of Minas Tirith in the south east." return table.concat(desc, "\n") end + +-- Finding the truth about the staff means we can now create "evil" characters +on_grant = function(self, who) + game.logPlayer(who, "#00FFFF#You can feel the power of this staff just by carrying it. This is both ancient and dangerous.") + game.logPlayer(who, "#00FFFF#It should be shown to the wise elders in Minas Tirith!") +end diff --git a/game/modules/tome/data/zones/town-minas-tirith/grids.lua b/game/modules/tome/data/zones/town-minas-tirith/grids.lua new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/game/modules/tome/data/zones/town-minas-tirith/npcs.lua b/game/modules/tome/data/zones/town-minas-tirith/npcs.lua new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/game/modules/tome/data/zones/town-minas-tirith/objects.lua b/game/modules/tome/data/zones/town-minas-tirith/objects.lua new file mode 100644 index 0000000000000000000000000000000000000000..5e3421492348e0c9f54c25ad85a4a1c323c12a21 --- /dev/null +++ b/game/modules/tome/data/zones/town-minas-tirith/objects.lua @@ -0,0 +1 @@ +load("/data/general/objects/objects.lua") diff --git a/game/modules/tome/data/zones/town-minas-tirith/zone.lua b/game/modules/tome/data/zones/town-minas-tirith/zone.lua new file mode 100644 index 0000000000000000000000000000000000000000..5c1969166c301a12daed345e587bb35485111766 --- /dev/null +++ b/game/modules/tome/data/zones/town-minas-tirith/zone.lua @@ -0,0 +1,22 @@ +return { + name = "Minas Tirith", + level_range = {15, 15}, + max_level = 1, + width = 196, height = 80, + all_remembered = true, + all_lited = true, + generator = { + map = { + class = "engine.generator.map.Static", + map = "towns/minas-tirith", + }, + actor = { + class = "engine.generator.actor.Random", + nb_npc = {0, 0}, + }, + object = { + class = "engine.generator.object.Random", + nb_object = {0, 0}, + }, + } +} diff --git a/game/modules/tome/resolvers.lua b/game/modules/tome/resolvers.lua index d57d907ac65cb60aa958474dd3603c3d7a370a61..3db1811c4f87cd69625f5b48c53d40903048f6d8 100644 --- a/game/modules/tome/resolvers.lua +++ b/game/modules/tome/resolvers.lua @@ -118,3 +118,22 @@ function resolvers.calc.store(t, e) -- Delete the origin field return nil end + +--- Resolves chat creation for an actor +function resolvers.chatfeature(def) + return {__resolver="chatfeature", def} +end +--- Actually resolve the drops creation +function resolvers.calc.chatfeature(t, e) + t = t[1] + + e.on_move = function(self, x, y, who) + local Chat = require("engine.Chat") + local chat = Chat.new(self.chat, self, who) + chat:invoke() + end + e.chat = t + + -- Delete the origin field + return nil +end diff --git a/ideas/spells.ods b/ideas/spells.ods index 326d6a05777925e454fc0f60dbf2bae357bbbd6e..330e6f931c17a1827d0f03542ecaeeedcaa7fe2e 100644 Binary files a/ideas/spells.ods and b/ideas/spells.ods differ