Commit a784489c5d957fb29e7c7bd9bc41e6be769e0830

Authored by DarkGod
1 parent 17dcdf80

Many new artifacts

... ... @@ -653,6 +653,10 @@ function _M:getTextualDesc(compare_with, use_actor)
653 653 elseif found then
654 654 desc:add({"color","RED"}, "When used from stealth a simple attack with it will not break stealth.", {"color","LAST"}, true)
655 655 end
  656 +
  657 + if combat.crushing_blow then
  658 + 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)
  659 + end
656 660
657 661 compare_fields(combat, compare_with, field, "travel_speed", "%+d%%", "Travel speed: ", 100, false, false, add_table)
658 662
... ... @@ -969,6 +973,7 @@ function _M:getTextualDesc(compare_with, use_actor)
969 973 end
970 974
971 975 compare_fields(w, compare_with, field, "combat_critical_power", "%+.2f%%", "Critical mult.: ")
  976 + compare_fields(w, compare_with, field, "ignore_direct_crits", "%-.2f%%", "Reduces incoming crit damage: ")
972 977 compare_fields(w, compare_with, field, "combat_crit_reduction", "%-d%%", "Reduces opponents crit chance: ")
973 978
974 979 compare_fields(w, compare_with, field, "disarm_bonus", "%+d", "Trap disarming bonus: ")
... ... @@ -1067,6 +1072,7 @@ function _M:getTextualDesc(compare_with, use_actor)
1067 1072
1068 1073 compare_fields(w, compare_with, field, "projectile_evasion", "%+d%%", "Deflect projectiles away: ")
1069 1074 compare_fields(w, compare_with, field, "evasion", "%+d%%", "Chance to avoid attacks: ")
  1075 + compare_fields(w, compare_with, field, "cancel_damage_chance", "%+d%%", "Chance to avoid any damage: ")
1070 1076
1071 1077 compare_fields(w, compare_with, field, "defense_on_teleport", "%+d", "Defense after a teleport: ")
1072 1078 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)
1081 1087
1082 1088 compare_fields(w, compare_with, field, "shield_dur", "%+d", "Damage Shield Duration: ")
1083 1089 compare_fields(w, compare_with, field, "shield_factor", "%+d%%", "Damage Shield Power: ")
  1090 +
  1091 + compare_fields(w, compare_with, field, "iceblock_pierce", "%+d%%", "Ice block penetration: ")
1084 1092
1085 1093 compare_fields(w, compare_with, field, "slow_projectiles", "%+d%%", "Slows Projectiles: ")
1086 1094
1087 1095 compare_fields(w, compare_with, field, "paradox_reduce_fails", "%+d", "Reduces paradox failures(equivalent to willpower): ")
1088 1096
1089 1097 compare_fields(w, compare_with, field, "damage_backfire", "%+d%%", "Damage Backlash: ", nil, true)
  1098 +
  1099 + compare_fields(w, compare_with, field, "resist_unseen", "%-d%%", "Reduce all damage from unseen attackers: ")
1090 1100
1091 1101 if w.undead then
1092 1102 desc:add("The wearer is treated as an undead.", true)
... ... @@ -1105,11 +1115,11 @@ function _M:getTextualDesc(compare_with, use_actor)
1105 1115 end
1106 1116
1107 1117 if w.blind_fight then
1108   - desc:add({"color", "YELLOW"}, "Blind-Fight:", {"color", "LAST"}, "This item allows the wearer to attack unseen targets without any penalties.", true)
  1118 + desc:add({"color", "YELLOW"}, "Blind-Fight: ", {"color", "LAST"}, "This item allows the wearer to attack unseen targets without any penalties.", true)
1109 1119 end
1110 1120
1111 1121 if w.lucid_dreamer then
1112   - desc:add({"color", "YELLOW"}, "Lucid-Dreamer:", {"color", "LAST"}, "This item allows the wearer to act while sleeping.", true)
  1122 + desc:add({"color", "YELLOW"}, "Lucid Dreamer: ", {"color", "LAST"}, "This item allows the wearer to act while sleeping.", true)
1113 1123 end
1114 1124
1115 1125 if w.no_breath then
... ...
... ... @@ -468,6 +468,8 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
468 468
469 469 local oldproj = DamageType:getProjectingFor(self)
470 470 if self.__talent_running then DamageType:projectingFor(self, {project_type={talent=self.__talent_running}}) end
  471 +
  472 + if weapon and weapon.crushing_blow then self:attr("crushing_blow", 1) end
471 473
472 474 -- Damage conversion?
473 475 -- Reduces base damage but converts it into another damage type
... ... @@ -491,6 +493,8 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
491 493 if dam > 0 then
492 494 DamageType:get(damtype).projector(self, target.x, target.y, damtype, math.max(0, dam))
493 495 end
  496 +
  497 + if weapon and weapon.crushing_blow then self:attr("crushing_blow", -1) end
494 498
495 499 if self.__talent_running then DamageType:projectingFor(self, oldproj) end
496 500
... ... @@ -752,15 +756,15 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
752 756
753 757 -- Special effect
754 758 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
755   - weapon.special_on_hit.fct(weapon, self, target)
  759 + weapon.special_on_hit.fct(weapon, self, target, dam)
756 760 end
757 761
758 762 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
759   - weapon.special_on_crit.fct(weapon, self, target)
  763 + weapon.special_on_crit.fct(weapon, self, target, dam)
760 764 end
761 765
762 766 if hitted and weapon and weapon.special_on_kill and weapon.special_on_kill.fct and target.dead then
763   - weapon.special_on_kill.fct(weapon, self, target)
  767 + weapon.special_on_kill.fct(weapon, self, target, dam)
764 768 end
765 769
766 770 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
... ...
... ... @@ -337,6 +337,16 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
337 337 local def = src.tempeffect_def[src.EFF_CURSE_OF_MISFORTUNE]
338 338 dam = def.doUnfortunateEnd(src, eff, target, dam)
339 339 end
  340 +
  341 + if src:attr("crushing_blow") and (dam * (1.25 + (src.combat_critical_power or 0)/200)) > target.life then
  342 + dam = dam * (1.25 + (src.combat_critical_power or 0)/200)
  343 + game.logPlayer(src, "You end your target with a crushing blow!")
  344 + end
  345 +
  346 + if target:attr("resist_unseen") and not target:canSee(src) then
  347 + dam = dam * (1 - math.min(target.resist_unseen,100)/100)
  348 + end
  349 +
340 350 -- Sanctuary: reduces damage if it comes from outside of Gloom
341 351 if target.isTalentActive and target:isTalentActive(target.T_GLOOM) and target:knowTalent(target.T_SANCTUARY) then
342 352 if tmp and tmp.sanctuaryDamageChange then
... ... @@ -985,6 +995,7 @@ newDamageType{
985 995 newDamageType{
986 996 name = "flameshock", type = "FLAMESHOCK",
987 997 projector = function(src, x, y, type, dam)
  998 + if _G.type(dam) == "number" then dam = {dam=dam, dur=4} end
988 999 local target = game.level.map(x, y, Map.ACTOR)
989 1000 if target then
990 1001 -- Set on fire!
... ... @@ -1096,7 +1107,7 @@ newDamageType{
1096 1107
1097 1108 -- Light damage + blind chance
1098 1109 newDamageType{
1099   - name = "blinding light", type = "LIGHT_BLIND",
  1110 + name = "blinding light", type = "LIGHT_BLIND", text_color = "#YELLOW#",
1100 1111 projector = function(src, x, y, type, dam)
1101 1112 local realdam = DamageType:get(DamageType.LIGHT).projector(src, x, y, DamageType.LIGHT, dam)
1102 1113 local target = game.level.map(x, y, Map.ACTOR)
... ... @@ -1113,7 +1124,7 @@ newDamageType{
1113 1124
1114 1125 -- Lightning damage + daze chance
1115 1126 newDamageType{
1116   - name = "lightning", type = "LIGHTNING_DAZE", text_color = "#ROYAL_BLUE#",
  1127 + name = "dazing lightning", type = "LIGHTNING_DAZE", text_color = "#ROYAL_BLUE#",
1117 1128 projector = function(src, x, y, type, dam)
1118 1129 if _G.type(dam) == "number" then dam = {dam=dam, daze=25} end
1119 1130 dam.daze = dam.daze or 25
... ... @@ -1564,7 +1575,7 @@ newDamageType{
1564 1575 }
1565 1576
1566 1577 newDamageType{
1567   - name = "gloom", type = "RANDOM_GLOOM",
  1578 + name = "% chance of gloom effects", type = "RANDOM_GLOOM",
1568 1579 projector = function(src, x, y, type, dam)
1569 1580 local target = game.level.map(x, y, Map.ACTOR)
1570 1581 if target and rng.percent(dam) then
... ... @@ -1674,7 +1685,7 @@ newDamageType{
1674 1685
1675 1686 -- Drain Vim
1676 1687 newDamageType{
1677   - name = "enervating blight", type = "DRAIN_VIM",
  1688 + name = "vim draining blight", type = "DRAIN_VIM", text_color = "#DARK_GREEN#",
1678 1689 projector = function(src, x, y, type, dam)
1679 1690 if _G.type(dam) == "number" then dam = {dam=dam, vim=0.2} end
1680 1691 local target = game.level.map(x, y, Map.ACTOR)
... ... @@ -1821,7 +1832,7 @@ newDamageType{
1821 1832
1822 1833 -- blood boiled, blight damage + slow
1823 1834 newDamageType{
1824   - name = "hindering_blight", type = "BLOOD_BOIL",
  1835 + name = "hindering blight", type = "BLOOD_BOIL", text_color = "#DARK_GREEN#",
1825 1836 projector = function(src, x, y, type, dam)
1826 1837 DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam)
1827 1838 local target = game.level.map(x, y, Map.ACTOR)
... ... @@ -2729,7 +2740,7 @@ newDamageType{
2729 2740
2730 2741 -- Acid damage + Slow
2731 2742 newDamageType{
2732   - name = "cautic mire", type = "CAUSTIC_MIRE",
  2743 + name = "caustic mire", type = "CAUSTIC_MIRE",
2733 2744 projector = function(src, x, y, type, dam, tmp)
2734 2745 if _G.type(dam) == "number" then dam = {dur = 2, slow=20} end
2735 2746 local target = game.level.map(x, y, Map.ACTOR)
... ...
... ... @@ -48,7 +48,7 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD",
48 48 desc ="This putrid mass of rotting flesh shifts and quivers, but shows no signs of intelligence or mobility.",
49 49 resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_horror_necrotic_mass.png", display_h=2, display_y=-1}}},
50 50 level_range = {15, nil}, exp_worth = 1,
51   - rarity = 3,
  51 + rarity = 4,
52 52 rank = 1,
53 53 size_category = 2, life_rating = 7,
54 54 combat_armor = 0, combat_def = 0,
... ... @@ -63,17 +63,17 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD",
63 63 desc ="This monstrous form of putrid, torn flesh and chipped bone drags its mass towards you, spurting blood and viscera along the way.",
64 64 resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_horror_necrotic_abomination.png", display_h=2, display_y=-1}}},
65 65 level_range = {30, nil}, exp_worth = 1,
66   - rarity = 8,
  66 + rarity = 7,
67 67 rank = 3,
68 68 size_category = 4,
69 69 combat_armor = 0, combat_def = 40,
70   - max_life=400,
  70 + max_life=400, life_rating=11,
71 71 disease_immune = 1,
72 72
73 73 combat = {
74 74 dam=resolvers.levelup(resolvers.rngavg(40,45), 1, 1.2),
75 75 atk=resolvers.rngavg(60,80), apr=20,
76   - dammod={mag=1.2}, physcrit = 10,
  76 + dammod={mag=1.3}, physcrit = 10,
77 77 damtype=engine.DamageType.BLIGHT,
78 78 },
79 79
... ... @@ -106,7 +106,7 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD",
106 106 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.",
107 107 resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_horror_bone_horror.png", display_h=2, display_y=-1}}},
108 108 level_range = {30, nil}, exp_worth = 1,
109   - rarity = 8,
  109 + rarity = 7,
110 110 rank = 3,
111 111 size_category = 4,
112 112 combat_armor = 30, combat_def = 0,
... ... @@ -124,7 +124,7 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD",
124 124 autolevel = "warriormage",
125 125
126 126 summon = {
127   - {type="undead", subtype = "skeleton", number=4, hasxp=false},
  127 + {type="undead", subtype = "skeleton", number=5, hasxp=false},
128 128 },
129 129
130 130 resolvers.talents{
... ... @@ -151,13 +151,15 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD",
151 151 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.",
152 152 resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_horror_sanguine_horror.png", display_h=2, display_y=-1}}},
153 153 level_range = {30, nil}, exp_worth = 1,
154   - rarity = 8,
155   - rank = 3,
  154 + rarity = 7,
  155 + rank = 3, life_rating = 13,
156 156 size_category = 4,
157 157 combat_armor = 30, combat_def = 0,
158 158 max_life=400,
159 159 stats = { con=50, },
160 160
  161 + lifesteal=15,
  162 +
161 163 combat = {
162 164 dam=resolvers.levelup(resolvers.rngavg(50,60), 1, 1.2),
163 165 atk=resolvers.rngavg(60,80), apr=20,
... ... @@ -197,5 +199,5 @@ newEntity{ base = "BASE_NPC_HORROR_UNDEAD",
197 199 size_category = 2, life_rating = 7,
198 200 combat_armor = 0, combat_def = 0,
199 201 max_life=100,
200   - combat = {dam=resolvers.levelup(resolvers.mbonus(25, 15), 1, 1.1), apr=0, atk=resolvers.mbonus(30, 15), dammod={str=0.6}},
  202 + 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,},
201 203 }
\ No newline at end of file
... ...
... ... @@ -921,6 +921,7 @@ newEntity{ base = "BASE_NPC_HORROR",
921 921 combat_armor = 30, combat_def = 18,
922 922 is_akgishil = true,
923 923 can_spawn = 1,
  924 + psionic_shield_override = 1,
924 925
925 926 resolvers.drops{chance=100, nb=1, {defined="BLADE_RIFT"} },
926 927
... ... @@ -982,7 +983,7 @@ newEntity{ base="BASE_NPC_HORROR", define_as = "ANIMATED_BLADE",
982 983 no_breath = 1,
983 984 size_category = 2,
984 985
985   - negative_status_immune = 1,
  986 + negative_status_effect_immune = 1,
986 987 body = { INVEN = 10, MAINHAND=1 },
987 988
988 989 resolvers.equip{
... ... @@ -1041,7 +1042,7 @@ newEntity{ base="BASE_NPC_HORROR", define_as = "DISTORTED_BLADE",
1041 1042 no_breath = 1,
1042 1043 size_category = 2,
1043 1044
1044   - negative_status_immune = 1,
  1045 + negative_status_effect_immune = 1,
1045 1046
1046 1047 body = { INVEN = 10, MAINHAND=1 },
1047 1048
... ...
... ... @@ -458,14 +458,12 @@ newEntity{ base = "BASE_GREATMAUL", define_as="ROTTING_MAUL",
458 458 dammod = {str=1.4},
459 459 convert_damage = {[DamageType.BLIGHT] = 20},
460 460 melee_project={[DamageType.CORRUPTED_BLOOD] = 30},
461   - special_on_hit = {desc="25% chance to damage nearby creatures", on_kill=1, fct=function(combat, who, target)
462   - if rng.percent(25) then
  461 + special_on_hit = {desc="Damage nearby creatures", on_kill=1, fct=function(combat, who, target)
463 462 local o, item, inven_id = who:findInAllInventoriesBy("define_as", "ROTTING_MAUL")
464   - local dam = rng.avg(1,2) * (70+ who:getStr() * 1.8)
465   - game.logSeen(who, "The ground shakes as the %s hits!", o:getName())
466   - local tg = {type="ball", range=0, selffire=false, radius=2, no_restrict=true}
467   - who:project(tg, target.x, target.y, engine.DamageType.PHYSICAL, dam)
468   - end
  463 + local dam = rng.avg(1,2) * (70+ who:getStr())
  464 + game.logSeen(who, "The ground shakes as the %s hits!", o:getName())
  465 + local tg = {type="ball", range=0, selffire=false, radius=2, no_restrict=true}
  466 + who:project(tg, target.x, target.y, engine.DamageType.PHYSICAL, dam)
469 467 end},
470 468 },
471 469 wielder = {
... ...
... ... @@ -291,9 +291,7 @@ newEntity{ base = "BASE_SHIELD",
291 291 rarity = 200,
292 292 cost = 20,
293 293 material_level = 2,
294   - rarity = false,
295 294 metallic = false,
296   -
297 295 special_combat = {
298 296 dam = resolvers.rngavg(20,30),
299 297 block = 60,
... ... @@ -318,22 +316,23 @@ newEntity{ base = "BASE_GEM",
318 316 power_source = {nature=true},
319 317 unique = true, define_as = "PETRIFIED_WOOD",
320 318 unided_name = "burned piece of wood",
321   - name = "Petrified Wood", subtype = "black",
  319 + name = "Petrified Wood", subtype = "red", --Visually black, but associate with fire, not acid
322 320 color = colors.WHITE, image = "object/artifact/petrified_wood.png",
323 321 level_range = {35, 45},
324 322 rarity = 280,
325   - identified = false,
326 323 desc = [[A piece of the scorched wood taken from the remains of Snaproot.]],
327   - rarity = false,
328 324 cost = 100,
329 325 material_level = 4,
  326 + identified = false,
330 327 imbue_powers = {
331 328 resists = { [DamageType.NATURE] = 25, [DamageType.DARKNESS] = 10, [DamageType.COLD] = 10 },
332 329 inc_stats = { [Stats.STAT_CON] = 25, },
  330 + ignore_direct_crits = 23,
333 331 },
334 332 wielder = {
335 333 resists = { [DamageType.NATURE] = 25, [DamageType.DARKNESS] = 10, [DamageType.COLD] = 10 },
336 334 inc_stats = { [Stats.STAT_CON] = 25, },
  335 + ignore_direct_crits = 23,
337 336 },
338 337 }
339 338
... ...
... ... @@ -114,7 +114,7 @@ newEntity{ base = "BASE_LONGSWORD", define_as = "RIFT_SWORD",
114 114 unided_name = "time-warped sword",
115 115 desc = [[The remnants of a damaged timeline, this blade shifts and fades at random.]],
116 116 level_range = {30, 50},
117   - rarity = nil, --Not random!
  117 + rarity = 220,
118 118 require = { stat = { str=44 }, },
119 119 cost = 300,
120 120 material_level = 4,
... ...
... ... @@ -315,21 +315,27 @@ newEntity{ base = "BASE_GEM",
315 315 quest = 1,
316 316 material_level = 5,
317 317 wielder = {
318   - inc_stats = {[Stats.STAT_CON] = 10, },
  318 + inc_stats = {[Stats.STAT_CON] = 15, },
319 319 healing_factor = 0.3,
320 320 life_regen = 2,
321 321 resists = {
322 322 [DamageType.BLIGHT] = 10,
323 323 },
  324 + damage_affinity = {
  325 + [DamageType.NATURE] = 15,
  326 + },
324 327 },
325 328 imbue_powers = {
326   - inc_stats = {[Stats.STAT_CON] = 10, },
  329 + inc_stats = {[Stats.STAT_CON] = 15, },
327 330 healing_factor = 0.3,
328 331 life_regen = 2,
329 332 stun_immune = 0.3,
330 333 resists = {
331 334 [DamageType.BLIGHT] = 10,
332 335 },
  336 + damage_affinity = {
  337 + [DamageType.NATURE] = 15,
  338 + },
333 339 },
334 340 }
335 341
... ...
... ... @@ -159,7 +159,7 @@ newEntity{ base = "BASE_GEM",
159 159 power_source = {arcane=true},
160 160 unique = true,
161 161 unided_name = "unearthly black stone",
162   - name = "Goedalath Rock", subtype = "black", image = "object/artifact/goedalath_rock.png",
  162 + name = "Goedalath Rock", subtype = "demonic", image = "object/artifact/goedalath_rock.png",
163 163 color = colors.PURPLE,
164 164 level_range = {42, 50},
165 165 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,
280 280 type = "undead", subtype = "blood",
281 281 display = "L",
282 282 name = "animated blood", color=colors.RED,
283   - resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_lich_blood_lich.png", display_h=1, display_y=0}}},
  283 + resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_horror_animated_blood.png", display_h=1, display_y=0}}},
284 284 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.",
285 285 body = { INVEN = 10, MAINHAND=1, OFFHAND=1, },
286 286 rank = 3,
... ...
... ... @@ -612,7 +612,6 @@ newEntity{ base = "BASE_WARAXE",
612 612 [DamageType.COLD] = 20,
613 613 },
614 614 iceblock_pierce=25,
615   - talent_on_hit = { [Talents.T_ICE_BREATH] = {level=2, chance=15} },
616 615 },
617 616 combat = {
618 617 dam = 33,
... ... @@ -622,6 +621,7 @@ newEntity{ base = "BASE_WARAXE",
622 621 convert_damage = {
623 622 [DamageType.ICE] = 50,
624 623 },
  624 + talent_on_hit = { [Talents.T_ICE_BREATH] = {level=2, chance=15} },
625 625 },
626 626 }
627 627
... ...
... ... @@ -50,15 +50,23 @@ newEntity{ base = "BASE_GEM",
50 50 movement_speed = 0.2,
51 51 },
52 52 imbue_powers = {
53   - inc_stats = {[Stats.STAT_DEX] = 10, [Stats.STAT_CUN] = 10 },
  53 + inc_stats = {[Stats.STAT_DEX] = 8, [Stats.STAT_CUN] = 8 },
54 54 inc_damage = {[DamageType.LIGHTNING] = 20 },
55   - cancel_damage_chance = 10, -- add to tooltip
  55 + cancel_damage_chance = 8,
56 56 damage_affinity={
57 57 [DamageType.LIGHTNING] = 20,
58 58 },
59   - movement_speed = 0.2,
  59 + movement_speed = 0.15,
  60 + },
  61 + wielder = {
  62 + inc_stats = {[Stats.STAT_DEX] = 8, [Stats.STAT_CUN] = 8 },
  63 + inc_damage = {[DamageType.LIGHTNING] = 20 },
  64 + cancel_damage_chance = 8,
  65 + damage_affinity={
  66 + [DamageType.LIGHTNING] = 20,
  67 + },
  68 + movement_speed = 0.15,
60 69 },
61   -
62 70 }
63 71
64 72 -- Low base values because you can stack affinity and resist
... ... @@ -3890,7 +3898,7 @@ newEntity{ base = "BASE_TOOL_MISC",
3890 3898 combat_mindpower=8,
3891 3899 },
3892 3900 max_power = 35, power_regen = 1,
3893   - use_power = { name = "call an antimagic pillar", power = 35,
  3901 + use_power = { name = "call an antimagic pillar, but silence yourself", power = 35,
3894 3902 use = function(self, who)
3895 3903 local x, y = util.findFreeGrid(who.x, who.y, 5, true, {[engine.Map.ACTOR]=true})
3896 3904 if not x then
... ... @@ -3908,10 +3916,11 @@ newEntity{ base = "BASE_TOOL_MISC",
3908 3916 blood_color = colors.GREEN,
3909 3917 display = "T", color=colors.GREEN,
3910 3918 life_rating=18,
  3919 + combat_dam = 40,
3911 3920 combat = {
3912 3921 dam=resolvers.rngavg(50,60),
3913 3922 atk=resolvers.rngavg(50,75), apr=25,
3914   - dammod={wil=1.1}, physcrit = 10,
  3923 + dammod={wil=1.2}, physcrit = 10,
3915 3924 damtype=engine.DamageType.SLIME,
3916 3925 },
3917 3926 level_range = {1, nil}, exp_worth = 0,
... ... @@ -3925,7 +3934,7 @@ newEntity{ base = "BASE_TOOL_MISC",
3925 3934 size_category = 5,
3926 3935 blind=1,
3927 3936 esp_all=1,
3928   - resists={[engine.DamageType.BLIGHT] = 40, [engine.DamageType.ARCANE] = 40, [engine.DamageType.NATURE] = 70},
  3937 + resists={all = 15, [engine.DamageType.BLIGHT] = 40, [engine.DamageType.ARCANE] = 40, [engine.DamageType.NATURE] = 70},
3929 3938 no_breath = 1,
3930 3939 cant_be_moved = 1,
3931 3940 stone_immune = 1,
... ... @@ -3937,10 +3946,10 @@ newEntity{ base = "BASE_TOOL_MISC",
3937 3946 stun_immune = 1,
3938 3947 blind_immune = 1,
3939 3948 cut_immune = 1,
3940   - knockback_resist,
  3949 + knockback_resist=1,
3941 3950 combat_mentalresist=50,
3942 3951 combat_spellresist=100,
3943   - 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,
  3952 + 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,
3944 3953 resolvers.talents{
3945 3954 [Talents.T_RESOLVE]={base=3, every=6},
3946 3955 [Talents.T_MANA_CLASH]={base=3, every=5},
... ... @@ -3963,6 +3972,7 @@ newEntity{ base = "BASE_TOOL_MISC",
3963 3972 title="Summon",
3964 3973 orders = {target=true, leash=true, anchor=true, talents=true},
3965 3974 })
  3975 + who:setEffect(who.EFF_SILENCED, 5, {})
3966 3976 return {id=true, used=true}
3967 3977 end
3968 3978 },
... ... @@ -5329,7 +5339,7 @@ newEntity{ base = "BASE_AMULET",
5329 5339 rarity = 220,
5330 5340 cost = 350,
5331 5341 material_level = 5,
5332   - 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,
  5342 + special_desc = function(self) return "Gives all your cold damage a 20% chance to freeze the target." end,
5333 5343 wielder = {
5334 5344 combat_spellpower=12,
5335 5345 inc_damage={
... ... @@ -5952,7 +5962,7 @@ newEntity{ base = "BASE_SHIELD",
5952 5962 special_desc = function(self) return "When you block an attack, there is a 30% chance of petrifying the attacker." end,
5953 5963 special_combat = {
5954 5964 dam = 40,
5955   - block = 100,
  5965 + block = 180,
5956 5966 physcrit = 5,
5957 5967 dammod = {str=1},
5958 5968 },
... ... @@ -6039,6 +6049,408 @@ newEntity{ base = "BASE_KNIFE", --Shibari's #1
6039 6049 quick_weapon_swap = 1,
6040 6050 },
6041 6051 }
  6052 +
  6053 +newEntity{ base = "BASE_KNIFE",
  6054 + power_source = {technique=true},
  6055 + unique = true,
  6056 + name = "Swordbreaker", image = "object/artifact/swordbreaker.png",
  6057 + unided_name = "hooked blade",
  6058 + 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.]],
  6059 + level_range = {20, 30},
  6060 + rarity = 250,
  6061 + require = { stat = { dex=10, cun=10 }, },
  6062 + cost = 300,
  6063 + material_level = 3,
  6064 + special_desc = function(self) return "Can block like a shield, potentially disarming the enemy." end,
  6065 + combat = {
  6066 + dam = 25,
  6067 + apr = 20,
  6068 + physcrit = 15,
  6069 + physspeed = 0.9,
  6070 + dammod = {dex=0.5,cun=0.5},
  6071 + special_on_crit = {desc="Breaks enemy weapon.", fct=function(combat, who, target)
  6072 + target:setEffect(target.EFF_SUNDER_ARMS, 5, {power=5+(who:combatPhysicalpower()*0.33), apply_power=who:combatPhysicalpower()})
  6073 + end},
  6074 + },
  6075 + wielder = {
  6076 + combat_def = 15,
  6077 + disarm_immune=0.5,
  6078 + combat_physresist = 15,
  6079 + inc_stats = {
  6080 + [Stats.STAT_DEX] = 8,
  6081 + [Stats.STAT_CUN] = 8,
  6082 + },
  6083 + combat_armor_hardiness = 20,
  6084 + learn_talent = { [Talents.T_DAGGER_BLOCK] = 1, },
  6085 + },
  6086 +}
  6087 +
  6088 +newEntity{ base = "BASE_SHIELD",
  6089 + power_source = {arcane=true},
  6090 + unique = true,
  6091 + name = "Shieldsmaiden", image = "object/artifact/shieldmaiden.png",
  6092 + unided_name = "icy shield",
  6093 + 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."]],
  6094 + color = colors.BROWN,
  6095 + level_range = {36, 48},
  6096 + rarity = 270,
  6097 + require = { stat = { str=28 }, },
  6098 + cost = 400,
  6099 + material_level = 5,
  6100 + metallic = false,
  6101 + special_desc = function(self) return "Granted talent can block up to 1 instance of damage each 10 turns." end,
  6102 + special_combat = {
  6103 + dam = 48,
  6104 + block = 150,
  6105 + physcrit = 8,
  6106 + dammod = {str=1},
  6107 + damtype = DamageType.ICE,
  6108 + talent_on_hit = { [Talents.T_ICE_SHARDS] = {level=3, chance=15} },
  6109 + },
  6110 + wielder = {
  6111 + combat_armor = 20,
  6112 + combat_def = 5,
  6113 + combat_def_ranged = 12,
  6114 + fatigue = 10,
  6115 + learn_talent = { [Talents.T_BLOCK] = 4, [Talents.T_SHIELDSMAIDEN_AURA] = 1, },
  6116 + resists = { [DamageType.COLD] = 25, [DamageType.FIRE] = 25,},
  6117 + },
  6118 +}
  6119 +
  6120 +-- Thanks to Naghyal's Beholder code for the basic socket skeleton
  6121 +newEntity{ base = "BASE_GREATMAUL",
  6122 + power_source = {arcane=true}, -- Should really make this only arcane for some gems
  6123 + unique = true,
  6124 + color = colors.BLUE,
  6125 + name = "Tirakai's Maul",
  6126 + 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.]],
  6127 + gemDesc = "None", -- Defined by the elemental properties and used by special_desc
  6128 + special_desc = function(self)
  6129 + -- You'll want to color this and such
  6130 + if not self.Gem then return ("No gem") end
  6131 + return ("%s: %s"):format(self.Gem.name:capitalize(), self.gemDesc or ("Write a description for this gem's properties!"))
  6132 + end,
  6133 + cost = 1000,
  6134 + material_level = 1, -- Changes to gem material level on socket
  6135 + evel_range = {1, 15},
  6136 + rarity = 280,
  6137 + combat = {
  6138 + dam = 10,
  6139 + apr = 7,
  6140 + physcrit = 4,
  6141 + damrange=1.3,
  6142 + dammod = {str=1.2},
  6143 + },
  6144 + max_power = 1, power_regen = 1,
  6145 + use_power = { name = "imbue the hammer with a gem of your choice", power = 0,
  6146 + use = function(self, who)
  6147 + local DamageType = require "engine.DamageType"
  6148 + local Stats = require "engine.interface.ActorStats"
  6149 + local d
  6150 + d = who:showInventory("Use which gem?", who:getInven("INVEN"), function(gem) return gem.type == "gem" and gem.imbue_powers and gem.material_level end,
  6151 + function(gem, gem_item)
  6152 + who:onTakeoff(self)
  6153 + local name_old=self.name
  6154 + local old_hotkey
  6155 + for i, v in pairs(who.hotkey) do
  6156 + if v[2]==name_old then
  6157 + old_hotkey=i
  6158 + end
  6159 + end
  6160 +
  6161 + -- Recycle the old gem
  6162 + local old_gem=self.Gem
  6163 + if old_gem then
  6164 + who:addObject(who:getInven("INVEN"), old_gem)
  6165 + game.logPlayer(who, "You remove your %s.", old_gem:getName{do_colour=true, no_count=true})
  6166 + end
  6167 +
  6168 + if gem then
  6169 +
  6170 + -- 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.
  6171 + self.Gem = nil
  6172 + self.Gem = gem
  6173 + self.gemDesc = "Describe all the goddamn colors. NOW."
  6174 +
  6175 + self.sentient = false
  6176 + self.act = mod.class.Object.act
  6177 +
  6178 + self.talent_on_spell = nil
  6179 +
  6180 + self.material_level=gem.material_level
  6181 + local scalingFactor = self.material_level
  6182 +
  6183 + self.combat = {
  6184 + dam = (14 * scalingFactor),
  6185 + apr = (3 * scalingFactor),
  6186 + physcrit = (2.5 * scalingFactor),
  6187 + dammod = {str=1.2},
  6188 + damrange = 1.3,
  6189 + }
  6190 +
  6191 + self.wielder = {
  6192 + inc_stats = {[Stats.STAT_MAG] = (2 * scalingFactor), [Stats.STAT_CUN] = (2 * scalingFactor), [Stats.STAT_DEX] = (2 * scalingFactor),},
  6193 + }
  6194 +
  6195 + who:removeObject(who:getInven("INVEN"), gem_item)
  6196 +
  6197 + -- Each element merges its effect into the combat/wielder tables (or anything else) after the base stats are scaled
  6198 + -- You can modify damage and such here too but you should probably make static tables instead of merging
  6199 + if gem.subtype =="black" then -- Acid
  6200 + self.combat.damtype = DamageType.ACID
  6201 + table.mergeAdd(self.wielder, {inc_damage = { [DamageType.ACID] = 4 * scalingFactor} }, true)
  6202 +
  6203 + self.combat.burst_on_crit = {[DamageType.ACID_DISARM] = 12 * scalingFactor,}
  6204 + self.gemDesc = "Acid"
  6205 + end
  6206 + if gem.subtype =="blue" then -- Lightning
  6207 + self.combat.damtype = DamageType.LIGHTNING
  6208 + table.mergeAdd(self.wielder, {
  6209 + inc_damage = { [DamageType.LIGHTNING] = 4 * scalingFactor}
  6210 +
  6211 + }, true)
  6212 + self.combat.burst_on_crit = {[DamageType.LIGHTNING_DAZE] = 12 * scalingFactor,}
  6213 + self.gemDesc = "Lightning"
  6214 + end
  6215 + if gem.subtype =="green" then -- Nature
  6216 + self.combat.damtype = DamageType.NATURE
  6217 + table.mergeAdd(self.wielder, {
  6218 + inc_damage = { [DamageType.NATURE] = 4 * scalingFactor}
  6219 +
  6220 + }, true)
  6221 + self.combat.burst_on_crit = {[DamageType.SPYDRIC_POISON] = 12 * scalingFactor,}
  6222 + self.gemDesc = "Nature"
  6223 + end
  6224 + if gem.subtype =="red" then -- Fire
  6225 + self.combat.damtype = DamageType.FIRE
  6226 + table.mergeAdd(self.wielder, {
  6227 + inc_damage = { [DamageType.FIRE] = 4 * scalingFactor},
  6228 + }, true)
  6229 + self.combat.burst_on_crit = {[DamageType.FLAMESHOCK] = 12 * scalingFactor,}
  6230 + self.gemDesc = "Fire"
  6231 + end
  6232 + if gem.subtype =="violet" then -- Arcane
  6233 + self.combat.damtype = DamageType.ARCANE
  6234 + table.mergeAdd(self.wielder, {
  6235 + inc_damage = { [DamageType.ARCANE] = 4 * scalingFactor}
  6236 +
  6237 + }, true)
  6238 + self.combat.burst_on_crit = {[DamageType.ARCANE_SILENCE] = 12 * scalingFactor,}
  6239 + self.gemDesc = "Arcane"
  6240 + end
  6241 + if gem.subtype =="white" then -- Cold
  6242 + self.combat.damtype = DamageType.COLD
  6243 + table.mergeAdd(self.wielder, {
  6244 + inc_damage = { [DamageType.COLD] = 4 * scalingFactor}
  6245 +
  6246 + }, true)
  6247 + self.combat.burst_on_crit = {[DamageType.ICE] = 12 * scalingFactor,}
  6248 + self.gemDesc = "Cold"
  6249 + end
  6250 + if gem.subtype =="yellow" then -- Light
  6251 + self.combat.damtype = DamageType.LIGHT
  6252 + table.mergeAdd(self.wielder, {
  6253 + inc_damage = { [DamageType.LIGHT] = 4 * scalingFactor}
  6254 +
  6255 + }, true)
  6256 + self.combat.burst_on_crit = {[DamageType.LIGHT_BLIND] = 12 * scalingFactor,}
  6257 + self.gemDesc = "Light"
  6258 + end
  6259 + 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
  6260 + table.mergeAdd(self.combat, {convert_damage = {[DamageType.COLD] = 25, [DamageType.FIRE] = 25, [DamageType.LIGHTNING] = 25, [DamageType.ARCANE] = 25,} }, true)
  6261 + table.mergeAdd(self.wielder, {
  6262 + inc_damage = { all = 2 * scalingFactor},
  6263 + resists_pen = { all = 2 * scalingFactor},
  6264 + }, true)
  6265 + self.gemDesc = "Unique"
  6266 + end
  6267 + if gem.subtype == "demonic" then -- Goedalath Rock
  6268 + self.combat.damtype = DamageType.SHADOWFLAME
  6269 + table.mergeAdd(self.wielder, {
  6270 + inc_damage = { [DamageType.FIRE] = 3 * scalingFactor, [DamageType.DARKNESS] = 3 * scalingFactor,},
  6271 + resists_pen = { all = 2 * scalingFactor},
  6272 + }, true)
  6273 + self.gemDesc = "Demonic"
  6274 + end
  6275 + 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})
  6276 +
  6277 + --self.name = (gem.name .. " of Divinity")
  6278 +
  6279 + table.mergeAdd(self.wielder, gem.imbue_powers, true)
  6280 +
  6281 + end
  6282 + if gem.talent_on_spell then
  6283 + self.talent_on_spell = self.talent_on_spell or {}
  6284 + table.append(self.talent_on_spell, gem.talent_on_spell)
  6285 + end
  6286 + who:onWear(self)
  6287 + for i, v in pairs(who.hotkey) do
  6288 + if v[2]==name_old then
  6289 + v[2]=self.name
  6290 + end
  6291 + if v[2]==self.name and old_hotkey and i~=old_hotkey then
  6292 + who.hotkey[i] = nil
  6293 + end
  6294 + end
  6295 + d.used_talent=true
  6296 + game:unregisterDialog(d)
  6297 + return true
  6298 + end)
  6299 + return {id=true, used=true}
  6300 + end
  6301 + },
  6302 + on_wear = function(self, who)
  6303 +
  6304 + return true
  6305 + end,
  6306 + wielder = {
  6307 + -- Stats only from gems
  6308 + },
  6309 +}
  6310 +
  6311 +newEntity{ base = "BASE_GLOVES", define_as = "SET_GLOVE_DESTROYER",
  6312 + power_source = {arcane=true, technique=true},
  6313 + unique = true,
  6314 + name = "Fist of the Destroyer", color = colors.RED, image = "object/artifact/fist_of_the_destroyer.png",
  6315 + unided_name = "vile gauntlets",
  6316 + desc = [[These terrible looking gloves glow with untold power.]],
  6317 + level_range = {40, 50},
  6318 + rarity = 300,
  6319 + cost = 800,
  6320 + material_level = 5,
  6321 + special_desc = function(self)
  6322 + local num=4
  6323 + if self.set_complete then
  6324 + num=6
  6325 + end
  6326 + return ("Increases all damage by %d%% of current vim \nCurrent Bonus: %d%%"):format(num, num*0.01*(game.player:getVim() or 0))
  6327 + end,
  6328 + wielder = {
  6329 + inc_stats = { [Stats.STAT_STR] = 9, [Stats.STAT_MAG] = 9, [Stats.STAT_CUN] = 3, },
  6330 + demonblood_dam=0.04,
  6331 + max_vim = 25,
  6332 + combat_def = 8,
  6333 + stun_immune = 0.2,
  6334 + talents_types_mastery = { ["corruption/shadowflame"] = 0.2, ["corruption/vim"] = 0.2,},
  6335 + combat = {
  6336 + dam = 35,
  6337 + apr = 15,
  6338 + physcrit = 10,
  6339 + physspeed = 0,
  6340 + dammod = {dex=0.4, str=-0.6, cun=0.4, mag=0.2,},
  6341 + damrange = 0.3,
  6342 + talent_on_hit = { T_DRAIN = {level=2, chance=8}, T_SOUL_ROT = {level=3, chance=12}, T_BLOOD_GRASP = {level=3, chance=10}},
  6343 + },
  6344 + },
  6345 + max_power = 12, power_regen = 1,
  6346 + use_talent = { id = Talents.T_DARKFIRE, level = 5, power = 12 },
  6347 + set_list = { {"define_as", "SET_ARMOR_MASOCHISM"} },
  6348 + on_set_complete = function(self, who)
  6349 + game.logPlayer(who, "#STEEL_BLUE#The fist and the mangled clothing glow ominously!")
  6350 + self:specialSetAdd({"wielder","demonblood_dam"}, 0.02)
  6351 + self:specialSetAdd({"wielder","inc_damage"}, { [engine.DamageType.FIRE] = 15, [engine.DamageType.DARKNESS] = 15, all = 5 })
  6352 + end,
  6353 + on_set_broken = function(self, who)
  6354 + game.logPlayer(who, "#STEEL_BLUE#The ominous glow dies down.")
  6355 + end,
  6356 +}
  6357 +
  6358 +newEntity{ base = "BASE_LIGHT_ARMOR", define_as = "SET_ARMOR_MASOCHISM",
  6359 + power_source = {arcane=true, technique=true},
  6360 + unique = true,
  6361 + name = "Masochism", color = colors.RED, image = "object/artifact/masochism.png",
  6362 + unided_name = "mangled clothing",
  6363 + desc = [[Stolen flesh,
  6364 + Stolen pain,
  6365 + To give it up,
  6366 + Is to live again.]],
  6367 + level_range = {40, 50},
  6368 + rarity = 300,
  6369 + cost = 800,
  6370 + material_level = 5,
  6371 + special_desc = function(self)
  6372 + local num=7
  6373 + if self.set_complete then
  6374 + num=10
  6375 + end
  6376 + 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))
  6377 + end,
  6378 + wielder = {
  6379 + inc_stats = {[Stats.STAT_MAG] = 9, [Stats.STAT_CUN] = 3, },
  6380 + combat_spellpower = 10,
  6381 + demonblood_def=0.07,
  6382 + max_vim = 25,
  6383 + disease_immune = 1,
  6384 + combat_physresist = 10,
  6385 + combat_mentalresist = 10,
  6386 + combat_spellresist = 10,
  6387 + on_melee_hit={[DamageType.DRAIN_VIM] = 25},
  6388 + melee_project={[DamageType.DRAIN_VIM] = 25},
  6389 + talents_types_mastery = { ["corruption/sanguisuge"] = 0.2, ["corruption/blood"] = 0.2,},
  6390 + },
  6391 + max_power = 12, power_regen = 1,
  6392 + use_talent = { id = Talents.T_BLOOD_GRASP, level = 5, power = 12 },
  6393 + set_list = { {"define_as", "SET_GLOVE_DESTROYER"} },
  6394 + on_set_complete = function(self, who)
  6395 + self:specialSetAdd({"wielder","demonblood_def"}, 0.03)
  6396 + self:specialSetAdd({"wielder","resists"}, { [engine.DamageType.FIRE] = 15, [engine.DamageType.DARKNESS] = 15, all = 5 })
  6397 + end,
  6398 + on_set_broken = function(self, who)
  6399 + end,
  6400 +}
  6401 +
  6402 +newEntity{ base = "BASE_GREATMAUL",
  6403 + power_source = {technique=true},
  6404 + unique = true,
  6405 + name = "Obliterator", color = colors.UMBER, image = "object/artifact/obliterator.png",
  6406 + unided_name = "titanic maul",
  6407 + desc = [[This massive hammer strikes with an impact that could shatter bones.]],
  6408 + level_range = {23, 30},
  6409 + rarity = 270,
  6410 + require = { stat = { str=40 }, },
  6411 + cost = 250,
  6412 + material_level = 3,
  6413 + combat = {
  6414 + dam = 48,
  6415 + apr = 10,
  6416 + physcrit = 0,
  6417 + dammod = {str=1.2},
  6418 + crushing_blow=1,
  6419 + },
  6420 + wielder = {
  6421 + combat_critical_power = 10,
  6422 + },
  6423 +}
  6424 +
  6425 +newEntity{ base = "BASE_HELM",
  6426 + power_source = {technique=true},
  6427 + unique = true,
  6428 + name = "Yaldan Baoth", image = "object/artifact/yaldan_baoth.png",
  6429 + unided_name = "obscuring helm",
  6430 + 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.]],
  6431 + level_range = {28, 39,},
  6432 + rarity = 240,
  6433 + cost = 700,
  6434 + material_level = 4,
  6435 + wielder = {
  6436 + combat_armor = 6,
  6437 + fatigue = 4,
  6438 + resist_unseen = 25,
  6439 + sight = -2,
  6440 + inc_stats = { [Stats.STAT_WIL] = 10, [Stats.STAT_CON] = 7, },
  6441 + inc_damage={
  6442 + [DamageType.LIGHT] = 10,
  6443 + },
  6444 + resists={
  6445 + [DamageType.LIGHT] = 10,
  6446 + [DamageType.DARKNESS] = 15,
  6447 + },
  6448 + resists_cap={
  6449 + [DamageType.DARKNESS] = 10,
  6450 + },
  6451 + blind_fight = 1,
  6452 + },
  6453 +}
6042 6454 --[=[
6043 6455 newEntity{
6044 6456 unique = true,
... ...
... ... @@ -528,3 +528,91 @@ newTalent{
528 528 return ([[Reset up to 3 wild gift, psionic or cursed talents.]])
529 529 end,
530 530 }
  531 +
  532 +newTalent{
  533 + name = "Dagger Block",
  534 + image = "talents/block.png",
  535 + type = {"technique/objects", 1},
  536 + cooldown = function(self, t)
  537 + return 8 - util.bound(self:getTalentLevelRaw(t), 1, 5)
  538 + end,
  539 + points = 5,
  540 + hard_cap = 5,
  541 + range = 1,
  542 + requires_target = true,
  543 + tactical = { ATTACK = 3, DEFEND = 3 },
  544 +
  545 + getProperties = function(self, t)
  546 + local p = {
  547 + sp = false,
  548 + ref = false,
  549 + br = false,
  550 + sb = true
  551 + }
  552 + return p
  553 + end,
  554 +
  555 + getBlockedTypes = function(self, t)
  556 +
  557 + local bt = {[DamageType.PHYSICAL]=true}
  558 + bt[DamageType.FIRE] = false
  559 + bt[DamageType.LIGHTNING] = false
  560 + bt[DamageType.COLD] = false
  561 + bt[DamageType.ACID] = false
  562 + bt[DamageType.NATURE] = false
  563 + bt[DamageType.BLIGHT] = false
  564 + bt[DamageType.LIGHT] = false
  565 + bt[DamageType.DARKNESS] = false
  566 + bt[DamageType.ARCANE] = false
  567 + bt[DamageType.MIND] = false
  568 + bt[DamageType.TEMPORAL] = false
  569 +
  570 + local n = 0
  571 + for t, _ in pairs(bt) do n = n + 1 end
  572 +
  573 + if n < 1 then return "(error 2)" end
  574 + local e_string = ""
  575 + if n == 1 then
  576 + e_string = DamageType.dam_def[next(bt)].name
  577 + else
  578 + local list = table.keys(bt)
  579 + for i = 1, #list do
  580 + list[i] = DamageType.dam_def[list[i]].name
  581 + end
  582 + e_string = table.concat(list, ", ")
  583 + end
  584 + return bt, e_string
  585 + end,
  586 +
  587 + action = function(self, t)
  588 + local properties = t.getProperties(self, t)
  589 + local bt, bt_string = t.getBlockedTypes(self, t)
  590 + 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})
  591 + return true
  592 + end,
  593 + info = function(self, t)
  594 + 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.
  595 + The blocking value will increase with your Dexterity and Cunning.]]):format(120 + self:getCun() + self:getDex())
  596 + end,
  597 +}
  598 +
  599 +newTalent{
  600 + name = "Shieldsmaiden Aura",
  601 + type = {"misc/objects", 1},
  602 + points = 1,
  603 + mode = "passive",
  604 + cooldown = 10,
  605 + callbackOnHit = function(self, t, cb)
  606 + if not self:isTalentCoolingDown(t) then
  607 + self:startTalentCooldown(t)
  608 + cb.value=0
  609 + game.logPlayer(self, "Your shield protects you from the blow!")
  610 + return true
  611 + else
  612 + return false
  613 + end
  614 + end,
  615 + info = function(self, t)
  616 + return ([[Can block up to 1 hit per 10 turns.]])
  617 + end,
  618 +}
... ...
... ... @@ -76,7 +76,7 @@ newTalent{
76 76 no_energy = true,
77 77 tactical = { DEFEND = 2 },
78 78 on_pre_use = function(self, t, silent)
79   - if self:isTalentActive(self.T_THERMAL_SHIELD) and self:isTalentActive(self.T_CHARGED_SHIELD) then
  79 + if self:isTalentActive(self.T_THERMAL_SHIELD) and self:isTalentActive(self.T_CHARGED_SHIELD) and not self:attr("psionic_shield_override") then
80 80 if not silent then game.logSeen(self, "You may only sustain two shields at once. Shield activation cancelled.") end
81 81 return false
82 82 end
... ... @@ -202,7 +202,7 @@ newTalent{
202 202 no_energy = true,
203 203 tactical = { DEFEND = 2 },
204 204 on_pre_use = function(self, t, silent)
205   - if self:isTalentActive(self.T_KINETIC_SHIELD) and self:isTalentActive(self.T_CHARGED_SHIELD) then
  205 + if self:isTalentActive(self.T_KINETIC_SHIELD) and self:isTalentActive(self.T_CHARGED_SHIELD) and not self:attr("psionic_shield_override") then
206 206 if not silent then game.logSeen(self, "You may only sustain two shields at once. Shield activation cancelled.") end
207 207 return false
208 208 end
... ... @@ -325,7 +325,7 @@ newTalent{
325 325 no_energy = true,
326 326 tactical = { DEFEND = 2 },
327 327 on_pre_use = function(self, t, silent)
328   - if self:isTalentActive(self.T_KINETIC_SHIELD) and self:isTalentActive(self.T_THERMAL_SHIELD) then
  328 + if self:isTalentActive(self.T_KINETIC_SHIELD) and self:isTalentActive(self.T_THERMAL_SHIELD) and not self:attr("psionic_shield_override") then
329 329 if not silent then game.logSeen(self, "You may only sustain two shields at once. Shield activation cancelled.") end
330 330 return false
331 331 end
... ...
... ... @@ -1838,7 +1838,7 @@ newEffect{
1838 1838 game:delayedLogMessage(self, src, "block_heal", "#CRIMSON##Source# heals from blocking with %s shield!", string.his_her(self))
1839 1839 end
1840 1840 if eff.properties.ref and src.life then DamageType.defaultProjector(src, src.x, src.y, type, blocked, tmp, true) end
1841   - 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
  1841 + 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
1842 1842 return amt
1843 1843 end,
1844 1844 activate = function(self, eff)
... ... @@ -2011,7 +2011,7 @@ newEffect{
2011 2011 newEffect{
2012 2012 name = "DISABLE", image = "talents/cripple.png",
2013 2013 desc = "Disable",
2014   - 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,
  2014 + 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,
2015 2015 type = "physical",
2016 2016 subtype = { wound=true },
2017 2017 status = "detrimental",
... ... @@ -2308,3 +2308,4 @@ newEffect{
2308 2308 self:incEquilibrium(-eff.power)
2309 2309 end,
2310 2310 }
  2311 +
... ...
... ... @@ -110,7 +110,7 @@ newEntity{ base = "BASE_NPC_GHOUL", define_as = "ROTTING_TITAN",
110 110 resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_ghoul_rotting_titan.png", display_h=2, display_y=-1}}},
111 111 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.]],
112 112 level_range = {45, nil}, exp_worth = 2,
113   - rarity = 40,
  113 + rarity = 28,
114 114 max_life = resolvers.rngavg(150,200), life_rating = 40,
115 115 combat_armor = 40, combat_def = 10,
116 116 ai_state = { talent_in=2 },
... ... @@ -138,15 +138,17 @@ newEntity{ base = "BASE_NPC_GHOUL", define_as = "ROTTING_TITAN",
138 138 combat_atk=40,
139 139 combat_spellpower=25,
140 140
  141 + inc_damage = { [DamageType.PHYSICAL] = 15 },
  142 +
141 143 disarm_immune=1, --Since disarming him would be, well, DISARMING him.
142 144
143 145 on_move = function(self)
144   - if rng.percent(20) then
145   - game.logSeen(self, "The ground shakes as %s steps!", self.name:capitalize())
146   - local tg = {type="ball", range=0, selffire=false, radius=3, no_restrict=true}
147   - local DamageType = require "engine.DamageType"
148   - self:project(tg, self.x, self.y, DamageType.PHYSKNOCKBACK, {dam=24, dist=1})
149   - self:doQuake(tg, self.x, self.y)
  146 + if rng.percent(35) then
  147 + game.logSeen(self, "The ground shakes as %s steps!", self.name:capitalize())
  148 + local tg = {type="ball", range=0, selffire=false, radius=4, no_restrict=true}
  149 + local DamageType = require "engine.DamageType"
  150 + --self:project(tg, self.x, self.y, DamageType.PHYSKNOCKBACK, {dam=24, dist=5})
  151 + self:doQuake(tg, self.x, self.y)
150 152 end
151 153 self:project({type="ball", range=0, selffire=false, radius=1}, self.x, self.y, engine.DamageType.DIG, 1)
152 154 end,
... ... @@ -180,7 +182,7 @@ newEntity{ base = "BASE_NPC_GHOST", define_as = "GLACIAL_LEGION",
180 182 resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_ghost_glacial_legion.png", display_h=2, display_y=-1}}},
181 183 desc = [[A massive, shifting, ethereal form floats in the air around an orb of frozen blood. Vapor pools on the floor beneath it.]],
182 184 level_range = {45, nil}, exp_worth = 2,
183   - rarity = 40,
  185 + rarity = 28,
184 186 size_category=5,
185 187 rank = 3.5,
186 188 max_life = resolvers.rngavg(90,100), life_rating = 18,
... ... @@ -188,34 +190,36 @@ newEntity{ base = "BASE_NPC_GHOST", define_as = "GLACIAL_LEGION",
188 190 ai = "tactical", ai_state = { talent_in=1, },
189 191 ai_tactic = resolvers.tactic"ranged",
190 192 stats = { str=13, dex=15, mag=45, con=14 },
191   - combat_spellpower=40,
  193 + combat_spellpower = 100,
192 194
193 195 resists = {all = -10, [DamageType.FIRE] = -100, [DamageType.LIGHT] = 30, [DamageType.COLD] = 100},
194 196 combat_armor = 0, combat_def = resolvers.mbonus(10, 10),
195 197 --stealth = resolvers.mbonus(40, 10),
196 198
197   - combat = { dam=50, atk=50, apr=100, dammod={mag=1.1} },
  199 + combat = { dam=50, atk=90, apr=100, dammod={mag=1.1} },
198 200 melee_project = {[DamageType.COLD]=resolvers.mbonus(15, 25)},
199 201 on_melee_hit = {[DamageType.COLD]=resolvers.mbonus(15, 5)},
  202 +
  203 + inc_damage = { [DamageType.COLD] = 25 },
200 204
201 205 on_move = function(self)
202   - local DamageType = require "engine.DamageType"
203   - local duration = 7
204   - local radius = 0
205   - local dam = 25
206   - -- Add a lasting map effect
207   - game.level.map:addEffect(self,
208   - self.x, self.y, duration,
209   - engine.DamageType.ICE, 25,
210   - radius,
211   - 5, nil,
212   - engine.Entity.new{alpha=100, display='', color_br=30, color_bg=60, color_bb=200},
213   - function(e)
214   - e.radius = e.radius
215   - return true
216   - end,
217   - false
218   - )
  206 + local DamageType = require "engine.DamageType"
  207 + local duration = 9
  208 + local radius = 0
  209 + local dam = 100
  210 + -- Add a lasting map effect
  211 + game.level.map:addEffect(self,
  212 + self.x, self.y, duration,
  213 + engine.DamageType.ICE, dam,
  214 + radius,
  215 + 5, nil,
  216 + engine.Entity.new{alpha=100, display='', color_br=30, color_bg=60, color_bb=200},
  217 + function(e)
  218 + e.radius = e.radius
  219 + return true
  220 + end,
  221 + false
  222 + )
219 223 end,
220 224
221 225 resolvers.talents{
... ... @@ -223,13 +227,12 @@ newEntity{ base = "BASE_NPC_GHOST", define_as = "GLACIAL_LEGION",
223 227 [Talents.T_FREEZE]={base=5, every=4, max=10},
224 228 [Talents.T_ICE_STORM]={base=4, every=6, max=8},
225 229 [Talents.T_ICE_SHARDS]={base=5, every=5, max=9},
226   - [Talents.T_ARCANE_POWER]={base=4, every=3, max = 11},
227 230 [Talents.T_SHATTER]={base=3, every=6, max=8},
228 231 [Talents.T_UTTERCOLD]={base=3, every=7, max = 5},
229 232 [Talents.T_FROZEN_GROUND]={base=4, every=6, max = 6},
230 233 [Talents.T_CHILL_OF_THE_TOMB]={base=5, every=5, max=10},
231 234 [Talents.T_SPELLCRAFT]={base=3, every=7, max=8},
232   - [Talents.T_MANAFLOW]={base=5, every=4, max = 12},
  235 + --[Talents.T_MANAFLOW]={base=5, every=4, max = 12},
233 236 [Talents.T_FROST_HANDS]={base=3, every=7, max=8},
234 237 },
235 238 resolvers.drops{chance=100, nb=3, {tome_drops="boss"} },
... ... @@ -243,7 +246,7 @@ newEntity{ base = "BASE_NPC_BONE_GIANT", define_as = "HEAVY_SENTINEL",
243 246 desc = [[A towering creature, made from the bones of countless bodies. An aura of flame bellows from within its chest.]],
244 247 resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_giant_heavy_sentinel.png", display_h=2, display_y=-1}}},
245 248 level_range = {45, nil}, exp_worth = 2,
246   - rarity = 40,
  249 + rarity = 28,
247 250 rank = 3.5,
248 251 ai = "tactical",
249 252 size=5,
... ... @@ -251,12 +254,12 @@ newEntity{ base = "BASE_NPC_BONE_GIANT", define_as = "HEAVY_SENTINEL",
251 254 combat_armor = 20, combat_def = 35,
252 255 life_rating = 28,
253 256
254