Commit 26919676d2c9254bc4faec31a2d5595b5084d34b

Authored by DarkGod
1 parent 90ff4a70

True Grit banned from NPCs

More brawlers and Sun Paladin updates
Reduced the critical damage power on egos
Buffed many charms
Colored temporary effects by type in Actor tooltips
Added Actor:checkClassification which checks if an actor is in an arbitrary set of classifications
Changed die_at to show actual negative HP
Minimalist UI now shows a timer left for summons
Showing 62 changed files with 890 additions and 397 deletions
... ... @@ -982,3 +982,9 @@ end
982 982 function _M:getEntityKind()
983 983 return "entity"
984 984 end
  985 +
  986 +--- Putting this here to avoid errors, not sure if appropriate
  987 +function _M:checkClassification(type_str)
  988 + return false
  989 +end
  990 +
... ...
... ... @@ -1674,19 +1674,38 @@ function _M:tooltip(x, y, seen_by)
1674 1674 if self.faction and Faction.factions[self.faction] then ts:add("Faction: ") ts:merge(factcolor:toTString()) ts:add(("%s (%s, %d)"):format(Faction.factions[self.faction].name, factstate, factlevel), {"color", "WHITE"}, true) end
1675 1675 if game.player ~= self then ts:add("Personal reaction: ") ts:merge(pfactcolor:toTString()) ts:add(("%s, %d"):format(pfactstate, pfactlevel), {"color", "WHITE"} ) end
1676 1676
  1677 + ts:add(true, {"color", "ORANGE"}, "Sustained Talents: ",{"color", "WHITE"})
1677 1678 for tid, act in pairs(self.sustain_talents) do
1678 1679 if act then ts:add(true, "- ", {"color", "LIGHT_GREEN"}, self:getTalentFromId(tid) and self:getTalentFromId(tid).name or "???", {"color", "WHITE"} ) end
1679 1680 end
  1681 +
  1682 + if ts[#ts-1] == "Sustained Talents: " then table.remove(ts) table.remove(ts) table.remove(ts) table.remove(ts) end
  1683 +
  1684 + ts:add(true, {"color", "ORANGE"}, "Temporary Status Effects: ",{"color", "WHITE"})
1680 1685 for eff_id, p in pairs(self.tmp) do
1681 1686 local e = self.tempeffect_def[eff_id]
1682 1687 local dur = p.dur + 1
1683 1688 if e.status == "detrimental" then
1684   - if act then ts:add(true, "- ", {"color", "LIGHT_RED"}, (e.decrease > 0) and ("%s(%d)"):format(e.desc,dur) or e.desc, {"color", "WHITE"} ) end
  1689 + if e.type == "physical" then
  1690 + if act then ts:add(true, "- ", {"color", "LIGHT_RED"}, (e.decrease > 0) and ("%s(%d)"):format(e.desc,dur) or e.desc, {"color", "WHITE"} ) end
  1691 + elseif e.type == "magical" then
  1692 + if act then ts:add(true, "- ", {"color", "DARK_ORCHID"}, (e.decrease > 0) and ("%s(%d)"):format(e.desc,dur) or e.desc, {"color", "WHITE"} ) end
  1693 + elseif e.type == "mental" then
  1694 + if act then ts:add(true, "- ", {"color", "YELLOW"}, (e.decrease > 0) and ("%s(%d)"):format(e.desc,dur) or e.desc, {"color", "WHITE"} ) end
  1695 + elseif e.type == "other" then
  1696 + if act then ts:add(true, "- ", {"color", "ORCHID"}, (e.decrease > 0) and ("%s(%d)"):format(e.desc,dur) or e.desc, {"color", "WHITE"} ) end
  1697 +
  1698 + else
  1699 + if act then ts:add(true, "- ", {"color", "LIGHT_RED"}, (e.decrease > 0) and ("%s(%d)"):format(e.desc,dur) or e.desc, {"color", "WHITE"} ) end
  1700 +
  1701 + end
1685 1702 else
1686 1703 if act then ts:add(true, "- ", {"color", "LIGHT_GREEN"}, (e.decrease > 0) and ("%s(%d)"):format(e.desc,dur) or e.desc, {"color", "WHITE"} ) end
1687 1704 end
1688 1705 end
1689 1706
  1707 + if ts[#ts-1] == "Temporary Status Effects: " then table.remove(ts) table.remove(ts) table.remove(ts) table.remove(ts) end
  1708 +
1690 1709 return ts
1691 1710 end
1692 1711
... ... @@ -4843,6 +4862,32 @@ function _M:checkSetTalentAuto(tid, v, opt)
4843 4862 end
4844 4863 end
4845 4864
  4865 +
  4866 +
  4867 +-- Classifications for actor resist/damage
  4868 +-- Thanks to grayswandir for this really neat code structure
  4869 +_M.classifications = {
  4870 + unliving = {undead = true, construct = true, crystal = true},
  4871 + unnatural = {demon = true, elemental = true, horror = true, construct = true, undead = true},
  4872 + living = function(self) return not self:checkClassification('unliving') end,
  4873 + natural = function(self) return not self:checkClassification('unnatural') end,
  4874 + summoned = function(self) return (self.summoner ~= nil) end
  4875 +,}
  4876 +
  4877 +--- Check if the actor is a certain type or in an arbitrary set of classifications
  4878 +-- @param string representing the classification to check
  4879 +-- @return whether the actor is in this classification
  4880 +function _M:checkClassification(type_str)
  4881 + -- Living and Natural are defined as not being Unliving or not Unnatural
  4882 + -- Thus, all actors are in one category or the other
  4883 + if not self.type or not type_str then return end
  4884 + if (tostring(self.type).."/"..tostring(self.subtype) == type_str) or self.type == type_str then return true end
  4885 + local class = _M.classifications[type_str]
  4886 + if not class then return false end
  4887 + if type(class) == 'function' then return class(self) end
  4888 + return class[self.type or "unknown"]
  4889 +end
  4890 +
4846 4891 --- How much experience is this actor worth
4847 4892 -- @param target to whom is the exp rewarded
4848 4893 -- @return the experience rewarded
... ...
... ... @@ -427,13 +427,13 @@ function _M:addedToLevel(level, x, y)
427 427 if game.difficulty == game.DIFFICULTY_NIGHTMARE and not game.party:hasMember(self) then
428 428 -- Increase talent level
429 429 for tid, lev in pairs(self.talents) do
430   - self:learnTalent(tid, true, math.ceil(lev / 2))
  430 + self:learnTalent(tid, true, math.floor(lev / 3))
431 431 end
432 432 self:attr("difficulty_boosted", 1)
433 433 elseif game.difficulty == game.DIFFICULTY_INSANE and not game.party:hasMember(self) then
434 434 -- Increase talent level
435 435 for tid, lev in pairs(self.talents) do
436   - self:learnTalent(tid, true, lev / 2)
  436 + self:learnTalent(tid, true, math.floor(lev / 3))
437 437 end
438 438 -- Give unrand bosses extra classes
439 439 if not self.randboss and self.rank >= 3.5 then
... ...
... ... @@ -1190,7 +1190,7 @@ function _M:getTextualDesc(compare_with, use_actor)
1190 1190 compare_fields(w, compare_with, field, "damage_backfire", "%+d%%", "Damage Backlash: ", nil, true)
1191 1191
1192 1192 compare_fields(w, compare_with, field, "resist_unseen", "%-d%%", "Reduce all damage from unseen attackers: ")
1193   -
  1193 +
1194 1194 if w.undead then
1195 1195 desc:add("The wearer is treated as an undead.", true)
1196 1196 end
... ... @@ -1425,6 +1425,11 @@ function _M:getTextualDesc(compare_with, use_actor)
1425 1425 desc:add(talents[tid][3] and {"color","GREEN"} or {"color","WHITE"}, ("Talent on hit(mindpower): %s (%d%% chance level %d)."):format(self:getTalentFromId(tid).name, talents[tid][1], talents[tid][2]), {"color","LAST"}, true)
1426 1426 end
1427 1427
  1428 + if self.use_no_energy then
  1429 + desc:add("Activating this item is instant.", true)
  1430 + end
  1431 +
  1432 +
1428 1433 if self.curse then
1429 1434 local t = use_actor:getTalentFromId(use_actor.T_DEFILING_TOUCH)
1430 1435 if t and t.canCurseItem(use_actor, t, self) then
... ... @@ -1434,6 +1439,7 @@ function _M:getTextualDesc(compare_with, use_actor)
1434 1439
1435 1440 self:triggerHook{"Object:descMisc", compare_with=compare_with, compare_fields=compare_fields, compare_table_fields=compare_table_fields, desc=desc, object=self}
1436 1441
  1442 +
1437 1443 local use_desc = self:getUseDesc(use_actor)
1438 1444 if use_desc then desc:merge(use_desc:toTString()) end
1439 1445 return desc
... ...
... ... @@ -294,7 +294,8 @@ function _M:display()
294 294 h = h + self.font_h
295 295
296 296 if player.life < 0 then
297   - self:mouseTooltip(self.TOOLTIP_LIFE, self:makeTextureBar("#c00000#Life:", "???", 0, player.max_life, player.life_regen * util.bound((player.healing_factor or 1), 0, 2.5), x, h, 255, 255, 255, colors.DARK_RED, colors.VERY_DARK_RED)) h = h + self.font_h
  297 + --self:mouseTooltip(self.TOOLTIP_LIFE, self:makeTextureBar("#c00000#Life:", "???", 0, player.max_life, player.life_regen * util.bound((player.healing_factor or 1), 0, 2.5), x, h, 255, 255, 255, colors.DARK_RED, colors.VERY_DARK_RED)) h = h + self.font_h
  298 + self:mouseTooltip(self.TOOLTIP_LIFE, self:makeTextureBar("#c00000#Life:", nil, player.life, player.max_life, player.life_regen * util.bound((player.healing_factor or 1), 0, 2.5), x, h, 255, 255, 255, colors.DARK_RED, colors.VERY_DARK_RED)) h = h + self.font_h
298 299 else
299 300 self:mouseTooltip(self.TOOLTIP_LIFE, self:makeTextureBar("#c00000#Life:", nil, player.life, player.max_life, player.life_regen * util.bound((player.healing_factor or 1), 0, 2.5), x, h, 255, 255, 255, colors.DARK_RED, colors.VERY_DARK_RED)) h = h + self.font_h
300 301 end
... ...
... ... @@ -214,9 +214,14 @@ local function archery_projectile(tx, ty, tg, self, tmp)
214 214 end
215 215
216 216 if ammo and ammo.inc_damage_type then
217   - for t, idt in pairs(ammo.inc_damage_type) do
218   - if target.type.."/"..target.subtype == t or target.type == t then dam = dam + dam * idt / 100 break end
  217 + local inc = 0
  218 +
  219 + for k, v in pairs(ammo.inc_damage_type) do
  220 + if target:checkClassification(tostring(k)) then inc = math.max(inc, v) end
219 221 end
  222 +
  223 + dam = dam + dam * inc / 100
  224 +
220 225 print("[ATTACK] after inc by type", dam)
221 226 end
222 227
... ...
... ... @@ -453,9 +453,16 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
453 453 end
454 454
455 455 if weapon and weapon.inc_damage_type then
456   - for t, idt in pairs(weapon.inc_damage_type) do
457   - if target.type.."/"..target.subtype == t or target.type == t then dam = dam + dam * idt / 100 break end
  456 + local inc = 0
  457 +
  458 + for k, v in pairs(weapon.inc_damage_type) do
  459 + if target:checkClassification(tostring(k)) then inc = math.max(inc, v) end
458 460 end
  461 + dam = dam + dam * inc / 100
  462 +
  463 + --for t, idt in pairs(weapon.inc_damage_type) do
  464 + --if target.type.."/"..target.subtype == t or target.type == t then dam = dam + dam * idt / 100 break end
  465 + --end
459 466 print("[ATTACK] after inc by type", dam)
460 467 end
461 468
... ... @@ -1122,6 +1129,7 @@ function _M:combatAttack(weapon, ammo)
1122 1129 end
1123 1130 local d = self:combatAttackBase(weapon, ammo) + stats
1124 1131 if self:attr("dazed") then d = d / 2 end
  1132 + if self:attr("scoured") then d = d / 1.5 end
1125 1133 return self:rescaleCombatStats(d)
1126 1134 end
1127 1135
... ... @@ -1133,6 +1141,8 @@ function _M:combatAttackRanged(weapon, ammo)
1133 1141 end
1134 1142 local d = self:combatAttackBase(weapon, ammo) + stats + (self.combat_atk_ranged or 0)
1135 1143 if self:attr("dazed") then d = d / 2 end
  1144 + if self:attr("scoured") then d = d / 1.5 end
  1145 +
1136 1146 return self:rescaleCombatStats(d)
1137 1147 end
1138 1148
... ... @@ -1140,6 +1150,7 @@ end
1140 1150 function _M:combatAttackStr(weapon, ammo)
1141 1151 local d = self:combatAttackBase(weapon, ammo) + (self:getStr(100, true) - 10)
1142 1152 if self:attr("dazed") then d = d / 2 end
  1153 + if self:attr("scoured") then d = d / 1.5 end
1143 1154 return self:rescaleCombatStats(d)
1144 1155 end
1145 1156
... ... @@ -1147,6 +1158,7 @@ end
1147 1158 function _M:combatAttackDex(weapon, ammo)
1148 1159 local d = self:combatAttackBase(weapon, ammo) + (self:getDex(100, true) - 10)
1149 1160 if self:attr("dazed") then d = d / 2 end
  1161 + if self:attr("scoured") then d = d / 1.5 end
1150 1162 return self:rescaleCombatStats(d)
1151 1163 end
1152 1164
... ... @@ -1154,6 +1166,8 @@ end
1154 1166 function _M:combatAttackMag(weapon, ammo)
1155 1167 local d = self:combatAttackBase(weapon, ammo) + (self:getMag(100, true) - 10)
1156 1168 if self:attr("dazed") then d = d / 2 end
  1169 + if self:attr("scoured") then d = d / 1.5 end
  1170 +
1157 1171 return self:rescaleCombatStats(d)
1158 1172 end
1159 1173
... ... @@ -1425,6 +1439,8 @@ function _M:combatPhysicalpower(mod, weapon, add)
1425 1439
1426 1440 local d = math.max(0, self.combat_dam + add) + self:getStr() -- allows strong debuffs to offset strength
1427 1441 if self:attr("dazed") then d = d / 2 end
  1442 + if self:attr("scoured") then d = d / 1.5 end
  1443 +
1428 1444 return self:rescaleCombatStats(d) * mod
1429 1445 end
1430 1446
... ... @@ -1455,6 +1471,8 @@ function _M:combatSpellpower(mod, add)
1455 1471
1456 1472 local d = (self.combat_spellpower > 0 and self.combat_spellpower or 0) + add + self:getMag()
1457 1473 if self:attr("dazed") then d = d / 2 end
  1474 + if self:attr("scoured") then d = d / 1.5 end
  1475 +
1458 1476 return self:rescaleCombatStats(d) * mod * am
1459 1477 end
1460 1478
... ... @@ -1744,6 +1762,8 @@ function _M:combatMindpower(mod, add)
1744 1762
1745 1763 local d = (self.combat_mindpower > 0 and self.combat_mindpower or 0) + add + self:getWil() * 0.7 + self:getCun() * 0.4
1746 1764 if self:attr("dazed") then d = d / 2 end
  1765 + if self:attr("scoured") then d = d / 1.5 end
  1766 +
1747 1767 return self:rescaleCombatStats(d) * mod
1748 1768 end
1749 1769
... ... @@ -1799,6 +1819,8 @@ function _M:combatPhysicalResist(fake)
1799 1819 -- To return later
1800 1820 local d = self.combat_physresist + (self:getCon() + self:getStr() + (self:getLck() - 50) * 0.5) * 0.35 + add
1801 1821 if self:attr("dazed") then d = d / 2 end
  1822 +
  1823 +
1802 1824 local total = self:rescaleCombatStats(d)
1803 1825
1804 1826 -- Psionic Balance
... ...
... ... @@ -516,7 +516,37 @@ function _M:computePadding(what, x1, y1, x2, y2)
516 516 size.x2 = x2
517 517 size.y1 = y1
518 518 size.y2 = y2
  519 + -- This is Marson's code to make you not get stuck under UI elements
  520 + -- I have tested and love it but I don't understand it very well, may be oversights
  521 + --if config.settings.marson.view_scrolling == "No Hiding" then
  522 + if x2 <= Map.viewport.width / 4 then
  523 + Map.viewport_padding_4 = math.max(Map.viewport_padding_4, math.ceil(x2 / Map.tile_w))
  524 + end
  525 + if x1 >= (Map.viewport.width / 4) * 3 then
  526 + Map.viewport_padding_6 = math.max(Map.viewport_padding_6, math.ceil((Map.viewport.width - x1) / Map.tile_w))
  527 + end
  528 + if y2 <= Map.viewport.height / 4 then
  529 + Map.viewport_padding_8 = math.max(Map.viewport_padding_8, math.ceil(y2 / Map.tile_h))
  530 + end
  531 + if y1 >= (Map.viewport.height / 4) * 3 then
  532 + Map.viewport_padding_2 = math.max(Map.viewport_padding_2, math.ceil((Map.viewport.height - y1) / Map.tile_h))
  533 + end
  534 +
519 535 if x1 <= 0 then
  536 + size.orient = "right"
  537 + end
  538 + if x2 >= Map.viewport.width then
  539 + size.orient = "left"
  540 + end
  541 + if y1 <= 0 then
  542 + size.orient = "down"
  543 + end
  544 + if y2 >= Map.viewport.height then
  545 + size.orient = "up"
  546 + end
  547 + --[[
  548 + else
  549 + if x1 <= 0 then
520 550 Map.viewport_padding_4 = math.max(Map.viewport_padding_4, math.floor((x2 - x1) / Map.tile_w))
521 551 size.left = true
522 552 end
... ... @@ -538,6 +568,7 @@ function _M:computePadding(what, x1, y1, x2, y2)
538 568 elseif size.left then size.orient = "right"
539 569 elseif size.right then size.orient = "left"
540 570 end
  571 + end --]]
541 572 end
542 573
543 574 function _M:showResourceTooltip(x, y, w, h, id, desc, is_first)
... ... @@ -641,7 +672,8 @@ function _M:displayResources(scale, bx, by, a)
641 672 if not self.res.life or self.res.life.vc ~= player.life or self.res.life.vm ~= player.max_life or self.res.life.vr ~= life_regen then
642 673 self.res.life = {
643 674 vc = player.life, vm = player.max_life, vr = life_regen,
644   - cur = {core.display.drawStringBlendedNewSurface(font_sha, (player.life < 0) and "???" or ("%d/%d"):format(player.life, player.max_life), 255, 255, 255):glTexture()},
  675 + --cur = {core.display.drawStringBlendedNewSurface(font_sha, (player.life < 0) and "???" or ("%d/%d"):format(player.life, player.max_life), 255, 255, 255):glTexture()},
  676 + cur = {core.display.drawStringBlendedNewSurface(font_sha, ("%d/%d"):format(player.life, player.max_life), 255, 255, 255):glTexture()},
645 677 regen={core.display.drawStringBlendedNewSurface(sfont_sha, ("%+0.2f"):format(life_regen), 255, 255, 255):glTexture()},
646 678 }
647 679 end
... ... @@ -1501,6 +1533,9 @@ function _M:displayParty(scale, bx, by)
1501 1533 local def = game.party.members[a]
1502 1534
1503 1535 local text = "#GOLD##{bold}#"..a.name.."\n#WHITE##{normal}#Life: "..math.floor(100 * a.life / a.max_life).."%\nLevel: "..a.level.."\n"..def.title
  1536 + if a.summon_time then
  1537 + text = text.."\nTurns remaining: "..a.summon_time
  1538 + end
1504 1539 local is_first = is_first
1505 1540 local desc_fct = function(button, mx, my, xrel, yrel, bx, by, event)
1506 1541 if is_first then
... ... @@ -1537,6 +1572,27 @@ function _M:displayParty(scale, bx, by)
1537 1572 p = (game.player == a) and portrait_lev or portrait_unsel_lev
1538 1573 end
1539 1574 p[1]:toScreenFull(x, y, p[6], p[7], p[2], p[3])
  1575 + -- Display turns remaining on summon's portrait — Marson
  1576 + if a.summon_time and a.name ~= "shadow" then
  1577 + local gtxt = self.party[a].txt_summon_time
  1578 + if not gtxt or self.party[a].cur_summon_time ~= a.summon_time then
  1579 + local txt = tostring(a.summon_time)
  1580 + local fw, fh = self.buff_font_small:size(txt)
  1581 + self.party[a].txt_summon_time = self.buff_font_small:draw(txt, fw, colors.WHITE.r, colors.WHITE.g, colors.WHITE.b, true)[1]
  1582 + gtxt = self.party[a].txt_summon_time
  1583 + gtxt.fw, gtxt.fh = fw, fh
  1584 + self.party[a].cur_summon_time = a.summon_time
  1585 + end
  1586 + if shader then
  1587 + shader:use(true)
  1588 + shader:uniOutlineSize(0.7, 0.7)
  1589 + shader:uniTextSize(gtxt._tex_w, gtxt._tex_h)
  1590 + else
  1591 + gtxt._tex:toScreenFull(x-gtxt.fw+36+1, y-2+1, gtxt.w, gtxt.h, gtxt._tex_w, gtxt._tex_h, 0, 0, 0, self.shadow or 0.6)
  1592 + end
  1593 + gtxt._tex:toScreenFull(x-gtxt.fw+36, y-2, gtxt.w, gtxt.h, gtxt._tex_w, gtxt._tex_h)
  1594 + if shader then shader:use(false) end
  1595 + end
1540 1596 end, desc_fct}
1541 1597 end
1542 1598
... ...
... ... @@ -190,7 +190,7 @@ newBirthDescriptor{
190 190 "#GOLD##{bold}#Nightmare mode#WHITE##{normal}#",
191 191 "Unfair game setting",
192 192 "All zone levels increased by 50% + 3",
193   - "All creature talent levels increased by 50%",
  193 + "All creature talent levels increased by 30%",
194 194 "Player can earn Nightmare version of achievements if also playing in Roguelike or Adventure permadeath mode.",
195 195 },
196 196 descriptor_choices =
... ... @@ -212,8 +212,8 @@ newBirthDescriptor{
212 212 {
213 213 "#GOLD##{bold}#Insane mode#WHITE##{normal}#",
214 214 "Similar rules to Nightmare, but with more random bosses!",
215   - "All zone levels increased by 50% + 5",
216   - "All creature talent levels increased by 50%",
  215 + "All zone levels increased by 50% + 6",
  216 + "All creature talent levels increased by 30%",
217 217 "Rare creatures are far more frequent and random bosses start to appear",
218 218 "Nonrandom bosses will have randomly selected talents",
219 219 "All enemies have 20% more life",
... ...
... ... @@ -19,9 +19,7 @@
19 19
20 20 -- The basic stuff used to damage a grid
21 21
22   --- Classifications for actor resist/damage
23   -local unliving = {"undead", "construct", "crystal"}
24   -local unnatural = {"demon", "elemental", "horror", "construct", "undead"}
  22 +
25 23
26 24 setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
27 25 if not game.level.map:isBound(x, y) then return 0 end
... ... @@ -135,11 +133,14 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
135 133 if src.getVim and src:attr("demonblood_dam") then inc = inc + ((src.demonblood_dam or 0) * (src:getVim() or 0)) end
136 134
137 135 -- Increases damage for the entity type (Demon, Undead, etc)
138   - if target.type and src.inc_damage_actor_type then
139   - local incEntity = src.inc_damage_actor_type[target.type]
140   - if incEntity and incEntity ~= 0 then
  136 + if target.type and src and src.inc_damage_actor_type then
  137 + local increase = 0
  138 + for k, v in pairs(src.inc_damage_actor_type) do
  139 + if target:checkClassification(tostring(k)) then increase = math.max(increase, v) end
  140 + end
  141 + if increase and increase~= 0 then
141 142 print("[PROJECTOR] before inc_damage_actor_type", dam + (dam * inc / 100))
142   - inc = inc + src.inc_damage_actor_type[target.type]
  143 + inc = inc + increase
143 144 print("[PROJECTOR] after inc_damage_actor_type", dam + (dam * inc / 100))
144 145 end
145 146 end
... ... @@ -254,9 +255,16 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
254 255 end
255 256
256 257 -- reduce by resistance to entity type (Demon, Undead, etc)
  258 + -- Summoned, Unnatural, Unliving still go into this table, we just parse them differently in checkClassification
257 259 if target.resists_actor_type and src and src.type then
  260 + local res = 0
  261 +
  262 + for k, v in pairs(target.resists_actor_type) do
  263 + if src:checkClassification(tostring(k)) then res = math.max(res, v) end
  264 + end
258 265
259   - local res = math.min(target.resists_actor_type[src.type] or 0, target.resists_cap_actor_type or 100)
  266 + res = math.min(res, target.resists_cap_actor_type or 90)
  267 +
260 268 if res ~= 0 then
261 269 print("[PROJECTOR] before entity", src.type, "resists dam", dam)
262 270 if res >= 100 then dam = 0
... ... @@ -378,12 +386,12 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
378 386 end
379 387 end
380 388
381   - -- Chant of Fortress, reduces damage from attackers over range 3
  389 + -- Chant of Fortress, reduces damage from attackers over range 2
382 390 if target.isTalentActive and target:isTalentActive(target.T_CHANT_OF_FORTRESS) and target:knowTalent(target.T_CHANT_OF_FORTRESS) then
383 391 if src and src.x and src.y then
384 392 -- assume instantaneous projection and check range to source
385 393 local t = target:getTalentFromId(target.T_CHANT_OF_FORTRESS)
386   - if core.fov.distance(target.x, target.y, src.x, src.y) > 3 then
  394 + if core.fov.distance(target.x, target.y, src.x, src.y) > 2 then
387 395 t = target:getTalentFromId(target.T_CHANT_OF_FORTRESS)
388 396 dam = dam * (100 + t.getDamageChange(target, t)) / 100
389 397 print("[PROJECTOR] Chant of Fortress (source) dam", dam)
... ... @@ -1722,7 +1730,7 @@ newDamageType{
1722 1730 local target = game.level.map(x, y, Map.ACTOR)
1723 1731 if target and src and src.name and rng.percent(dam) then
1724 1732 if src.turn_procs and src.turn_procs.item_temporal_energize and src.turn_procs.item_temporal_energize > 5 then
1725   - game.logSeen(target, "#LIGHT_STEEL_BLUE#%s can't gain any more energy this turn! ", src.name:capitalize())
  1733 + game.logSeen(src, "#LIGHT_STEEL_BLUE#%s can't gain any more energy this turn! ", src.name:capitalize())
1726 1734 return
1727 1735 end
1728 1736
... ... @@ -1796,7 +1804,7 @@ newDamageType{
1796 1804 local target = game.level.map(x, y, Map.ACTOR)
1797 1805 if target and target:canBe("disease") and rng.percent(dam) then
1798 1806 local check = math.max(src:combatSpellpower(), src:combatMindpower(), src:combatAttack())
1799   - local disease_power = math.min(30, dam / 3)
  1807 + local disease_power = math.min(30, dam / 2)
1800 1808 local disease_dam = 0
1801 1809 local eff = rng.table{{target.EFF_ROTTING_DISEASE, "con"}, {target.EFF_DECREPITUDE_DISEASE, "dex"}, {target.EFF_WEAKNESS_DISEASE, "str"}}
1802 1810 target:setEffect(eff[1], 5, { src = src, apply_power = check, no_ct_effect=true, [eff[2]] = disease_power, dam = disease_dam })
... ... @@ -1848,6 +1856,21 @@ newDamageType{
1848 1856 end,
1849 1857 }
1850 1858
  1859 +-- Mostly used on specific egos
  1860 +newDamageType{
  1861 + name = "item antimagic scouring", type = "ITEM_ANTIMAGIC_SCOURING", text_color = "#ORCHID#",
  1862 + tdesc = function(dam)
  1863 + return ("#LIGHT_GREEN#%d%%#LAST# chance to #ORCHID#reduce power ratings#LAST# by %d%%"):format(dam, 30)
  1864 + end,
  1865 + projector = function(src, x, y, type, dam)
  1866 + local target = game.level.map(x, y, Map.ACTOR)
  1867 + if target then
  1868 + target:setEffect(target.EFF_ITEM_ANTIMAGIC_SCOURED, 3, {pct = 0.3, no_ct_effect=true})
  1869 + end
  1870 + end,
  1871 +}
  1872 +
  1873 +
1851 1874
1852 1875
1853 1876 ------------------------------------------------------------------------------------
... ...
... ... @@ -31,7 +31,7 @@ newEntity{
31 31 combat = { talented = "axe", damrange = 1.5, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2} },
32 32 desc = [[Massive two-handed battleaxes.]],
33 33 twohanded = true,
34   - ego_bonus_mult = 0.2,
  34 + ego_bonus_mult = 0.4,
35 35 randart_able = "/data/general/objects/random-artifacts/melee.lua",
36 36 egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) },
37 37 }
... ...
... ... @@ -31,7 +31,7 @@ newEntity{
31 31 combat = { talented = "mace", damrange = 1.5, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2} },
32 32 desc = [[Massive two-handed mauls.]],
33 33 twohanded = true,
34   - ego_bonus_mult = 0.2,
  34 + ego_bonus_mult = 0.4,
35 35 randart_able = "/data/general/objects/random-artifacts/melee.lua",
36 36 egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) },
37 37 }
... ...
... ... @@ -31,7 +31,7 @@ newEntity{
31 31 desc = [[Massive two-handed swords.]],
32 32 twohanded = true,
33 33 metallic = true,
34   - ego_bonus_mult = 0.2,
  34 + ego_bonus_mult = 0.4,
35 35 randart_able = "/data/general/objects/random-artifacts/melee.lua",
36 36 egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) },
37 37 }
... ...
... ... @@ -33,7 +33,7 @@ newEntity{
33 33 desc = [[A two-handed massive trident.
34 34 Tridents require the exotic weapons mastery talent to use correctly.]],
35 35 twohanded = true,
36   - ego_bonus_mult = 0.2,
  36 + ego_bonus_mult = 0.4,
37 37 randart_able = "/data/general/objects/random-artifacts/melee.lua",
38 38 egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) },
39 39 }
... ...
... ... @@ -156,6 +156,7 @@ newEntity{ base = "BASE_HEAVY_ARMOR",
156 156 },
157 157 }
158 158
  159 +-- Randart rings are REALLY good, these need to be brought up to par
159 160 newEntity{ base = "BASE_RING",
160 161 power_source = {technique=true},
161 162 define_as = "PRIDE_GLORY",
... ... @@ -175,6 +176,7 @@ newEntity{ base = "BASE_RING",
175 176 combat_dam = 10,
176 177 combat_def = 5,
177 178 combat_armor = 10,
  179 + combat_armor_hardiness = 20,
178 180 fatigue = -15,
179 181 talent_cd_reduction={
180 182 [Talents.T_RUSH]=6,
... ... @@ -265,17 +267,17 @@ newEntity{ base = "BASE_GREATSWORD",
265 267 if not rng.percent(10) then return end
266 268 who:setEffect(who.EFF_FRENZY, 3, {crit=12, power=0.3, dieat=0.25})
267 269 end},
  270 + inc_damage_type = {living=20},
268 271 },
269 272 wielder = {
270   - see_invisible = 25,
271   - inc_stats = { [Stats.STAT_CON] = 5, [Stats.STAT_STR] = 5, [Stats.STAT_DEX] = 5, },
  273 + inc_stats = { [Stats.STAT_CON] = 15, [Stats.STAT_STR] = 15, [Stats.STAT_DEX] = 5, },
272 274 talents_types_mastery = {
273 275 ["technique/2hweapon-cripple"] = 0.2,
274 276 ["technique/2hweapon-offense"] = 0.2,
  277 + ["technique/2hweapon-assault"] = 0.2,
275 278 },
  279 + resists_actor_type = {living=20},
276 280 },
277   - max_power = 60, power_regen = 1,
278   - use_talent = { id = Talents.T_UNSTOPPABLE, level = 1, power = 60 },
279 281 }
280 282
281 283 newEntity{ base = "BASE_WHIP",
... ... @@ -424,7 +426,7 @@ newEntity{ base = "BASE_CLOAK", define_as="GLACIAL_CLOAK",
424 426 engine.DamageType.ICE, dam,
425 427 radius,
426 428 5, nil,
427   - engine.Entity.new{alpha=100, display='', color_br=30, color_bg=60, color_bb=200},
  429 + engine.MapEffect.new{color_br=255, color_bg=255, color_bb=255, effect_shader="shader_images/ice_effect.png"},
428 430 function(e)
429 431 e.radius = e.radius
430 432 return true
... ... @@ -457,7 +459,7 @@ newEntity{ base = "BASE_GREATMAUL", define_as="ROTTING_MAUL",
457 459 physspeed=1.2,
458 460 dammod = {str=1.4},
459 461 convert_damage = {[DamageType.BLIGHT] = 20},
460   - melee_project={[DamageType.CORRUPTED_BLOOD] = 30},
  462 + melee_project={[DamageType.ITEM_BLIGHT_DISEASE] = 50},
461 463 special_on_hit = {desc="Damage nearby creatures", on_kill=1, fct=function(combat, who, target)
462 464 local o, item, inven_id = who:findInAllInventoriesBy("define_as", "ROTTING_MAUL")
463 465 local dam = rng.avg(1,2) * (70+ who:getStr())
... ...
... ... @@ -194,11 +194,11 @@ newEntity{ base = "BASE_LITE", define_as = "WINTERTIDE_PHIAL",
194 194 unided_name = "phial filled with darkness", unique = true, image="object/artifact/wintertide_phial.png",
195 195 name = "Wintertide Phial", color=colors.DARK_GREY,
196 196 desc = [[This phial seems filled with darkness, yet it cleanses your thoughts.]],
197   - level_range = {1, 10},
  197 + level_range = {1, 25},
198 198 rarity = 200,
199 199 encumber = 2,
200 200 cost = 50,
201   - material_level = 1,
  201 + material_level = 2,
202 202
203 203 wielder = {
204 204 lite = 1,
... ... @@ -796,12 +796,13 @@ newEntity{ base = "BASE_SHIELD",
796 796 block = 220,
797 797 physcrit = 9,
798 798 dammod = {str=1.2},
  799 + lifesteal = 8,
799 800 },
800 801 wielder = {
801 802 combat_armor = 4,
802 803 combat_def = 14,
803 804 combat_def_ranged = 14,
804   - inc_stats = { [Stats.STAT_CON] = 5, },
  805 + inc_stats = { [Stats.STAT_CON] = 10, },
805 806 fatigue = 19,
806 807 resists = { [DamageType.BLIGHT] = 25, },
807 808 life_regen = 5,
... ...
... ... @@ -61,20 +61,11 @@ newEntity{
61 61 name = "high-capacity ", prefix=true, instant_resolve=true,
62 62 keywords = {capacity=true},
63 63 level_range = {1, 50},
64   - rarity = 5,
  64 + rarity = 7,
65 65 cost = 6,
66 66 combat = {
67 67 capacity = resolvers.generic(function(e) return e.combat.capacity * rng.float(1.3, 1.6) end),
68 68 },
69   -}
70   -
71   -newEntity{
72   - power_source = {technique=true},
73   - name = "quick-loading ", prefix=true, instant_resolve=true,
74   - keywords = {quick=true},
75   - level_range = {1, 50},
76   - rarity = 5,
77   - cost = 6,
78 69 wielder = {
79 70 ammo_reload_speed = resolvers.mbonus_material(4, 1),
80 71 },
... ... @@ -98,34 +89,17 @@ newEntity{
98 89 name = " of crippling", suffix=true, instant_resolve=true,
99 90 keywords = {crippling=true},
100 91 level_range = {1, 50},
101   - rarity = 3,
  92 + rarity = 15,
  93 + greater_ego = 1,
102 94 cost = 4,
103 95 combat = {
104 96 physcrit = resolvers.mbonus_material(10, 5),
105 97 special_on_crit = {desc="cripple the target", fct=function(combat, who, target)
106   - local power = 5 + (who:combatPhysicalpower()/5)
107   - target:setEffect(target.EFF_CRIPPLE, 4, {src=who, atk=power, dam=power, apply_power=who:combatAttack(combat)})
  98 + target:setEffect(target.EFF_CRIPPLE, 4, {src=who, apply_power=who:combatAttack(combat)})
108 99 end},
109 100 },
110 101 }
111 102
112   --- Greater
113   -newEntity{
114   - power_source = {technique=true},
115   - name = "battle-ranger's ", prefix=true, instant_resolve=true,
116   - keywords = {ranger=true},
117   - level_range = {30, 50},
118   - rarity = 30,
119   - greater_ego = 1,
120   - cost = 6,
121   - combat = {
122   - capacity = resolvers.generic(function(e) return e.combat.capacity * rng.float(1.2, 1.5) end),
123   - },
124   - wielder = {
125   - ammo_reload_speed = resolvers.mbonus_material(4, 1),
126   - },
127   -}
128   -
129 103 newEntity{
130 104 power_source = {technique=true},
131 105 name = " of annihilation", suffix=true, instant_resolve=true,
... ... @@ -158,7 +132,8 @@ newEntity{
158 132 },
159 133 special_on_crit = {desc="splashes the target with acid", fct=function(combat, who, target)
160 134 local power = 5 + (who:combatSpellpower()/10)
161   - target:setEffect(target.EFF_ACID_SPLASH, 5, {src=who, dam=power, atk=power, armor=power})
  135 + local check = math.max(who:combatSpellpower(), who:combatMindpower(), who:combatAttack())
  136 + target:setEffect(target.EFF_ACID_SPLASH, 5, {apply_power = check, src=who, dam=power, atk=power, armor=power})
162 137 end},
163 138 },
164 139 }
... ... @@ -191,7 +166,7 @@ newEntity{
191 166 if #tgts <= 0 then return end
192 167 local a, id = rng.table(tgts)
193 168 table.remove(tgts, id)
194   - local dam = 30 + (who:combatSpellpower())
  169 + local dam = 30 + (who:combatSpellpower())*2
195 170
196 171 who:project(tg, a.x, a.y, engine.DamageType.LIGHTNING, rng.avg(1, dam, 3))
197 172 game.level.map:particleEmitter(x, y, math.max(math.abs(a.x-x), math.abs(a.y-y)), "lightning", {tx=a.x-x, ty=a.y-y})
... ... @@ -265,11 +240,10 @@ newEntity{
265 240 cost = 30,
266 241 combat={
267 242 ranged_project = {
268   - [DamageType.BLIGHT] = resolvers.mbonus_material(15, 5)
269   - },
270   - burst_on_crit = {
271   - [DamageType.CORRUPTED_BLOOD] = resolvers.mbonus_material(25, 5),
  243 + [DamageType.BLIGHT] = resolvers.mbonus_material(15, 5),
  244 + [DamageType.ITEM_BLIGHT_DISEASE] = resolvers.mbonus_material(15, 5),
272 245 },
  246 +
273 247 },
274 248 }
275 249
... ... @@ -283,12 +257,13 @@ newEntity{
283 257 combat = {
284 258 ranged_project = {
285 259 [DamageType.TEMPORAL] = resolvers.mbonus_material(15, 5),
286   - [DamageType.RANDOM_CONFUSION] = resolvers.mbonus_material(10, 5),
  260 + [DamageType.ITEM_TEMPORAL_ENERGIZE] = resolvers.mbonus_material(10, 5),
287 261 },
288 262 },
289 263 }
290 264
291 265 -- Greater Egos
  266 +-- This keeps its conversion because its an excellent swap ego for resistance problems
292 267 newEntity{
293 268 power_source = {arcane=true},
294 269 name = "elemental ", prefix=true, instant_resolve=true,
... ... @@ -324,25 +299,7 @@ newEntity{
324 299 },
325 300 }
326 301
327   -newEntity{
328   - power_source = {arcane=true},
329   - name = "enchanted ", prefix=true, instant_resolve=true,
330   - keywords = {enchanted=true},
331   - level_range = {30, 50},
332   - rarity = 25,
333   - greater_ego = 1,
334   - cost = 6,
335   - combat = {
336   - ammo_regen = resolvers.mbonus_material(3, 1),
337   - },
338   - wielder = {
339   - ammo_reload_speed = resolvers.mbonus_material(4, 1),
340   - },
341   - resolvers.genericlast(function(e)
342   - e.combat.ammo_every = 6 - e.combat.ammo_regen
343   - end),
344   -}
345   -
  302 +-- Fix me
346 303 newEntity{
347 304 power_source = {arcane=true},
348 305 name = "plaguebringer's ", prefix=true, instant_resolve=true,
... ... @@ -354,6 +311,7 @@ newEntity{
354 311 combat = {
355 312 ranged_project = {
356 313 [DamageType.BLIGHT] = resolvers.mbonus_material(15, 5),
  314 + [DamageType.ITEM_BLIGHT_DISEASE] = resolvers.mbonus_material(15, 5),
357 315 },
358 316 talent_on_hit = { [Talents.T_EPIDEMIC] = {level=1, chance=10} },
359 317 },
... ... @@ -376,6 +334,7 @@ newEntity{
376 334 end),
377 335 }
378 336
  337 +-- Pretty scary!
379 338 newEntity{
380 339 power_source = {arcane=true},
381 340 name = " of corruption", suffix=true, instant_resolve=true,
... ... @@ -391,8 +350,9 @@ newEntity{
391 350 },
392 351 special_on_hit = {desc="20% chance to curse the target", fct=function(combat, who, target)
393 352 if not rng.percent(20) then return end
  353 + local check = math.max(who:combatSpellpower(), who:combatMindpower(), who:combatAttack())
394 354 local eff = rng.table{"vuln", "defenseless", "impotence", "death", }
395   - if not who:checkHit(who:combatSpellpower(), target:combatSpellResist()) then return end
  355 + if not who:checkHit(check, target:combatSpellResist()) then return end
396 356 if eff == "vuln" then target:setEffect(target.EFF_CURSE_VULNERABILITY, 2, {power=20})
397 357 elseif eff == "defenseless" then target:setEffect(target.EFF_CURSE_DEFENSELESSNESS, 2, {power=20})
398 358 elseif eff == "impotence" then target:setEffect(target.EFF_CURSE_IMPOTENCE, 2, {power=20})
... ... @@ -416,7 +376,7 @@ newEntity{
416 376 ranged_project = {
417 377 [DamageType.FIRE] = resolvers.mbonus_material(25, 8),
418 378 },
419   - convert_damage = { [DamageType.FIRE] = resolvers.mbonus_material(25, 25),}
  379 + burst_on_crit = { [DamageType.FIRE] = resolvers.mbonus_material(10, 5),}
420 380 },
421 381 }
422 382
... ... @@ -445,7 +405,7 @@ newEntity{
445 405 ranged_project = {
446 406 [DamageType.LIGHTNING] = resolvers.mbonus_material(25, 8),
447 407 },
448   - convert_damage = { [DamageType.LIGHTNING] = resolvers.mbonus_material(25, 25),}
  408 + burst_on_crit = { [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5),}
449 409 },
450 410 }
451 411
... ... @@ -460,7 +420,7 @@ newEntity{
460 420 ranged_project = {
461 421 [DamageType.COLD] = resolvers.mbonus_material(25, 8),
462 422 },
463   - convert_damage = { [DamageType.COLD] = resolvers.mbonus_material(25, 25),}
  423 + burst_on_crit = { [DamageType.COLD] = resolvers.mbonus_material(10, 5),}
464 424 },
465 425 }
466 426
... ... @@ -534,7 +494,7 @@ newEntity{
534 494 cost = 40,
535 495 combat = {
536 496 ranged_project = {
537   - [DamageType.MANABURN] = resolvers.mbonus_material(25, 10),
  497 + [DamageType.ITEM_ANTIMAGIC_MANABURN] = resolvers.mbonus_material(15, 10),
538 498 },
539 499 },
540 500 }
... ... @@ -547,7 +507,7 @@ newEntity{
547 507 rarity = 20,
548 508 cost = 15,
549 509 combat = {
550   - ranged_project={[DamageType.SLIME] = resolvers.mbonus_material(15, 5)},
  510 + ranged_project={[DamageType.ITEM_NATURE_SLOW] = resolvers.mbonus_material(15, 5)},
551 511 },
552 512 }
553 513
... ... @@ -562,7 +522,8 @@ newEntity{
562 522 ranged_project={[DamageType.NATURE] = resolvers.mbonus_material(15, 5)},
563 523 special_on_hit = {desc="25% chance to remove a magical effect", fct=function(combat, who, target)
564 524 if not rng.percent(25) then return end
565   - if not who:checkHit(who:combatMindpower(), target:combatMentalResist()) then game.logSeen(target, "%s resists!", target.name:capitalize()) return nil end
  525 + local check = math.max(who:combatSpellpower(), who:combatMindpower(), who:combatAttack())
  526 + if not who:checkHit(check, target:combatMentalResist()) then game.logSeen(target, "%s resists!", target.name:capitalize()) return nil end
566 527
567 528 local effs = {}
568 529
... ... @@ -606,12 +567,14 @@ newEntity{
606 567 cost = 40,
607 568 combat = {
608 569 ranged_project = {
609   - [DamageType.MANABURN] = resolvers.mbonus_material(25, 10),
  570 + [DamageType.MANABURN] = resolvers.mbonus_material(15, 10),
610 571 },
611 572 special_on_crit = {desc="burns latent spell energy", fct=function(combat, who, target)
612 573 local turns = 1 + math.ceil(who:combatMindpower() / 20)
613   - if not who:checkHit(who:combatMindpower(), target:combatMentalResist()) then game.logSeen(target, "%s resists!", target.name:capitalize()) return nil end
  574 + local check = math.max(who:combatSpellpower(), who:combatMindpower(), who:combatAttack())
  575 + if not who:checkHit(check, target:combatMentalResist()) then game.logSeen(target, "%s resists!", target.name:capitalize()) return nil end
614 576
  577 + -- Pick a spell
615 578 local tids = {}
616 579 for tid, lev in pairs(target.talents) do
617 580 local t = target:getTalentFromId(tid)
... ... @@ -646,7 +609,7 @@ newEntity{
646 609
647 610 newEntity{
648 611 power_source = {antimagic=true},
649   - name = " of disruption", suffix=true, instant_resolve=true,
  612 + name = " of persecution", suffix=true, instant_resolve=true,
650 613 keywords = {disruption=true},
651 614 level_range = {30, 50},
652 615 greater_ego = 1,
... ... @@ -654,11 +617,11 @@ newEntity{
654 617 cost = 40,
655 618 combat = {
656 619 inc_damage_type = {
657   - undead=resolvers.mbonus_material(25, 5),
658   - construct=resolvers.mbonus_material(25, 5),
  620 + unnatural=resolvers.mbonus_material(25, 5),
659 621 },
660 622 special_on_hit = {desc="disrupts spell-casting", fct=function(combat, who, target)
661   - target:setEffect(target.EFF_SPELL_DISRUPTION, 10, {src=who, power = 10, max = 50, apply_power=who:combatMindpower()})
  623 + local check = math.max(who:combatSpellpower(), who:combatMindpower(), who:combatAttack())
  624 + target:setEffect(target.EFF_SPELL_DISRUPTION, 10, {src=who, power = 10, max = 50, apply_power=check})
662 625 end},
663 626 },
664 627 }
... ... @@ -672,10 +635,11 @@ newEntity{
672 635 rarity = 50,
673 636 cost = 40,
674 637 combat = {
675   - ranged_project={[DamageType.SLIME] = resolvers.mbonus_material(15, 5)},
  638 + ranged_project={[DamageType.ITEM_NATURE_SLOW] = resolvers.mbonus_material(15, 5)},
676 639 special_on_hit = {desc="leeches stamina from the target", fct=function(combat, who, target)
677 640 if target and target:getStamina() > 0 then
678   - local leech = who:combatMindpower() / 50
  641 + local check = math.max(who:combatSpellpower(), who:combatMindpower(), who:combatAttack())
  642 + local leech = check / 50
679 643 local leeched = math.min(leech, target:getStamina())
680 644 who:incStamina(leeched)
681 645 target:incStamina(-leeched)
... ... @@ -696,8 +660,7 @@ newEntity{
696 660 cost = 20,
697 661 combat = {
698 662 ranged_project={[DamageType.DARKNESS] = resolvers.mbonus_material(15, 5)},
699   - inc_damage_type = {humanoid=resolvers.mbonus_material(25, 5)},
700   - inc_damage_type = {animal=resolvers.mbonus_material(25, 5)},
  663 + inc_damage_type = {living=resolvers.mbonus_material(15, 5)},
701 664 },
702 665 }
703 666
... ... @@ -709,16 +672,19 @@ newEntity{
709 672 rarity = 15,
710 673 cost = 10,
711 674 combat = {
712   - ammo_regen = resolvers.mbonus_material(3, 1),
713 675 ranged_project={
714   - [DamageType.MIND] = resolvers.mbonus_material(30, 10),
  676 + [DamageType.MIND] = resolvers.mbonus_material(20, 5),
  677 + [DamageType.ITEM_MIND_GLOOM] = resolvers.mbonus_material(25, 10)
715 678 },
716   - convert_damage = {
717   - [DamageType.MIND] = resolvers.mbonus_material(25, 25),
  679 + },
  680 + wielder = {
  681 + inc_stats = {
  682 + [Stats.STAT_WIL] = resolvers.mbonus_material(6, 1),
  683 + [Stats.STAT_CUN] = resolvers.mbonus_material(6, 1),
718 684 },
719 685 },
720 686 resolvers.genericlast(function(e)
721   - e.combat.ammo_every = 6 - e.combat.ammo_regen
  687 + e.combat.ammo_every = 6 - (e.combat.ammo_regen or 0)
722 688 end),
723 689 }
724 690
... ... @@ -731,11 +697,12 @@ newEntity{
731 697 cost = 10,
732 698 combat = {
733 699 ranged_project={
734   - [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 5),
  700 + [DamageType.PHYSICAL] = resolvers.mbonus_material(35, 15),
735 701 },
736 702 special_on_hit = {desc="10% chance to knock the target back", fct=function(combat, who, target)
737 703 if not rng.percent(10) then return nil end
738   - if not who:checkHit(who:combatMindpower(), target:combatPhysicalResist()) then game.logSeen(target, "%s resists!", target.name:capitalize()) return nil end
  704 + local check = math.max(who:combatSpellpower(), who:combatMindpower(), who:combatAttack())
  705 + if not who:checkHit(check, target:combatPhysicalResist()) then game.logSeen(target, "%s resists!", target.name:capitalize()) return nil end
739 706 if target:canBe("knockback") then
740 707 target:knockback(who.x, who.y, 2)
741 708 game.logSeen(target, "%s is knocked back!", target.name:capitalize())
... ... @@ -744,6 +711,7 @@ newEntity{
744 711 },
745 712 }
746 713
  714 +-- Very, very powerful. Perhaps turn proc limit
747 715 newEntity{
748 716 power_source = {psionic=true},
749 717 name = " of amnesia", suffix=true, instant_resolve=true,
... ... @@ -751,12 +719,14 @@ newEntity{
751 719 level_range = {10, 50},
752 720 rarity = 25, -- very rare because no one can remember how to make them... haha
753 721 cost = 15,
  722 + greater_ego = 1,
754 723 combat = {
755 724 special_on_hit = {desc="25% chance to put talents on cooldown", fct=function(combat, who, target)
756 725 if not rng.percent(25) then return nil end
757 726 local turns = 1 + math.ceil(who:combatMindpower() / 20)
758 727 local number = 2 + math.ceil(who:combatMindpower() / 50)
759   - if not who:checkHit(who:combatMindpower(), target:combatMentalResist()) then game.logSeen(target, "%s resists!", target.name:capitalize()) return nil end
  728 + local check = math.max(who:combatSpellpower(), who:combatMindpower(), who:combatAttack())
  729 + if not who:checkHit(check, target:combatMentalResist()) then game.logSeen(target, "%s resists!", target.name:capitalize()) return nil end
760 730
761 731 local tids = {}
762 732 for tid, lev in pairs(target.talents) do
... ... @@ -788,15 +758,12 @@ newEntity{
788 758 [DamageType.MIND] = resolvers.mbonus_material(15, 5),
789 759 [DamageType.DARKNESS] = resolvers.mbonus_material(15, 5),
790 760 },
791   - convert_damage ={
792   - [DamageType.MIND] = resolvers.mbonus_material(20, 10),
793   - [DamageType.DARKNESS] = resolvers.mbonus_material(15, 10),
794   - },
795 761 special_on_hit = {desc="20% chance to torment the target", fct=function(combat, who, target)
796 762 if not rng.percent(20) then return end
797 763 local eff = rng.table{"stun", "blind", "pin", "confusion", "silence",}
798 764 if not target:canBe(eff) then return end
799   - if not who:checkHit(who:combatMindpower(), target:combatMentalResist()) then return end
  765 + local check = math.max(who:combatSpellpower(), who:combatMindpower(), who:combatAttack())
  766 + if not who:checkHit(check, target:combatMentalResist()) then return end
800 767 if eff == "stun" then target:setEffect(target.EFF_STUNNED, 3, {})
801 768 elseif eff == "blind" then target:setEffect(target.EFF_BLINDED, 3, {})
802 769 elseif eff == "pin" then target:setEffect(target.EFF_PINNED, 3, {})
... ...
... ... @@ -413,6 +413,9 @@ newEntity{
413 413 wielder = {
414 414 combat_spellpower = resolvers.mbonus_material(3, 3),
415 415 combat_spellcrit = resolvers.mbonus_material(3, 3),
  416 + inc_stats = {
  417 + [Stats.STAT_MAG] = resolvers.mbonus_material(5, 1),
  418 + },
416 419 inc_damage = {
417 420 [DamageType.FIRE] = resolvers.mbonus_material(4, 4),
418 421 [DamageType.COLD] = resolvers.mbonus_material(4, 4),
... ... @@ -560,8 +563,8 @@ newEntity{
560 563 [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5),
561 564 },
562 565 on_melee_hit = {
563   - [DamageType.LIGHT] = resolvers.mbonus_material(10, 5),
564   - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5),
  566 + [DamageType.ITEM_LIGHT_BLIND] = resolvers.mbonus_material(10, 5),
  567 + [DamageType.ITEM_DARKNESS_NUMBING] = resolvers.mbonus_material(10, 5),
565 568 },
566 569 melee_project={
567 570 [DamageType.LIGHT] = resolvers.mbonus_material(10, 5),
... ...
... ... @@ -327,4 +327,24 @@ newEntity{
327 327 wielder = {
328 328 max_life = resolvers.mbonus_material(40, 20),
329 329 },
  330 +}
  331 +
  332 +-- The "unnatural" classification partly exists to add another in-theme defense for anti-magic that isn't reactive like healing
  333 +--
  334 +newEntity{
  335 + power_source = {antimagic=true},
  336 + name = " of natural resilience", suffix=true, instant_resolve=true,
  337 + keywords = {natural_resilience=true},
  338 + level_range = {30, 50},
  339 + rarity = 20,
  340 + cost = 10,
  341 + greater_ego = 1,
  342 + wielder = {
  343 + resists_actor_type = {unnatural=resolvers.mbonus_material(10, 5)},
  344 + resists={
  345 + [DamageType.NATURE] = resolvers.mbonus_material(10, 10),
  346 + [DamageType.BLIGHT] = resolvers.mbonus_material(10, 10),
  347 + },
  348 + max_life = resolvers.mbonus_material(40, 20),
  349 + },
330 350 }
\ No newline at end of file
... ...
... ... @@ -444,4 +444,18 @@ newEntity{
444 444 paradox_reduce_fails = resolvers.mbonus_material(20, 20),
445 445 max_psi = resolvers.mbonus_material(20, 20),
446 446 },
  447 +}
  448 +
  449 +-- Noble's hate the common folk. or common hydras. or something.
  450 +newEntity{
  451 + power_source = {technique=true},
  452 + name = "noble's ", prefix=true, instant_resolve=true,
  453 + keywords = {noble=true},
  454 + level_range = {10, 50},
  455 + greater_ego = 1,
  456 + rarity = 20,
  457 + cost = 40,
  458 + wielder = {
  459 + resists_actor_type = {["summoned"] = resolvers.mbonus_material(30, 15),},
  460 + },
447 461 }
\ No newline at end of file
... ...
... ... @@ -81,6 +81,7 @@ newEntity{
81 81 greater_ego = 1,
82 82 rarity = 18,
83 83 cost = 40,
  84 + use_no_energy = true,
84 85 wielder = {
85 86 inc_stats = {
86 87 [Stats.STAT_MAG] = resolvers.mbonus_material(2, 2),
... ... @@ -172,6 +173,7 @@ newEntity{
172 173 greater_ego = 1,
173 174 rarity = 18,
174 175 cost = 40,
  176 + use_no_energy = true,
175 177 resolvers.charmt(Talents.T_DISENGAGE, {1,2,3}, 15),
176 178 wielder = {
177 179 inc_stats = {
... ... @@ -191,7 +193,7 @@ newEntity{
191 193 cost = 20,
192 194 wielder = {
193 195 combat_dam = resolvers.mbonus_material(3, 3),
194   - combat_apr = resolvers.mbonus_material(3, 3),
  196 + combat_apr = resolvers.mbonus_material(10, 3),
195 197 combat_physcrit = resolvers.mbonus_material(3, 3),
196 198 },
197 199 }
... ... @@ -265,6 +267,22 @@ newEntity{
265 267 },
266 268 }
267 269
  270 +
  271 +newEntity{
  272 + power_source = {arcane=true},
  273 + name = "undeterred ", prefix=true, instant_resolve=true,
  274 + keywords = {undeterred=true},
  275 + level_range = {10, 50},
  276 + greater_ego = 1,
  277 + rarity = 15,
  278 + cost = 60,
  279 + wielder = {
  280 + stun_immune = resolvers.mbonus_material(30, 20, function(e, v) v=v/100 return 0, v end),
  281 + silence_immune = resolvers.mbonus_material(30, 20, function(e, v) v=v/100 return 0, v end),
  282 + confusion_immune = resolvers.mbonus_material(30, 20, function(e, v) v=v/100 return 0, v end),
  283 + },
  284 +}
  285 +
268 286 newEntity{
269 287 power_source = {technique=true},
270 288 name = "reinforced ", prefix=true, instant_resolve=true,
... ... @@ -311,7 +329,8 @@ newEntity{
311 329 greater_ego = 1,
312 330 rarity = 30,
313 331 cost = 60,
314   - resolvers.charmt(Talents.T_HEAVE, {2,3,4}, 15),
  332 + use_no_energy = true,
  333 + resolvers.charmt(Talents.T_HEAVE, {2,3,4}, 10),
315 334 wielder = {
316 335 inc_stats = {
317 336 [Stats.STAT_STR] = resolvers.mbonus_material(7, 3),
... ...
... ... @@ -122,7 +122,7 @@ newEntity{
122 122 wielder = {
123 123 combat_dam = resolvers.mbonus_material(5, 5),
124 124 combat_apr = resolvers.mbonus_material(4, 4),
125   - combat_critical_power = resolvers.mbonus_material(15, 15),
  125 + combat_critical_power = resolvers.mbonus_material(10, 10),
126 126 },
127 127 resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 2) end),
128 128 }
... ... @@ -249,7 +249,7 @@ newEntity{
249 249 combat_mentalresist = resolvers.mbonus_material(10, 5),
250 250 combat_physresist = resolvers.mbonus_material(10, 5),
251 251 combat_spellresist = resolvers.mbonus_material(10, 5),
252   - max_life = resolvers.mbonus_material(70, 40),
  252 + max_life = resolvers.mbonus_material(50, 40),
253 253 },
254 254 }
255 255
... ...
... ... @@ -135,7 +135,6 @@ newEntity{
135 135 melee_project= { [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5) },
136 136 combat = {
137 137 burst_on_crit= { [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5) },
138   - convert_damage = { [DamageType.LIGHTNING] = resolvers.mbonus_material(25, 25) },
139 138 talent_on_hit = { [Talents.T_LIGHTNING_BREATH] = {level=resolvers.genericlast(function(e) return e.material_level end), chance=10} },
140 139 },
141 140 },
... ... @@ -167,11 +166,11 @@ newEntity{
167 166 cost = 5,
168 167 wielder = {
169 168 inc_damage= { [DamageType.DARKNESS] = resolvers.mbonus_material(8, 3), },
170   - resists = { [DamageType.DARKNESS] = resolvers.mbonus_material(5, 5), },
171   - melee_project= { [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5) },
  169 + resists = { [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), },
  170 + melee_project= { [DamageType.DARKNESS] = resolvers.mbonus_material(15, 5) },
172 171 combat = {
173   - burst_on_crit= { [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5) },
174   - talent_on_hit = { [Talents.T_MOONLIGHT_RAY] = {level=resolvers.genericlast(function(e) return e.material_level end), chance=20} },
  172 + melee_project= { [DamageType.ITEM_DARKNESS_NUMBING] = resolvers.mbonus_material(10, 5) },
  173 + --talent_on_hit = { [Talents.T_MOONLIGHT_RAY] = {level=resolvers.genericlast(function(e) return e.material_level end), chance=20} },
175 174 },
176 175 },
177 176 }
... ... @@ -184,11 +183,11 @@ newEntity{
184 183 cost = 5,
185 184 wielder = {
186 185 inc_damage= { [DamageType.LIGHT] = resolvers.mbonus_material(8, 3), },
187   - resists = { [DamageType.LIGHT] = resolvers.mbonus_material(5, 5), },
188   - melee_project= { [DamageType.LIGHT] = resolvers.mbonus_material(10, 5) },
  186 + resists = { [DamageType.LIGHT] = resolvers.mbonus_material(10, 5), },
  187 + melee_project= { [DamageType.LIGHT] = resolvers.mbonus_material(15, 5) },
189 188 combat = {
190   - burst_on_crit= { [DamageType.LIGHT] = resolvers.mbonus_material(10, 5) },
191   - talent_on_hit = { [Talents.T_SEARING_LIGHT] = {level=resolvers.genericlast(function(e) return e.material_level end), chance=20} },
  189 + melee_project= { [DamageType.ITEM_LIGHT_BLIND] = resolvers.mbonus_material(10, 5) },
  190 + --talent_on_hit = { [Talents.T_SEARING_LIGHT] = {level=resolvers.genericlast(function(e) return e.material_level end), chance=20} },
192 191 },
193 192 },
194 193 }
... ... @@ -201,11 +200,11 @@ newEntity{
201 200 cost = 5,
202 201 wielder = {
203 202 inc_damage= { [DamageType.TEMPORAL] = resolvers.mbonus_material(8, 3), },
204   - resists = { [DamageType.TEMPORAL] = resolvers.mbonus_material(5, 5), },
205   - melee_project= { [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5) },
  203 + resists = { [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), },
  204 + melee_project= { [DamageType.TEMPORAL] = resolvers.mbonus_material(15, 5) },
206 205 combat = {
207   - burst_on_crit= { [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5) },
208   - talent_on_hit = { [Talents.T_QUANTUM_SPIKE] = {level=resolvers.genericlast(function(e) return e.material_level end), chance=20} },
  206 + melee_project= { [DamageType.ITEM_TEMPORAL_ENERGIZE] = resolvers.mbonus_material(10, 5) },
  207 + --talent_on_hit = { [Talents.T_QUANTUM_SPIKE] = {level=resolvers.genericlast(function(e) return e.material_level end), chance=20} },
209 208 },
210 209 },
211 210 }
... ... @@ -306,7 +305,7 @@ newEntity{
306 305 combat_spellcrit = resolvers.mbonus_material(15, 5),
307 306 combat_mindcrit = resolvers.mbonus_material(15, 5),
308 307 combat_physcrit = resolvers.mbonus_material(15, 5),
309   - combat_critical_power = resolvers.mbonus_material(35, 5),
  308 + combat_critical_power = resolvers.mbonus_material(10, 5),
310 309 combat = {
311 310 physcrit = resolvers.mbonus_material(10, 4),
312 311 dam = resolvers.mbonus_material(7, 3),
... ... @@ -396,7 +395,7 @@ newEntity{
396 395 power_source = {antimagic=true},
397 396 name = " of butchering", suffix=true, instant_resolve=true,
398 397 keywords = {butchering=true},
399   - level_range = {30, 50},
  398 + level_range = {10, 50},
400 399 greater_ego = 1,
401 400 rarity = 30,
402 401 cost = 60,
... ... @@ -406,12 +405,62 @@ newEntity{
406 405 },
407 406 combat_spellresist = resolvers.mbonus_material(15, 8),
408 407 combat_atk = resolvers.mbonus_material(10, 4),