diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua index e7fd2972edb8f16c73054df590c4d986bd8cbef3..fb4e07f83b5606e59dad0ffcf9b05597dcbb42ba 100644 --- a/game/modules/tome/class/Object.lua +++ b/game/modules/tome/class/Object.lua @@ -653,6 +653,10 @@ function _M:getTextualDesc(compare_with, use_actor) elseif found then desc:add({"color","RED"}, "When used from stealth a simple attack with it will not break stealth.", {"color","LAST"}, true) end + + if combat.crushing_blow then + desc:add({"color", "YELLOW"}, "Crushing Blows: ", {"color", "LAST"}, "Damage dealt by this weapon is increased by your critical multiplier, if doing so would kill the target.", true) + end compare_fields(combat, compare_with, field, "travel_speed", "%+d%%", "Travel speed: ", 100, false, false, add_table) @@ -969,6 +973,7 @@ function _M:getTextualDesc(compare_with, use_actor) end compare_fields(w, compare_with, field, "combat_critical_power", "%+.2f%%", "Critical mult.: ") + compare_fields(w, compare_with, field, "ignore_direct_crits", "%-.2f%%", "Reduces incoming crit damage: ") compare_fields(w, compare_with, field, "combat_crit_reduction", "%-d%%", "Reduces opponents crit chance: ") compare_fields(w, compare_with, field, "disarm_bonus", "%+d", "Trap disarming bonus: ") @@ -1067,6 +1072,7 @@ function _M:getTextualDesc(compare_with, use_actor) compare_fields(w, compare_with, field, "projectile_evasion", "%+d%%", "Deflect projectiles away: ") compare_fields(w, compare_with, field, "evasion", "%+d%%", "Chance to avoid attacks: ") + compare_fields(w, compare_with, field, "cancel_damage_chance", "%+d%%", "Chance to avoid any damage: ") compare_fields(w, compare_with, field, "defense_on_teleport", "%+d", "Defense after a teleport: ") compare_fields(w, compare_with, field, "resist_all_on_teleport", "%+d%%", "Resist all after a teleport: ") @@ -1081,12 +1087,16 @@ function _M:getTextualDesc(compare_with, use_actor) compare_fields(w, compare_with, field, "shield_dur", "%+d", "Damage Shield Duration: ") compare_fields(w, compare_with, field, "shield_factor", "%+d%%", "Damage Shield Power: ") + + compare_fields(w, compare_with, field, "iceblock_pierce", "%+d%%", "Ice block penetration: ") compare_fields(w, compare_with, field, "slow_projectiles", "%+d%%", "Slows Projectiles: ") compare_fields(w, compare_with, field, "paradox_reduce_fails", "%+d", "Reduces paradox failures(equivalent to willpower): ") compare_fields(w, compare_with, field, "damage_backfire", "%+d%%", "Damage Backlash: ", nil, true) + + compare_fields(w, compare_with, field, "resist_unseen", "%-d%%", "Reduce all damage from unseen attackers: ") if w.undead then desc:add("The wearer is treated as an undead.", true) @@ -1105,11 +1115,11 @@ function _M:getTextualDesc(compare_with, use_actor) end if w.blind_fight then - desc:add({"color", "YELLOW"}, "Blind-Fight:", {"color", "LAST"}, "This item allows the wearer to attack unseen targets without any penalties.", true) + desc:add({"color", "YELLOW"}, "Blind-Fight: ", {"color", "LAST"}, "This item allows the wearer to attack unseen targets without any penalties.", true) end if w.lucid_dreamer then - desc:add({"color", "YELLOW"}, "Lucid-Dreamer:", {"color", "LAST"}, "This item allows the wearer to act while sleeping.", true) + desc:add({"color", "YELLOW"}, "Lucid Dreamer: ", {"color", "LAST"}, "This item allows the wearer to act while sleeping.", true) end if w.no_breath then diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 45cab167ed87eba27357f59277e7fee58150c0ea..0a06f94abc58437e4241b5ff278a319775efbe11 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -468,6 +468,8 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) local oldproj = DamageType:getProjectingFor(self) if self.__talent_running then DamageType:projectingFor(self, {project_type={talent=self.__talent_running}}) end + + if weapon and weapon.crushing_blow then self:attr("crushing_blow", 1) end -- Damage conversion? -- Reduces base damage but converts it into another damage type @@ -491,6 +493,8 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) if dam > 0 then DamageType:get(damtype).projector(self, target.x, target.y, damtype, math.max(0, dam)) end + + if weapon and weapon.crushing_blow then self:attr("crushing_blow", -1) end if self.__talent_running then DamageType:projectingFor(self, oldproj) end @@ -752,15 +756,15 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) -- Special effect if hitted and weapon and weapon.special_on_hit and weapon.special_on_hit.fct and (not target.dead or weapon.special_on_hit.on_kill) then - weapon.special_on_hit.fct(weapon, self, target) + weapon.special_on_hit.fct(weapon, self, target, dam) end if hitted and crit and weapon and weapon.special_on_crit and weapon.special_on_crit.fct and (not target.dead or weapon.special_on_crit.on_kill) then - weapon.special_on_crit.fct(weapon, self, target) + weapon.special_on_crit.fct(weapon, self, target, dam) end if hitted and weapon and weapon.special_on_kill and weapon.special_on_kill.fct and target.dead then - weapon.special_on_kill.fct(weapon, self, target) + weapon.special_on_kill.fct(weapon, self, target, dam) end if hitted and crit and not target.dead and self:knowTalent(self.T_BACKSTAB) and not target:attr("stunned") and rng.percent(self:callTalent(self.T_BACKSTAB, "getStunChance")) then diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 622dfefe23aac0a4b6658536e16a448d1460d56b..e8b9d185eee3e54a651cb7232c1abc6137053f87 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -337,6 +337,16 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) local def = src.tempeffect_def[src.EFF_CURSE_OF_MISFORTUNE] dam = def.doUnfortunateEnd(src, eff, target, dam) end + + if src:attr("crushing_blow") and (dam * (1.25 + (src.combat_critical_power or 0)/200)) > target.life then + dam = dam * (1.25 + (src.combat_critical_power or 0)/200) + game.logPlayer(src, "You end your target with a crushing blow!") + end + + if target:attr("resist_unseen") and not target:canSee(src) then + dam = dam * (1 - math.min(target.resist_unseen,100)/100) + end + -- Sanctuary: reduces damage if it comes from outside of Gloom if target.isTalentActive and target:isTalentActive(target.T_GLOOM) and target:knowTalent(target.T_SANCTUARY) then if tmp and tmp.sanctuaryDamageChange then @@ -985,6 +995,7 @@ newDamageType{ newDamageType{ name = "flameshock", type = "FLAMESHOCK", projector = function(src, x, y, type, dam) + if _G.type(dam) == "number" then dam = {dam=dam, dur=4} end local target = game.level.map(x, y, Map.ACTOR) if target then -- Set on fire! @@ -1096,7 +1107,7 @@ newDamageType{ -- Light damage + blind chance newDamageType{ - name = "blinding light", type = "LIGHT_BLIND", + name = "blinding light", type = "LIGHT_BLIND", text_color = "#YELLOW#", projector = function(src, x, y, type, dam) local realdam = DamageType:get(DamageType.LIGHT).projector(src, x, y, DamageType.LIGHT, dam) local target = game.level.map(x, y, Map.ACTOR) @@ -1113,7 +1124,7 @@ newDamageType{ -- Lightning damage + daze chance newDamageType{ - name = "lightning", type = "LIGHTNING_DAZE", text_color = "#ROYAL_BLUE#", + name = "dazing lightning", type = "LIGHTNING_DAZE", text_color = "#ROYAL_BLUE#", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam, daze=25} end dam.daze = dam.daze or 25 @@ -1564,7 +1575,7 @@ newDamageType{ } newDamageType{ - name = "gloom", type = "RANDOM_GLOOM", + name = "% chance of gloom effects", type = "RANDOM_GLOOM", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target and rng.percent(dam) then @@ -1674,7 +1685,7 @@ newDamageType{ -- Drain Vim newDamageType{ - name = "enervating blight", type = "DRAIN_VIM", + name = "vim draining blight", type = "DRAIN_VIM", text_color = "#DARK_GREEN#", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam, vim=0.2} end local target = game.level.map(x, y, Map.ACTOR) @@ -1821,7 +1832,7 @@ newDamageType{ -- blood boiled, blight damage + slow newDamageType{ - name = "hindering_blight", type = "BLOOD_BOIL", + name = "hindering blight", type = "BLOOD_BOIL", text_color = "#DARK_GREEN#", projector = function(src, x, y, type, dam) DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam) local target = game.level.map(x, y, Map.ACTOR) @@ -2729,7 +2740,7 @@ newDamageType{ -- Acid damage + Slow newDamageType{ - name = "cautic mire", type = "CAUSTIC_MIRE", + name = "caustic mire", type = "CAUSTIC_MIRE", projector = function(src, x, y, type, dam, tmp) if _G.type(dam) == "number" then dam = {dur = 2, slow=20} end local target = game.level.map(x, y, Map.ACTOR) diff --git a/game/modules/tome/data/general/npcs/horror-undead.lua b/game/modules/tome/data/general/npcs/horror-undead.lua index ccee4662f01ec18a301d8592365c5da7f9830bda..0843706f065a5a35634a1c1ea5599663657d9c15 100644 --- a/game/modules/tome/data/general/npcs/horror-undead.lua +++ b/game/modules/tome/data/general/npcs/horror-undead.lua @@ -48,7 +48,7 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD", desc ="This putrid mass of rotting flesh shifts and quivers, but shows no signs of intelligence or mobility.", resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_horror_necrotic_mass.png", display_h=2, display_y=-1}}}, level_range = {15, nil}, exp_worth = 1, - rarity = 3, + rarity = 4, rank = 1, size_category = 2, life_rating = 7, combat_armor = 0, combat_def = 0, @@ -63,17 +63,17 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD", desc ="This monstrous form of putrid, torn flesh and chipped bone drags its mass towards you, spurting blood and viscera along the way.", resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_horror_necrotic_abomination.png", display_h=2, display_y=-1}}}, level_range = {30, nil}, exp_worth = 1, - rarity = 8, + rarity = 7, rank = 3, size_category = 4, combat_armor = 0, combat_def = 40, - max_life=400, + max_life=400, life_rating=11, disease_immune = 1, combat = { dam=resolvers.levelup(resolvers.rngavg(40,45), 1, 1.2), atk=resolvers.rngavg(60,80), apr=20, - dammod={mag=1.2}, physcrit = 10, + dammod={mag=1.3}, physcrit = 10, damtype=engine.DamageType.BLIGHT, }, @@ -106,7 +106,7 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD", desc ="The massive ribcage in the middle beats with loud, audible cracks, as many a skeletal hand protrude forth, entwining, fusing, forming long skeletal appendages to support itself, while others crumble and collapse inward. During all this, somehow, it seems they grasp for you.", resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_horror_bone_horror.png", display_h=2, display_y=-1}}}, level_range = {30, nil}, exp_worth = 1, - rarity = 8, + rarity = 7, rank = 3, size_category = 4, combat_armor = 30, combat_def = 0, @@ -124,7 +124,7 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD", autolevel = "warriormage", summon = { - {type="undead", subtype = "skeleton", number=4, hasxp=false}, + {type="undead", subtype = "skeleton", number=5, hasxp=false}, }, resolvers.talents{ @@ -151,13 +151,15 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD", desc ="This pulsing, quivering form is a deep crimson, and appears to be composed entirely of thick, virulent blood. Waves rhythmically ripple across its surface, indicating a still beating heart somewhere in its body.", resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_horror_sanguine_horror.png", display_h=2, display_y=-1}}}, level_range = {30, nil}, exp_worth = 1, - rarity = 8, - rank = 3, + rarity = 7, + rank = 3, life_rating = 13, size_category = 4, combat_armor = 30, combat_def = 0, max_life=400, stats = { con=50, }, + lifesteal=15, + combat = { dam=resolvers.levelup(resolvers.rngavg(50,60), 1, 1.2), atk=resolvers.rngavg(60,80), apr=20, @@ -197,5 +199,5 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD", size_category = 2, life_rating = 7, combat_armor = 0, combat_def = 0, max_life=100, - combat = {dam=resolvers.levelup(resolvers.mbonus(25, 15), 1, 1.1), apr=0, atk=resolvers.mbonus(30, 15), dammod={str=0.6}}, + combat = {dam=resolvers.levelup(resolvers.mbonus(25, 15), 1, 1.1), apr=0, atk=resolvers.mbonus(30, 15), dammod={str=0.6}, damtype=engine.DamageType.DRAINLIFE,}, } \ No newline at end of file diff --git a/game/modules/tome/data/general/npcs/horror.lua b/game/modules/tome/data/general/npcs/horror.lua index 2bdf4f71d822e7654d7c75bce67bc2c9d1c704dc..dea319476222ca6bb148cefdf9fcc83183b78d94 100644 --- a/game/modules/tome/data/general/npcs/horror.lua +++ b/game/modules/tome/data/general/npcs/horror.lua @@ -921,6 +921,7 @@ newEntity{ base = "BASE_NPC_HORROR", combat_armor = 30, combat_def = 18, is_akgishil = true, can_spawn = 1, + psionic_shield_override = 1, resolvers.drops{chance=100, nb=1, {defined="BLADE_RIFT"} }, @@ -982,7 +983,7 @@ newEntity{ base="BASE_NPC_HORROR", define_as = "ANIMATED_BLADE", no_breath = 1, size_category = 2, - negative_status_immune = 1, + negative_status_effect_immune = 1, body = { INVEN = 10, MAINHAND=1 }, resolvers.equip{ @@ -1041,7 +1042,7 @@ newEntity{ base="BASE_NPC_HORROR", define_as = "DISTORTED_BLADE", no_breath = 1, size_category = 2, - negative_status_immune = 1, + negative_status_effect_immune = 1, body = { INVEN = 10, MAINHAND=1 }, diff --git a/game/modules/tome/data/general/objects/boss-artifacts-far-east.lua b/game/modules/tome/data/general/objects/boss-artifacts-far-east.lua index c97334f73747fcc48d8c55bce2302a073459ad67..f762ac48b97f859dc9ae301c05d4c922dc70b3d7 100644 --- a/game/modules/tome/data/general/objects/boss-artifacts-far-east.lua +++ b/game/modules/tome/data/general/objects/boss-artifacts-far-east.lua @@ -458,14 +458,12 @@ newEntity{ base = "BASE_GREATMAUL", define_as="ROTTING_MAUL", dammod = {str=1.4}, convert_damage = {[DamageType.BLIGHT] = 20}, melee_project={[DamageType.CORRUPTED_BLOOD] = 30}, - special_on_hit = {desc="25% chance to damage nearby creatures", on_kill=1, fct=function(combat, who, target) - if rng.percent(25) then + special_on_hit = {desc="Damage nearby creatures", on_kill=1, fct=function(combat, who, target) local o, item, inven_id = who:findInAllInventoriesBy("define_as", "ROTTING_MAUL") - local dam = rng.avg(1,2) * (70+ who:getStr() * 1.8) - game.logSeen(who, "The ground shakes as the %s hits!", o:getName()) - local tg = {type="ball", range=0, selffire=false, radius=2, no_restrict=true} - who:project(tg, target.x, target.y, engine.DamageType.PHYSICAL, dam) - end + local dam = rng.avg(1,2) * (70+ who:getStr()) + game.logSeen(who, "The ground shakes as the %s hits!", o:getName()) + local tg = {type="ball", range=0, selffire=false, radius=2, no_restrict=true} + who:project(tg, target.x, target.y, engine.DamageType.PHYSICAL, dam) end}, }, wielder = { diff --git a/game/modules/tome/data/general/objects/boss-artifacts-maj-eyal.lua b/game/modules/tome/data/general/objects/boss-artifacts-maj-eyal.lua index 92a4f7008a1ee9fb6149ea7b3a20adda575470e8..137a51c0d990ff0fb14ea7160a13f3fda18ac977 100644 --- a/game/modules/tome/data/general/objects/boss-artifacts-maj-eyal.lua +++ b/game/modules/tome/data/general/objects/boss-artifacts-maj-eyal.lua @@ -291,9 +291,7 @@ newEntity{ base = "BASE_SHIELD", rarity = 200, cost = 20, material_level = 2, - rarity = false, metallic = false, - special_combat = { dam = resolvers.rngavg(20,30), block = 60, @@ -318,22 +316,23 @@ newEntity{ base = "BASE_GEM", power_source = {nature=true}, unique = true, define_as = "PETRIFIED_WOOD", unided_name = "burned piece of wood", - name = "Petrified Wood", subtype = "black", + name = "Petrified Wood", subtype = "red", --Visually black, but associate with fire, not acid color = colors.WHITE, image = "object/artifact/petrified_wood.png", level_range = {35, 45}, rarity = 280, - identified = false, desc = [[A piece of the scorched wood taken from the remains of Snaproot.]], - rarity = false, cost = 100, material_level = 4, + identified = false, imbue_powers = { resists = { [DamageType.NATURE] = 25, [DamageType.DARKNESS] = 10, [DamageType.COLD] = 10 }, inc_stats = { [Stats.STAT_CON] = 25, }, + ignore_direct_crits = 23, }, wielder = { resists = { [DamageType.NATURE] = 25, [DamageType.DARKNESS] = 10, [DamageType.COLD] = 10 }, inc_stats = { [Stats.STAT_CON] = 25, }, + ignore_direct_crits = 23, }, } diff --git a/game/modules/tome/data/general/objects/boss-artifacts.lua b/game/modules/tome/data/general/objects/boss-artifacts.lua index 9b41a05c0846320cf7e50172078fec590039801b..35f575f2d4c2010aeb0aa71e0849fbe1aabd4e27 100644 --- a/game/modules/tome/data/general/objects/boss-artifacts.lua +++ b/game/modules/tome/data/general/objects/boss-artifacts.lua @@ -114,7 +114,7 @@ newEntity{ base = "BASE_LONGSWORD", define_as = "RIFT_SWORD", unided_name = "time-warped sword", desc = [[The remnants of a damaged timeline, this blade shifts and fades at random.]], level_range = {30, 50}, - rarity = nil, --Not random! + rarity = 220, require = { stat = { str=44 }, }, cost = 300, material_level = 4, diff --git a/game/modules/tome/data/general/objects/brotherhood-artifacts.lua b/game/modules/tome/data/general/objects/brotherhood-artifacts.lua index 5ae99007c4543caf79cb217c3f04bdd6d8731f79..218725f057acebde228de85f05567bb577480602 100644 --- a/game/modules/tome/data/general/objects/brotherhood-artifacts.lua +++ b/game/modules/tome/data/general/objects/brotherhood-artifacts.lua @@ -315,21 +315,27 @@ newEntity{ base = "BASE_GEM", quest = 1, material_level = 5, wielder = { - inc_stats = {[Stats.STAT_CON] = 10, }, + inc_stats = {[Stats.STAT_CON] = 15, }, healing_factor = 0.3, life_regen = 2, resists = { [DamageType.BLIGHT] = 10, }, + damage_affinity = { + [DamageType.NATURE] = 15, + }, }, imbue_powers = { - inc_stats = {[Stats.STAT_CON] = 10, }, + inc_stats = {[Stats.STAT_CON] = 15, }, healing_factor = 0.3, life_regen = 2, stun_immune = 0.3, resists = { [DamageType.BLIGHT] = 10, }, + damage_affinity = { + [DamageType.NATURE] = 15, + }, }, } diff --git a/game/modules/tome/data/general/objects/world-artifacts-far-east.lua b/game/modules/tome/data/general/objects/world-artifacts-far-east.lua index 51190c645bdded6d92f6fd3047f1904d2b467103..5664eb9e2b546a709370dc7d738c5f0a669671e1 100644 --- a/game/modules/tome/data/general/objects/world-artifacts-far-east.lua +++ b/game/modules/tome/data/general/objects/world-artifacts-far-east.lua @@ -159,7 +159,7 @@ newEntity{ base = "BASE_GEM", power_source = {arcane=true}, unique = true, unided_name = "unearthly black stone", - name = "Goedalath Rock", subtype = "black", image = "object/artifact/goedalath_rock.png", + name = "Goedalath Rock", subtype = "demonic", image = "object/artifact/goedalath_rock.png", color = colors.PURPLE, level_range = {42, 50}, desc = [[A small rock that seems from beyond this world, vibrating with a fierce energy. It feels warped and terrible and evil... and yet oh so powerful.]], @@ -280,7 +280,7 @@ Now the broken fragments of Raasul's soul are trapped in this terrible artifact, type = "undead", subtype = "blood", display = "L", name = "animated blood", color=colors.RED, - resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_lich_blood_lich.png", display_h=1, display_y=0}}}, + resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_horror_animated_blood.png", display_h=1, display_y=0}}}, desc = "A haze of blood, vibrant and pulsing through the air, possessed by a warped and cracked soul. Every now and then a scream or wail of agony garbles through it, telling of the mindless suffering undergone by its possessor.", body = { INVEN = 10, MAINHAND=1, OFFHAND=1, }, rank = 3, diff --git a/game/modules/tome/data/general/objects/world-artifacts-maj-eyal.lua b/game/modules/tome/data/general/objects/world-artifacts-maj-eyal.lua index 9135abf4e3c9bac2759806ba1a6467a188f8b41f..a4e9b7719499d866bc43f6d174fc43ff393e0d8e 100644 --- a/game/modules/tome/data/general/objects/world-artifacts-maj-eyal.lua +++ b/game/modules/tome/data/general/objects/world-artifacts-maj-eyal.lua @@ -612,7 +612,6 @@ newEntity{ base = "BASE_WARAXE", [DamageType.COLD] = 20, }, iceblock_pierce=25, - talent_on_hit = { [Talents.T_ICE_BREATH] = {level=2, chance=15} }, }, combat = { dam = 33, @@ -622,6 +621,7 @@ newEntity{ base = "BASE_WARAXE", convert_damage = { [DamageType.ICE] = 50, }, + talent_on_hit = { [Talents.T_ICE_BREATH] = {level=2, chance=15} }, }, } diff --git a/game/modules/tome/data/general/objects/world-artifacts.lua b/game/modules/tome/data/general/objects/world-artifacts.lua index fe39eb3c8943c4d32922828665b4b0e7d5211b22..9cf221420915d28d006f47db542437f22d2f6fa5 100644 --- a/game/modules/tome/data/general/objects/world-artifacts.lua +++ b/game/modules/tome/data/general/objects/world-artifacts.lua @@ -50,15 +50,23 @@ newEntity{ base = "BASE_GEM", movement_speed = 0.2, }, imbue_powers = { - inc_stats = {[Stats.STAT_DEX] = 10, [Stats.STAT_CUN] = 10 }, + inc_stats = {[Stats.STAT_DEX] = 8, [Stats.STAT_CUN] = 8 }, inc_damage = {[DamageType.LIGHTNING] = 20 }, - cancel_damage_chance = 10, -- add to tooltip + cancel_damage_chance = 8, damage_affinity={ [DamageType.LIGHTNING] = 20, }, - movement_speed = 0.2, + movement_speed = 0.15, + }, + wielder = { + inc_stats = {[Stats.STAT_DEX] = 8, [Stats.STAT_CUN] = 8 }, + inc_damage = {[DamageType.LIGHTNING] = 20 }, + cancel_damage_chance = 8, + damage_affinity={ + [DamageType.LIGHTNING] = 20, + }, + movement_speed = 0.15, }, - } -- Low base values because you can stack affinity and resist @@ -3890,7 +3898,7 @@ newEntity{ base = "BASE_TOOL_MISC", combat_mindpower=8, }, max_power = 35, power_regen = 1, - use_power = { name = "call an antimagic pillar", power = 35, + use_power = { name = "call an antimagic pillar, but silence yourself", power = 35, use = function(self, who) local x, y = util.findFreeGrid(who.x, who.y, 5, true, {[engine.Map.ACTOR]=true}) if not x then @@ -3908,10 +3916,11 @@ newEntity{ base = "BASE_TOOL_MISC", blood_color = colors.GREEN, display = "T", color=colors.GREEN, life_rating=18, + combat_dam = 40, combat = { dam=resolvers.rngavg(50,60), atk=resolvers.rngavg(50,75), apr=25, - dammod={wil=1.1}, physcrit = 10, + dammod={wil=1.2}, physcrit = 10, damtype=engine.DamageType.SLIME, }, level_range = {1, nil}, exp_worth = 0, @@ -3925,7 +3934,7 @@ newEntity{ base = "BASE_TOOL_MISC", size_category = 5, blind=1, esp_all=1, - resists={[engine.DamageType.BLIGHT] = 40, [engine.DamageType.ARCANE] = 40, [engine.DamageType.NATURE] = 70}, + resists={all = 15, [engine.DamageType.BLIGHT] = 40, [engine.DamageType.ARCANE] = 40, [engine.DamageType.NATURE] = 70}, no_breath = 1, cant_be_moved = 1, stone_immune = 1, @@ -3937,10 +3946,10 @@ newEntity{ base = "BASE_TOOL_MISC", stun_immune = 1, blind_immune = 1, cut_immune = 1, - knockback_resist, + knockback_resist=1, combat_mentalresist=50, combat_spellresist=100, - on_act = function(self) self:project({type="ball", range=0, radius=5, selffire=false}, self.x, self.y, engine.DamageType.SILENCE, {dur=2, power_check=self:combatMindpower()}) end, + on_act = function(self) self:project({type="ball", range=0, radius=5, friendlyfire=false}, self.x, self.y, engine.DamageType.SILENCE, {dur=2, power_check=self:combatMindpower()}) end, resolvers.talents{ [Talents.T_RESOLVE]={base=3, every=6}, [Talents.T_MANA_CLASH]={base=3, every=5}, @@ -3963,6 +3972,7 @@ newEntity{ base = "BASE_TOOL_MISC", title="Summon", orders = {target=true, leash=true, anchor=true, talents=true}, }) + who:setEffect(who.EFF_SILENCED, 5, {}) return {id=true, used=true} end }, @@ -5329,7 +5339,7 @@ newEntity{ base = "BASE_AMULET", rarity = 220, cost = 350, material_level = 5, - special_desc = function(self) return "Gives all your cold damage a 20% chance to freeze the target, and allows 20% of your damage to ignore ice blocks." end, + special_desc = function(self) return "Gives all your cold damage a 20% chance to freeze the target." end, wielder = { combat_spellpower=12, inc_damage={ @@ -5952,7 +5962,7 @@ newEntity{ base = "BASE_SHIELD", special_desc = function(self) return "When you block an attack, there is a 30% chance of petrifying the attacker." end, special_combat = { dam = 40, - block = 100, + block = 180, physcrit = 5, dammod = {str=1}, }, @@ -6039,6 +6049,408 @@ newEntity{ base = "BASE_KNIFE", --Shibari's #1 quick_weapon_swap = 1, }, } + +newEntity{ base = "BASE_KNIFE", + power_source = {technique=true}, + unique = true, + name = "Swordbreaker", image = "object/artifact/swordbreaker.png", + unided_name = "hooked blade", + desc = [[This ordinary blade is made of fine, sturdy voratun and outfitted with jagged hooks along the edge. This simple appearance belies a great power - the hooked maw of this dagger broke many a blade and the stride of many would-be warriors.]], + level_range = {20, 30}, + rarity = 250, + require = { stat = { dex=10, cun=10 }, }, + cost = 300, + material_level = 3, + special_desc = function(self) return "Can block like a shield, potentially disarming the enemy." end, + combat = { + dam = 25, + apr = 20, + physcrit = 15, + physspeed = 0.9, + dammod = {dex=0.5,cun=0.5}, + special_on_crit = {desc="Breaks enemy weapon.", fct=function(combat, who, target) + target:setEffect(target.EFF_SUNDER_ARMS, 5, {power=5+(who:combatPhysicalpower()*0.33), apply_power=who:combatPhysicalpower()}) + end}, + }, + wielder = { + combat_def = 15, + disarm_immune=0.5, + combat_physresist = 15, + inc_stats = { + [Stats.STAT_DEX] = 8, + [Stats.STAT_CUN] = 8, + }, + combat_armor_hardiness = 20, + learn_talent = { [Talents.T_DAGGER_BLOCK] = 1, }, + }, +} + +newEntity{ base = "BASE_SHIELD", + power_source = {arcane=true}, + unique = true, + name = "Shieldsmaiden", image = "object/artifact/shieldmaiden.png", + unided_name = "icy shield", + desc = [["Myths tell of shieldsmaidens, a tribe of warrior women from the northern wastes of Maj'Eyal. Their martial prowess and beauty drew the fascination of swaths of admirers, yet all unrequited. So began the saying, that a shieldsmaidens heart is as cold and unbreakable as her shield."]], + color = colors.BROWN, + level_range = {36, 48}, + rarity = 270, + require = { stat = { str=28 }, }, + cost = 400, + material_level = 5, + metallic = false, + special_desc = function(self) return "Granted talent can block up to 1 instance of damage each 10 turns." end, + special_combat = { + dam = 48, + block = 150, + physcrit = 8, + dammod = {str=1}, + damtype = DamageType.ICE, + talent_on_hit = { [Talents.T_ICE_SHARDS] = {level=3, chance=15} }, + }, + wielder = { + combat_armor = 20, + combat_def = 5, + combat_def_ranged = 12, + fatigue = 10, + learn_talent = { [Talents.T_BLOCK] = 4, [Talents.T_SHIELDSMAIDEN_AURA] = 1, }, + resists = { [DamageType.COLD] = 25, [DamageType.FIRE] = 25,}, + }, +} + +-- Thanks to Naghyal's Beholder code for the basic socket skeleton +newEntity{ base = "BASE_GREATMAUL", + power_source = {arcane=true}, -- Should really make this only arcane for some gems + unique = true, + color = colors.BLUE, + name = "Tirakai's Maul", + desc = [[This massive hammer is formed from a thick mass of strange crystalline growths. In the side of the hammer itself you see an empty slot; it looks like a gem of your own could easily fit inside it.]], + gemDesc = "None", -- Defined by the elemental properties and used by special_desc + special_desc = function(self) + -- You'll want to color this and such + if not self.Gem then return ("No gem") end + return ("%s: %s"):format(self.Gem.name:capitalize(), self.gemDesc or ("Write a description for this gem's properties!")) + end, + cost = 1000, + material_level = 1, -- Changes to gem material level on socket + evel_range = {1, 15}, + rarity = 280, + combat = { + dam = 10, + apr = 7, + physcrit = 4, + damrange=1.3, + dammod = {str=1.2}, + }, + max_power = 1, power_regen = 1, + use_power = { name = "imbue the hammer with a gem of your choice", power = 0, + use = function(self, who) + local DamageType = require "engine.DamageType" + local Stats = require "engine.interface.ActorStats" + local d + d = who:showInventory("Use which gem?", who:getInven("INVEN"), function(gem) return gem.type == "gem" and gem.imbue_powers and gem.material_level end, + function(gem, gem_item) + who:onTakeoff(self) + local name_old=self.name + local old_hotkey + for i, v in pairs(who.hotkey) do + if v[2]==name_old then + old_hotkey=i + end + end + + -- Recycle the old gem + local old_gem=self.Gem + if old_gem then + who:addObject(who:getInven("INVEN"), old_gem) + game.logPlayer(who, "You remove your %s.", old_gem:getName{do_colour=true, no_count=true}) + end + + if gem then + + -- The Blank Slate. This is a horrible method of changing modes, but it is the easiest to avoid fucking up. This doesn't do much better than just making a static table for every element but its much easier to work with. + self.Gem = nil + self.Gem = gem + self.gemDesc = "Describe all the goddamn colors. NOW." + + self.sentient = false + self.act = mod.class.Object.act + + self.talent_on_spell = nil + + self.material_level=gem.material_level + local scalingFactor = self.material_level + + self.combat = { + dam = (14 * scalingFactor), + apr = (3 * scalingFactor), + physcrit = (2.5 * scalingFactor), + dammod = {str=1.2}, + damrange = 1.3, + } + + self.wielder = { + inc_stats = {[Stats.STAT_MAG] = (2 * scalingFactor), [Stats.STAT_CUN] = (2 * scalingFactor), [Stats.STAT_DEX] = (2 * scalingFactor),}, + } + + who:removeObject(who:getInven("INVEN"), gem_item) + + -- Each element merges its effect into the combat/wielder tables (or anything else) after the base stats are scaled + -- You can modify damage and such here too but you should probably make static tables instead of merging + if gem.subtype =="black" then -- Acid + self.combat.damtype = DamageType.ACID + table.mergeAdd(self.wielder, {inc_damage = { [DamageType.ACID] = 4 * scalingFactor} }, true) + + self.combat.burst_on_crit = {[DamageType.ACID_DISARM] = 12 * scalingFactor,} + self.gemDesc = "Acid" + end + if gem.subtype =="blue" then -- Lightning + self.combat.damtype = DamageType.LIGHTNING + table.mergeAdd(self.wielder, { + inc_damage = { [DamageType.LIGHTNING] = 4 * scalingFactor} + + }, true) + self.combat.burst_on_crit = {[DamageType.LIGHTNING_DAZE] = 12 * scalingFactor,} + self.gemDesc = "Lightning" + end + if gem.subtype =="green" then -- Nature + self.combat.damtype = DamageType.NATURE + table.mergeAdd(self.wielder, { + inc_damage = { [DamageType.NATURE] = 4 * scalingFactor} + + }, true) + self.combat.burst_on_crit = {[DamageType.SPYDRIC_POISON] = 12 * scalingFactor,} + self.gemDesc = "Nature" + end + if gem.subtype =="red" then -- Fire + self.combat.damtype = DamageType.FIRE + table.mergeAdd(self.wielder, { + inc_damage = { [DamageType.FIRE] = 4 * scalingFactor}, + }, true) + self.combat.burst_on_crit = {[DamageType.FLAMESHOCK] = 12 * scalingFactor,} + self.gemDesc = "Fire" + end + if gem.subtype =="violet" then -- Arcane + self.combat.damtype = DamageType.ARCANE + table.mergeAdd(self.wielder, { + inc_damage = { [DamageType.ARCANE] = 4 * scalingFactor} + + }, true) + self.combat.burst_on_crit = {[DamageType.ARCANE_SILENCE] = 12 * scalingFactor,} + self.gemDesc = "Arcane" + end + if gem.subtype =="white" then -- Cold + self.combat.damtype = DamageType.COLD + table.mergeAdd(self.wielder, { + inc_damage = { [DamageType.COLD] = 4 * scalingFactor} + + }, true) + self.combat.burst_on_crit = {[DamageType.ICE] = 12 * scalingFactor,} + self.gemDesc = "Cold" + end + if gem.subtype =="yellow" then -- Light + self.combat.damtype = DamageType.LIGHT + table.mergeAdd(self.wielder, { + inc_damage = { [DamageType.LIGHT] = 4 * scalingFactor} + + }, true) + self.combat.burst_on_crit = {[DamageType.LIGHT_BLIND] = 12 * scalingFactor,} + self.gemDesc = "Light" + end + if gem.subtype == "multi-hued" then -- Some but not all artifacts, if you want to do artifact specific effects make conditionals by name, don't use this + table.mergeAdd(self.combat, {convert_damage = {[DamageType.COLD] = 25, [DamageType.FIRE] = 25, [DamageType.LIGHTNING] = 25, [DamageType.ARCANE] = 25,} }, true) + table.mergeAdd(self.wielder, { + inc_damage = { all = 2 * scalingFactor}, + resists_pen = { all = 2 * scalingFactor}, + }, true) + self.gemDesc = "Unique" + end + if gem.subtype == "demonic" then -- Goedalath Rock + self.combat.damtype = DamageType.SHADOWFLAME + table.mergeAdd(self.wielder, { + inc_damage = { [DamageType.FIRE] = 3 * scalingFactor, [DamageType.DARKNESS] = 3 * scalingFactor,}, + resists_pen = { all = 2 * scalingFactor}, + }, true) + self.gemDesc = "Demonic" + end + game.logPlayer(who, "You imbue your %s with %s.", self:getName{do_colour=true, no_count=true}, gem:getName{do_colour=true, no_count=true}) + + --self.name = (gem.name .. " of Divinity") + + table.mergeAdd(self.wielder, gem.imbue_powers, true) + + end + if gem.talent_on_spell then + self.talent_on_spell = self.talent_on_spell or {} + table.append(self.talent_on_spell, gem.talent_on_spell) + end + who:onWear(self) + for i, v in pairs(who.hotkey) do + if v[2]==name_old then + v[2]=self.name + end + if v[2]==self.name and old_hotkey and i~=old_hotkey then + who.hotkey[i] = nil + end + end + d.used_talent=true + game:unregisterDialog(d) + return true + end) + return {id=true, used=true} + end + }, + on_wear = function(self, who) + + return true + end, + wielder = { + -- Stats only from gems + }, +} + +newEntity{ base = "BASE_GLOVES", define_as = "SET_GLOVE_DESTROYER", + power_source = {arcane=true, technique=true}, + unique = true, + name = "Fist of the Destroyer", color = colors.RED, image = "object/artifact/fist_of_the_destroyer.png", + unided_name = "vile gauntlets", + desc = [[These terrible looking gloves glow with untold power.]], + level_range = {40, 50}, + rarity = 300, + cost = 800, + material_level = 5, + special_desc = function(self) + local num=4 + if self.set_complete then + num=6 + end + return ("Increases all damage by %d%% of current vim \nCurrent Bonus: %d%%"):format(num, num*0.01*(game.player:getVim() or 0)) + end, + wielder = { + inc_stats = { [Stats.STAT_STR] = 9, [Stats.STAT_MAG] = 9, [Stats.STAT_CUN] = 3, }, + demonblood_dam=0.04, + max_vim = 25, + combat_def = 8, + stun_immune = 0.2, + talents_types_mastery = { ["corruption/shadowflame"] = 0.2, ["corruption/vim"] = 0.2,}, + combat = { + dam = 35, + apr = 15, + physcrit = 10, + physspeed = 0, + dammod = {dex=0.4, str=-0.6, cun=0.4, mag=0.2,}, + damrange = 0.3, + talent_on_hit = { T_DRAIN = {level=2, chance=8}, T_SOUL_ROT = {level=3, chance=12}, T_BLOOD_GRASP = {level=3, chance=10}}, + }, + }, + max_power = 12, power_regen = 1, + use_talent = { id = Talents.T_DARKFIRE, level = 5, power = 12 }, + set_list = { {"define_as", "SET_ARMOR_MASOCHISM"} }, + on_set_complete = function(self, who) + game.logPlayer(who, "#STEEL_BLUE#The fist and the mangled clothing glow ominously!") + self:specialSetAdd({"wielder","demonblood_dam"}, 0.02) + self:specialSetAdd({"wielder","inc_damage"}, { [engine.DamageType.FIRE] = 15, [engine.DamageType.DARKNESS] = 15, all = 5 }) + end, + on_set_broken = function(self, who) + game.logPlayer(who, "#STEEL_BLUE#The ominous glow dies down.") + end, +} + +newEntity{ base = "BASE_LIGHT_ARMOR", define_as = "SET_ARMOR_MASOCHISM", + power_source = {arcane=true, technique=true}, + unique = true, + name = "Masochism", color = colors.RED, image = "object/artifact/masochism.png", + unided_name = "mangled clothing", + desc = [[Stolen flesh, + Stolen pain, + To give it up, + Is to live again.]], + level_range = {40, 50}, + rarity = 300, + cost = 800, + material_level = 5, + special_desc = function(self) + local num=7 + if self.set_complete then + num=10 + end + return ("Reduces all damage by %d%% of current vim or 50%% of the damage, whichever is lower; but at the cost of vim equal to 5%% of the damage blocked. \nCurrent Bonus: %d"):format(num, num*0.01*(game.player:getVim() or 0)) + end, + wielder = { + inc_stats = {[Stats.STAT_MAG] = 9, [Stats.STAT_CUN] = 3, }, + combat_spellpower = 10, + demonblood_def=0.07, + max_vim = 25, + disease_immune = 1, + combat_physresist = 10, + combat_mentalresist = 10, + combat_spellresist = 10, + on_melee_hit={[DamageType.DRAIN_VIM] = 25}, + melee_project={[DamageType.DRAIN_VIM] = 25}, + talents_types_mastery = { ["corruption/sanguisuge"] = 0.2, ["corruption/blood"] = 0.2,}, + }, + max_power = 12, power_regen = 1, + use_talent = { id = Talents.T_BLOOD_GRASP, level = 5, power = 12 }, + set_list = { {"define_as", "SET_GLOVE_DESTROYER"} }, + on_set_complete = function(self, who) + self:specialSetAdd({"wielder","demonblood_def"}, 0.03) + self:specialSetAdd({"wielder","resists"}, { [engine.DamageType.FIRE] = 15, [engine.DamageType.DARKNESS] = 15, all = 5 }) + end, + on_set_broken = function(self, who) + end, +} + +newEntity{ base = "BASE_GREATMAUL", + power_source = {technique=true}, + unique = true, + name = "Obliterator", color = colors.UMBER, image = "object/artifact/obliterator.png", + unided_name = "titanic maul", + desc = [[This massive hammer strikes with an impact that could shatter bones.]], + level_range = {23, 30}, + rarity = 270, + require = { stat = { str=40 }, }, + cost = 250, + material_level = 3, + combat = { + dam = 48, + apr = 10, + physcrit = 0, + dammod = {str=1.2}, + crushing_blow=1, + }, + wielder = { + combat_critical_power = 10, + }, +} + +newEntity{ base = "BASE_HELM", + power_source = {technique=true}, + unique = true, + name = "Yaldan Baoth", image = "object/artifact/yaldan_baoth.png", + unided_name = "obscuring helm", + desc = [[The golden bascinet crown, affiliated to Veluca of Yaldan. King of the mythical city of Yaldan, that was struck from the face of Eyal by the arrogance of its people. Lone survivor of his kin, he spent his last years wandering the early world, teaching man to stand against the darkness. With his dying words, "Fear no evil", the crown was passed onto his successor.]], + level_range = {28, 39,}, + rarity = 240, + cost = 700, + material_level = 4, + wielder = { + combat_armor = 6, + fatigue = 4, + resist_unseen = 25, + sight = -2, + inc_stats = { [Stats.STAT_WIL] = 10, [Stats.STAT_CON] = 7, }, + inc_damage={ + [DamageType.LIGHT] = 10, + }, + resists={ + [DamageType.LIGHT] = 10, + [DamageType.DARKNESS] = 15, + }, + resists_cap={ + [DamageType.DARKNESS] = 10, + }, + blind_fight = 1, + }, +} --[=[ newEntity{ unique = true, diff --git a/game/modules/tome/data/gfx/shockbolt/object/artifact/fist_of_the_destroyer.png b/game/modules/tome/data/gfx/shockbolt/object/artifact/fist_of_the_destroyer.png new file mode 100644 index 0000000000000000000000000000000000000000..80870ad911ce63dc57dff257265a7062424aa8ef Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/artifact/fist_of_the_destroyer.png differ diff --git a/game/modules/tome/data/gfx/shockbolt/object/artifact/masochism.png b/game/modules/tome/data/gfx/shockbolt/object/artifact/masochism.png new file mode 100644 index 0000000000000000000000000000000000000000..ced22684ca13353fc9c1202997f026673e20112d Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/artifact/masochism.png differ diff --git a/game/modules/tome/data/gfx/shockbolt/object/artifact/obliterator.png b/game/modules/tome/data/gfx/shockbolt/object/artifact/obliterator.png new file mode 100644 index 0000000000000000000000000000000000000000..cae5836cdba68864f733fba17089a28c6ce0fca9 Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/artifact/obliterator.png differ diff --git a/game/modules/tome/data/gfx/shockbolt/object/artifact/shieldmaiden.png b/game/modules/tome/data/gfx/shockbolt/object/artifact/shieldmaiden.png new file mode 100644 index 0000000000000000000000000000000000000000..95a2065f3c0c96a02a331f2f592d094958ed1846 Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/artifact/shieldmaiden.png differ diff --git a/game/modules/tome/data/gfx/shockbolt/object/artifact/swordbreaker.png b/game/modules/tome/data/gfx/shockbolt/object/artifact/swordbreaker.png new file mode 100644 index 0000000000000000000000000000000000000000..4288b810898c7ad53a3a003f06517343aa427830 Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/artifact/swordbreaker.png differ diff --git a/game/modules/tome/data/gfx/shockbolt/object/artifact/tirakais_maul.png b/game/modules/tome/data/gfx/shockbolt/object/artifact/tirakais_maul.png new file mode 100644 index 0000000000000000000000000000000000000000..8ef0accf0a0b5c86bdd2c8fb477cf582658b896c Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/artifact/tirakais_maul.png differ diff --git a/game/modules/tome/data/gfx/shockbolt/object/artifact/yaldan_baoth.png b/game/modules/tome/data/gfx/shockbolt/object/artifact/yaldan_baoth.png new file mode 100644 index 0000000000000000000000000000000000000000..7ee4bdf279c2d1646fb86d9679da01e412c3530b Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/artifact/yaldan_baoth.png differ diff --git a/game/modules/tome/data/gfx/talents/shieldsmaiden_aura.png b/game/modules/tome/data/gfx/talents/shieldsmaiden_aura.png new file mode 100644 index 0000000000000000000000000000000000000000..5db2a5eb5e5e04d1a2df84e9206b5c898e08cc43 Binary files /dev/null and b/game/modules/tome/data/gfx/talents/shieldsmaiden_aura.png differ diff --git a/game/modules/tome/data/talents/misc/objects.lua b/game/modules/tome/data/talents/misc/objects.lua index 5d45f4d49f50140fb6aa3e3d211fdeb53788fa3c..0e852182d4773567eb3124e5ecf6917e06bdf876 100644 --- a/game/modules/tome/data/talents/misc/objects.lua +++ b/game/modules/tome/data/talents/misc/objects.lua @@ -528,3 +528,91 @@ newTalent{ return ([[Reset up to 3 wild gift, psionic or cursed talents.]]) end, } + +newTalent{ + name = "Dagger Block", + image = "talents/block.png", + type = {"technique/objects", 1}, + cooldown = function(self, t) + return 8 - util.bound(self:getTalentLevelRaw(t), 1, 5) + end, + points = 5, + hard_cap = 5, + range = 1, + requires_target = true, + tactical = { ATTACK = 3, DEFEND = 3 }, + + getProperties = function(self, t) + local p = { + sp = false, + ref = false, + br = false, + sb = true + } + return p + end, + + getBlockedTypes = function(self, t) + + local bt = {[DamageType.PHYSICAL]=true} + bt[DamageType.FIRE] = false + bt[DamageType.LIGHTNING] = false + bt[DamageType.COLD] = false + bt[DamageType.ACID] = false + bt[DamageType.NATURE] = false + bt[DamageType.BLIGHT] = false + bt[DamageType.LIGHT] = false + bt[DamageType.DARKNESS] = false + bt[DamageType.ARCANE] = false + bt[DamageType.MIND] = false + bt[DamageType.TEMPORAL] = false + + local n = 0 + for t, _ in pairs(bt) do n = n + 1 end + + if n < 1 then return "(error 2)" end + local e_string = "" + if n == 1 then + e_string = DamageType.dam_def[next(bt)].name + else + local list = table.keys(bt) + for i = 1, #list do + list[i] = DamageType.dam_def[list[i]].name + end + e_string = table.concat(list, ", ") + end + return bt, e_string + end, + + action = function(self, t) + local properties = t.getProperties(self, t) + local bt, bt_string = t.getBlockedTypes(self, t) + self:setEffect(self.EFF_BLOCKING, 1 + (self:knowTalent(self.T_ETERNAL_GUARD) and 1 or 0), {power = 120+self:getCun()+self:getDex(), d_types=bt, properties=properties}) + return true + end, + info = function(self, t) + return ([[Raise your dagger into blocking position for one turn, reducing the damage of all physical attacks by %d. If you block all of an attack's damage, the attacker will be vulnerable to a deadly counterstrike (a normal attack will instead deal 200%% damage) for one turn and be left disarmed for 3 turns. + The blocking value will increase with your Dexterity and Cunning.]]):format(120 + self:getCun() + self:getDex()) + end, +} + +newTalent{ + name = "Shieldsmaiden Aura", + type = {"misc/objects", 1}, + points = 1, + mode = "passive", + cooldown = 10, + callbackOnHit = function(self, t, cb) + if not self:isTalentCoolingDown(t) then + self:startTalentCooldown(t) + cb.value=0 + game.logPlayer(self, "Your shield protects you from the blow!") + return true + else + return false + end + end, + info = function(self, t) + return ([[Can block up to 1 hit per 10 turns.]]) + end, +} diff --git a/game/modules/tome/data/talents/psionic/absorption.lua b/game/modules/tome/data/talents/psionic/absorption.lua index 724a1c9aa4dcd0d89d7732ce51d92ae01ebdc846..4a9402e186906594acca6c597a407a574ea0f2fa 100644 --- a/game/modules/tome/data/talents/psionic/absorption.lua +++ b/game/modules/tome/data/talents/psionic/absorption.lua @@ -76,7 +76,7 @@ newTalent{ no_energy = true, tactical = { DEFEND = 2 }, on_pre_use = function(self, t, silent) - if self:isTalentActive(self.T_THERMAL_SHIELD) and self:isTalentActive(self.T_CHARGED_SHIELD) then + if self:isTalentActive(self.T_THERMAL_SHIELD) and self:isTalentActive(self.T_CHARGED_SHIELD) and not self:attr("psionic_shield_override") then if not silent then game.logSeen(self, "You may only sustain two shields at once. Shield activation cancelled.") end return false end @@ -202,7 +202,7 @@ newTalent{ no_energy = true, tactical = { DEFEND = 2 }, on_pre_use = function(self, t, silent) - if self:isTalentActive(self.T_KINETIC_SHIELD) and self:isTalentActive(self.T_CHARGED_SHIELD) then + if self:isTalentActive(self.T_KINETIC_SHIELD) and self:isTalentActive(self.T_CHARGED_SHIELD) and not self:attr("psionic_shield_override") then if not silent then game.logSeen(self, "You may only sustain two shields at once. Shield activation cancelled.") end return false end @@ -325,7 +325,7 @@ newTalent{ no_energy = true, tactical = { DEFEND = 2 }, on_pre_use = function(self, t, silent) - if self:isTalentActive(self.T_KINETIC_SHIELD) and self:isTalentActive(self.T_THERMAL_SHIELD) then + if self:isTalentActive(self.T_KINETIC_SHIELD) and self:isTalentActive(self.T_THERMAL_SHIELD) and not self:attr("psionic_shield_override") then if not silent then game.logSeen(self, "You may only sustain two shields at once. Shield activation cancelled.") end return false end diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua index f49de2deff2d84ae4de0cc9c43ec1e8b504429ad..671d34e15827e516f361e2825ccb3afc8837c258 100644 --- a/game/modules/tome/data/timed_effects/physical.lua +++ b/game/modules/tome/data/timed_effects/physical.lua @@ -1838,7 +1838,7 @@ newEffect{ game:delayedLogMessage(self, src, "block_heal", "#CRIMSON##Source# heals from blocking with %s shield!", string.his_her(self)) end if eff.properties.ref and src.life then DamageType.defaultProjector(src, src.x, src.y, type, blocked, tmp, true) end - if (self:knowTalent(self.T_RIPOSTE) or amt == 0) and src.life then src:setEffect(src.EFF_COUNTERSTRIKE, (1 + dur_inc) * (src.global_speed or 1), {power=eff.power, no_ct_effect=true, src=self, crit_inc=crit_inc, nb=nb}) end -- specify duration here to avoid stacking for high speed attackers + if (self:knowTalent(self.T_RIPOSTE) or amt == 0) and src.life then src:setEffect(src.EFF_COUNTERSTRIKE, (1 + dur_inc) * (src.global_speed or 1), {power=eff.power, no_ct_effect=true, src=self, crit_inc=crit_inc, nb=nb}) if eff.properties.sb then if src:canBe("disarm") then src:setEffect(src.EFF_DISARMED, 3, {apply_power=self:combatPhysicalpower()}) else game.logSeen(target, "%s resists the disarming attempt!", src.name:capitalize()) end end end-- specify duration here to avoid stacking for high speed attackers return amt end, activate = function(self, eff) @@ -2011,7 +2011,7 @@ newEffect{ newEffect{ name = "DISABLE", image = "talents/cripple.png", desc = "Disable", - long_desc = function(self, eff) return ("The target is disabled, reducing movement speed by %d%% and physical power by %d."):format(eff.speed * 100, eff.atk) end, + long_desc = function(self, eff) return ("The target is disabled, reducing movement speed by %d%% and accuracy by %d."):format(eff.speed * 100, eff.atk) end, type = "physical", subtype = { wound=true }, status = "detrimental", @@ -2308,3 +2308,4 @@ newEffect{ self:incEquilibrium(-eff.power) end, } + diff --git a/game/modules/tome/data/zones/rak-shor-pride/npcs.lua b/game/modules/tome/data/zones/rak-shor-pride/npcs.lua index 84625373d2fc319e27cfe05d76927f03d8e2dd50..96475482bce404d35656afbafc3efbcf2e73757c 100644 --- a/game/modules/tome/data/zones/rak-shor-pride/npcs.lua +++ b/game/modules/tome/data/zones/rak-shor-pride/npcs.lua @@ -110,7 +110,7 @@ newEntity{ base = "BASE_NPC_GHOUL", define_as = "ROTTING_TITAN", resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_ghoul_rotting_titan.png", display_h=2, display_y=-1}}}, desc = [[This gigantic mass of flesh and stone moves slowly, the ground rumbling with each step it takes. Its body seems to constantly pulsate and reform. Massive stones at the end of each limb form massive blunt weapons.]], level_range = {45, nil}, exp_worth = 2, - rarity = 40, + rarity = 28, max_life = resolvers.rngavg(150,200), life_rating = 40, combat_armor = 40, combat_def = 10, ai_state = { talent_in=2 }, @@ -138,15 +138,17 @@ newEntity{ base = "BASE_NPC_GHOUL", define_as = "ROTTING_TITAN", combat_atk=40, combat_spellpower=25, + inc_damage = { [DamageType.PHYSICAL] = 15 }, + disarm_immune=1, --Since disarming him would be, well, DISARMING him. on_move = function(self) - if rng.percent(20) then - game.logSeen(self, "The ground shakes as %s steps!", self.name:capitalize()) - local tg = {type="ball", range=0, selffire=false, radius=3, no_restrict=true} - local DamageType = require "engine.DamageType" - self:project(tg, self.x, self.y, DamageType.PHYSKNOCKBACK, {dam=24, dist=1}) - self:doQuake(tg, self.x, self.y) + if rng.percent(35) then + game.logSeen(self, "The ground shakes as %s steps!", self.name:capitalize()) + local tg = {type="ball", range=0, selffire=false, radius=4, no_restrict=true} + local DamageType = require "engine.DamageType" + --self:project(tg, self.x, self.y, DamageType.PHYSKNOCKBACK, {dam=24, dist=5}) + self:doQuake(tg, self.x, self.y) end self:project({type="ball", range=0, selffire=false, radius=1}, self.x, self.y, engine.DamageType.DIG, 1) end, @@ -180,7 +182,7 @@ newEntity{ base = "BASE_NPC_GHOST", define_as = "GLACIAL_LEGION", resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_ghost_glacial_legion.png", display_h=2, display_y=-1}}}, desc = [[A massive, shifting, ethereal form floats in the air around an orb of frozen blood. Vapor pools on the floor beneath it.]], level_range = {45, nil}, exp_worth = 2, - rarity = 40, + rarity = 28, size_category=5, rank = 3.5, max_life = resolvers.rngavg(90,100), life_rating = 18, @@ -188,34 +190,36 @@ newEntity{ base = "BASE_NPC_GHOST", define_as = "GLACIAL_LEGION", ai = "tactical", ai_state = { talent_in=1, }, ai_tactic = resolvers.tactic"ranged", stats = { str=13, dex=15, mag=45, con=14 }, - combat_spellpower=40, + combat_spellpower = 100, resists = {all = -10, [DamageType.FIRE] = -100, [DamageType.LIGHT] = 30, [DamageType.COLD] = 100}, combat_armor = 0, combat_def = resolvers.mbonus(10, 10), --stealth = resolvers.mbonus(40, 10), - combat = { dam=50, atk=50, apr=100, dammod={mag=1.1} }, + combat = { dam=50, atk=90, apr=100, dammod={mag=1.1} }, melee_project = {[DamageType.COLD]=resolvers.mbonus(15, 25)}, on_melee_hit = {[DamageType.COLD]=resolvers.mbonus(15, 5)}, + + inc_damage = { [DamageType.COLD] = 25 }, on_move = function(self) - local DamageType = require "engine.DamageType" - local duration = 7 - local radius = 0 - local dam = 25 - -- Add a lasting map effect - game.level.map:addEffect(self, - self.x, self.y, duration, - engine.DamageType.ICE, 25, - radius, - 5, nil, - engine.Entity.new{alpha=100, display='', color_br=30, color_bg=60, color_bb=200}, - function(e) - e.radius = e.radius - return true - end, - false - ) + local DamageType = require "engine.DamageType" + local duration = 9 + local radius = 0 + local dam = 100 + -- Add a lasting map effect + game.level.map:addEffect(self, + self.x, self.y, duration, + engine.DamageType.ICE, dam, + radius, + 5, nil, + engine.Entity.new{alpha=100, display='', color_br=30, color_bg=60, color_bb=200}, + function(e) + e.radius = e.radius + return true + end, + false + ) end, resolvers.talents{ @@ -223,13 +227,12 @@ newEntity{ base = "BASE_NPC_GHOST", define_as = "GLACIAL_LEGION", [Talents.T_FREEZE]={base=5, every=4, max=10}, [Talents.T_ICE_STORM]={base=4, every=6, max=8}, [Talents.T_ICE_SHARDS]={base=5, every=5, max=9}, - [Talents.T_ARCANE_POWER]={base=4, every=3, max = 11}, [Talents.T_SHATTER]={base=3, every=6, max=8}, [Talents.T_UTTERCOLD]={base=3, every=7, max = 5}, [Talents.T_FROZEN_GROUND]={base=4, every=6, max = 6}, [Talents.T_CHILL_OF_THE_TOMB]={base=5, every=5, max=10}, [Talents.T_SPELLCRAFT]={base=3, every=7, max=8}, - [Talents.T_MANAFLOW]={base=5, every=4, max = 12}, + --[Talents.T_MANAFLOW]={base=5, every=4, max = 12}, [Talents.T_FROST_HANDS]={base=3, every=7, max=8}, }, resolvers.drops{chance=100, nb=3, {tome_drops="boss"} }, @@ -243,7 +246,7 @@ newEntity{ base = "BASE_NPC_BONE_GIANT", define_as = "HEAVY_SENTINEL", desc = [[A towering creature, made from the bones of countless bodies. An aura of flame bellows from within its chest.]], resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_giant_heavy_sentinel.png", display_h=2, display_y=-1}}}, level_range = {45, nil}, exp_worth = 2, - rarity = 40, + rarity = 28, rank = 3.5, ai = "tactical", size=5, @@ -251,12 +254,12 @@ newEntity{ base = "BASE_NPC_BONE_GIANT", define_as = "HEAVY_SENTINEL", combat_armor = 20, combat_def = 35, life_rating = 28, - combat_atk=30, - combat_spellpower=15, + combat_atk = 60, + combat_spellpower=35, stats = { str=28, dex=60, mag=20, con=20 }, - combat = { dam=resolvers.levelup(60, 1, 2), atk=resolvers.levelup(70, 1, 1), apr=20, dammod={str=1.2}, damtype=engine.DamageType.FIRE, convert_damage={[engine.DamageType.PHYSICAL]=50}}, + combat = { dam=resolvers.levelup(60, 1, 2), atk=resolvers.levelup(110, 1, 1), apr=20, dammod={str=1.2}, damtype=engine.DamageType.FIRE, convert_damage={[engine.DamageType.PHYSICAL]=50}}, melee_project = {[DamageType.FIRE]=resolvers.mbonus(15, 25)}, on_melee_hit = {[DamageType.FIRE]=resolvers.mbonus(15, 5)}, @@ -268,12 +271,10 @@ newEntity{ base = "BASE_NPC_BONE_GIANT", define_as = "HEAVY_SENTINEL", [Talents.T_SKELETON_REASSEMBLE]=5, [Talents.T_ARCANE_POWER]={base=3, every=3, max = 6}, [Talents.T_FLAME]={base=3, every=4, max = 8}, - [Talents.T_FLAMESHOCK]={base=2, every=6, max = 7}, - [Talents.T_MANAFLOW]={base=5, every=5, max = 10}, + [Talents.T_FLAMESHOCK]={base=3, every=6, max = 7}, [Talents.T_INFERNO]={base=2, every=5, max = 6}, [Talents.T_BURNING_WAKE]={base=1, every=4, max = 5}, [Talents.T_WILDFIRE]={base=3, every=7, max=5}, - --[Talents.T_GOLEM_MOLTEN_SKIN]={base=3, every=6, max=6}, [Talents.T_CLEANSING_FLAMES]={base=2, every=6, max = 5}, [Talents.T_ARCANE_COMBAT]=3, [Talents.T_SPELLCRAFT]={base=3, every=7, max=7}, @@ -291,20 +292,25 @@ newEntity{ base = "BASE_NPC_VAMPIRE", unique=true, define_as="ARCH_ZEPHYR", resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_vampire_arch_zephyr.png", display_h=2, display_y=-1}}}, desc=[[The robes of this ancient vampire billow with intense winds. Bolts of lightning arc along its body. In its hand it holds a bow, electricity streaking across it.]], level_range = {45, nil}, exp_worth = 1, - rarity = 40, + rarity = 28, autolevel="warriormage", stats = { str=24, dex=40, mag=24, con=20 }, max_life = resolvers.rngavg(100,120), life_rating=25, combat_armor = 15, combat_def = 15, rank = 3.5, - mana_regen=6, + mana_regen = 20, --Maintain Thunderstorm + + body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1, QUIVER=1 }, - movement_speed=1.5, + movement_speed=1.75, - combat_atk = 40, - combat_spellpower = 40, + combat_atk = 120, + combat_spellpower = 60, + + ranged_project = {[DamageType.LIGHTNING] = resolvers.mbonus(30, 30)}, - ai = "tactical", ai_state = { talent_in=4, }, + ai = "tactical", ai_state = { talent_in=3, }, + ai_tactic = resolvers.tactic"ranged", resolvers.equip{ {type="weapon", subtype="longbow", defined="STORM_FURY", random_art_replace={chance=50}, autoreq=true, force_drop=true}, {type="ammo", subtype="arrow", autoreq=true} }, resists = { [DamageType.LIGHTNING] = 100, [DamageType.PHYSICAL] = -20, [DamageType.LIGHT] = 30, }, @@ -322,7 +328,7 @@ newEntity{ base = "BASE_NPC_VAMPIRE", unique=true, define_as="ARCH_ZEPHYR", [Talents.T_SHOOT]=1, -- If possible, add talent that lets it temporarily fire lightning instead of arrows. [Talents.T_RELOAD]=1, - [Talents.T_BOW_MASTERY]={base=3, every=10}, + [Talents.T_BOW_MASTERY]={base=4, every=10}, [Talents.T_DUAL_ARROWS]={base=3, every=6, max=8}, [Talents.T_PINNING_SHOT]={base=2, every=6, max=4}, [Talents.T_CRIPPLING_SHOT]={base=2, every=6, max=7}, @@ -339,18 +345,23 @@ newEntity{ base = "BASE_NPC_WIGHT", desc=[[Intense Arcane energy whirls in the air around this ethereal form. ]], level_range = {45, nil}, exp_worth = 2, life_rating=16, - rarity = 40, + rarity = 28, rank = 3.5, max_life = resolvers.rngavg(200,300), max_mana = resolvers.rngavg(800,1200), - mana_regen = 5, + mana_regen = 100, --RAW ARCANE POWER combat_armor = 12, combat_def = 30, combat_atk=30, + combat_spellpower = resolvers.mbonus(90, 30), - combat = { dam=resolvers.mbonus(40, 20), atk=20, apr=15, damtype=DamageType.ARCANE }, + arcane_cooldown_divide = 4, --Aether Avatar ++ + inc_damage = { [DamageType.ARCANE] = 30 }, - resists = { [DamageType.COLD] = 30, [DamageType.FIRE] = 30, [DamageType.LIGHTNING] = 30, [DamageType.PHYSICAL] = 0, [DamageType.LIGHT] = 0, [DamageType.ARCANE] = 100}, + combat = { dam=resolvers.mbonus(40, 20), atk=20, apr=15, damtype=DamageType.ARCANE }, + + resists = { [DamageType.COLD] = 30, [DamageType.FIRE] = 30, [DamageType.LIGHTNING] = 30, [DamageType.PHYSICAL] = 0, [DamageType.LIGHT] = 0, [DamageType.ARCANE] = 100}, ai = "tactical", + ai_tactic = resolvers.tactic"ranged", resolvers.talents{ [Talents.T_FLAMESHOCK]={base=3, every=5, max=7}, [Talents.T_LIGHTNING]={base=4, every=5, max=8}, [Talents.T_GLACIAL_VAPOUR]={base=3, every=5, max=7}, [Talents.T_STRIKE]={base=3, every=5, max=7}, [Talents.T_ARCANE_POWER]={base=6, every=2, max=12}, [Talents.T_MANATHRUST]={base=6, every=4, max=10}, @@ -358,9 +369,9 @@ newEntity{ base = "BASE_NPC_WIGHT", [Talents.T_SPELLCRAFT]=5, [Talents.T_AETHER_BEAM]={base=6, every=7, max=9}, [Talents.T_AETHER_BREACH]={base=3, every=6, max=6}, - [Talents.T_HEAL]={base=2, every=6, max=6}, + [Talents.T_HEAL]={base=3, every=6, max=6}, [Talents.T_SHIELDING]={base=3, every=6, max=6}, - [Talents.T_ARCANE_SHIELD]={base=2, every=5, max=5}, + [Talents.T_ARCANE_SHIELD]={base=3, every=5, max=5}, [Talents.T_PURE_AETHER]={base=3, every=7, max=5}, [Talents.T_PHASE_DOOR]=10, },