Showing
24 changed files
with
648 additions
and
105 deletions
... | ... | @@ -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, | ... | ... |

9.8 KB

6.97 KB

9.36 KB

8.52 KB

11.1 KB

2.65 KB
... | ... | @@ -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 |