From f327ac9d1f5775b290958e677cb1ed7404cc9147 Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Mon, 6 Jun 2011 18:14:33 +0000 Subject: [PATCH] New birth UI! All NPCs now have tiles! git-svn-id: http://svn.net-core.org/repos/t-engine4@3598 51575b47-30f0-44d4-a5cc-537603b46e54 --- game/engines/default/engine/ui/Base.lua | 3 + game/engines/default/engine/ui/Dialog.lua | 61 ++++++++--- game/engines/default/engine/ui/Dropdown.lua | 96 ++++++++++++++++++ game/engines/default/engine/ui/Textbox.lua | 7 +- game/engines/default/engine/ui/TreeList.lua | 4 +- game/modules/tome/class/Game.lua | 15 ++- game/modules/tome/class/NPC.lua | 2 + .../tome/class/interface/PlayerStats.lua | 8 +- .../tome/data/birth/classes/afflicted.lua | 10 +- .../tome/data/birth/classes/chronomancer.lua | 10 +- .../tome/data/birth/classes/corrupted.lua | 10 +- .../tome/data/birth/classes/divine.lua | 10 +- game/modules/tome/data/birth/classes/mage.lua | 4 +- .../tome/data/birth/classes/psionic.lua | 6 +- .../tome/data/birth/classes/warrior.lua | 4 +- .../tome/data/birth/classes/wilder.lua | 14 ++- game/modules/tome/data/birth/descriptors.lua | 4 +- .../tome/data/birth/races/construct.lua | 6 +- game/modules/tome/data/birth/races/undead.lua | 14 ++- game/modules/tome/data/birth/races/yeek.lua | 4 + game/modules/tome/data/birth/worlds.lua | 59 +++++------ .../tome/data/chats/escort-quest-start.lua | 2 + game/modules/tome/data/chats/escort-quest.lua | 2 + .../tome/data/general/npcs/sandworm.lua | 1 + .../shockbolt/npc/dragon_sand_sand_drake.png | Bin 0 -> 10287 bytes .../humanoid_shalore_archmage_tarelion.png | Bin 0 -> 14977 bytes game/modules/tome/data/quests/escort-duty.lua | 3 + .../tome/data/zones/town-angolwen/npcs.lua | 3 +- 28 files changed, 285 insertions(+), 77 deletions(-) create mode 100644 game/engines/default/engine/ui/Dropdown.lua create mode 100644 game/modules/tome/data/gfx/shockbolt/npc/dragon_sand_sand_drake.png create mode 100644 game/modules/tome/data/gfx/shockbolt/npc/humanoid_shalore_archmage_tarelion.png diff --git a/game/engines/default/engine/ui/Base.lua b/game/engines/default/engine/ui/Base.lua index e23b2277fb..38c96c8482 100644 --- a/game/engines/default/engine/ui/Base.lua +++ b/game/engines/default/engine/ui/Base.lua @@ -157,3 +157,6 @@ end function _M:setTextShadow(v) self.text_shadow = v end + +function _M:positioned(x, y) +end diff --git a/game/engines/default/engine/ui/Dialog.lua b/game/engines/default/engine/ui/Dialog.lua index 24fa0240fd..92c67e7e7c 100644 --- a/game/engines/default/engine/ui/Dialog.lua +++ b/game/engines/default/engine/ui/Dialog.lua @@ -145,8 +145,8 @@ end title_shadow = true -function _M:init(title, w, h, x, y, alpha, font, showup) - self.title = assert(title, "no dialog title") +function _M:init(title, w, h, x, y, alpha, font, showup, skin) + self.title = title self.alpha = self.alpha or 255 if showup ~= nil then self.__showup = showup @@ -154,6 +154,7 @@ function _M:init(title, w, h, x, y, alpha, font, showup) self.__showup = 2 end self.color = self.color or {r=255, g=255, b=255} + if skin then self.ui = skin end local conf = self.ui_conf[self.ui] self.frame = self.frame or { @@ -175,6 +176,7 @@ function _M:init(title, w, h, x, y, alpha, font, showup) self.frame.oy2 = self.frame.oy2 or conf.frame_oy2 self.uis = {} + self.ui_by_ui = {} self.focus_ui = nil self.focus_ui_id = 0 @@ -191,8 +193,13 @@ function _M:resize(w, h, nogen) self.w, self.h = math.floor(w), math.floor(h) self.display_x = math.floor(self.force_x or (gamew - self.w) / 2) self.display_y = math.floor(self.force_y or (gameh - self.h) / 2) - self.ix, self.iy = 5, 8 + 3 + self.font_bold_h - self.iw, self.ih = w - 2 * 5, h - 8 - 8 - 3 - self.font_bold_h + if self.title then + self.ix, self.iy = 5, 8 + 3 + self.font_bold_h + self.iw, self.ih = w - 2 * 5, h - 8 - 8 - 3 - self.font_bold_h + else + self.ix, self.iy = 5, 8 + self.iw, self.ih = w - 2 * 5, h - 8 - 8 + end -- self.display_x = util.bound(self.display_x, 0, game.w - (self.w+self.frame.ox2)) -- self.display_y = util.bound(self.display_y, 0, game.h - (self.h+self.frame.oy2)) @@ -248,6 +255,7 @@ function _M:generate() end function _M:updateTitle(title) + if not title then return end local title = title if type(title)=="function" then title = title() end local tw, th = self.font_bold:size(title) @@ -262,11 +270,13 @@ end function _M:loadUI(t) if not t.no_reset then self.uis = {} + self.ui_by_ui = {} self.focus_ui = nil self.focus_ui_id = 0 end for i, ui in ipairs(t) do self.uis[#self.uis+1] = ui + self.ui_by_ui[ui.ui] = ui if not self.focus_ui and ui.ui.can_focus then self:setFocus(i) @@ -302,7 +312,8 @@ function _M:setupUI(resizex, resizey, on_resize, addmw, addmh) mw = mw + addw + 5 * 2 + (addmw or 0) -- print("===", mw, addw) - local tw, th = self.font_bold:size(self.title) + local tw, th = 0, 0 + if self.title then tw, th = self.font_bold:size(self.title) end mw = math.max(tw + 6, mw) mh = mh + addh + 5 + 22 + 3 + (addmh or 0) + th @@ -320,13 +331,27 @@ function _M:setupUI(resizex, resizey, on_resize, addmw, addmh) if not ui.absolute then ux, uy = self.ix, self.iy - if ui.top then uy = uy + ui.top - elseif ui.bottom then uy = uy + self.ih - ui.bottom - ui.ui.h - elseif ui.vcenter then uy = uy + math.floor(self.ih / 2) + ui.vcenter - ui.ui.h / 2 end + if ui.top then + if type(ui.top) == "table" then ui.top = self.ui_by_ui[ui.top].y end + uy = uy + ui.top + elseif ui.bottom then + if type(ui.bottom) == "table" then ui.bottom = self.ui_by_ui[ui.bottom].y end + uy = uy + self.ih - ui.bottom - ui.ui.h + elseif ui.vcenter then + if type(ui.vcenter) == "table" then ui.vcenter = self.ui_by_ui[ui.vcenter].y + ui.vcenter.h end + uy = uy + math.floor(self.ih / 2) + ui.vcenter - ui.ui.h / 2 + end - if ui.left then ux = ux + ui.left - elseif ui.right then ux = ux + self.iw - ui.right - ui.ui.w - elseif ui.hcenter then ux = ux + math.floor(self.iw / 2) + ui.hcenter - ui.ui.w / 2 end + if ui.left then + if type(ui.left) == "table" then ui.left = self.ui_by_ui[ui.left].x + ui.left.w end + ux = ux + ui.left + elseif ui.right then + if type(ui.right) == "table" then ui.right = self.ui_by_ui[ui.right].x end + ux = ux + self.iw - ui.right - ui.ui.w + elseif ui.hcenter then + if type(ui.hcenter) == "table" then ui.hcenter = self.ui_by_ui[ui.hcenter].x + ui.hcenter.w end + ux = ux + math.floor(self.iw / 2) + ui.hcenter - ui.ui.w / 2 + end else ux, uy = 0, 0 @@ -346,6 +371,7 @@ function _M:setupUI(resizex, resizey, on_resize, addmw, addmh) ui.y = uy ui.ui.mouse.delegate_offset_x = ux ui.ui.mouse.delegate_offset_y = uy + ui.ui:positioned(ux, uy, self.display_x + ux, self.display_y + uy) end self.setuped = true @@ -394,6 +420,11 @@ function _M:getUIElement(id) return self.uis[id] end +function _M:toggleDisplay(ui, show) + if not self.ui_by_ui[ui] then return end + self.ui_by_ui[ui].hidden = not show +end + function _M:moveFocus(v) local id = self.focus_ui_id local start = id or 1 @@ -514,13 +545,15 @@ function _M:toScreen(x, y, nb_keyframes) self:drawFrame(x, y, 1, 1, 1, self.frame.a) -- Title - if self.title_shadow then self.title_tex[1]:toScreenFull(x + (self.w - self.title_tex.w) / 2 + 3, y + 3, self.title_tex.w, self.title_tex.h, self.title_tex[2], self.title_tex[3], 0, 0, 0, 0.5) end - self.title_tex[1]:toScreenFull(x + (self.w - self.title_tex.w) / 2, y, self.title_tex.w, self.title_tex.h, self.title_tex[2], self.title_tex[3]) + if self.title then + if self.title_shadow then self.title_tex[1]:toScreenFull(x + (self.w - self.title_tex.w) / 2 + 3, y + 3, self.title_tex.w, self.title_tex.h, self.title_tex[2], self.title_tex[3], 0, 0, 0, 0.5) end + self.title_tex[1]:toScreenFull(x + (self.w - self.title_tex.w) / 2, y, self.title_tex.w, self.title_tex.h, self.title_tex[2], self.title_tex[3]) + end -- UI elements for i = 1, #self.uis do local ui = self.uis[i] - ui.ui:display(x + ui.x, y + ui.y, nb_keyframes, ox + ui.x, oy + ui.y) + if not ui.hidden then ui.ui:display(x + ui.x, y + ui.y, nb_keyframes, ox + ui.x, oy + ui.y) end end self:innerDisplay(x, y, nb_keyframes) diff --git a/game/engines/default/engine/ui/Dropdown.lua b/game/engines/default/engine/ui/Dropdown.lua new file mode 100644 index 0000000000..2982985e5c --- /dev/null +++ b/game/engines/default/engine/ui/Dropdown.lua @@ -0,0 +1,96 @@ +-- 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" +local List = require "engine.ui.List" +local Dialog = require "engine.ui.Dialog" + +--- A generic UI list dropdown box +module(..., package.seeall, class.inherit(Base, Focusable)) + +function _M:init(t) + self.text = t.text or "" + self.w = assert(t.width, "no dropdown width") + self.fct = assert(t.fct, "no dropdown fct") + self.list = assert(t.list, "no dropdown list") + self.nb_items = assert(t.nb_items, "no dropdown nb_items") + self.on_select = t.on_select + self.display_prop = t.display_prop or "name" + self.scrollbar = t.scrollbar + + Base.init(self, t) +end + +function _M:generate() + self.mouse:reset() + self.key:reset() + + -- Draw UI + self.h = self.font_h + 6 + self.height = self.h + + self.frame = self:makeFrame("ui/textbox", self.w, self.h) + self.frame_sel = self:makeFrame("ui/textbox-sel", self.w, self.h) + + -- Add UI controls + self.mouse:registerZone(0, 0, self.w, self.h, function(button, x, y, xrel, yrel, bx, by, event) + if event == "button" and button == "left" then self:showSelect() end + end) + self.key:addBind("ACCEPT", function() self:showSelect() end) +end + +function _M:positioned(x, y, sx, sy) + self.c_list = List.new{width=self.w, list=self.list, select=self.on_select, display_prop=self.display_prop, scrollbar=self.scrollbar, nb_items=self.nb_items, fct=function() + game:unregisterDialog(self.popup) + self.fct(self.c_list.list[self.c_list.sel]) + end} + self.popup = Dialog.new(nil, self.w, self.c_list.h, sx, sy + self.h, nil, nil, false, "simple") + self.popup.frame.a = 0.7 + self.popup:loadUI{{left=0, top=0, ui=self.c_list}} + self.popup:setupUI(true, true) + self.popup.key:addBind("EXIT", function() + game:unregisterDialog(self.popup) + self.c_list.sel = self.previous + self.fct(self.c_list.list[self.c_list.sel]) + end) +end + +function _M:showSelect() + self.previous = self.c_list.sel + game:registerDialog(self.popup) +end + +function _M:display(x, y, nb_keyframes) + if self.focused then + self:drawFrame(self.frame_sel, x, y) + else + self:drawFrame(self.frame, x, y) + if self.focus_decay then + self:drawFrame(self.frame_sel, x, y, 1, 1, 1, self.focus_decay / self.focus_decay_max_d) + self.focus_decay = self.focus_decay - nb_keyframes + if self.focus_decay <= 0 then self.focus_decay = nil end + end + end + + local item = self.c_list.list[self.c_list.sel] + if self.text_shadow then item._tex[1]:toScreenFull(x+1 + self.frame_sel.b4.w, y+1, self.c_list.fw, self.c_list.fh, item._tex[2], item._tex[3], 0, 0, 0, self.text_shadow) end + item._tex[1]:toScreenFull(x + self.frame_sel.b4.w, y, self.c_list.fw, self.c_list.fh, item._tex[2], item._tex[3]) +end diff --git a/game/engines/default/engine/ui/Textbox.lua b/game/engines/default/engine/ui/Textbox.lua index 9947f0dccf..20fbe9e845 100644 --- a/game/engines/default/engine/ui/Textbox.lua +++ b/game/engines/default/engine/ui/Textbox.lua @@ -27,7 +27,9 @@ module(..., package.seeall, class.inherit(Base, Focusable)) function _M:init(t) self.title = assert(t.title, "no textbox title") self.text = t.text or "" + self.old_text = self.text self.hide = t.hide + self.on_change = t.on_change self.max_len = t.max_len or 999 self.fct = assert(t.fct, "no textbox fct") self.chars = assert(t.chars, "no textbox chars") @@ -82,7 +84,8 @@ function _M:generate() end end) self.key:addBind("ACCEPT", function() self.fct(self.text) end) - self.key:addIgnore("_ESCAPE", v) + self.key:addIgnore("_ESCAPE", true) + self.key:addIgnore("_TAV", true) self.key:addCommands{ _LEFT = function() self.cursor = util.bound(self.cursor - 1, 1, #self.tmp+1) self.scroll = util.scroll(self.cursor, self.scroll, self.max_display) self:updateText() end, _RIGHT = function() self.cursor = util.bound(self.cursor + 1, 1, #self.tmp+1) self.scroll = util.scroll(self.cursor, self.scroll, self.max_display) self:updateText() end, @@ -135,6 +138,8 @@ function _M:updateText() self.text_surf:erase(0, 0, 0, 0) self.text_surf:drawStringBlended(self.font_mono, text, 0, 0, 255, 255, 255, true) self.text_surf:updateTexture(self.text_tex) + if self.on_change and self.old_text ~= self.text then self.on_change(self.text) end + self.old_text = self.text end function _M:display(x, y, nb_keyframes) diff --git a/game/engines/default/engine/ui/TreeList.lua b/game/engines/default/engine/ui/TreeList.lua index 1eba2cf553..b466308832 100644 --- a/game/engines/default/engine/ui/TreeList.lua +++ b/game/engines/default/engine/ui/TreeList.lua @@ -268,8 +268,8 @@ function _M:outputList() self.cur_col = self.cur_col or 1 end -function _M:treeExpand(v) - local item = self.list[self.sel] +function _M:treeExpand(v, item) + local item = item or self.list[self.sel] if not item then return end if v == nil then item.shown = not item.shown diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 17ce00e48c..9f79a1341c 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -29,7 +29,7 @@ local Zone = require "engine.Zone" local Tiles = require "engine.Tiles" local Map = require "engine.Map" local Level = require "engine.Level" -local Birther = require "engine.Birther" +local Birther = require "mod.dialogs.Birther" local Astar = require "engine.Astar" local DirectPath = require "engine.DirectPath" local Shader = require "engine.Shader" @@ -164,6 +164,15 @@ function _M:isTainted() return (game.player and game.player.__cheated) and true or false end +--- Sets the player name +function _M:setPlayerName(name) + self.save_name = name + self.player_name = name + if self.party and self.party:findMember{main=true} then + self.party:findMember{main=true}.name = name + end +end + function _M:newGame() self.party = Party.new() local player = Player.new{name=self.player_name, game_ender=true} @@ -205,7 +214,7 @@ function _M:newGame() local nb_unlocks, max_unlocks = self:countBirthUnlocks() self.creating_player = true - local birth; birth = Birther.new("Character Creation: "..self.player.name.." ("..nb_unlocks.."/"..max_unlocks.." unlocked birth options)", self.player, {"base", "world", "difficulty", "race", "subrace", "sex", "class", "subclass" }, function() + local birth; birth = Birther.new("Character Creation ("..nb_unlocks.."/"..max_unlocks.." unlocked birth options)", self.player, {"base", "world", "difficulty", "race", "subrace", "sex", "class", "subclass" }, function() self.calendar = Calendar.new("/data/calendar_"..(self.player.calendar or "allied")..".lua", "Today is the %s %s of the %s year of the Age of Ascendancy of Maj'Eyal.\nThe time is %02d:%02d.", 122, 167, 11) self.player:check("make_tile") self.player.make_tile = nil @@ -267,7 +276,7 @@ function _M:newGame() if self.player.no_birth_levelup or __module_extra_info.no_birth_popup then birthend() else self.player:playerLevelup(birthend) end - end, quickbirth, 720, 500) + end, quickbirth, 800, 600) -- Load a full player instead of a simpler quickbirthing, if possible birth.quickBirth = function(b) diff --git a/game/modules/tome/class/NPC.lua b/game/modules/tome/class/NPC.lua index dd73ee0f63..552bd1dda1 100644 --- a/game/modules/tome/class/NPC.lua +++ b/game/modules/tome/class/NPC.lua @@ -208,6 +208,8 @@ function _M:die(src) game.state:allowRodRecall(false) end end + -- Ok the player managed to kill a boss dont bother him with tutorial anymore + if self.rank >= 3.5 and not profile.mod.allow_build.tutorial_done then game:setAllowedBuild("tutorial_done") end return mod.class.Actor.die(self, src) end diff --git a/game/modules/tome/class/interface/PlayerStats.lua b/game/modules/tome/class/interface/PlayerStats.lua index e96f801477..2ebf2ad857 100644 --- a/game/modules/tome/class/interface/PlayerStats.lua +++ b/game/modules/tome/class/interface/PlayerStats.lua @@ -68,9 +68,13 @@ function _M:registerCharacterPlayed() end function _M:registerLoreFound(lore) - local pid = self:playerStatGetCharacterIdentifier(game.party:findMember{main=true}) - profile.mod.lore = profile.mod.lore or { lore={} } profile.mod.lore.lore[lore] = true profile:saveModuleProfile("lore", profile.mod.lore) end + +function _M:registerEscorts(status) + profile.mod.escorts = profile.mod.escorts or { saved=0, lost=0, betrayed=0, zigur=0 } + profile.mod.escorts[status] = profile.mod.escorts[status] + 1 + profile:saveModuleProfile("escorts", profile.mod.escorts) +end diff --git a/game/modules/tome/data/birth/classes/afflicted.lua b/game/modules/tome/data/birth/classes/afflicted.lua index 1cf3372520..d249deb678 100644 --- a/game/modules/tome/data/birth/classes/afflicted.lua +++ b/game/modules/tome/data/birth/classes/afflicted.lua @@ -20,6 +20,8 @@ newBirthDescriptor{ type = "class", name = "Afflicted", + locked = function() return profile.mod.allow_build.afflicted end, + locked_desc = "Some walk in shadow, alone, unloved, unwanted. What powers they wield may be mighty, but their names are forever cursed.", desc = { "Afflicted classes have been twisted by their association with evil forces.", "They can use these forces to their advantage, but at a cost...", @@ -29,8 +31,8 @@ newBirthDescriptor{ subclass = { __ALL__ = "disallow", - Cursed = function() return profile.mod.allow_build.afflicted_cursed and "allow" or "disallow" end, - Doomed = function() return profile.mod.allow_build.afflicted_doomed and "allow" or "disallow" end, + Cursed = "allow", + Doomed = "allow", }, }, copy = { @@ -40,6 +42,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Cursed", + locked = function() return profile.mod.allow_build.afflicted_cursed end, + locked_desc = "Affliction can run to the soul, and hatred can fill one's entire being. Overcome someone else's hated curse to know its dreaded meaning.", desc = { "Through ignorance, greed or folly the Cursed served some dark design and are now doomed to pay for their sins.", "Their only master now is the hatred they carry for every living thing.", @@ -82,6 +86,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Doomed", + locked = function() return profile.mod.allow_build.afflicted_doomed end, + locked_desc = "In shaded places in unknown lands thou must overcome thyself and see thy doom.", desc = { "The Doomed are fallen mages who once wielded powerful magic wrought by ambition and dark bargains.", "They now possess only a twisted shadow of that power as they struggle to keep it from consuming them.", diff --git a/game/modules/tome/data/birth/classes/chronomancer.lua b/game/modules/tome/data/birth/classes/chronomancer.lua index 3f40bc1b96..4272a6b717 100644 --- a/game/modules/tome/data/birth/classes/chronomancer.lua +++ b/game/modules/tome/data/birth/classes/chronomancer.lua @@ -20,6 +20,8 @@ newBirthDescriptor{ type = "class", name = "Chronomancer", + locked = function() return profile.mod.allow_build.chronomancer end, + locked_desc = "Some do not walk upon the straight road others follow. Seek the hidden paths outside the normal course of life.", desc = { "With one foot literally in the past and one in the future, Chronomancers manipulate the present at a whim and wield a power that only bows to nature's own need to keep the balance. The wake in spacetime they leave behind them makes their own Chronomantic abilites that much stronger and that much harder to control. The wise Chronomancer learns to maintain the balance between his own thirst for cosmic power and the universe's need to flow undisturbed, for the hole he tears that amplifies his own abilities just may be the same hole that one day swallows him.", }, @@ -28,8 +30,8 @@ newBirthDescriptor{ subclass = { __ALL__ = "disallow", - ["Paradox Mage"] = function() return profile.mod.allow_build.chronomancer_paradox_mage and "allow" or "disallow" end, - ["Temporal Warden"] = function() return profile.mod.allow_build.chronomancer_temporal_warden and "allow" or "disallow" end, + ["Paradox Mage"] = "allow", + ["Temporal Warden"] = "allow", }, }, copy = { @@ -39,6 +41,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Paradox Mage", + locked = function() return profile.mod.allow_build.chronomancer_paradox_mage end, + locked_desc = "A hand may clap alone if it returns to clap itself. Search for the power in the paradox.", desc = { "A Paradox Mage studies the very fabric of spacetime, learning not just to bend it but shape it and remake it.", "Most Paradox Mages lack basic skills that others take for granted (like general fighting sense), but they make up for it through control of cosmic forces.", @@ -85,6 +89,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Temporal Warden", + locked = function() return profile.mod.allow_build.chronomancer_temporal_warden end, + locked_desc = "We preserve the past to protect the future. The hands of time are guarded by the arms of war.", desc = { "The Temporal Wardens have learned to blend archery, dual-weapon fighting, and chronomancy into a fearsome whole.", "Through their use of the chronomantic arts, the Temporal Wardens seek to control the battlefield while peppering their foes with arrows or engaging in hand-to-hand combat.", diff --git a/game/modules/tome/data/birth/classes/corrupted.lua b/game/modules/tome/data/birth/classes/corrupted.lua index 056be39b45..01ea7b9c6f 100644 --- a/game/modules/tome/data/birth/classes/corrupted.lua +++ b/game/modules/tome/data/birth/classes/corrupted.lua @@ -20,6 +20,8 @@ newBirthDescriptor{ type = "class", name = "Corrupter", + locked = function() return profile.mod.allow_build.corrupter end, + locked_desc = "Dark thoughts, black bloods, vile deeds... Those who spill their brethren's blood will find its power.", desc = { "Corrupters are touched by the mark of evil. They are a blight on the world. Working to promote the cause of evil, they serve their masters, or themselves become masters.", }, @@ -28,8 +30,8 @@ newBirthDescriptor{ subclass = { __ALL__ = "disallow", - Reaver = function() return profile.mod.allow_build.corrupter_reaver and "allow" or "disallow" end, - Corruptor = function() return profile.mod.allow_build.corrupter_corruptor and "allow" or "disallow" end, + Reaver = "allow", + Corruptor = "allow", }, }, copy = { @@ -40,6 +42,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Reaver", + locked = function() return profile.mod.allow_build.corrupter_reaver end, + locked_desc = "Reap thee the souls of thine enemies, and the powers of darkness shall enter thine flesh.", desc = { "Reavers are terrible foes, charging their enemies with a weapon in each hand.", "They can harness the blight of evil, infecting their foes with terrible contagious diseases while crushing their skulls with devastating combat techniques.", @@ -81,6 +85,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Corruptor", + locked = function() return profile.mod.allow_build.corrupter_corruptor end, + locked_desc = "Blight and depravity hold the greatest powers. Accept temptation and become one with corruption.", desc = { "A corruptor is a terrible foe, wielding dark magics that can sap the very soul of her target.", "They can harness the blight of evil, crushing souls, stealing life force to replenish themselves.", diff --git a/game/modules/tome/data/birth/classes/divine.lua b/game/modules/tome/data/birth/classes/divine.lua index 45c071b40a..32a2d05490 100644 --- a/game/modules/tome/data/birth/classes/divine.lua +++ b/game/modules/tome/data/birth/classes/divine.lua @@ -20,6 +20,8 @@ newBirthDescriptor{ type = "class", name = "Divine", + locked = function() return profile.mod.allow_build.divine end, + locked_desc = "The magic of the heavens is known to but a few, and that knowledge has long passed east, forgotten.", desc = { "Divine classes are worshippers of various gods and entities.", "They include the worship of the Sun, the Moon, powerful spirits, ...", @@ -29,8 +31,8 @@ newBirthDescriptor{ subclass = { __ALL__ = "disallow", - ['Sun Paladin'] = function() return profile.mod.allow_build.divine_sun_paladin and "allow" or "disallow" end, - Anorithil = function() return profile.mod.allow_build.divine_anorithil and "allow" or "disallow" end, + ['Sun Paladin'] = "allow", + Anorithil = "allow", }, }, copy = { @@ -42,6 +44,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Sun Paladin", + locked = function() return profile.mod.allow_build.divine_sun_paladin end, + locked_desc = "The sun rises in the east in full glory, but you must look for it first amidst the darkest places.", desc = { "Sun Paladins hail from the Gates of Morning, the last bastion of the free people in the Far East.", "Their way of life is well represented by their motto 'The Sun is our giver, our purity, our essence. We carry the light into dark places, and against our strength none shall pass.'", @@ -87,6 +91,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Anorithil", + locked = function() return profile.mod.allow_build.divine_anorithil end, + locked_desc = "The balance of the heavens' powers is a daunting task. Mighty are those that stand in the twilight places, wielding both light and darkness in their mind.", desc = { "Anorithils hail from the Gates of Morning, the last bastion of the free people in the Far East.", "Their way of life is well represented by their motto 'We stand betwixt the Sun and Moon, where light and darkness meet. In the grey twilight we seek our destiny.'", diff --git a/game/modules/tome/data/birth/classes/mage.lua b/game/modules/tome/data/birth/classes/mage.lua index 477347d55d..1439d28ffb 100644 --- a/game/modules/tome/data/birth/classes/mage.lua +++ b/game/modules/tome/data/birth/classes/mage.lua @@ -29,7 +29,7 @@ newBirthDescriptor{ { __ALL__ = "disallow", Alchemist = "allow", - Archmage = function() return profile.mod.allow_build.mage and "allow" or "disallow" end, + Archmage = "allow", }, }, copy = { @@ -42,6 +42,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Archmage", + locked = function() return profile.mod.allow_build.mage end, + locked_desc = "Hated, harrowed, hunted, hidden... Our ways are forbidden, but our cause is just. In our veiled valley we find solace from the world's wrath, free to study our arts. Only through charity and friendship can you earn our trust.", desc = { "An Archmage devotes his whole life to the study of magic above anything else.", "Most Archmagi lack basic skills that others take for granted (like general fighting sense), but they make up for it by their raw magical power.", diff --git a/game/modules/tome/data/birth/classes/psionic.lua b/game/modules/tome/data/birth/classes/psionic.lua index 4974f9db8e..890ff9d6a0 100644 --- a/game/modules/tome/data/birth/classes/psionic.lua +++ b/game/modules/tome/data/birth/classes/psionic.lua @@ -20,6 +20,8 @@ newBirthDescriptor{ type = "class", name = "Psionic", + locked = function() return profile.mod.allow_build.psionic end, + locked_desc = "Weakness of flesh can be overcome by mental prowess. Find the way and fight for the way to open the key to your mind.", desc = { "Psionics find their power within themselves. Their highly trained minds can harness energy from many different sources and manipulate it to produce physical effects.", }, @@ -28,7 +30,7 @@ newBirthDescriptor{ subclass = { __ALL__ = "disallow", - Mindslayer = function() return profile.mod.allow_build.psionic_mindslayer and "allow" or "disallow" end, + Mindslayer = "allow", }, }, copy = { @@ -40,6 +42,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Mindslayer", + locked = function() return profile.mod.allow_build.psionic_mindslayer end, + locked_desc = "A thought can inspire, a thought can kill. After centuries of oppression, years of imprisonment, a thought shall break us free and vengeance will strike from our darkest dreams.", desc = { "Mindslayers specialize in direct and brutal application of mental forces to their immediate surroundings.", "When Mindslayers do battle, they will most often be found in the thick of the fighting, vast energies churning around them and telekinetically-wielded weapons hewing nearby foes at the speed of thought.", diff --git a/game/modules/tome/data/birth/classes/warrior.lua b/game/modules/tome/data/birth/classes/warrior.lua index 15c289f278..e7aefda99d 100644 --- a/game/modules/tome/data/birth/classes/warrior.lua +++ b/game/modules/tome/data/birth/classes/warrior.lua @@ -30,7 +30,7 @@ newBirthDescriptor{ __ALL__ = "disallow", Fighter = "allow", Berserker = "allow", - Brawler = function() return profile.mod.allow_build.warrior_brawler and "allow" or "disallow" end, + Brawler = "allow", ["Arcane Blade"] = "allow", }, }, @@ -179,6 +179,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Brawler", + locked = function() return profile.mod.allow_build.warrior_brawler end, + locked_desc = "Though you may fight alone against many, destined to fight till you die, still you do not relent. In a ring of blood you learn that a pair of fists can face the world.", desc = { "The ravages of the Spellblaze stretched armies thin and left many unprotected. Not everyone could afford the luxury of a weapon.", "Without steel or iron, poor communities of all races turned to the strength of their own bodies for defense against the darkness.", diff --git a/game/modules/tome/data/birth/classes/wilder.lua b/game/modules/tome/data/birth/classes/wilder.lua index 8e6e910be6..5088d70c24 100644 --- a/game/modules/tome/data/birth/classes/wilder.lua +++ b/game/modules/tome/data/birth/classes/wilder.lua @@ -20,6 +20,8 @@ newBirthDescriptor{ type = "class", name = "Wilder", + locked = function() return profile.mod.allow_build.wilder_wyrmic or profile.mod.allow_build.wilder_summoner or profile.mod.allow_build.wilder_stone_warden end, + locked_desc = "Natural abilities can go beyond mere skill. Experience the true powers of nature to learn of its amazing gifts.", desc = { "Wilders are one with nature, in one manner or another. There are as many different Wilders as there are aspects of nature.", "They can take on the aspects of creatures, summon creatures to them, feel the druidic call, ...", @@ -29,9 +31,9 @@ newBirthDescriptor{ subclass = { __ALL__ = "disallow", - Summoner = function() return profile.mod.allow_build.wilder_summoner and "allow" or "disallow" end, - Wyrmic = function() return profile.mod.allow_build.wilder_wyrmic and "allow" or "disallow" end, - ["Stone Warden"] = function(birth) return birth.descriptors_by_type.race and birth.descriptors_by_type.race.name == "Dwarf" and profile.mod.allow_build.wilder_stone_warden and "allow" or "disallow" end, + Summoner = "allow", + Wyrmic = "allow", + ["Stone Warden"] = "allow", }, }, copy = { @@ -41,6 +43,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Summoner", + locked = function() return profile.mod.allow_build.wilder_summoner end, + locked_desc = "Not all might comes from within. Hear the invocations of nature, hear its calling power. See that from without we can find our true strengths.", desc = { "Summoners never fight alone. They are always ready to summon one of their many minions to fight at their side.", "Summons can range from a combat hound to a fire drake.", @@ -84,6 +88,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Wyrmic", + locked = function() return profile.mod.allow_build.wilder_wyrmic end, + locked_desc = "Sleek, majestic, powerful... In the path of dragons we walk, and their breath is our breath. See their beating hearts with your eyes and taste their majesty between your teeth.", desc = { "Wyrmics are fighters who have learnt how to mimic some of the aspects of the dragons.", "They have access to talents normally belonging to the various kind of drakes.", @@ -128,6 +134,8 @@ newBirthDescriptor{ newBirthDescriptor{ type = "subclass", name = "Stone Warden", + locked = function() return profile.mod.allow_build.wilder_stone_warden and true or "hide" end, + locked_desc = "", desc = { "Stone Wardens are dwarves trained in both the eldritch arts and the worship of nature.", "While other races are stuck in their belief that arcane forces and natural forces are meant to oppose, dwarves have found a way to combine them in harmony.", diff --git a/game/modules/tome/data/birth/descriptors.lua b/game/modules/tome/data/birth/descriptors.lua index ef1da42a0c..cdbd015df5 100644 --- a/game/modules/tome/data/birth/descriptors.lua +++ b/game/modules/tome/data/birth/descriptors.lua @@ -39,8 +39,8 @@ newBirthDescriptor{ { Tutorial = "disallow", ["Maj'Eyal"] = "allow", - Infinite = function() return profile.mod.allow_build.campaign_infinite_dungeon and "allow" or "disallow" end, - Arena = function() return profile.mod.allow_build.campaign_arena and "allow" or "disallow" end, + Infinite = "allow", + Arena = "allow", Ents = "disallow", Spydre = "disallow", Orcs = "disallow", diff --git a/game/modules/tome/data/birth/races/construct.lua b/game/modules/tome/data/birth/races/construct.lua index 0275d7e7b6..5e74962344 100644 --- a/game/modules/tome/data/birth/races/construct.lua +++ b/game/modules/tome/data/birth/races/construct.lua @@ -23,6 +23,8 @@ newBirthDescriptor{ type = "race", name = "Construct", + locked = function() return profile.mod.allow_build.construct and true or "hide" end, + locked_desc = "", desc = { "Constructs are not natural creatures.", "The most usual contructs are golems, but they can vary in shape, form and abilities.", @@ -32,7 +34,7 @@ newBirthDescriptor{ subrace = { __ALL__ = "disallow", - ["Runic Golem"] = function() return profile.mod.allow_build.construct_runic_golem and "allow" or "disallow" end, + ["Runic Golem"] = "allow", }, }, random_escort_possibilities = { {"trollmire", 2, 3}, {"ruins-kor-pul", 1, 2}, {"daikara", 1, 5}, {"old-forest", 1, 5}, {"dreadfell", 1, 8}, {"reknor", 1, 1}, }, @@ -42,6 +44,8 @@ newBirthDescriptor { type = "subrace", name = "Runic Golem", + locked = function() return profile.mod.allow_build.construct_runic_golem and true or "hide" end, + locked_desc = "", desc = { "Runic Golems are creatures made of solid rock and animated using arcane forces.", "They can not be of any class, but they have many intrinsinc abilities.", diff --git a/game/modules/tome/data/birth/races/undead.lua b/game/modules/tome/data/birth/races/undead.lua index 16e81bc90b..4b36b57302 100644 --- a/game/modules/tome/data/birth/races/undead.lua +++ b/game/modules/tome/data/birth/races/undead.lua @@ -23,6 +23,8 @@ newBirthDescriptor{ type = "race", name = "Undead", + locked = function() return profile.mod.allow_build.undead end, + locked_desc = "Grave strength, dread will, this flesh cannot stay still. Kings die, masters fall, we will outlast them all.", desc = { "Undead are humanoids (Humans, Elves, Dwarves, ...) that have been brought back to life by the corruption of dark magics.", "Undead can take many forms, from ghouls to vampires and liches.", @@ -32,10 +34,10 @@ newBirthDescriptor{ subrace = { __ALL__ = "disallow", - Ghoul = function() return profile.mod.allow_build.undead_ghoul and "allow" or "disallow" end, - Skeleton = function() return profile.mod.allow_build.undead_skeleton and "allow" or "disallow" end, - Vampire = function() return profile.mod.allow_build.undead_vampire and "allow" or "disallow" end, - Wight = function() return profile.mod.allow_build.undead_wight and "allow" or "disallow" end, + Ghoul = "allow", + Skeleton = "allow", + Vampire = "allow", + Wight = "allow", }, class = { @@ -64,6 +66,8 @@ newBirthDescriptor { type = "subrace", name = "Ghoul", + locked = function() return profile.mod.allow_build.undead_ghoul end, + locked_desc = "Slow to shuffle, quick to bite, learn from master, rule the night!", desc = { "Ghouls are dumb, but resilient, rotting undead creatures, making good fighters.", "They have access to #GOLD#special ghoul talents#WHITE# and a wide range of undead abilities:", @@ -113,6 +117,8 @@ newBirthDescriptor { type = "subrace", name = "Skeleton", + locked = function() return profile.mod.allow_build.undead_skeleton end, + locked_desc = "The marching bones, each step we rattle, but servants no more, we march to battle!", desc = { "Skeletons are animated bones, undead creatures both strong and dexterous.", "They have access to #GOLD#special skeleton talents#WHITE# and a wide range of undead abilities:", diff --git a/game/modules/tome/data/birth/races/yeek.lua b/game/modules/tome/data/birth/races/yeek.lua index b65617e639..1d3e756410 100644 --- a/game/modules/tome/data/birth/races/yeek.lua +++ b/game/modules/tome/data/birth/races/yeek.lua @@ -23,6 +23,8 @@ newBirthDescriptor{ type = "race", name = "Yeek", + locked = function() return profile.mod.allow_build.yeek end, + locked_desc = "One race, one mind, one way. Our oppression shall end, and we shall inherit Eyal. Do not presume we are weak - our way is true, and only those who help us shall see our strength.", desc = { "Yeeks are a mysterious race of small humanoids native to the tropical island of Rel.", "Their body is covered with white fur and their disproportionate heads give them a ridiculous look.", @@ -59,6 +61,8 @@ newBirthDescriptor { type = "subrace", name = "Yeek", + locked = function() return profile.mod.allow_build.yeek end, + locked_desc = "One race, one mind, one way. Our oppression shall end, and we shall inherit Eyal. Do not presume we are weak - our way is true, and only those who help us shall see our strength.", desc = { "Yeeks are a mysterious race native to the tropical island of Rel.", "Although they are now nearly unheard of in Maj'Eyal, they spent many centuries as secret slaves to the Halfling nation of Nargol.", diff --git a/game/modules/tome/data/birth/worlds.lua b/game/modules/tome/data/birth/worlds.lua index 3645fb8028..6f50942fce 100644 --- a/game/modules/tome/data/birth/worlds.lua +++ b/game/modules/tome/data/birth/worlds.lua @@ -27,9 +27,9 @@ local default_eyal_descriptors = function(add) Elf = "allow", Dwarf = "allow", Halfling = "allow", - Yeek = function() return profile.mod.allow_build.yeek and "allow" or "disallow" end, - Undead = function() return profile.mod.allow_build.undead and "allow" or "disallow" end, - Construct = function() return profile.mod.allow_build.construct and "allow" or "disallow" end, + Yeek = "allow", + Undead = "allow", + Construct = "allow", }, class = @@ -41,16 +41,12 @@ local default_eyal_descriptors = function(add) Archer = "allow", Rogue = "allow", Mage = "allow", - Divine = function() return profile.mod.allow_build.divine and "allow" or "disallow" end, - Wilder = function() return ( - profile.mod.allow_build.wilder_summoner or - profile.mod.allow_build.wilder_wyrmic - ) and "allow" or "disallow" - end, - Corrupter = function() return profile.mod.allow_build.corrupter and "allow" or "disallow" end, - Afflicted = function() return profile.mod.allow_build.afflicted and "allow" or "disallow" end, - Chronomancer = function() return profile.mod.allow_build.chronomancer and "allow" or "disallow" end, - Psionic = function() return profile.mod.allow_build.psionic and "allow" or "disallow" end, + Divine = "allow", + Wilder = "allow", + Corrupter = "allow", + Afflicted = "allow", + Chronomancer = "allow", + Psionic = "allow", }, } if add then table.merge(base, add) end @@ -79,6 +75,8 @@ newBirthDescriptor{ type = "world", name = "Infinite", display_name = "Infinite Dungeon: The Neverending Descent", + locked = function() return profile.mod.allow_build.campaign_infinite_dungeon end, + locked_desc = "Ever deeper, never ending, no reprieve, keep descending. In ruins old, through barred gate, once riddle solved, find thy fate.", desc = { "Play as your favorite race and class and venture into the infinite dungeon.", @@ -105,6 +103,8 @@ newBirthDescriptor{ type = "world", name = "Arena", display_name = "The Arena: Challenge of the Master", + locked = function() return profile.mod.allow_build.campaign_arena end, + locked_desc = "Blood spilled on sand, only the strong survive. Prove yourself worthy to enter.", desc = { "Play as a lone warrior facing the Arena's challenge!", @@ -135,6 +135,8 @@ newBirthDescriptor{ type = "world", name = "Orcs", display_name = "Orcs: The Rise to Power", + locked = function() return profile.mod.allow_build.campaign_orc and true or "hide" end, + locked_desc = "", desc = { "Baston!", @@ -153,7 +155,9 @@ newBirthDescriptor{ newBirthDescriptor{ type = "world", name = "Spydre", - display_name = "Spydrë: Legacy of Ungoliant", + display_name = "Spydrë: Thouch of the Spider", + locked = function() return profile.mod.allow_build.campaign_spidre and true or "hide" end, + locked_desc = "", desc = { "Spydrë is home to the essence of spiders. The mighty Ungoliant of Arda actually originated from this world.", @@ -171,29 +175,12 @@ newBirthDescriptor{ }, } -newBirthDescriptor{ - type = "world", - name = "Ents", - display_name = "Ents: The March of the Entwifes", - desc = - { - "", - }, - descriptor_choices = - { - race = - { - __ALL__ = "disallow", - Human = "allow", --- Spider = function() return profile.mod.allow_build.spider and "allow" or "disallow" end, - }, - }, -} - newBirthDescriptor{ type = "world", name = "Trolls", display_name = "Trolls: Pirates of the Kar'Haib", + locked = function() return profile.mod.allow_build.campaign_troll and true or "hide" end, + locked_desc = "", desc = { "", @@ -213,6 +200,8 @@ newBirthDescriptor{ type = "world", name = "Nagas", display_name = "Nagas: Guardians of the Tide", + locked = function() return profile.mod.allow_build.campaign_naga and true or "hide" end, + locked_desc = "", desc = { "", @@ -232,6 +221,8 @@ newBirthDescriptor{ type = "world", name = "Faeros", display_name = "Urthalath: Treason or the High Guards", + locked = function() return profile.mod.allow_build.campaign_faeros and true or "hide" end, + locked_desc = "", desc = { "", @@ -251,6 +242,8 @@ newBirthDescriptor{ type = "world", name = "Undeads", display_name = "Broken Oath: The Curse of Undeath", + locked = function() return profile.mod.allow_build.campaign_undead and true or "hide" end, + locked_desc = "", desc = { "", diff --git a/game/modules/tome/data/chats/escort-quest-start.lua b/game/modules/tome/data/chats/escort-quest-start.lua index 1ce59e7840..86e8e4526f 100644 --- a/game/modules/tome/data/chats/escort-quest-start.lua +++ b/game/modules/tome/data/chats/escort-quest-start.lua @@ -35,6 +35,7 @@ newChat{ id="welcome", }) end}, {"Go away; I do not help filthy arcane users!", action=function(npc, player) + game.player:registerEscorts("lost") npc:disappear() npc:removed() player:hasQuest(npc.quest_id).abandoned = true @@ -59,6 +60,7 @@ newChat{ id="welcome", }) end}, {"Go away; I do not care for the weak.", action=function(npc, player) + game.player:registerEscorts("lost") npc:disappear() npc:removed() player:hasQuest(npc.quest_id).abandoned = true diff --git a/game/modules/tome/data/chats/escort-quest.lua b/game/modules/tome/data/chats/escort-quest.lua index 9540236ee9..693d671047 100644 --- a/game/modules/tome/data/chats/escort-quest.lua +++ b/game/modules/tome/data/chats/escort-quest.lua @@ -182,6 +182,8 @@ local reward = reward_types[npc.reward_type] local quest = game.player:hasQuest(npc.quest_id) if quest.to_zigur and reward.antimagic then reward = reward.antimagic reward.is_antimagic = true end +game.player:registerEscorts(quest.to_zigur and "zigur" or "saved") + local saves_name = { mind="mental", spell="spell", phys="physical"} local saves_tooltips = { mind="MENTAL", spell="SPELL", phys="PHYS"} diff --git a/game/modules/tome/data/general/npcs/sandworm.lua b/game/modules/tome/data/general/npcs/sandworm.lua index 953cd21ac9..d5797bfe40 100644 --- a/game/modules/tome/data/general/npcs/sandworm.lua +++ b/game/modules/tome/data/general/npcs/sandworm.lua @@ -71,6 +71,7 @@ newEntity{ base = "BASE_NPC_SANDWORM", newEntity{ base = "BASE_NPC_SANDWORM", name = "sand-drake", display = 'D', + type = "dragon", subtype = "sand", color={r=204,g=255,b=95}, desc = [[This unholy creature looks like a wingless dragon in shape, but resembles a sandworm in color.]], rarity = 5, diff --git a/game/modules/tome/data/gfx/shockbolt/npc/dragon_sand_sand_drake.png b/game/modules/tome/data/gfx/shockbolt/npc/dragon_sand_sand_drake.png new file mode 100644 index 0000000000000000000000000000000000000000..5986724a1e20b0e63897854011c7e8dbc4272a9f GIT binary patch literal 10287 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 BMLPfh literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/shockbolt/npc/humanoid_shalore_archmage_tarelion.png b/game/modules/tome/data/gfx/shockbolt/npc/humanoid_shalore_archmage_tarelion.png new file mode 100644 index 0000000000000000000000000000000000000000..4bb3fd4e245582183150ad0476b6b5100f32eafb GIT binary patch literal 14977 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 literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/quests/escort-duty.lua b/game/modules/tome/data/quests/escort-duty.lua index bf9b3888ba..c07d733429 100644 --- a/game/modules/tome/data/quests/escort-duty.lua +++ b/game/modules/tome/data/quests/escort-duty.lua @@ -330,6 +330,9 @@ on_grant = function(self, who) game.player:hasQuest(self.quest_id).killing_npc = who and who.name or "something" if who.resolveSource and who:resolveSource().player then world:gainAchievement("ESCORT_KILL", game.player) + game.player:registerEscorts("betrayed") + else + game.player:registerEscorts("lost") end end diff --git a/game/modules/tome/data/zones/town-angolwen/npcs.lua b/game/modules/tome/data/zones/town-angolwen/npcs.lua index 4e7558d5d5..867a79d2f3 100644 --- a/game/modules/tome/data/zones/town-angolwen/npcs.lua +++ b/game/modules/tome/data/zones/town-angolwen/npcs.lua @@ -89,7 +89,8 @@ newEntity{ define_as = "TARELION", display = "p", faction = "angolwen", name = "Archmage Tarelion", color=colors.CRIMSON, unique = true, - desc = [[A tall shalore elf, in a flowing robe.]], + resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/humanoid_shalore_archmage_tarelion.png", display_h=2, display_y=-1}}}, + desc = [[A tall shalore elf, in a flowing robe, he looks calm and at peace but you can feel his tremendous power.]], level_range = {30, nil}, exp_worth = 2, rank = 4, size_category = 3, -- GitLab