diff --git a/game/engine/Chat.lua b/game/engine/Chat.lua index fbd6bee0b5db5a1f08a5c2399ae7bf8b62616540..7cdd2b4fda0c30ddd088b4c8a620caaf7bf158db 100644 --- a/game/engine/Chat.lua +++ b/game/engine/Chat.lua @@ -48,6 +48,9 @@ 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) + if self.npc.onChat then self.npc:onChat() end + if self.player.onChat then self.player:onChat() end + local d = engine.dialogs.Chat.new(self, id or self.default_id) game:registerDialog(d) end diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index c0b1ebee3613855e8f853adaf87be75ec4d4b726..62afc1482cd9ea4341bae52c6efe399582ce436c 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -269,6 +269,11 @@ function _M:suffocate(value, src) return dead, affected end +function _M:onChat() + self:runStop("chat started") + self:restStop("chat started") +end + function _M:setName(name) self.name = name game.save_name = name diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 0d406b7036b4d17a3cb0099cb3bd065e62a7389e..09604cbaedd73d20af40ff49d68531d0cafa732b 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -325,6 +325,8 @@ local weapon_talents = { axe = Talents.T_AXE_MASTERY, mace = Talents.T_MACE_MASTERY, knife = Talents.T_KNIFE_MASTERY, + whip = Talents.T_EXOTIC_WEAPONS_MASTERY, + trident=Talents.T_EXOTIC_WEAPONS_MASTERY, bow = Talents.T_BOW_MASTERY, sling = Talents.T_SLING_MASTERY, staff = Talents.T_STAFF_MASTERY, diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 2ae0ef116d9004b8aa1506d03dde9a1718c76771..c7492b26cda5ad9ea8ea0814af01b13ba18d6ba3 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -355,11 +355,12 @@ newDamageType{ end, } --- Cold damage + repulsion; checks for spell power against physical resistance +-- Cold/physical damage + repulsion; checks for spell power against physical resistance newDamageType{ name = "wave", type = "WAVE", projector = function(src, x, y, type, dam) - DamageType:get(DamageType.COLD).projector(src, x, y, DamageType.COLD, dam) + DamageType:get(DamageType.COLD).projector(src, x, y, DamageType.COLD, dam / 2) + DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam / 2) local target = game.level.map(x, y, Map.ACTOR) if target then if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then diff --git a/game/modules/tome/data/general/npcs/all.lua b/game/modules/tome/data/general/npcs/all.lua index 3a7027574193df3457c1882137b110f7fff0e8cf..be0c669dcab91c3f7b3b49f93b02d445deda1dce 100644 --- a/game/modules/tome/data/general/npcs/all.lua +++ b/game/modules/tome/data/general/npcs/all.lua @@ -34,6 +34,8 @@ loadIfNot("/data/general/npcs/cold-drake.lua") loadIfNot("/data/general/npcs/fire-drake.lua") loadIfNot("/data/general/npcs/ghoul.lua") loadIfNot("/data/general/npcs/jelly.lua") +loadIfNot("/data/general/npcs/minor-demon.lua") +loadIfNot("/data/general/npcs/major-demon.lua") loadIfNot("/data/general/npcs/minotaur.lua") loadIfNot("/data/general/npcs/molds.lua") loadIfNot("/data/general/npcs/multihued-drake.lua") diff --git a/game/modules/tome/data/general/npcs/major-demon.lua b/game/modules/tome/data/general/npcs/major-demon.lua new file mode 100644 index 0000000000000000000000000000000000000000..afacf523abfd5ad33e4f58c87703c9be42e32522 --- /dev/null +++ b/game/modules/tome/data/general/npcs/major-demon.lua @@ -0,0 +1,115 @@ +-- ToME - Tales of Middle-Earth +-- Copyright (C) 2009, 2010 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 + +-- last updated: 10:46 AM 2/3/2010 + +local Talents = require("engine.interface.ActorTalents") + +newEntity{ + define_as = "BASE_NPC_MAJOR_DEMON", + type = "demon", subtype = "major", + display = "U", color=colors.WHITE, + body = { INVEN = 10 }, + autolevel = "warrior", + ai = "dumb_talented_simple", ai_state = { talent_in=1, }, + stats = { str=22, dex=10, mag=20, con=13 }, + energy = { mod=1 }, + combat_armor = 1, combat_def = 1, + body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1, QUIVER=1 }, + combat = { dam=resolvers.mbonus(46, 20), atk=15, apr=7, dammod={str=0.7} }, + max_life = resolvers.rngavg(100,120), + infravision = 20, + open_door = true, + rank = 2, + size_category = 3, + no_breath = 1, + demon = 1, +} + +newEntity{ base = "BASE_NPC_MAJOR_DEMON", + name = "dolleg", color=colors.GREEN, -- Dark thorn + desc = "A monstrous demon, covered in acidic thorns.", + level_range = {30, nil}, exp_worth = 1, + rarity = 1, + rank = 2, + autolevel = "warrior", + combat_armor = 26, combat_def = 0, + combat = { dam=resolvers.mbonus(56, 30), atk=35, apr=18, dammod={str=1}, damtype=DamageType.ACID }, + + resists={[DamageType.ACID] = resolvers.mbonus(30, 20)}, + + confusion_immune = 1, + stun_immune = 1, + + resolvers.talents{ + [Talents.T_ACIDIC_SKIN]=5, + [Talents.T_SLIME_SPIT]=4, + }, +} + + +newEntity{ base = "BASE_NPC_MAJOR_DEMON", + name = "dĂÂșathedlen", color=colors.DARK_GREY, -- Darkness exiled + desc = "Under a shroud of darkness you discern an evil shape.", + level_range = {30, nil}, exp_worth = 1, + rarity = 1, + rank = 2, + autolevel = "warrior", + combat_armor = 0, combat_def = 26, + combat = { dam=resolvers.mbonus(46, 30), atk=35, apr=18, dammod={str=1}, damtype=DamageType.DARKNESS }, + + resists={[DamageType.DARKNESS] = resolvers.mbonus(30, 20)}, + + poison_immune = 1, + disease_immune = 1, + + resolvers.talents{ + [Talents.T_DARKNESS]=3, + [Talents.T_BLOOD_GRASP]=5, + }, +} + +newEntity{ base = "BASE_NPC_MAJOR_DEMON", + name = "uruivellas", color=colors.LIGHT_RED, -- Hot strength + desc = [[This demon would look like a minautor, if minautors had a fiery aura surrounding them and horns all over the body. +Oh and it is twice as big too.]], + level_range = {30, nil}, exp_worth = 1, + rarity = 4, + rank = 3, + energy = {mod=1.4}, + size_category = 5, + autolevel = "warriormage", + life_rating = 20, + combat_armor = 26, combat_def = 0, + + resolvers.equip{ {type="weapon", subtype="battleaxe", autoreq=true}, }, + + resists={[DamageType.PHYSICAL] = resolvers.mbonus(15, 10), [DamageType.FIRE] = resolvers.mbonus(15, 10)}, + + stun_immune = 1, + + resolvers.talents{ + [Talents.T_RUSH]=5, + [Talents.T_BATTLE_CALL]=5, + [Talents.T_WEAPON_COMBAT]=8, + [Talents.T_AXE_MASTERY]=10, + [Talents.T_FIRE_STORM]=5, + }, +} + diff --git a/game/modules/tome/data/general/npcs/minor-demon.lua b/game/modules/tome/data/general/npcs/minor-demon.lua index 84b461ccdc1d99b5c4c558c0dfacd014ad666760..e00645d5fd81f6146ec3442166f83aab60f0101f 100644 --- a/game/modules/tome/data/general/npcs/minor-demon.lua +++ b/game/modules/tome/data/general/npcs/minor-demon.lua @@ -30,6 +30,7 @@ newEntity{ ai = "dumb_talented_simple", ai_state = { talent_in=1, }, stats = { str=12, dex=10, mag=3, con=13 }, energy = { mod=1 }, + life_rating = 7, combat_armor = 1, combat_def = 1, combat = { dam=resolvers.mbonus(46, 20), atk=15, apr=7, dammod={str=0.7} }, max_life = resolvers.rngavg(100,120), diff --git a/game/modules/tome/data/general/npcs/naga.lua b/game/modules/tome/data/general/npcs/naga.lua index 87410aec799872f0df6ab588605e98d5344a5c46..37acc630e84b9433a5f595c99d7bbd8a7662b37b 100644 --- a/game/modules/tome/data/general/npcs/naga.lua +++ b/game/modules/tome/data/general/npcs/naga.lua @@ -61,7 +61,7 @@ Myrmidons are the most devoted warriors, following the orders of Maglor whatever [Talents.T_STUNNING_BLOW]=3, [Talents.T_RUSH]=8, [Talents.T_WEAPON_COMBAT]=6, - [Talents.T_AXE_MASTERY]=6, + [Talents.T_EXOTIC_WEAPONS_MASTERY]=6, }, } diff --git a/game/modules/tome/data/general/objects/2htridents.lua b/game/modules/tome/data/general/objects/2htridents.lua index 74cf7f91d73aa88bea9e40e21f314c555b6b1a17..636fdfd849ddc6c6520a3aeda8df521b73b69f79 100644 --- a/game/modules/tome/data/general/objects/2htridents.lua +++ b/game/modules/tome/data/general/objects/2htridents.lua @@ -28,9 +28,9 @@ newEntity{ trident_rarity = 5, -- Special rarity field, converted to "rarity" when needed metallic = true, no_rust = true, - combat = { talented = "axe", damrange = 1.6, sound = "actions/melee", sound_miss = "actions/melee_miss", }, + combat = { talented = "trident", damrange = 1.6, sound = "actions/melee", sound_miss = "actions/melee_miss", }, desc = [[A two handed massive trident. -The trident counts as an axe for purpose of weapon combat talents.]], +Tridents require the exotic weapons mastery talent to correctly use.]], twohanded = true, egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, } diff --git a/game/modules/tome/data/talents/gifts/slime.lua b/game/modules/tome/data/talents/gifts/slime.lua index db3c8f282667b10d483916a4803f592129bbb853..a91cdcefeedd48b9996324befd52f57f54d79c97 100644 --- a/game/modules/tome/data/talents/gifts/slime.lua +++ b/game/modules/tome/data/talents/gifts/slime.lua @@ -92,7 +92,7 @@ newTalent{ local tg = {type="bolt", range=self:getTalentRange(t), display={particle="bolt_arcane"}} local x, y = self:getTarget(tg) if not x or not y then return nil end - self:projecticle(tg, x, y, DamageType.SLIME, 20 + (self:getDex() * self:getTalentLevel(t)) * 0.3, {type="slime"}) + self:projectile(tg, x, y, DamageType.SLIME, 20 + (self:getDex() * self:getTalentLevel(t)) * 0.3, {type="slime"}) game:playSoundNear(self, "talents/slime") return true end, diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua index 1d48da8789f3f697c7256570a3970dd0b92adc4d..19601003daa3b529bf1abd676a3f48b0338bc07e 100644 --- a/game/modules/tome/data/talents/misc/npcs.lua +++ b/game/modules/tome/data/talents/misc/npcs.lua @@ -642,7 +642,7 @@ newTalent{ local x, y = self:getTarget(tg) if not x or not y then return nil end self:project(tg, x, y, function(px, py) - local g = engine.Entity.new{block_sight=true, always_remember=false, unlit=self:getTalentLevel(t) * 10} + local g = engine.Entity.new{name="darkness", show_tooltip=true, block_sight=true, always_remember=false, unlit=self:getTalentLevel(t) * 10} game.level.map(px, py, Map.TERRAIN+1, g) game.level.map.remembers(px, py, false) game.level.map.lites(px, py, false) diff --git a/game/modules/tome/data/talents/spells/fire-alchemy.lua b/game/modules/tome/data/talents/spells/fire-alchemy.lua index fd453ba65d6e8256a78afbdbe706f3c5ecceeb67..48e995d5ef942b3090c8ea3eddc82f34ac66ef85 100644 --- a/game/modules/tome/data/talents/spells/fire-alchemy.lua +++ b/game/modules/tome/data/talents/spells/fire-alchemy.lua @@ -85,42 +85,44 @@ newTalent{ } newTalent{ - name = "Magma Pool", + name = "Fire Storm", type = {"spell/fire-alchemy",3}, - require = spells_req3, + require = spells_req4, points = 5, - mana = 80, - cooldown = 15, - range = function(self, t) - if self:getTalentLevel(t) < 3 then return 1 - else return math.floor(self:getTalentLevel(t)) end - end, + random_ego = "attack", + mana = 40, + cooldown = 30, + tactical = { + ATTACKAREA = 20, + }, action = function(self, t) - local tg = {type="beam", range=self:getTalentRange(t), talent=t} - if self:getTalentLevel(t) >= 3 then tg.type = "beam" end - local x, y = self:getTarget(tg) - if not x or not y then return nil end - self:project(tg, x, y, function(tx, ty) - local target = game.level.map(tx, ty, Map.ACTOR) - if not target then return end - - if target:checkHit(self:combatSpellpower(), target:combatSpellResist(), 0, 95, 10) and target:canBe("stone") and target:canBe("instakill") then - target:setEffect(target.EFF_STONED, math.floor((3 + self:getTalentLevel(t)) / 1.5), {}) - game.level.map:particleEmitter(tx, ty, 1, "archery") - end - end) - game:playSoundNear(self, "talents/earth") + local duration = 5 + self:combatSpellpower(0.05) + self:getTalentLevel(t) + local radius = 3 + local dam = self:combatTalentSpellDamage(t, 5, 90) + -- Add a lasting map effect + game.level.map:addEffect(self, + self.x, self.y, duration, + DamageType.FIRE, dam, + radius, + 5, nil, + engine.Entity.new{alpha=100, display='', color_br=200, color_bg=60, color_bb=30}, + function(e) + e.x = e.src.x + e.y = e.src.y + return true + end, + false + ) + game:playSoundNear(self, "talents/fire") return true end, info = function(self, t) - return ([[Touch your foe and turn it into stone for %d turns. - Stoned creatures are unable to act or regen life and are very brittle. - If a stoned creature is hit by an attack that deals more than 30%% of its life it will shatter and be destroyed. - Stoned creatures are highly resistant to fire and lightning and somewhat resistant to physical attacks. - At level 3 it will become a beam.]]):format(math.floor((3 + self:getTalentLevel(t)) / 1.5)) + return ([[A furious fire storm rages around the caster doing %0.2f fire damage in a radius of 3 each turn for %d turns. + The damage and duration will increase with the Magic stat]]):format(self:combatTalentSpellDamage(t, 5, 90), 5 + self:combatSpellpower(0.05) + self:getTalentLevel(t)) end, } + newTalent{ name = "Body of Fire", type = {"spell/fire-alchemy",4}, diff --git a/game/modules/tome/data/talents/techniques/combat-training.lua b/game/modules/tome/data/talents/techniques/combat-training.lua index 83572d580b0aac0609ae20a4887d360dd5caacb2..9387ff28ee6d0ccf8023513d86d07b2698e56bea 100644 --- a/game/modules/tome/data/talents/techniques/combat-training.lua +++ b/game/modules/tome/data/talents/techniques/combat-training.lua @@ -112,3 +112,15 @@ newTalent{ return ([[Increases damage done with knives by %d%%.]]):format(100 * (math.sqrt(self:getTalentLevel(t) / 10))) end, } + +newTalent{ + name = "Exotic Weapons Mastery", + type = {"technique/combat-training", 1}, + hide = true, + points = 10, + require = { stat = { dex=function(level) return 10 + level * 3 end }, }, + mode = "passive", + info = function(self, t) + return ([[Increases damage done with exotic weapons(whips, tridents, ...) by %d%%.]]):format(100 * (math.sqrt(self:getTalentLevel(t) / 10))) + end, +} diff --git a/game/modules/tome/data/zones/flooded-cave/npcs.lua b/game/modules/tome/data/zones/flooded-cave/npcs.lua index 78a1d286421250d5a418ae8ec94170d74e81d475..90cbef67a5c28a6992248d2245de00444648c13e 100644 --- a/game/modules/tome/data/zones/flooded-cave/npcs.lua +++ b/game/modules/tome/data/zones/flooded-cave/npcs.lua @@ -50,7 +50,7 @@ newEntity{ define_as = "UKLLMSWWIK", resists = { [DamageType.COLD] = 60, [DamageType.LIGHTNING] = 20, }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, - resolvers.drops{chance=100, nb=1, {type="weapon", subtype="greatmaul", defined="TRIDENT_TIDES", autoreq=true} }, + resolvers.drops{chance=100, nb=1, {defined="TRIDENT_TIDES", autoreq=true} }, resolvers.drops{chance=100, nb=5, {ego_chance=100} }, resolvers.drops{chance=100, nb=10, {type="money"} }, diff --git a/game/modules/tome/data/zones/flooded-cave/objects.lua b/game/modules/tome/data/zones/flooded-cave/objects.lua index 91fe78608cbeb2a5f1844c01dcc8c2e6c6aa2436..b7a3ce4cadfb92a78000d168009432db53ff7f77 100644 --- a/game/modules/tome/data/zones/flooded-cave/objects.lua +++ b/game/modules/tome/data/zones/flooded-cave/objects.lua @@ -30,7 +30,7 @@ newEntity{ base = "BASE_TRIDENT", define_as = "TRIDENT_TIDES", name = "Trident of the Tides", unique=true, desc = [[As you wield this trident you can feel the power of the tides rushing through your arms. -The trident counts as an axe for purpose of weapon combat talents.]], +Tridents require the exotic weapons mastery talent to correctly use.]], require = { stat = { str=35 }, }, cost = 300, material_level = 4, diff --git a/game/modules/tome/data/zones/valley-moon-caverns/npcs.lua b/game/modules/tome/data/zones/valley-moon-caverns/npcs.lua index 3df9861f70452f35e04091044633863c9819ba92..1308b66b9fc33b3e364ec0ee48adc78ed8495ff7 100644 --- a/game/modules/tome/data/zones/valley-moon-caverns/npcs.lua +++ b/game/modules/tome/data/zones/valley-moon-caverns/npcs.lua @@ -18,4 +18,5 @@ -- darkgod@te4.org load("/data/general/npcs/minor-demon.lua", rarity(0)) -load("/data/general/npcs/all.lua", rarity(4, 35)) +load("/data/general/npcs/major-demon.lua", rarity(3)) +load("/data/general/npcs/all.lua", rarity(4, 65)) diff --git a/game/modules/tome/data/zones/valley-moon/npcs.lua b/game/modules/tome/data/zones/valley-moon/npcs.lua index 8174c1062ea90660e2ac68e9888e490acdcf9452..efd5525673d038478302e26e358557dfb9e01e86 100644 --- a/game/modules/tome/data/zones/valley-moon/npcs.lua +++ b/game/modules/tome/data/zones/valley-moon/npcs.lua @@ -18,6 +18,7 @@ -- darkgod@te4.org load("/data/general/npcs/minor-demon.lua", rarity(0)) +load("/data/general/npcs/major-demon.lua", rarity(3)) local Talents = require("engine.interface.ActorTalents") @@ -37,6 +38,7 @@ newEntity{ define_as = "CORRUPTED_BALROG", no_breath = 1, move_others=true, demon = 1, + invisible = 40, on_melee_hit = { [DamageType.FIRE] = 50, [DamageType.LIGHT] = 30, }, @@ -54,6 +56,7 @@ newEntity{ define_as = "CORRUPTED_BALROG", [Talents.T_FIRE_BREATH]=5, [Talents.T_RUSH]=5, [Talents.T_WEAPON_COMBAT]=10, + [Talents.T_EXOTIC_WEAPONS_MASTERY]=7, }, autolevel = "dexmage", diff --git a/game/modules/tome/dialogs/LevelupTalentsDialog.lua b/game/modules/tome/dialogs/LevelupTalentsDialog.lua index c580a4a7c46788f561857ee1860ad38bf5039359..804c0c2a79c8e46a488a4b929c5ed3adc095cb8c 100644 --- a/game/modules/tome/dialogs/LevelupTalentsDialog.lua +++ b/game/modules/tome/dialogs/LevelupTalentsDialog.lua @@ -79,6 +79,8 @@ function _M:init(actor, on_finish) end function _M:generateList() + self.actor.__show_special_talents = self.actor.__show_special_talents or {} + -- Makes up the list local list, known = {}, {} for i, tt in ipairs(self.actor.talents_types_def) do @@ -95,7 +97,7 @@ function _M:generateList() -- Find all talents of this school if (self.actor.__hidden_talent_types[tt.type] == nil and ttknown) or (self.actor.__hidden_talent_types[tt.type] ~= nil and not self.actor.__hidden_talent_types[tt.type]) then for j, t in ipairs(tt.talents) do - if not t.hide then + if not t.hide or self.actor.__show_special_talents[t.id] then local typename = "class" if t.generic then typename = "generic" end list[#list+1] = { name=" "..t.name.." ("..typename..")", talent=t.id, color=not ttknown and {128,128,128} } diff --git a/ideas/quests.ods b/ideas/quests.ods index e68cd8916d68d1a5ce8a32fac8143f21d565ef12..9d7f3a1ebb7b01520bbe7a7732794dfb48bd837f 100644 Binary files a/ideas/quests.ods and b/ideas/quests.ods differ diff --git a/ideas/zones.ods b/ideas/zones.ods index 6e64664b1be25dbd26f8379343d3be073c5b6b0a..e2a57fb1e34ba4e8a4563c05127263420b1d66b7 100644 Binary files a/ideas/zones.ods and b/ideas/zones.ods differ