From cd08e8076b5cc67ba4f68b0a1bbe92031b0789a9 Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Sun, 12 Feb 2012 21:28:42 +0000 Subject: [PATCH] Weapons now (mostly) have three stats: damage, maximum accuracy (used in checkHit()), and critical power (replaces the default 1.5x crit multiplier). Item tooltips much easier to read Weapon tooltips display useful information, such as how much damage the weapon will actually do. (This needs further improvement, as it doesn't account for percentage damage increases and decreases, such as those imposed by shield wall or offhand penalties) Quivers and shot pouches are now non-consumable items, but require reloading using the new 'Reload' talent. Shields are much more active and focus on damage mitigation. Riposte now works with a Shield's Block talent Staff, shield, bow, sling, and ammo egos mostly rewritten. Resolver for egos has been changed to centralize default ego value information for ease of balancing. Items can now grant talents (passive or active) Use talents dialog now displays passive talents, so that item-granted passives show up someplace. git-svn-id: http://svn.net-core.org/repos/t-engine4@4842 51575b47-30f0-44d4-a5cc-537603b46e54 --- game/engines/default/engine/Projectile.lua | 2 +- game/modules/tome/ai/tactical.lua | 15 +- game/modules/tome/class/Actor.lua | 98 ++- game/modules/tome/class/Object.lua | 467 ++++++++++---- game/modules/tome/class/PlayerDisplay.lua | 5 +- game/modules/tome/class/interface/Archery.lua | 126 ++-- game/modules/tome/class/interface/Combat.lua | 189 ++++-- .../tome/class/interface/PlayerDumpJSON.lua | 10 +- .../tome/class/interface/TooltipsData.lua | 15 +- game/modules/tome/class/uiset/Minimalist.lua | 2 +- .../tome/data/birth/classes/warrior.lua | 5 +- .../modules/tome/data/chats/command-staff.lua | 269 ++++++++ game/modules/tome/data/chats/ward.lua | 84 +++ game/modules/tome/data/damage_types.lua | 85 ++- game/modules/tome/data/general/npcs/ant.lua | 2 +- .../data/general/npcs/aquatic_critter.lua | 2 +- game/modules/tome/data/general/npcs/bear.lua | 2 +- .../modules/tome/data/general/npcs/canine.lua | 2 +- .../tome/data/general/npcs/cold-drake.lua | 2 +- .../modules/tome/data/general/npcs/feline.lua | 10 +- .../tome/data/general/npcs/fire-drake.lua | 2 +- game/modules/tome/data/general/npcs/ghoul.lua | 4 +- .../tome/data/general/npcs/gwelgoroth.lua | 2 +- .../data/general/npcs/multihued-drake.lua | 2 +- game/modules/tome/data/general/npcs/ritch.lua | 2 +- .../tome/data/general/npcs/sandworm.lua | 2 +- .../tome/data/general/npcs/snow-giant.lua | 2 +- .../modules/tome/data/general/npcs/spider.lua | 10 +- .../tome/data/general/npcs/storm-drake.lua | 2 +- .../tome/data/general/npcs/telugoroth.lua | 10 +- game/modules/tome/data/general/npcs/troll.lua | 2 +- .../tome/data/general/npcs/vampire.lua | 2 +- game/modules/tome/data/general/npcs/xorn.lua | 2 +- .../tome/data/general/objects/2haxes.lua | 53 +- .../tome/data/general/objects/2hmaces.lua | 53 +- .../tome/data/general/objects/2hswords.lua | 51 +- .../tome/data/general/objects/2htridents.lua | 50 +- .../tome/data/general/objects/axes.lua | 49 +- .../objects/boss-artifacts-far-east.lua | 7 +- .../data/general/objects/boss-artifacts.lua | 128 ++-- .../tome/data/general/objects/bows.lua | 158 +++-- .../tome/data/general/objects/egos/ammo.lua | 226 +++++-- .../data/general/objects/egos/amulets.lua | 174 +++--- .../tome/data/general/objects/egos/armor.lua | 185 +++--- .../tome/data/general/objects/egos/belt.lua | 178 +++--- .../tome/data/general/objects/egos/boots.lua | 132 ++-- .../tome/data/general/objects/egos/bow.lua | 81 +-- .../tome/data/general/objects/egos/cloak.lua | 175 +++--- .../tome/data/general/objects/egos/digger.lua | 100 +-- .../tome/data/general/objects/egos/gloves.lua | 274 ++++----- .../data/general/objects/egos/heavy-armor.lua | 22 +- .../tome/data/general/objects/egos/helm.lua | 185 +++--- .../data/general/objects/egos/light-armor.lua | 8 +- .../data/general/objects/egos/light-boots.lua | 2 +- .../tome/data/general/objects/egos/lite.lua | 122 ++-- .../general/objects/egos/massive-armor.lua | 24 +- .../tome/data/general/objects/egos/ranged.lua | 277 +++++++++ .../tome/data/general/objects/egos/rings.lua | 201 +++--- .../tome/data/general/objects/egos/robe.lua | 222 +++---- .../tome/data/general/objects/egos/shield.lua | 284 +++++---- .../tome/data/general/objects/egos/sling.lua | 81 +-- .../tome/data/general/objects/egos/staves.lua | 575 ++++++++---------- .../tome/data/general/objects/egos/weapon.lua | 248 ++++---- .../data/general/objects/egos/wizard-hat.lua | 130 ++-- .../tome/data/general/objects/gauntlets.lua | 37 +- .../tome/data/general/objects/gloves.lua | 34 +- .../tome/data/general/objects/knifes.lua | 53 +- .../tome/data/general/objects/maces.lua | 49 +- .../data/general/objects/quest-artifacts.lua | 18 +- .../tome/data/general/objects/shields.lua | 80 +-- .../tome/data/general/objects/slings.lua | 154 +++-- .../tome/data/general/objects/staves.lua | 84 ++- .../tome/data/general/objects/swords.lua | 49 +- .../tome/data/general/objects/whips.lua | 3 +- .../objects/world-artifacts-far-east.lua | 6 +- .../data/general/objects/world-artifacts.lua | 327 +++++----- .../tome/data/gfx/effects/counterstrike.png | Bin 0 -> 2275 bytes game/modules/tome/data/gfx/particles/ward.lua | 53 ++ game/modules/tome/data/gfx/talents/block.png | Bin 0 -> 4274 bytes .../tome/data/gfx/talents/bloodflow.png | Bin 0 -> 3295 bytes .../tome/data/gfx/talents/command_staff.png | Bin 0 -> 3803 bytes .../gfx/talents/elemental_retribution.png | Bin 0 -> 4320 bytes .../tome/data/gfx/talents/fearscape_fog.png | Bin 0 -> 3100 bytes .../tome/data/gfx/talents/lifebind.png | Bin 0 -> 2214 bytes .../tome/data/gfx/talents/perception.png | Bin 0 -> 3049 bytes game/modules/tome/data/gfx/talents/reload.png | Bin 0 -> 4773 bytes .../tome/data/gfx/talents/savagery.png | Bin 0 -> 3767 bytes .../tome/data/gfx/talents/soul_drain.png | Bin 0 -> 4903 bytes game/modules/tome/data/gfx/talents/ward.png | Bin 0 -> 3552 bytes .../tome/data/talents/celestial/light.lua | 2 +- .../tome/data/talents/chronomancy/energy.lua | 2 +- .../tome/data/talents/chronomancy/matter.lua | 2 +- .../tome/data/talents/chronomancy/paradox.lua | 2 +- .../talents/chronomancy/spacetime-folding.lua | 2 +- .../talents/chronomancy/spacetime-weaving.lua | 4 +- .../data/talents/chronomancy/timetravel.lua | 22 +- .../tome/data/talents/corruptions/blight.lua | 2 +- .../tome/data/talents/cunning/stealth.lua | 6 +- .../tome/data/talents/gifts/earthen-vines.lua | 2 +- .../data/talents/gifts/summon-distance.lua | 4 +- .../tome/data/talents/gifts/summon-melee.lua | 6 +- .../data/talents/gifts/summon-utility.lua | 2 +- .../tome/data/talents/misc/horrors.lua | 2 +- .../tome/data/talents/misc/inscriptions.lua | 8 +- game/modules/tome/data/talents/misc/item.lua | 491 +++++++++++++++ game/modules/tome/data/talents/misc/misc.lua | 3 + game/modules/tome/data/talents/misc/races.lua | 2 +- .../tome/data/talents/psionic/other.lua | 19 +- .../spells/advanced-necrotic-minions.lua | 8 +- .../tome/data/talents/spells/conveyance.lua | 4 +- .../tome/data/talents/spells/golemancy.lua | 2 +- .../data/talents/spells/necrotic-minions.lua | 14 +- .../tome/data/talents/spells/staff-combat.lua | 9 +- .../tome/data/talents/techniques/2hweapon.lua | 2 +- .../tome/data/talents/techniques/archery.lua | 3 + .../tome/data/talents/techniques/bow.lua | 12 +- .../talents/techniques/combat-training.lua | 26 +- .../talents/techniques/finishing-moves.lua | 2 +- .../tome/data/talents/techniques/sling.lua | 13 +- .../talents/techniques/unarmed-discipline.lua | 2 +- .../data/talents/techniques/weaponshield.lua | 15 +- .../tome/data/timed_effects/magical.lua | 82 +++ .../tome/data/timed_effects/mental.lua | 41 +- .../modules/tome/data/timed_effects/other.lua | 31 +- .../tome/data/timed_effects/physical.lua | 72 ++- .../modules/tome/data/zones/arena/objects.lua | 24 +- .../tome/data/zones/deep-bellow/npcs.lua | 2 +- .../tome/data/zones/high-peak/objects.lua | 34 +- .../tome/data/zones/norgos-lair/npcs.lua | 2 +- .../tome/data/zones/old-forest/npcs.lua | 2 +- .../tome/data/zones/paradox-plane/objects.lua | 11 +- .../tome/data/zones/ritch-tunnels/npcs.lua | 4 +- .../tome/data/zones/telmur/objects.lua | 13 +- .../data/zones/tutorial-combat-stats/npcs.lua | 4 +- game/modules/tome/dialogs/CharacterSheet.lua | 166 +++-- game/modules/tome/dialogs/LevelupDialog.lua | 10 +- game/modules/tome/dialogs/SentientWeapon.lua | 205 +++++++ game/modules/tome/dialogs/UseTalents.lua | 11 +- game/modules/tome/resolvers.lua | 219 ++++++- 139 files changed, 5409 insertions(+), 3057 deletions(-) create mode 100644 game/modules/tome/data/chats/command-staff.lua create mode 100644 game/modules/tome/data/chats/ward.lua create mode 100644 game/modules/tome/data/general/objects/egos/ranged.lua create mode 100644 game/modules/tome/data/gfx/effects/counterstrike.png create mode 100644 game/modules/tome/data/gfx/particles/ward.lua create mode 100644 game/modules/tome/data/gfx/talents/block.png create mode 100644 game/modules/tome/data/gfx/talents/bloodflow.png create mode 100644 game/modules/tome/data/gfx/talents/command_staff.png create mode 100644 game/modules/tome/data/gfx/talents/elemental_retribution.png create mode 100644 game/modules/tome/data/gfx/talents/fearscape_fog.png create mode 100644 game/modules/tome/data/gfx/talents/lifebind.png create mode 100644 game/modules/tome/data/gfx/talents/perception.png create mode 100644 game/modules/tome/data/gfx/talents/reload.png create mode 100644 game/modules/tome/data/gfx/talents/savagery.png create mode 100644 game/modules/tome/data/gfx/talents/soul_drain.png create mode 100644 game/modules/tome/data/gfx/talents/ward.png create mode 100644 game/modules/tome/data/talents/misc/item.lua create mode 100644 game/modules/tome/dialogs/SentientWeapon.lua diff --git a/game/engines/default/engine/Projectile.lua b/game/engines/default/engine/Projectile.lua index 1fe5486a28..7aed1cdb7f 100644 --- a/game/engines/default/engine/Projectile.lua +++ b/game/engines/default/engine/Projectile.lua @@ -261,7 +261,7 @@ function _M:makeProject(src, display, def, do_move, do_act, do_stop) def.tg.talent_id = def.tg.talent.id def.tg.talent = nil end - speed = speed or 10 + speed = def.tg.speed or speed or 10 local p = _M.new{ name = name, display = display.display or ' ', color = display.color or colors.WHITE, image = display.image or nil, diff --git a/game/modules/tome/ai/tactical.lua b/game/modules/tome/ai/tactical.lua index 1bb2239d84..99767abb57 100644 --- a/game/modules/tome/ai/tactical.lua +++ b/game/modules/tome/ai/tactical.lua @@ -166,7 +166,7 @@ newAI("use_tactical", function(self) val = val * (nb_foes_hit - ally_compassion * nb_allies_hit - self_compassion * nb_self_hit) end -- Only take values greater than 0... allows the ai_talents to turn talents off - if val > 0 then + if val > 0 and not self:hasEffect(self.EFF_RELOADING) then if not avail[tact] then avail[tact] = {} end -- Save the tactic, if the talent is instant it gets a huge bonus -- Note the addition of a less than one random value, this means the sorting will randomly shift equal values @@ -181,7 +181,7 @@ newAI("use_tactical", function(self) end if ok then local want = {} - + local need_heal = 0 local life = 100 * self.life / self.max_life if life < 20 then need_heal = need_heal + 10 * self_compassion / 5 @@ -196,6 +196,16 @@ newAI("use_tactical", function(self) want.heal = need_heal end + -- Need ammo + local a = self:hasAmmo() + if avail.ammo and a and not self:hasEffect(self.EFF_RELOADING) then + want.ammo = 0 + local ammo = 100 * a.combat.shots_left / a.combat.capacity + if ammo == 0 then want.ammo = want.ammo + 10 + elseif ammo < 100 then want.ammo = want.ammo + 0.5 + end + end + -- Need mana if avail.mana then want.mana = 0 @@ -363,6 +373,7 @@ newAI("use_tactical", function(self) table.sort(selected_talents, function(a,b) return a.val > b.val end) local tid = selected_talents[1].tid print("Tactical choice:", res[1][1], tid) + if a then print("shots left:", a.combat.shots_left) end self:useTalent(tid) return true else diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 7556125661..941eac4b5d 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -197,19 +197,27 @@ function _M:init(t, no_default) mod.class.interface.ActorInscriptions.init(self, t) -- Default melee barehanded damage + self.default_dam = 1 + self.default_max_acc = 75 + self.default_critical_power = 1.1 self.combat = self.combat or { - dam=1, - atk=1, apr=0, + dam=self.default_dam, + atk=0, apr=0, physcrit=0, physspeed =1, - dammod = { str=1 }, - damrange=1.1, + critical_power = self.default_critical_power, + max_acc = self.default_max_acc, + + dammod = { str=0.1 }, + damrange=1, talented = "unarmed", } -- Insures we have certain values for gloves to modify - self.combat.damrange = self.combat.damrange or 1.1 + self.combat.damrange = self.combat.damrange or 1 self.combat.physspeed = self.combat.physspeed or 1 - self.combat.dammod = self.combat.dammod or {str=0.6} + self.combat.dammod = self.combat.dammod or {str=0.1} + self.combat.critical_power = self.combat.critical_power or self.default_critical_power + self.combat.max_acc = self.combat.max_acc or self.default_max_acc self.talents[self.T_ATTACK] = self.talents[self.T_ATTACK] or 1 @@ -299,6 +307,7 @@ function _M:actBase() if not self:attr("no_talents_cooldown") then self:cooldownTalents() end -- Regen resources self:regenLife() + self:regenAmmo() if self:knowTalent(self.T_UNNATURAL_BODY) then local t = self:getTalentFromId(self.T_UNNATURAL_BODY) t.do_regenLife(self, t) @@ -1056,7 +1065,7 @@ function _M:tooltip(x, y, seen_by) if #resists > 0 then ts:add("Resists: ", table.concat(resists, ','), true) end ts:add("Hardiness/Armour: ", tostring(math.floor(self:combatArmorHardiness())), '% / ', tostring(math.floor(self:combatArmor())), true) ts:add("Size: ", {"color", "ANTIQUE_WHITE"}, self:TextSizeCategory(), {"color", "WHITE"}, true) - + ts:add("#FFD700#Accuracy#FFFFFF#: ", self:colorStats("combatAttack"), " ") ts:add("#0080FF#Defense#FFFFFF#: ", self:colorStats("combatDefense"), true) ts:add("#FFD700#P. power#FFFFFF#: ", self:colorStats("combatPhysicalpower"), " ") @@ -1096,6 +1105,22 @@ function _M:regenLife() end end +function _M:regenAmmo() + local ammo = self:hasAmmo() + --if not ammo then return end + local r = (ammo and ammo.combat and ammo.combat.ammo_every) + if not r then return end + if ammo.combat.shots_left == ammo.combat.capacity then return end + --print("reload every r, where r is:", r) + ammo.combat.reload_counter = (ammo.combat.reload_counter or 0) + 1 + --print("reload counter:", ammo.combat.reload_counter) + if ammo.combat.reload_counter == r then + ammo.combat.reload_counter = 0 + ammo.combat.shots_left = math.min(ammo.combat.capacity, (ammo.combat.shots_left + 1)) + end + +end + --- Called before healing function _M:onHeal(value, src) if self:hasEffect(self.EFF_UNSTOPPABLE) then return 0 end @@ -2093,6 +2118,14 @@ function _M:onWear(o, bypass_set) t.on_onWear(self, t, o) end + -- learn item talents + + if o.wielder and o.wielder.learn_talent then + for tid, level in pairs(o.wielder.learn_talent) do + self:learnItemTalent(o, tid, level) + end + end + self:updateModdableTile() if self == game.player then game:playSound("actions/wear") end end @@ -2145,6 +2178,16 @@ function _M:onTakeoff(o, bypass_set) t.on_onTakeOff(self, t, o) end + if o.wielder and o.wielder.learn_talent then + for tid, level in pairs(o.wielder.learn_talent) do + self:unlearnItemTalent(o, tid, level) + end + end + + if o.subtype == "arrow" or o.subtype == "shot" then + self:breakReloading() + end + self:updateModdableTile() if self == game.player then game:playSound("actions/takeoff") end end @@ -2277,6 +2320,7 @@ function _M:learnPool(t) end -- If we learn an archery talent, also learn to shoot if t.type[1]:find("^technique/archery") and not self:knowTalent(self.T_SHOOT) then + print("oddly, that thing in Actor.lua just taught us Shoot as if we didn't already know it.") self:learnTalent(self.T_SHOOT, true) self.resource_pool_refs[self.T_SHOOT] = (self.resource_pool_refs[self.T_SHOOT] or 0) + 1 end @@ -2312,6 +2356,37 @@ function _M:unlearnTalent(t_id) return true end +function _M:learnItemTalent(o, tid, level) + local t = self:getTalentFromId(tid) + local max = t.hard_cap or (t.points and t.points + 2) or 5 + if not self.item_talent_surplus_levels then self.item_talent_surplus_levels = {} end + --local item_talent_surplus_levels = self.item_talent_surplus_levels or {} + if not self.item_talent_surplus_levels[tid] then self.item_talent_surplus_levels[tid] = 0 end + --item_talent_levels[tid] = item_talent_levels[tid] + level + for i = 1, level do + if self:getTalentLevelRaw(t) >= max then + self.item_talent_surplus_levels[tid] = self.item_talent_surplus_levels[tid] + 1 + else + self:learnTalent(tid, true, 1) + end + end +end + +function _M:unlearnItemTalent(o, tid, level) + local t = self:getTalentFromId(tid) + local max = (t.points and t.points + 2) or 5 + if not self.item_talent_surplus_levels then self.item_talent_surplus_levels = {} end + --local item_talent_surplus_levels = self.item_talent_surplus_levels or {} + if not self.item_talent_surplus_levels[tid] then self.item_talent_surplus_levels[tid] = 0 end + for i = 1, level do + if self.item_talent_surplus_levels[tid] > 0 then + self.item_talent_surplus_levels[tid] = self.item_talent_surplus_levels[tid] - 1 + else + self:unlearnTalent(tid, true, 1) + end + end +end + --- Equilibrium check function _M:equilibriumChance(eq) eq = (eq or 0) + self:getEquilibrium() @@ -2635,7 +2710,7 @@ function _M:postUseTalent(ab, ret) self:setEffect(self.EFF_TAINT_COOLDOWN, 10, {power=1}) end end) - + if not ab.no_energy then if ab.is_spell then self:useEnergy(game.energy_to_act * self:combatSpellSpeed()) @@ -2749,6 +2824,7 @@ function _M:postUseTalent(ab, ret) if ab.id ~= self.T_STEALTH and ab.id ~= self.T_HIDE_IN_PLAIN_SIGHT and not ab.no_break_stealth then self:breakStealth() end if ab.id ~= self.T_LIGHTNING_SPEED then self:breakLightningSpeed() end if ab.id ~= self.T_GATHER_THE_THREADS then self:breakGatherTheThreads() end + if ab.id ~= self.T_RELOAD then self:breakReloading() end self:breakStepUp() if ab.id ~= self.T_REDUX and self:hasEffect(self.EFF_REDUX) and ab.type[1]:find("^chronomancy/") and ab.mode == "activated" and self:getTalentLevel(self.T_REDUX) >= self:getTalentLevel(ab.id) then @@ -2791,6 +2867,12 @@ function _M:breakStealth() end end +function _M:breakReloading() + if self:hasEffect(self.EFF_RELOADING) then + self:removeEffect(self.EFF_RELOADING) + end +end + --- Breaks step up if active function _M:breakStepUp() if self:hasEffect(self.EFF_STEP_UP) then diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua index f6b4586571..e0e107de03 100644 --- a/game/modules/tome/class/Object.lua +++ b/game/modules/tome/class/Object.lua @@ -132,7 +132,37 @@ function _M:descAttribute(attr) return ("%s%0.2f/turn"):format(i > 0 and "+" or "-", math.abs(i)) elseif attr == "COMBAT" then local c = self.combat - return c.dam.."-"..(c.dam*(c.damrange or 1.1)).." power, "..(c.apr or 0).." apr" + local m = math.min(c.max_acc or 75, 100) + return c.dam..", "..(c.critical_power or 1.1).."x, "..m.."%" + elseif attr == "COMBAT_RANGED" then + local c = self.combat + return (c.dam or 0)..", "..(c.critical_power or 1.1).."x" + elseif attr == "COMBAT_QUIVER" then + local c = self.combat + local m = math.min(c.max_acc or 75, 100) + --return (c.dam or 0)..", "..(c.max_acc or 75).."%, ".."["..(c.shots_left or 0).."/"..(c.capacity or 0).."]" + return (c.dam or 0)..", "..m.."%, "..(c.shots_left or 0).."/"..(c.capacity or 0) + elseif attr == "COMBAT_STAFF" then + local c = self.combat + local m = math.min(c.max_acc or 75, 100) + return "+"..c.dam.."%, "..(c.critical_power or 1.1).."x, "..m.."%" + elseif attr == "SHIELD" then + local c = self.special_combat + if c and (game.player:knowTalentType("technique/shield-offense") or game.player:knowTalentType("technique/shield-defense")) then + return c.dam.." dam, "..c.block.." block" + else + return c.block.." block" + end + elseif attr == "GLOVES" then + local c = (self.wielder and self.wielder.combat) or {} + if c and game.player:knowTalent(game.player.T_EMPTY_HAND) then + local d = c.dam + game.player.default_dam + local m = math.min((c.max_acc or 0) + game.player.default_max_acc, 100) + local c_power = (c.critical_power or 1.1) + game.player.default_critical_power + return d..", "..c_power.."x, "..m.."%" + else + return (self.wielder and self.wielder.combat_def or 0).." def, "..(self.wielder and self.wielder.combat_armor or 0).." armour" + end elseif attr == "COMBAT_DAMTYPE" then local c = self.combat return c.dam.."-"..(c.dam*(c.damrange or 1.1)).." power, "..(c.apr or 0).." apr, "..DamageType:get(c.damtype).name.." damage" @@ -258,6 +288,38 @@ function _M:getShortName(t) end end +function _M:getMeleeProjectDam() + local combat = self.combat or self.special_combat or self.wielder.combat or {} + if not combat["melee_project"] then return 0 end + local tab = {} + for k, v in pairs(combat["melee_project"]) do + tab[k] = {} + tab[k][1] = v + end + local total = 0 + for k, v in pairs(tab) do + total = total + v[1] + end + + return total +end + +function _M:getRangedProjectDam() + local combat = self.combat or {} + if not combat["ranged_project"] then return 0 end + local tab = {} + for k, v in pairs(combat["ranged_project"]) do + tab[k] = {} + tab[k][1] = v + end + local total = 0 + for k, v in pairs(tab) do + total = total + v[1] + end + + return total +end + --- Gets the full textual desc of the object without the name and requirements function _M:getTextualDesc(compare_with) compare_with = compare_with or {} @@ -265,36 +327,36 @@ function _M:getTextualDesc(compare_with) if self.quest then desc:add({"color", "VIOLET"},"[Plot Item]", {"color", "LAST"}, true) end - desc:add(("Type: %s / %s"):format(rawget(self, 'type') or "unknown", rawget(self, 'subtype') or "unknown"), true) - if self.slot_forbid == "OFFHAND" then desc:add("It must be held with both hands.", true) end - desc:add(true) - if self.set_list then desc:add({"color","GREEN"}, "It is part of a set of items.", {"color","LAST"}, true) if self.set_complete then desc:add({"color","LIGHT_GREEN"}, "The set is complete.", {"color","LAST"}, true) end end - -- Stop here if unided if not self:isIdentified() then return desc end - local compare_fields = function(item1, items, infield, field, outformat, text, mod, isinversed, isdiffinversed, add_table) + local compare_fields = function(item1, items, infield, field, outformat, text, mod, isinversed, isdiffinversed, add_table, change_order, affects_spells) add_table = add_table or {} mod = mod or 1 + change_order = change_order or true isinversed = isinversed or false isdiffinversed = isdiffinversed or false local ret = tstring{} local added = 0 local add = false - ret:add(text) + if not change_order then ret:add(text) end if isinversed then ret:add(((item1[field] or 0) + (add_table[field] or 0)) > 0 and {"color","RED"} or {"color","LIGHT_GREEN"}, outformat:format(((item1[field] or 0) + (add_table[field] or 0)) * mod), {"color", "LAST"}) else ret:add(((item1[field] or 0) + (add_table[field] or 0)) < 0 and {"color","RED"} or {"color","LIGHT_GREEN"}, outformat:format(((item1[field] or 0) + (add_table[field] or 0)) * mod), {"color", "LAST"}) end + --if change_order then ret:add(text) end + --if affects_spells then ret:add(" (affects spells)") end if item1[field] then add = true end for i=1, #items do + --if items[i][infield] and field == "max_acc" and items[i][infield][field] then items[i][infield]["max_acc"] = math.min(items[i][infield]["max_acc"], 100) end + --if items[i][infield] and field == "attack_speed_bonus" and items[i][infield][field] then items[i][infield]["attack_speed_bonus"] = (1 / (items[i][infield]["physspeed"] or 1))*100 -100 end if items[i][infield] and items[i][infield][field] then if added == 0 then ret:add(" (") @@ -317,19 +379,23 @@ function _M:getTextualDesc(compare_with) if added > 0 then ret:add(")") end + if change_order then ret:add(text) end + if affects_spells then ret:add(" (affects spells)") end if add then desc:merge(ret) desc:add(true) end end - local compare_table_fields = function(item1, items, infield, field, outformat, text, kfunct, mod, isinversed) + local compare_table_fields = function(item1, items, infield, field, outformat, text, kfunct, mod, isinversed, separator, change_order) mod = mod or 1 + separator = separator or ", " + change_order = change_order or true isinversed = isinversed or false local ret = tstring{} local added = 0 local add = false - ret:add(text) + if not change_order then ret:add(text) end local tab = {} if item1[field] then for k, v in pairs(item1[field]) do @@ -349,9 +415,9 @@ function _M:getTextualDesc(compare_with) for k, v in pairs(tab) do local count = 0 if isinversed then - ret:add(("%s"):format((count1 > 0) and " / " or ""), (v[1] or 0) > 0 and {"color","RED"} or {"color","LIGHT_GREEN"}, outformat:format((v[1] or 0)), {"color","LAST"}) + ret:add(("%s"):format((count1 > 0 and separator) or ""), (v[1] or 0) > 0 and {"color","RED"} or {"color","LIGHT_GREEN"}, outformat:format((v[1] or 0)), {"color","LAST"}) else - ret:add(("%s"):format((count1 > 0) and " / " or ""), (v[1] or 0) < 0 and {"color","RED"} or {"color","LIGHT_GREEN"}, outformat:format((v[1] or 0)), {"color","LAST"}) + ret:add(("%s"):format((count1 > 0 and separator) or ""), (v[1] or 0) < 0 and {"color","RED"} or {"color","LIGHT_GREEN"}, outformat:format((v[1] or 0)), {"color","LAST"}) end count1 = count1 + 1 if v[1] then @@ -383,6 +449,8 @@ function _M:getTextualDesc(compare_with) ret:add(kfunct(k)) end + if change_order then ret:add(text) end + if add then desc:merge(ret) desc:add(true) @@ -396,8 +464,20 @@ function _M:getTextualDesc(compare_with) compare_with = compare_with or {} local dm = {} for stat, i in pairs(combat.dammod or {}) do - dm[#dm+1] = ("%d%% %s"):format((i + (add_table.dammod[stat] or 0)) * 100, Stats.stats_def[stat].short_name:capitalize()) + dm[#dm+1] = ("#00ff00#%d%%#LAST# %s"):format((i + (add_table.dammod[stat] or 0)) * 100, Stats.stats_def[stat].short_name) end + local shooter = game.player:hasShooter() + local ammo = game.player:hasAmmo() + local add_ammo = false + local add_shooter = false + if self.archery_ammo and shooter and self.archery_ammo == shooter.archery then add_shooter = true end + if self.archery and ammo and self.archery == ammo.archery_ammo then add_ammo = true end + local ammo_dam = 0 + local shooter_dam = 0 + local melee_project_total = 0 + local ranged_project_total = 0 + local ranged_add_string = "" + local project_type = "melee_project" if #dm > 0 or combat.dam then local power_diff = "" local diff_count = 0 @@ -418,20 +498,78 @@ function _M:getTextualDesc(compare_with) else power_diff = ("(%s)"):format(power_diff) end - desc:add(("Base power: %.1f - %.1f"):format((combat.dam or 0) + (add_table.dam or 0), ((combat.damrange or (1.1 - (add_table.damrange or 0))) + (add_table.damrange or 0)) * ((combat.dam or 0) + (add_table.dam or 0)))) - desc:merge(power_diff:toTString()) + + local tot_dam_per_hit = 0 + local base_dam = (combat.dam or 0) + (add_table.dam or 0) + if add_ammo then + ammo_dam = game.player:combatDamage(ammo.combat) + ammo:getRangedProjectDam() + end + if add_shooter then + shooter_dam = game.player:combatDamage(shooter.combat) + shooter:getRangedProjectDam() + end + if not self.archery and not self.archery_ammo then + melee_project_total = self:getMeleeProjectDam() + else + ranged_project_total = self:getRangedProjectDam() + project_type = "ranged_project" + end + local u_combat = {} + u_combat = table.clone(combat, true) + if add_table and add_table.dam then u_combat.dam = u_combat.dam + add_table.dam or 0 end + if add_table and add_table.dammod then + for stat, i in pairs(u_combat.dammod or {}) do + u_combat.dammod[stat] = u_combat.dammod[stat] + (add_table.dammod[stat] or 0) + end + end + tot_dam_per_hit = game.player:combatDamage(u_combat) + melee_project_total + ranged_project_total + shooter_dam + ammo_dam + desc:add({"color","YELLOW"}, (" %d damage per hit"):format(tot_dam_per_hit), {"color", "LAST"}, true) desc:add(true) - desc:add(("Uses stat%s: %s"):format(#dm > 1 and "s" or "",table.concat(dm, ', ')), true) - local col = (combat.damtype and DamageType:get(combat.damtype) and DamageType:get(combat.damtype).text_color or "#WHITE#"):toTString() - desc:add("Damage type: ", col[2],DamageType:get(combat.damtype or DamageType.PHYSICAL).name:capitalize(),{"color","LAST"}, true) + local damage_type_text = "" + if combat.damtype and combat.damtype ~= DamageType.PHYSICAL then + local col = (combat.damtype and DamageType:get(combat.damtype) and DamageType:get(combat.damtype).text_color or "#WHITE#") + damage_type_text = " "..col..DamageType:get(combat.damtype).name + end + + desc:add({"color","LIGHT_GREEN"}, ("%d"):format(base_dam), {"color","LAST"}, ("%s"):format(damage_type_text), {"color","LAST"}, " dam + ", {"color","LIGHT_GREEN"}, ("%d"):format(tot_dam_per_hit - base_dam), {"color","LAST"}, " bonus dam", {"color","RED"}, "*", {"color","LAST"}, true) + end - compare_fields(combat, compare_with, field, "atk", "%+d", "Accuracy: ", 1, false, false, add_table) - compare_fields(combat, compare_with, field, "apr", "%+d", "Armour Penetration: ", 1, false, false, add_table) - compare_fields(combat, compare_with, field, "physcrit", "%+.1f%%", "Physical crit. chance: ", 1, false, false, add_table) - compare_fields(combat, compare_with, field, "physspeed", "%.0f%%", "Attack speed: ", 100, false, true, add_table) + compare_fields(combat, compare_with, field, "critical_power", "%.1f", " crit multiplier", 1, false, false, add_table, true, combat.affects_spells) + compare_fields(combat, compare_with, field, "max_acc", "%d%%", " max hit chance", 1, false, false, add_table, true, combat.affects_spells) + compare_fields(combat, compare_with, field, "capacity", "%d", " capacity", 1, false, false, add_table) + compare_fields(combat, compare_with, field, "shots_reloaded_per_turn", "%+d", " reload speed", 1, false, false, add_table) + compare_fields(combat, compare_with, field, "ammo_every", "%d", " turns elapse between self-loadings", 1, false, false, add_table) + desc:add(true) + desc:add({"color","RED"}, "*", {"color","LAST"}, ": ") + if add_ammo then + desc:add({"color","LIGHT_GREEN"}, ("%d "):format(ammo_dam), {"color","LAST"}, "ammo dam + ") + end + if add_shooter then + local s = shooter.archery + desc:add({"color","LIGHT_GREEN"}, ("%d "):format(shooter_dam), {"color","LAST"}, ("%s dam + "):format(s)) + end + local talent_dam = game.player:combatCheckTraining(combat) + if talent_dam > 0 then desc:add({"color","LIGHT_GREEN"}, ("%d "):format(talent_dam), {"color","LAST"}, "talent dam + ") end + desc:add(("%s "):format(table.concat(dm, ' + ')), {"color","LAST"}) + compare_table_fields(combat, compare_with, field, project_type, "%+d", "", function(item) + local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() + return col[2], (" %s"):format(DamageType.dam_def[item].name),{"color","LAST"} + end, nil, nil, " ") + desc:add(true) - compare_fields(combat, compare_with, field, "range", "%+d", "Firing range: ", 1, false, false, add_table) + local attack_speed_bonus = (1 / ((combat.physspeed or 1) + (add_table.physspeed or 0)))*100 -100 + if combat.physspeed and combat.physspeed ~= 1 then + desc:add({"color","LIGHT_GREEN"}, ("%d%% "):format(attack_speed_bonus), {"color","LAST"}, "attack speed bonus", true) + --compare_fields(combat, compare_with, field, "attack_speed_bonus", "%d%%", " attack speed bonus", 1, false, false, add_table, true) + end + compare_fields(combat, compare_with, field, "apr", "%d", " armour penetration", 1, false, false, add_table) + compare_fields(combat, compare_with, field, "range", "%d", " firing range", 1, false, false, add_table) + if combat.tg_type and combat.tg_type == "beam" then + desc:add({"color","YELLOW"}, ("Shots beam through all targets."), {"color","LAST"}, true) + end + if combat.concussion then + compare_fields(combat, compare_with, field, "concussion", "%d%%", " weapon damage done to nearby foes on crit", 1, false, false, add_table) + end local talents = {} if combat.talent_on_hit then @@ -483,85 +621,86 @@ function _M:getTextualDesc(compare_with) desc:add({"color","RED"}, "When used from stealth a simple attack with it will not break stealth.", {"color","LAST"}, true) end - compare_fields(combat, compare_with, field, "travel_speed", "%+d%%", "Travel speed: ", 1, false, false, add_table) - - compare_table_fields(combat, compare_with, field, "melee_project", "%+d", "Damage when this weapon hits: ", function(item) - local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() - return col[2], (" %s"):format(DamageType.dam_def[item].name),{"color","LAST"} - end) + compare_fields(combat, compare_with, field, "travel_speed", "%d%%", " projectile speed", 1, false, false, add_table) - compare_table_fields(combat, compare_with, field, "inc_damage_type", "%+d%%", "Damage against: ", function(item) + compare_table_fields(combat, compare_with, field, "inc_damage_type", "%+d%%", " damage against ", function(item) local _, _, t, st = item:find("^([^/]+)/?(.*)$") if st and st ~= "" then return st:capitalize() else return t:capitalize() end - end) - + end, nil, nil, nil, false) + desc:add(true, "---", true) end local desc_wielder = function(w, compare_with, field) w = w or {} w = w[field] or {} - compare_fields(w, compare_with, field, "combat_atk", "%+d", "Accuracy: ") - compare_fields(w, compare_with, field, "combat_apr", "%+d", "Armour penetration: ") - compare_fields(w, compare_with, field, "combat_physcrit", "%+.1f%%", "Physical crit. chance: ") - compare_fields(w, compare_with, field, "combat_dam", "%+d", "Physical power: ") + compare_fields(w, compare_with, field, "cross_tier_bonus", "%+d", " bonus to cross-tier effects") + compare_fields(w, compare_with, field, "combat_atk", "%+d", " accuracy") + compare_fields(w, compare_with, field, "combat_apr", "%+d", " armour penetration") + compare_fields(w, compare_with, field, "combat_physcrit", "%+d%%", " physical crit. chance") + compare_fields(w, compare_with, field, "combat_dam", "%+d", " physical power") - compare_fields(w, compare_with, field, "combat_armor", "%+d", "Armour: ") - compare_fields(w, compare_with, field, "combat_armor_hardiness", "%+d%%", "Armour Hardiness: ") - compare_fields(w, compare_with, field, "combat_def", "%+d", "Defense: ") - compare_fields(w, compare_with, field, "combat_def_ranged", "%+d", "Ranged Defense: ") + compare_fields(w, compare_with, field, "combat_armor", "%+d", " armor", nil, nil, nil, nil, true) + compare_fields(w, compare_with, field, "combat_armor_hardiness", "%+d%%", " armour hardiness") + compare_fields(w, compare_with, field, "combat_def", "%+d", " defense") + compare_fields(w, compare_with, field, "combat_def_ranged", "%+d", " ranged defense") - compare_fields(w, compare_with, field, "fatigue", "%+d%%", "Fatigue: ", 1, true, true) + compare_fields(w, compare_with, field, "fatigue", "%+d%%", " fatigue", 1, true, true) - compare_table_fields(w, compare_with, field, "inc_stats", "%+d", "Changes stats: ", function(item) + compare_table_fields(w, compare_with, field, "inc_stats", "%+d", "", function(item) return (" %s"):format(Stats.stats_def[item].short_name:capitalize()) end) - compare_table_fields(w, compare_with, field, "melee_project", "%d", "Damage when the wearer hits(melee): ", function(item) + compare_table_fields(w, compare_with, field, "melee_project", "+%d", " melee damage", function(item) local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() return col[2],(" %s"):format(DamageType.dam_def[item].name),{"color","LAST"} end) - compare_table_fields(w, compare_with, field, "ranged_project", "%d", "Damage when the wearer hits(ranged): ", function(item) + compare_table_fields(w, compare_with, field, "ranged_project", "+%d", " ranged damage", function(item) local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() return col[2],(" %s"):format(DamageType.dam_def[item].name),{"color","LAST"} end) - compare_table_fields(w, compare_with, field, "on_melee_hit", "%d", "Damage when the wearer is hit: ", function(item) + compare_table_fields(w, compare_with, field, "on_melee_hit", "%d", " damage to any who hits wearer", function(item) local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() return col[2],(" %s"):format(DamageType.dam_def[item].name),{"color","LAST"} end) - compare_table_fields(w, compare_with, field, "resists", "%+d%%", "Changes resistances: ", function(item) + compare_table_fields(w, compare_with, field, "resists", "%+d%%", " resistance", function(item) local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() return col[2], (" %s"):format(item == "all" and "all" or DamageType.dam_def[item].name), {"color","LAST"} end) - compare_table_fields(w, compare_with, field, "resists_cap", "%+d%%", "Changes resistances cap: ", function(item) + compare_table_fields(w, compare_with, field, "wards", "%+d", " ward", function(item) local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() return col[2], (" %s"):format(item == "all" and "all" or DamageType.dam_def[item].name), {"color","LAST"} end) - compare_table_fields(w, compare_with, field, "resists_pen", "%+d%%", "Changes resistances penetration: ", function(item) + compare_table_fields(w, compare_with, field, "resists_cap", "%+d%%", " max resistance", function(item) local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() return col[2], (" %s"):format(item == "all" and "all" or DamageType.dam_def[item].name), {"color","LAST"} end) - compare_table_fields(w, compare_with, field, "inc_damage", "%+d%%", "Changes damage: ", function(item) + compare_table_fields(w, compare_with, field, "resists_pen", "%+d%%", " resist penetration", function(item) local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() return col[2], (" %s"):format(item == "all" and "all" or DamageType.dam_def[item].name), {"color","LAST"} end) - compare_table_fields(w, compare_with, field, "damage_affinity", "%+d%%", "Damage affinity(heal): ", function(item) + compare_table_fields(w, compare_with, field, "inc_damage", "%+d%%", " damage", function(item) local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() return col[2], (" %s"):format(item == "all" and "all" or DamageType.dam_def[item].name), {"color","LAST"} end) + compare_table_fields(w, compare_with, field, "damage_affinity", "%+d%%", " affinity", function(item) + local col = (DamageType.dam_def[item] and DamageType.dam_def[item].text_color or "#WHITE#"):toTString() + return col[2], (" %s"):format(item == "all" and "all" or DamageType.dam_def[item].name), {"color","LAST"} + end) - compare_fields(w, compare_with, field, "esp_range", "%+d", "Change telepathy range by : ") + + compare_fields(w, compare_with, field, "esp_range", "%+d", " telepathy range") local any_esp = false local esps_compare = {} @@ -604,14 +743,20 @@ function _M:getTextualDesc(compare_with) any_esp = true end if any_esp then - desc:add("Grants telepathy: ") + --desc:add("Grants telepathy: ") + + local count = 0 for esp, isin in pairs(esps_compare) do + local separator = (#esps > 1 and ",") or "x" + count = count + 1 if isin[2] then - desc:add(isin[1] and {"color","WHITE"} or {"color","GREEN"}, ("%s "):format(esp), {"color","LAST"}) + desc:add(isin[1] and {"color","WHITE"} or {"color","GREEN"}, ("%s"):format(esp), ("%s "):format(((count < #esps_compare) and separator) or ""), {"color","LAST"}) else desc:add({"color","RED"}, ("%s "):format(esp), {"color","LAST"}) end + end + desc:add(" telepathy") desc:add(true) end @@ -632,7 +777,7 @@ function _M:getTextualDesc(compare_with) any_mastery = any_mastery + 1 end if any_mastery > 0 then - desc:add(("Talent master%s: "):format(any_mastery > 1 and "ies" or "y")) + --desc:add(("Talent master%s: "):format(any_mastery > 1 and "ies" or "y")) for ttn, ttid in pairs(masteries) do local tt = Talents.talents_types_def[ttn] local cat = tt.type:gsub("/.*", "") @@ -648,6 +793,7 @@ function _M:getTextualDesc(compare_with) desc:add({"color","WHITE"}, ("%+.2f(-) %s "):format(ttid[2] or ttid[1], name), {"color","LAST"}) end end + desc:add((" talent master%s"):format(any_mastery > 1 and "ies" or "y")) desc:add(true) end @@ -684,6 +830,70 @@ function _M:getTextualDesc(compare_with) desc:add(true) end + --display learned talents: + + local any_learn_talent = 0 + local learn_talents = {} + for i, v in ipairs(compare_with or {}) do + if v[field] and v[field].learn_talent then + for tid, tl in pairs(v[field].learn_talent) do + learn_talents[tid] = learn_talents[tid] or {} + learn_talents[tid][1] = tl + any_learn_talent = any_learn_talent + 1 + end + end + end + for tid, tl in pairs(w.learn_talent or {}) do + learn_talents[tid] = learn_talents[tid] or {} + learn_talents[tid][2] = tl + any_learn_talent = any_learn_talent + 1 + end + if any_learn_talent > 0 then + for tid, tl in pairs(learn_talents) do + local diff = (tl[2] or 0) - (tl[1] or 0) + if diff ~= 0 then + if tl[1] then + desc:add(("%+d"):format((tl[2] or 0)), diff < 0 and {"color","RED"} or {"color","LIGHT_GREEN"}, ("(%+d) "):format(diff), {"color","GREEN"}, (" %s "):format(Talents.talents_def[tid].name), {"color","WHITE"}, ("talent level%s"):format(((tl[2] or 0) > 1) and "s" or ""), true) + else + desc:add({"color","LIGHT_GREEN"}, ("%+d"):format((tl[2] or 0)), {"color","GREEN"}, (" %s "):format(Talents.talents_def[tid].name), {"color","WHITE"}, ("talent level%s"):format((tl[2] > 1) and "s" or ""), true) + end + else + --desc:add({"color","LIGHT_GREEN"}, ("(%+d(-) %s talent level%s)"):format(Talents.talents_def[tid].name, (tl[2] or tl[1]), ((tl[2] or 0) > 1) and "s" or ""), {"color","LAST"}) + desc:add({"color","LIGHT_GREEN"}, ("%+d(-)"):format((tl[2] or 0)), {"color","GREEN"}, (" %s "):format(Talents.talents_def[tid].name), {"color","WHITE"}, ("talent level%s"):format((tl[2] > 1) and "s" or ""), true) + end + end + desc:add(true) + end + + -- Retributions: + local ret_list = {} + local counter = 1 + for k, v in pairs(w.elemental_retribution or {}) do + if v > 0 then + ret_list[counter] = k + counter = counter + 1 + end + end + local n = #ret_list + if n >= 1 then + local e_string = "" + if n == 1 then + e_string = DamageType.dam_def[ret_list[1]].text_color..DamageType.dam_def[ret_list[1]].name.."#WHITE#" + print("1: e_string is ", e_string) + elseif n == 2 then + e_string = DamageType.dam_def[ret_list[1]].text_color..DamageType.dam_def[ret_list[1]].name.."#WHITE# and "..DamageType.dam_def[ret_list[2]].text_color..DamageType.dam_def[ret_list[2]].name + print("2: e_string is ", e_string) + else + for i = 1, #ret_list-1 do + e_string = e_string..DamageType.dam_def[ret_list[i]].text_color..DamageType.dam_def[ret_list[i]].name.."#WHITE#, " + print("3+: e_string is ", e_string) + end + e_string = e_string.."and "..DamageType.dam_def[ret_list[n]].text_color..DamageType.dam_def[ret_list[n]].name.."#WHITE#" + end + desc:add(e_string, " retribution", true) + end + + local any_breath = 0 local breaths = {} for i, v in ipairs(compare_with or {}) do @@ -712,83 +922,83 @@ function _M:getTextualDesc(compare_with) desc:add(true) end - compare_fields(w, compare_with, field, "combat_critical_power", "%+.2f%%", "Critical mult.: ") + compare_fields(w, compare_with, field, "combat_critical_power", "%+.1f", " crit multiplier") compare_fields(w, compare_with, field, "combat_critreduction", "%-d%%", "Reduces opponents crit chance: ") - compare_fields(w, compare_with, field, "disarm_bonus", "%+d", "Trap disarming bonus: ") - compare_fields(w, compare_with, field, "inc_stealth", "%+d", "Stealth bonus: ") - compare_fields(w, compare_with, field, "max_encumber", "%+d", "Maximum encumberance: ") + compare_fields(w, compare_with, field, "disarm_bonus", "%+d", " trap disarm bonus") + compare_fields(w, compare_with, field, "inc_stealth", "%+d", " stealth") + compare_fields(w, compare_with, field, "max_encumber", "%+d", " max encumberance") - compare_fields(w, compare_with, field, "combat_physresist", "%+d", "Physical save: ") - compare_fields(w, compare_with, field, "combat_spellresist", "%+d", "Spell save: ") - compare_fields(w, compare_with, field, "combat_mentalresist", "%+d", "Mental save: ") + compare_fields(w, compare_with, field, "combat_physresist", "%+d", " physical save") + compare_fields(w, compare_with, field, "combat_spellresist", "%+d", " spell save") + compare_fields(w, compare_with, field, "combat_mentalresist", "%+d", " mental save") - compare_fields(w, compare_with, field, "blind_immune", "%+d%%", "Blindness immunity: ", 100) - compare_fields(w, compare_with, field, "poison_immune", "%+d%%", "Poison immunity: ", 100) - compare_fields(w, compare_with, field, "disease_immune", "%+d%%", "Disease immunity: ", 100) - compare_fields(w, compare_with, field, "cut_immune", "%+d%%", "Cut immunity: ", 100) + compare_fields(w, compare_with, field, "blind_immune", "%+d%%", " blindness immunity", 100) + compare_fields(w, compare_with, field, "poison_immune", "%+d%%", " poison immunity", 100) + compare_fields(w, compare_with, field, "disease_immune", "%+d%%", " disease immunity", 100) + compare_fields(w, compare_with, field, "cut_immune", "%+d%%", " cut immunity", 100) - compare_fields(w, compare_with, field, "silence_immune", "%+d%%", "Silence immunity: ", 100) - compare_fields(w, compare_with, field, "disarm_immune", "%+d%%", "Disarm immunity: ", 100) - compare_fields(w, compare_with, field, "confusion_immune", "%+d%%", "Confusion immunity: ", 100) - compare_fields(w, compare_with, field, "pin_immune", "%+d%%", "Pinning immunity: ", 100) + compare_fields(w, compare_with, field, "silence_immune", "%+d%%", " silence immunity", 100) + compare_fields(w, compare_with, field, "disarm_immune", "%+d%%", " disarm immunity", 100) + compare_fields(w, compare_with, field, "confusion_immune", "%+d%%", " confusion immunity", 100) + compare_fields(w, compare_with, field, "pin_immune", "%+d%%", " pinning immunity", 100) - compare_fields(w, compare_with, field, "stun_immune", "%+d%%", "Stun/Freeze immunity: ", 100) - compare_fields(w, compare_with, field, "fear_immune", "%+d%%", "Fear immunity: ", 100) - compare_fields(w, compare_with, field, "knockback_immune", "%+d%%", "Knockback immunity: ", 100) - compare_fields(w, compare_with, field, "instakill_immune", "%+d%%", "Instant-death immunity: ", 100) - compare_fields(w, compare_with, field, "teleport_immune", "%+d%%", "Teleport immunity: ", 100) + compare_fields(w, compare_with, field, "stun_immune", "%+d%%", " stun/freeze immunity", 100) + compare_fields(w, compare_with, field, "fear_immune", "%+d%%", " fear immunity", 100) + compare_fields(w, compare_with, field, "knockback_immune", "%+d%%", " knockback immunity", 100) + compare_fields(w, compare_with, field, "instakill_immune", "%+d%%", " instant-death immunity", 100) + compare_fields(w, compare_with, field, "teleport_immune", "%+d%%", " teleport immunity", 100) - compare_fields(w, compare_with, field, "life_regen", "%+.2f", "Life regen: ") - compare_fields(w, compare_with, field, "stamina_regen", "%+.2f", "Stamina each turn: ") - compare_fields(w, compare_with, field, "mana_regen", "%+.2f", "Mana each turn: ") - compare_fields(w, compare_with, field, "hate_regen", "%+.2f", "Hate each turn: ") + compare_fields(w, compare_with, field, "life_regen", "%+.1f", " life regen") + compare_fields(w, compare_with, field, "stamina_regen", "%+.1f", " stamina each turn") + compare_fields(w, compare_with, field, "mana_regen", "%+.1f", " mana each turn") + compare_fields(w, compare_with, field, "hate_regen", "%+.3f", " hate each turn") - compare_fields(w, compare_with, field, "stamina_regen_on_hit", "%+.2f", "Stamina when hit: ") - compare_fields(w, compare_with, field, "mana_regen_on_hit", "%+.2f", "Mana when hit: ") - compare_fields(w, compare_with, field, "equilibrium_regen_on_hit", "%+.2f", "Equilibrium when hit: ") + compare_fields(w, compare_with, field, "stamina_regen_on_hit", "%+.1f", " stamina when hit") + compare_fields(w, compare_with, field, "mana_regen_on_hit", "%+.1f", " mana when hit") + compare_fields(w, compare_with, field, "equilibrium_regen_on_hit", "%+.1f", " equilibrium when hit") - compare_fields(w, compare_with, field, "mana_on_crit", "%+.2f", "Mana when firing critical spell: ") + compare_fields(w, compare_with, field, "mana_on_crit", "%+d", " mana when firing critical spell") - compare_fields(w, compare_with, field, "die_at", "%+.2f life", "Only die when reaching: ", 1, true, true) - compare_fields(w, compare_with, field, "max_life", "%+.2f", "Maximum life: ") - compare_fields(w, compare_with, field, "max_mana", "%+.2f", "Maximum mana: ") - compare_fields(w, compare_with, field, "max_stamina", "%+.2f", "Maximum stamina: ") - compare_fields(w, compare_with, field, "max_hate", "%+.2f", "Maximum hate: ") - compare_fields(w, compare_with, field, "max_vim", "%+.2f", "Maximum vim: ") - compare_fields(w, compare_with, field, "max_air", "%+.2f", "Maximum air capacity: ") + compare_fields(w, compare_with, field, "die_at", "%+d life:", " point at which death occurs", 1, true, true) + compare_fields(w, compare_with, field, "max_life", "%+d", " maximum life") + compare_fields(w, compare_with, field, "max_mana", "%+d", " maximum mana") + compare_fields(w, compare_with, field, "max_stamina", "%+d", " maximum stamina") + compare_fields(w, compare_with, field, "max_hate", "%+.1f", " maximum hate") + compare_fields(w, compare_with, field, "max_vim", "%+d", " maximum vim") + compare_fields(w, compare_with, field, "max_air", "%+d", " maximum air capacity") - compare_fields(w, compare_with, field, "combat_spellpower", "%+d", "Spellpower: ") - compare_fields(w, compare_with, field, "combat_spellcrit", "%+d%%", "Spell crit. chance: ") + compare_fields(w, compare_with, field, "combat_spellpower", "%+d", " spellpower") + compare_fields(w, compare_with, field, "combat_spellcrit", "%+d%%", " spell crit. chance") - compare_fields(w, compare_with, field, "combat_mindpower", "%+d", "Mindpower: ") - compare_fields(w, compare_with, field, "combat_mindcrit", "%+d%%", "Mental crit. chance: ") + compare_fields(w, compare_with, field, "combat_mindpower", "%+d", " mindpower") + compare_fields(w, compare_with, field, "combat_mindcrit", "%+d%%", " mental crit. chance") - compare_fields(w, compare_with, field, "lite", "%+d", "Light radius: ") - compare_fields(w, compare_with, field, "infravision", "%+d", "Infravision radius: ") - compare_fields(w, compare_with, field, "heightened_senses", "%+d", "Heightened senses radius: ") + compare_fields(w, compare_with, field, "lite", "%+d", " light radius") + compare_fields(w, compare_with, field, "infravision", "%+d", " infravision radius") + compare_fields(w, compare_with, field, "heightened_senses", "%+d", " heightened senses radius") - compare_fields(w, compare_with, field, "see_invisible", "%+d", "See invisible: ") - compare_fields(w, compare_with, field, "invisible", "%+d", "Invisibility: ") + compare_fields(w, compare_with, field, "see_invisible", "%+d", " see invisible") + compare_fields(w, compare_with, field, "invisible", "%+d", " invisibility") - compare_fields(w, compare_with, field, "movement_speed", "%+d%%", "Movement speed: ", 100) - compare_fields(w, compare_with, field, "combat_physspeed", "%+d%%", "Combat speed: ", 100) - compare_fields(w, compare_with, field, "combat_spellspeed", "%+d%%", "Casting speed: ", 100) + compare_fields(w, compare_with, field, "movement_speed", "%+d%%", " movement speed", 100) + compare_fields(w, compare_with, field, "combat_physspeed", "%+d%%", " combat speed", 100) + compare_fields(w, compare_with, field, "combat_spellspeed", "%+d%%", " casting speed", 100) - compare_fields(w, compare_with, field, "healing_factor", "%+d%%", "Healing mod.: ", 100) + compare_fields(w, compare_with, field, "healing_factor", "%+d%%", " healing mod.", 100) - compare_fields(w, compare_with, field, "life_leech_chance", "%+d%%", "Life leech chance: ") - compare_fields(w, compare_with, field, "life_leech_value", "%+d%%", "Life leech: ") + compare_fields(w, compare_with, field, "life_leech_chance", "%+d%%", " life leech chance") + compare_fields(w, compare_with, field, "life_leech_value", "%+d%%", " life leech") - compare_fields(w, compare_with, field, "resource_leech_chance", "%+d%%", "Resource leech chance: ") - compare_fields(w, compare_with, field, "resource_leech_value", "%+d", "Resource leech: ") + compare_fields(w, compare_with, field, "resource_leech_chance", "%+d%%", " resource leech chance") + compare_fields(w, compare_with, field, "resource_leech_value", "%+d", " resource leech") - compare_fields(w, compare_with, field, "size_category", "%+d", "Size category: ") + compare_fields(w, compare_with, field, "size_category", "%+d", " size category") if w.undead then desc:add("The wearer is treated as an undead.", true) end - + if w.blind_fight then desc:add({"color", "YELLOW"}, "Blind-Fight:", {"color", "LAST"}, "This item allows the wearer to attack unseen targets without any penalties.", true) end @@ -808,13 +1018,13 @@ function _M:getTextualDesc(compare_with) if (w and w.combat or can_combat_unarmed) and game.player:knowTalent(game.player.T_EMPTY_HAND) then desc:add({"color","YELLOW"}, "When used to modify unarmed attacks:", {"color", "LAST"}, true) - compare_tab = { dam=1, atk=1, apr=0, physcrit=0, physspeed =1, dammod={str=1}, damrange=1.1 } + compare_tab = { dam=1, critical_power = 1.1, max_acc = 75, atk=0, apr=0, physcrit=0, physspeed =1, dammod={str=0.1}, damrange=1, unarmed=true } desc_combat(w, compare_unarmed, "combat", compare_tab) end end + local can_combat = false local can_special_combat = false - local can_basic_ammo = false local can_wielder = false local can_carrier = false local can_imbue_powers = false @@ -826,9 +1036,6 @@ function _M:getTextualDesc(compare_with) if v.special_combat then can_special_combat = true end - if v.basic_ammo then - can_basic_ammo = true - end if v.wielder then can_wielder = true end @@ -846,6 +1053,7 @@ function _M:getTextualDesc(compare_with) if (self.special_combat or can_special_combat) and (game.player:knowTalentType("technique/shield-offense") or game.player:knowTalentType("technique/shield-defense")) then desc:add({"color","YELLOW"}, "When used to attack (with talents):", {"color", "LAST"}, true) + desc:add(true) desc_combat(self, compare_with, "special_combat") end @@ -862,16 +1070,11 @@ function _M:getTextualDesc(compare_with) desc:add({"color","RED"}, "It is immune to teleportation, if you teleport it will fall on the ground.", {"color", "LAST"}, true) end - if self.basic_ammo or can_basic_ammo then - desc:add({"color","YELLOW"}, "Default ammo(infinite):", {"color", "LAST"}, true) - desc_combat(self, compare_with, "basic_ammo") - end - if self.wielder or can_wielder then - desc:add({"color","YELLOW"}, "When wielded/worn:", {"color", "LAST"}, true) + desc:add({"color","YELLOW"}, " When wielded/worn:", {"color", "LAST"}, true) desc_wielder(self, compare_with, "wielder") if self:attr("skullcracker_mult") and game.player:knowTalent(game.player.T_SKULLCRACKER) then - compare_fields(self, compare_with, "wielder", "skullcracker_mult", "%+d", "Skullcracker multiplicator: ") + compare_fields(self, compare_with, "wielder", "skullcracker_mult", "%+d", " Skullcracker multiplicator", nil, nil, nil, nil, true) end end @@ -933,7 +1136,7 @@ function _M:getTextualDesc(compare_with) desc:add({"color",0xf5,0x3c,0xbe}, game.player.tempeffect_def[self.curse].desc, {"color","LAST"}, true) end end - + desc:add("---", true) local use_desc = self:getUseDesc() if use_desc then desc:merge(use_desc:toTString()) end return desc @@ -979,11 +1182,21 @@ function _M:getDesc(name_param, compare_with, never_compare) desc:add({"color", "WHITE"}, true) desc:add(true) desc:add({"color", "ANTIQUE_WHITE"}) - desc:merge(self.desc:toTString()) - desc:add(true, true) + --desc:merge(self.desc:toTString()) + --desc:add(true, true) desc:add({"color", "WHITE"}) end + local could_compare = false + if not name_param.force_compare and not core.key.modState("ctrl") then + if compare_with[1] then could_compare = true end + compare_with = {} + end + + desc:merge(self:getTextualDesc(compare_with, true)) + desc:add(true) + desc:add(true, ("Type: %s / %s"):format(rawget(self, 'type') or "unknown", rawget(self, 'subtype') or "unknown"), true) + if self.slot_forbid == "OFFHAND" then desc:add("It must be held with both hands. ") end local reqs = self:getRequirementDesc(game.player) if reqs then desc:merge(reqs) @@ -1004,14 +1217,6 @@ function _M:getDesc(name_param, compare_with, never_compare) desc:add(true, true) - local could_compare = false - if not name_param.force_compare and not core.key.modState("ctrl") then - if compare_with[1] then could_compare = true end - compare_with = {} - end - - desc:merge(self:getTextualDesc(compare_with)) - if could_compare and not never_compare then desc:add(true, {"font","italic"}, {"color","GOLD"}, "Press <control> to compare", {"color","LAST"}, {"font","normal"}) end return desc diff --git a/game/modules/tome/class/PlayerDisplay.lua b/game/modules/tome/class/PlayerDisplay.lua index 440a40add8..22f44923fe 100644 --- a/game/modules/tome/class/PlayerDisplay.lua +++ b/game/modules/tome/class/PlayerDisplay.lua @@ -375,8 +375,9 @@ function _M:display() local quiver = player:getInven("QUIVER") local ammo = quiver and quiver[1] - if ammo then - self:mouseTooltip(self.TOOLTIP_COMBAT_AMMO, self:makeTexture(("#ANTIQUE_WHITE#Ammo: #ffffff#%d"):format(ammo:getNumber()), 0, h, 255, 255, 255)) h = h + self.font_h + if ammo and ammo.combat then + local shots_left = ammo.combat.shots_left or 0 + self:mouseTooltip(self.TOOLTIP_COMBAT_AMMO, self:makeTexture(("#ANTIQUE_WHITE#Ammo: #ffffff#%d"):format(shots_left), 0, h, 255, 255, 255)) h = h + self.font_h end if savefile_pipe.saving then diff --git a/game/modules/tome/class/interface/Archery.lua b/game/modules/tome/class/interface/Archery.lua index e54b6055dc..41d2128997 100644 --- a/game/modules/tome/class/interface/Archery.lua +++ b/game/modules/tome/class/interface/Archery.lua @@ -32,7 +32,7 @@ module(..., package.seeall, class.make) function _M:archeryAcquireTargets(tg, params) local weapon, ammo = self:hasArcheryWeapon() if not weapon then - game.logPlayer(self, "You must wield a bow or a sling (%s)!", ammo) + game.logPlayer(self, "(%s)", ammo) return nil end params = params or {} @@ -42,28 +42,27 @@ function _M:archeryAcquireTargets(tg, params) weapon = weapon.combat local tg = tg or {type="bolt"} + tg.type = weapon.tg_type or ammo.combat.tg_type or tg.type if not tg.range then tg.range=weapon.range or 6 end tg.display = tg.display or {display='/'} - tg.speed = (tg.speed or 20) * (ammo.travel_speed or 100) / 100 + tg.speed = (tg.speed or 6) * ((ammo.combat.travel_speed or 100) / 100) * (weapon.travel_speed or 100) / 100 local x, y = self:getTarget(tg) if not x or not y then return nil end -- Find targets to know how many ammo we use local targets = {} if params.one_shot then - local a - if not ammo.infinite then - a = self:removeObject(self:getInven("QUIVER"), 1) - else - a = ammo - end - if a then - targets = {{x=x, y=y, ammo=a.combat}} + if not ammo.combat.shots_left then return nil end + if ammo.combat.shots_left == 0 then + game.logPlayer(self, "You are out of ammo!") + return nil end + ammo.combat.shots_left = ammo.combat.shots_left - 1 + targets = {{x=x, y=y, ammo=ammo.combat}} else + if not ammo.combat.shots_left then return nil end local limit_shots = params.limit_shots - self:project(tg, x, y, function(tx, ty) local target = game.level.map(tx, ty, game.level.map.ACTOR) if not target then return end @@ -75,14 +74,9 @@ function _M:archeryAcquireTargets(tg, params) end for i = 1, params.multishots or 1 do - local a - if not ammo.infinite then - a = self:removeObject(self:getInven("QUIVER"), 1) - else - a = ammo - end - if a then targets[#targets+1] = {x=tx, y=ty, ammo=a.combat} - else break end + if ammo.combat.shots_left == 0 then break end + ammo.combat.shots_left = ammo.combat.shots_left - 1 + targets[#targets+1] = {x=tx, y=ty, ammo=ammo.combat} end end) end @@ -95,11 +89,6 @@ function _M:archeryAcquireTargets(tg, params) self:useEnergy(game.energy_to_act * (speed or 1)) if sound then game:playSoundNear(self, sound) end - - if not ammo.infinite and (ammo:getNumber() < 10 or ammo:getNumber() == 50 or ammo:getNumber() == 40 or ammo:getNumber() == 25) then - game.logPlayer(self, "You only have %s left!", ammo:getName{do_color=true}) - end - return targets else return nil @@ -124,14 +113,17 @@ local function archery_projectile(tx, ty, tg, self, tmp) -- Does the blow connect? yes .. complex :/ if tg.archery.use_psi_archery then self.use_psi_combat = true end local atk, def = self:combatAttack(weapon, ammo), target:combatDefenseRanged() - local dam, apr, armor = self:combatDamage(ammo), self:combatAPR(ammo), target:combatArmor() + local armor = target:combatArmor() + local dam = self:combatDamage(ammo) + self:combatDamage(weapon) + local apr = self:combatAPR(ammo) + self:combatAPR(weapon) atk = atk + (tg.archery.atk or 0) dam = dam + (tg.archery.dam or 0) print("[ATTACK ARCHERY] to ", target.name, " :: ", dam, apr, armor, "::", mult) -- If hit is over 0 it connects, if it is 0 we still have 50% chance local hitted = false - if self:checkHit(atk, def) and (self:canSee(target) or self:attr("blind_fight") or rng.chance(3)) then + local crit = false + if self:checkHit(atk, def, 0, self:getMaxAccuracy("physical", ammo)) and (self:canSee(target) or self:attr("blind_fight") or rng.chance(3)) then apr = apr + (tg.archery.apr or 0) print("[ATTACK ARCHERY] raw dam", dam, "versus", armor, "with APR", apr) @@ -140,24 +132,28 @@ local function archery_projectile(tx, ty, tg, self, tmp) dam = math.max(dam * pres - armor, 0) + (dam * (1 - pres)) print("[ATTACK ARCHERY] after armor", dam) - local damrange = self:combatDamageRange(ammo) - dam = rng.range(dam, dam * damrange) - print("[ATTACK ARCHERY] after range", dam) - - local crit + local pre_crit_dam = dam if tg.archery.crit_chance then self.combat_physcrit = self.combat_physcrit + tg.archery.crit_chance end - dam, crit = self:physicalCrit(dam, ammo, target, atk, def) + dam, crit = self:physicalCrit(dam, weapon, target, atk, def) if tg.archery.crit_chance then self.combat_physcrit = self.combat_physcrit - tg.archery.crit_chance end print("[ATTACK ARCHERY] after crit", dam) dam = dam * mult print("[ATTACK ARCHERY] after mult", dam) - if crit then game.logSeen(self, "#{bold}#%s performs a critical strike!#{normal}#", self.name:capitalize()) end + if crit then + game.logSeen(self, "#{bold}#%s performs a critical strike!#{normal}#", self.name:capitalize()) + if (weapon.concussion or ammo.concussion) then + dam = pre_crit_dam + self:doConcussion(dam, target, {weapon, ammo}) + end + end DamageType:get(damtype).projector(self, target.x, target.y, damtype, math.max(0, dam), tmp) + game.level.map:particleEmitter(target.x, target.y, 1, "archery") hitted = true + if talent.archery_onhit then talent.archery_onhit(self, talent, target, target.x, target.y) end else local srcname = game.level.map.seens(self.x, self.y) and self.name:capitalize() or "Something" @@ -179,12 +175,27 @@ local function archery_projectile(tx, ty, tg, self, tmp) end -- Ranged project - if hitted and not target.dead then for typ, dam in pairs(self.ranged_project) do + local weapon_ranged_project = weapon.ranged_project or {} + local ammo_ranged_project = ammo.ranged_project or {} + local total_ranged_project = {} + table.mergeAdd(total_ranged_project, weapon_ranged_project, true) + table.mergeAdd(total_ranged_project, ammo_ranged_project, true) + if hitted and not target.dead then for typ, dam in pairs(total_ranged_project) do if dam > 0 then DamageType:get(typ).projector(self, target.x, target.y, typ, dam, tmp) end end end + -- Talent on hit + if hitted and not target.dead and weapon and weapon.talent_on_hit and next(weapon.talent_on_hit) then + self:doTalentOnHit(target, weapon) + end + + -- Special effect + if hitted and not target.dead and weapon and weapon.special_on_hit and weapon.special_on_hit.fct then + weapon.special_on_hit.fct(weapon, self, target) + end + -- Temporal cast if hitted and not target.dead and self:knowTalent(self.T_WEAPON_FOLDING) and self:isTalentActive(self.T_WEAPON_FOLDING) then local t = self:getTalentFromId(self.T_WEAPON_FOLDING) @@ -237,6 +248,12 @@ local function archery_projectile(tx, ty, tg, self, tmp) target:knockback(self.x, self.y, math.ceil(math.log(dam))) end + -- Savagery + if hitted and crit and self:knowTalent(self.T_SAVAGERY) then + local t = self:getTalentFromId(self.T_SAVAGERY) + t.do_savagery(self, t) + end + self.use_psi_combat = false end @@ -256,17 +273,20 @@ function _M:archeryShoot(targets, talent, tg, params) weapon = weapon.combat local tg = tg or {type="bolt"} + tg.type = weapon.tg_type or ammo.combat.tg_type or tg.type tg.talent = tg.talent or talent if not tg.range then tg.range=weapon.range or 6 end tg.display = tg.display or {display=' ', particle="arrow", particle_args={tile="shockbolt/"..(ammo.proj_image or realweapon.proj_image):gsub("%.png$", "")}} - tg.speed = (tg.speed or 20) * (ammo.travel_speed or 100) / 100 + tg.speed = (tg.speed or 6) * ((ammo.combat.travel_speed or 100) / 100) * (weapon.travel_speed or 100) / 100 tg.archery = params or {} tg.archery.weapon = weapon + local grids = nil for i = 1, #targets do local tg = table.clone(tg) tg.archery.ammo = targets[i].ammo self:projectile(tg, targets[i].x, targets[i].y, archery_projectile) + if ammo.combat.lite then self:project(tg, targets[i].x, targets[i].y, DamageType.LITE, 1) end end end @@ -290,13 +310,43 @@ function _M:hasArcheryWeapon(type) return nil, "no shooter" end if not ammo then - -- Launchers provide infinite basic ammo - ammo = {name="default", infinite=true, combat=weapon.basic_ammo} + return nil, "Your quiver is empty." else - if not ammo.archery_ammo or weapon.archery ~= ammo.archery_ammo then + if not ammo.archery_ammo or weapon.archery ~= ammo.archery_ammo or not ammo.combat then return nil, "bad ammo" end end if type and weapon.archery ~= type then return nil, "bad type" end return weapon, ammo end + +--- Check if the actor has a bow or sling +function _M:hasShooter(type) + if not self:getInven("MAINHAND") then return nil, "no shooter" end + local weapon = self:getInven("MAINHAND")[1] + if self.inven[self.INVEN_PSIONIC_FOCUS] then + local pf_weapon = self:getInven("PSIONIC_FOCUS")[1] + if pf_weapon and pf_weapon.archery then + weapon = pf_weapon + end + end + if not weapon or not weapon.archery then + return nil, "no shooter" + end + + if type and weapon.archery ~= type then return nil, "bad type" end + return weapon +end + +--- Check if the actor has a bow or sling and corresponding ammo +function _M:hasAmmo(type) + if not self:getInven("QUIVER") then return nil, "no ammo" end + local ammo = self:getInven("QUIVER")[1] + + if not ammo then return nil, "no ammo" end + if not ammo.archery_ammo then return nil, "bad ammo" end + if not ammo.combat then return nil, "bad ammo" end + if not ammo.combat.capacity then return nil, "bad ammo" end + if type and ammo.archery_ammo ~= type then return nil, "bad type" end + return ammo, "no problem" +end diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 7c13562791..185b73242d 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -252,7 +252,7 @@ function _M:crossTierEffect(eff_id, apply_power, apply_save, use_given_e) ct_effect = cross_tier_effects[save_for_effects[e.type]] end local dur = self:getTierDiff(apply_power, save) - self:setEffect(ct_effect, dur, {}) + self:setEffect(ct_effect, dur, {no_ct_effect=true}) end function _M:getTierDiff(atk, def) @@ -261,10 +261,28 @@ function _M:getTierDiff(atk, def) return math.max(0, math.max(math.ceil(atk/20), 1) - math.max(math.ceil(def/20), 1)) end +--- Gets crit magnitude +function _M:getMaxAccuracy(hit_type, combat) + if hit_type == "physical" then return (combat and combat.max_acc) or 75 end + local mh = (self:getInven("MAINHAND") and self:getInven("MAINHAND")[1]) or {} + local oh = (self:getInven("OFFHAND") and self:getInven("OFFHAND")[1]) or {} + local pf = (self:getInven("PSIONIC_FOCUS") and self:getInven("PSIONIC_FOCUS")[1]) or {} + if hit_type == "spell" then + --if combat and combat.max_acc then return combat.max_acc end + return (combat and combat.affects_spells and combat.max_acc) or math.max( + (mh.combat and mh.combat.affects_spells and mh.combat.max_acc) or 75, + (oh.combat and oh.combat.affects_spells and oh.combat.max_acc) or (oh.special_combat and oh.special_combat.affects_spells and oh.special_combat.max_acc) or 75, + (pf.combat and pf.combat.max_acc) or 75 + ) + end + return 75 + +end + --New, simpler checkHit that relies on rescaleCombatStats() being used elsewhere function _M:checkHit(atk, def, min, max, factor, p) local min = min or 0 - local max = max or 100 + local max = max or 75 if game.player:hasQuest("tutorial-combat-stats") then min = 0 max = 100 @@ -273,6 +291,7 @@ function _M:checkHit(atk, def, min, max, factor, p) local hit = math.ceil(50 + 2.5 * (atk - def)) hit = util.bound(hit, min, max) print("=> chance to hit", hit) + print("min: ", min, "max: ", max) return rng.percent(hit), hit end @@ -337,20 +356,21 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) local hitted = false local crit = false local evaded = false + local pre_crit_dam = 0 if repelled then game.logSeen(target, "%s repels an attack from %s.", target.name:capitalize(), self.name) elseif self:checkEvasion(target) then evaded = true game.logSeen(target, "%s evades %s.", target.name:capitalize(), self.name) - elseif self:checkHit(atk, def) and (self:canSee(target) or self:attr("blind_fight") or rng.chance(3)) then + elseif self:checkHit(atk, def, 0, self:getMaxAccuracy("physical", weapon)) and (self:canSee(target) or self:attr("blind_fight") or rng.chance(3)) then local pres = util.bound(target:combatArmorHardiness() / 100, 0, 1) print("[ATTACK] raw dam", dam, "versus", armor, pres, "with APR", apr) armor = math.max(0, armor - apr) dam = math.max(dam * pres - armor, 0) + (dam * (1 - pres)) print("[ATTACK] after armor", dam) - local damrange = self:combatDamageRange(weapon) - dam = rng.range(dam, dam * damrange) - print("[ATTACK] after range", dam) +-- local damrange = self:combatDamageRange(weapon) +-- dam = rng.range(dam, dam * damrange) +-- print("[ATTACK] after range", dam) dam, crit = self:physicalCrit(dam, weapon, target, atk, def) print("[ATTACK] after crit", dam) dam = dam * mult @@ -362,8 +382,25 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) end print("[ATTACK] after inc by type", dam) end - - if crit then game.logSeen(self, "#{bold}#%s performs a critical strike!#{normal}#", self.name:capitalize()) end + --if target:attr("counterstrike") then + if target:hasEffect(target.EFF_COUNTERSTRIKE) then + dam = dam * 2 + --self:removeEffect(target.EFF_COUNTERSTRIKE) + local eff = target.tmp[target.EFF_COUNTERSTRIKE] + eff.nb = eff.nb - 1 + if eff.nb == 0 then eff.dur = 0 end + end + pre_crit_dam = dam + dam, crit = self:physicalCrit(dam, weapon, target, atk, def) + print("[ATTACK] after crit", dam) + if crit then + game.logSeen(self, "#{bold}#%s performs a critical strike!#{normal}#", self.name:capitalize()) + -- Concussion + if weapon.concussion then + dam = pre_crit_dam + self:doConcussion(dam, target, {weapon, ammo}) + end + end DamageType:get(damtype).projector(self, target.x, target.y, damtype, math.max(0, dam)) hitted = true else @@ -464,7 +501,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) t.do_trigger(self, t, target) end - -- On hit talent +--[=[ -- On hit talent if hitted and not target.dead and weapon and weapon.talent_on_hit and next(weapon.talent_on_hit) then for tid, data in pairs(weapon.talent_on_hit) do if rng.percent(data.chance) then @@ -472,6 +509,10 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) end end end +]=] + if hitted and not target.dead and weapon and weapon.talent_on_hit and next(weapon.talent_on_hit) then + self:doTalentOnHit(target, weapon) + end -- Shattering Impact if hitted and self:attr("shattering_impact") and (not self.shattering_impact_last_turn or self.shattering_impact_last_turn < game.turn) then @@ -488,15 +529,15 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) local rx, ry = util.coordAddDir(self.x, self.y, dir_sides[dir or 6].right) local lt, rt = game.level.map(lx, ly, Map.ACTOR), game.level.map(rx, ry, Map.ACTOR) - if target:checkHit(self:combatAttack(weapon), target:combatPhysicalResist(), 0, 95, 10) and target:canBe("knockback") then + if target:checkHit(self:combatAttack(weapon), target:combatPhysicalResist(), 0, self:getMaxAccuracy("physical", weapon), 10) and target:canBe("knockback") then target:knockback(self.x, self.y, self:attr("onslaught")) target:crossTierEffect(target.EFF_OFFBALANCE, self:combatAttack()) end - if lt and lt:checkHit(self:combatAttack(weapon), lt:combatPhysicalResist(), 0, 95, 10) and lt:canBe("knockback") then + if lt and lt:checkHit(self:combatAttack(weapon), lt:combatPhysicalResist(), 0, self:getMaxAccuracy("physical", weapon), 10) and lt:canBe("knockback") then lt:knockback(self.x, self.y, self:attr("onslaught")) target:crossTierEffect(target.EFF_OFFBALANCE, self:combatAttack()) end - if rt and rt:checkHit(self:combatAttack(weapon), rt:combatPhysicalResist(), 0, 95, 10) and rt:canBe("knockback") then + if rt and rt:checkHit(self:combatAttack(weapon), rt:combatPhysicalResist(), 0, self:getMaxAccuracy("physical", weapon), 10) and rt:canBe("knockback") then rt:knockback(self.x, self.y, self:attr("onslaught")) target:crossTierEffect(target.EFF_OFFBALANCE, self:combatAttack()) end @@ -515,6 +556,12 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) t.do_splash(target, t, self) end + -- Savagery + if hitted and crit and self:knowTalent(self.T_SAVAGERY) then + local t = self:getTalentFromId(self.T_SAVAGERY) + t.do_savagery(self, t) + end + -- Bloodbath if hitted and crit and self:knowTalent(self.T_BLOODBATH) then local t = self:getTalentFromId(self.T_BLOODBATH) @@ -579,13 +626,13 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) local t = target:getTalentFromId(target.T_CARBON_SPIKES) t.do_carbonLoss(target, t) end - +--[=[ -- Riposte! if not hitted and not target.dead and not evaded and not target:attr("stunned") and not target:attr("dazed") and not target:attr("stoned") and target:knowTalent(target.T_RIPOSTE) and rng.percent(target:getTalentLevel(target.T_RIPOSTE) * (5 + target:getDex(5, true))) then game.logSeen(self, "%s ripostes!", target.name:capitalize()) target:attackTarget(self, nil, nil, true) end - +]=] -- Set Up if not hitted and not target.dead and not evaded and not target:attr("stunned") and not target:attr("dazed") and not target:attr("stoned") and target:hasEffect(target.EFF_DEFENSIVE_MANEUVER) then local t = target:getTalentFromId(target.T_SET_UP) @@ -720,7 +767,9 @@ local weapon_talents = { function _M:combatCheckTraining(weapon) if not weapon.talented then return 0 end if not weapon_talents[weapon.talented] then return 0 end - return self:getTalentLevel(weapon_talents[weapon.talented]) + local t = self:getTalentFromId(weapon_talents[weapon.talented]) + return t.getDamage(self, t) + --return self:getTalentLevel(weapon_talents[weapon.talented]) end --- Gets the defense @@ -848,10 +897,20 @@ function _M:combatCrit(weapon) return crit end +--- Gets crit magnitude +function _M:combatCritPower(crit_type, weapon) + local combat = weapon or self.combat or {} + if crit_type == "spell" and not combat.affects_spells then + return 1.1 + else + return (combat.critical_power or 1.1) + (self.combat_critical_power or 0) + end +end + --- Gets the damage range function _M:combatDamageRange(weapon) weapon = weapon or self.combat or {} - return (self.combat_damrange or 0) + (weapon.damrange or 1.1) + return (self.combat_damrange or 0) + (weapon.damrange or 1) end @@ -883,7 +942,7 @@ function _M:combatDamage(weapon) if weapon.talented and weapon.talented == "knife" and self:knowTalent(Talents.T_LETHALITY) then sub_cun_to_str = true end local totstat = 0 - local dammod = weapon.dammod or {str=0.6} + local dammod = weapon.dammod or {str=0.1} for stat, mod in pairs(dammod) do if sub_cun_to_str and stat == "str" then stat = "cun" end if self.use_psi_combat and stat == "str" then stat = "wil" end @@ -898,13 +957,22 @@ function _M:combatDamage(weapon) totstat = totstat * 0.6 end end + totstat = math.floor(totstat) + + local talent_dam = self:combatCheckTraining(weapon) + --print(("[COMBAT DAMAGE] dam(%f) totstat(%f) talent_dam (%f)"):format(weapon.dam, totstat, talent_dam)) + return math.floor(weapon.dam + totstat + talent_dam) +end - local talented_mod = math.sqrt(self:combatCheckTraining(weapon) / 10) / 2 + 1 +function _M:getCombinedDamage(o, offmult) + local offmult = offmult or 1 + local weapon, ammo = self:hasArcheryWeapon() + if weapon then + return self:combatDamage(weapon.combat)*offmult + self:combatDamage(ammo.combat) + weapon:getRangedProjectDam() + ammo:getRangedProjectDam() + else + return self:combatDamage(o.combat)*offmult + o:getRangedProjectDam() + o:getMeleeProjectDam() + end - local power = math.max((weapon.dam or 1), 1) - power = (math.sqrt(power / 10) - 1) * 0.5 + 1 - --print(("[COMBAT DAMAGE] power(%f) totstat(%f) talent_mod(%f)"):format(power, totstat, talented_mod)) - return self:rescaleDamage(0.3*(self:combatPhysicalpower() + totstat) * power * talented_mod) end function _M:combatPhysicalpower(mod) @@ -920,28 +988,6 @@ function _M:combatPhysicalpower(mod) local t = self:getTalentFromId(self.T_EMPTY_HAND) add = add + t.getDamage(self, t) end - if self:knowTalent(Talents.T_WEAPONS_MASTERY) then - add = add + 5 * self:getTalentLevel(Talents.T_WEAPONS_MASTERY) - end - if self:knowTalent(Talents.T_KNIFE_MASTERY) then - add = add + 5 * self:getTalentLevel(Talents.T_KNIFE_MASTERY) - end - if self:knowTalent(Talents.T_EXOTIC_WEAPONS_MASTERY) then - add = add + 5 * self:getTalentLevel(Talents.T_EXOTIC_WEAPONS_MASTERY) - end - if self:knowTalent(Talents.T_UNARMED_MASTERY) then - add = add + 5 * self:getTalentLevel(Talents.T_UNARMED_MASTERY) - end - if self:knowTalent(Talents.T_STAFF_MASTERY) then - add = add + 5 * self:getTalentLevel(Talents.T_STAFF_MASTERY) - end - if self:knowTalent(Talents.T_BOW_MASTERY) then - add = add + 5 * self:getTalentLevel(Talents.T_BOW_MASTERY) - end - if self:knowTalent(Talents.T_SLING_MASTERY) then - add = add + 5 * self:getTalentLevel(Talents.T_SLING_MASTERY) - end - return self:rescaleCombatStats((self.combat_dam > 0 and self.combat_dam or 0) + add + self:getStr()) * mod end @@ -1050,6 +1096,7 @@ function _M:physicalCrit(dam, weapon, target, atk, def) end local chance = self:combatCrit(weapon) + local magnitude = self:combatCritPower("physical", weapon) local crit_power_add = 0 local crit = false if self:knowTalent(self.T_BACKSTAB) and target:attr("stunned") then chance = chance + self:getTalentLevel(self.T_BACKSTAB) * 10 end @@ -1063,6 +1110,12 @@ function _M:physicalCrit(dam, weapon, target, atk, def) chance = chance + p.power end end + if target:hasEffect(target.EFF_COUNTERSTRIKE) then + local p = target:hasEffect(target.EFF_COUNTERSTRIKE) + if p and p.src == self then + chance = chance + p.crit_inc + end + end if target:hasEffect(target.EFF_OFFGUARD) then chance = chance + 10 end @@ -1070,7 +1123,7 @@ function _M:physicalCrit(dam, weapon, target, atk, def) if target:hasHeavyArmor() and target:knowTalent(target.T_ARMOUR_TRAINING) then chance = chance - target:getTalentLevel(target.T_ARMOUR_TRAINING) * 1.9 end - + if target:attr("combat_critreduction") then chance = chance - target:attr("combat_critreduction") end @@ -1086,7 +1139,7 @@ function _M:physicalCrit(dam, weapon, target, atk, def) if target:hasEffect(target.EFF_OFFGUARD) then crit_power_add = crit_power_add + 0.1 end - dam = dam * (1.5 + crit_power_add + (self.combat_critical_power or 0) / 100) + dam = dam * (magnitude + crit_power_add + (self.combat_critical_power or 0) / 100) crit = true end @@ -1095,21 +1148,31 @@ end --- Computes spell crit for a damage function _M:spellCrit(dam, add_chance) - if self:isTalentActive(self.T_STEALTH) and self:knowTalent(self.T_SHADOWSTRIKE) then - return dam * (1.5 + self:getTalentLevel(self.T_SHADOWSTRIKE) / 7), true - end local chance = self:combatSpellCrit() + (add_chance or 0) local crit = false + -- get all weapons and use the largest crit magnitude that applies + local mh = (self:getInven("MAINHAND") and self:getInven("MAINHAND")[1]) or {} + local oh = (self:getInven("OFFHAND") and self:getInven("OFFHAND")[1]) or {} + local pf = (self:getInven("PSIONIC_FOCUS") and self:getInven("PSIONIC_FOCUS")[1]) or {} + local critical_power = math.max(self:combatCritPower("spell", mh.combat), self:combatCritPower("spell", oh.combat), self:combatCritPower("spell", pf.combat), 1.1) + + if self:isTalentActive(self.T_STEALTH) and self:knowTalent(self.T_SHADOWSTRIKE) then + return dam * (critical_power + self:getTalentLevel(self.T_SHADOWSTRIKE) / 7), true + end print("[SPELL CRIT %]", chance) if rng.percent(chance) then - dam = dam * (1.5 + (self.combat_critical_power or 0) / 100) + dam = dam * (critical_power + (self.combat_critical_power or 0) / 100) crit = true game.logSeen(self, "#{bold}#%s's spell attains critical power!#{normal}#", self.name:capitalize()) if self:attr("mana_on_crit") then self:incMana(self:attr("mana_on_crit")) end - + -- Savagery + if self:knowTalent(self.T_SAVAGERY) then + local t = self:getTalentFromId(self.T_SAVAGERY) + t.do_savagery(self, t) + end if self:isTalentActive(self.T_BLOOD_FURY) then local t = self:getTalentFromId(self.T_BLOOD_FURY) t.on_crit(self, t) @@ -1308,6 +1371,15 @@ function _M:hasStaffWeapon() return weapon end +function _M:hasGloves() + if not self:getInven("HANDS") then return end + local weapon = self:getInven("HANDS")[1] + if not weapon then + return nil + end + return weapon +end + --- Check if the actor has an axe weapon function _M:hasAxeWeapon() if self:attr("disarmed") then @@ -1551,3 +1623,18 @@ function _M:startGrapple(target) end end +function _M:doConcussion(dam, target, weapons) + local weapon = weapons[1] or {} + local ammo = weapons[2] or {} + if not weapon and not ammo then return end + dam = dam * (weapon.concussion or 0) * 0.01 + dam * (ammo.concussion or 0) * 0.01 + self:project({type="ball", radius=1, selffire=false}, target.x, target.y, DamageType.PHYSICAL, dam) +end + +function _M:doTalentOnHit(target, weapon) + for tid, data in pairs(weapon.talent_on_hit) do + if rng.percent(data.chance) then + self:forceUseTalent(tid, {ignore_cd=true, ignore_energy=true, force_target=target, force_level=data.level, ignore_ressources=true}) + end + end +end diff --git a/game/modules/tome/class/interface/PlayerDumpJSON.lua b/game/modules/tome/class/interface/PlayerDumpJSON.lua index ba000501c7..50049d9c7e 100644 --- a/game/modules/tome/class/interface/PlayerDumpJSON.lua +++ b/game/modules/tome/class/interface/PlayerDumpJSON.lua @@ -120,12 +120,9 @@ function _M:dumpToJSON(js) if self:getInven(self.INVEN_MAINHAND) then for i, o in ipairs(self:getInven(self.INVEN_MAINHAND)) do local mean, dam = o.combat, o.combat - if o.archery and mean then - dam = (self:getInven("QUIVER")[1] and self:getInven("QUIVER")[1].combat) or o.basic_ammo - end if mean and dam then c[#c+1] = { ["accuracy (main hand)"] = string.format("%d", self:combatAttack(mean)) } - c[#c+1] = { ["damage (main hand)"] = string.format("%d", self:combatDamage(dam)) } + c[#c+1] = { ["damage (main hand)"] = string.format("%d", self:getCombinedDamage(o))} c[#c+1] = { ["APR (main hand)"] = string.format("%d", self:combatAPR(dam)) } c[#c+1] = { ["crit (main hand)"] = string.format("%d%%", self:combatCrit(dam)) } c[#c+1] = { ["speed (main hand)"] = string.format("%0.2f", self:combatSpeed(mean)) } @@ -149,12 +146,9 @@ function _M:dumpToJSON(js) local offmult = self:getOffHandMult() for i, o in ipairs(self:getInven(self.INVEN_OFFHAND)) do local mean, dam = o.combat, o.combat - if o.archery and mean then - dam = (self:getInven("QUIVER")[1] and self:getInven("QUIVER")[1].combat) or o.basic_ammo - end if mean and dam then c[#c+1] = { ["accuracy (off hand)"] = string.format("%d", self:combatAttack(mean)) } - c[#c+1] = { ["damage (off hand)"] = string.format("%d", self:combatDamage(dam) * offmult) } + c[#c+1] = { ["damage (off hand)"] = string.format("%d", self:getCombinedDamage(o) * offmult) } c[#c+1] = { ["APR (off hand)"] = string.format("%d", self:combatAPR(dam)) } c[#c+1] = { ["crit(off hand)"] = string.format("%d%%", self:combatCrit(dam)) } c[#c+1] = { ["speed(off hand)"] = string.format("%0.2f", self:combatSpeed(mean)) } diff --git a/game/modules/tome/class/interface/TooltipsData.lua b/game/modules/tome/class/interface/TooltipsData.lua index 05d6e9b5af..010399b4ef 100644 --- a/game/modules/tome/class/interface/TooltipsData.lua +++ b/game/modules/tome/class/interface/TooltipsData.lua @@ -196,22 +196,21 @@ Measures your ability to deal physical damage in combat. When you use Physical Power to inflict temporary physical effects on an enemy, every five points of Physical Power counteracts a single turn of duration reduction granted by the enemy's saving throws. ]] TOOLTIP_COMBAT_DAMAGE = [[#GOLD#Damage#LAST# -This is the damage you inflict on your foes when you hit them. -This damage can be reduced by the target's armour or by percentile damage resistances. -It is improved by both Strength and Dexterity, some talents can change the stats that affect it. +This is the damage you typically inflict on your foes when you hit them, though you +might do less than this because of the target's armour or percentile damage resistances. ]] TOOLTIP_COMBAT_APR = [[#GOLD#Armour Penetration#LAST# Armour penetration allows you to ignore a part of the target's armour (this only works for armour, not damage resistance). This can never increase the damage you do beyond reducing armour, so it is only useful against armoured foes. ]] TOOLTIP_COMBAT_CRIT = [[#GOLD#Critical chance#LAST# -Each time you deal damage you have a chance to make a critical hit that deals 150% of the normal damage. +Your chance of dealing a critical hit, which multiplies your normal damage by your critical multiplier. Some talents allow you to increase this percentage. It is improved by Cunning. ]] TOOLTIP_COMBAT_SPEED = [[#GOLD#Attack speed#LAST# -Attack speed represents how fast your attacks are compared to a normal turn. -The lower it is the faster your attacks are. +This percentage is the frequency with which you get extra attacks. A bonus of 50%, for example, +means that you will get in an extra strike on every other attack. ]] TOOLTIP_COMBAT_RANGE = [[#GOLD#Firing range#LAST# The maximum distance your weapon can reach. @@ -286,8 +285,8 @@ This stacks with individual damage type increases. TOOLTIP_INC_DAMAGE = [[#GOLD#Damage increase: specific#LAST# All damage of this type that you deal, through any means, is increased by this percentage. ]] -TOOLTIP_INC_CRIT_POWER = [[#GOLD#Critical multiplicator#LAST# -All critical damage (melee, spells, ...) do this much damage. +TOOLTIP_INC_CRIT_POWER = [[#GOLD#Critical multiplier#LAST# +Critical strikes multiply damage by this amount. ]] TOOLTIP_RESIST_ALL = [[#GOLD#Damage resistance: all#LAST# All damage you receive, through any means, is decreased by this percentage. diff --git a/game/modules/tome/class/uiset/Minimalist.lua b/game/modules/tome/class/uiset/Minimalist.lua index 3b94b0b8c7..fd749131df 100644 --- a/game/modules/tome/class/uiset/Minimalist.lua +++ b/game/modules/tome/class/uiset/Minimalist.lua @@ -834,7 +834,7 @@ function _M:displayResources(scale, bx, by, a) local quiver = player:getInven("QUIVER") local ammo = quiver and quiver[1] if ammo then - local amt = ammo:getNumber() + local amt = ammo.combat.shots_left local shad, bg if ammo.type == "alchemist-gem" then shad, bg = _M["ammo_shadow_alchemist-gem"], _M["ammo_alchemist-gem"] else shad, bg = _M["ammo_shadow_"..ammo.subtype] or ammo_shadow_default, _M["ammo_"..ammo.subtype] or ammo_default diff --git a/game/modules/tome/data/birth/classes/warrior.lua b/game/modules/tome/data/birth/classes/warrior.lua index 84d9168738..79a4cc2217 100644 --- a/game/modules/tome/data/birth/classes/warrior.lua +++ b/game/modules/tome/data/birth/classes/warrior.lua @@ -157,7 +157,6 @@ newBirthDescriptor{ ["cunning/dirty"]={false, 0}, }, talents = { - [ActorTalents.T_SHOOT] = 1, [ActorTalents.T_FLARE] = 1, [ActorTalents.T_STEADY_SHOT] = 1, [ActorTalents.T_BOW_MASTERY] = 1, @@ -168,11 +167,15 @@ newBirthDescriptor{ max_life = 110, resolvers.equip{ id=true, {type="weapon", subtype="longbow", name="elm longbow", autoreq=true, ego_chance=-1000}, + {type="ammo", subtype="arrow", name="quiver of elm arrows", autoreq=true, ego_chance=-1000}, {type="armor", subtype="light", name="rough leather armour", autoreq=true, ego_chance=-1000} }, resolvers.inventory{ id=true, inven="QS_MAINHAND", {type="weapon", subtype="sling", name="rough leather sling", autoreq=true, ego_chance=-1000}, }, + resolvers.inventory{ id=true, + {type="ammo", subtype="shot", name="pouch of iron shot", autoreq=true, ego_chance=-1000}, + }, resolvers.generic(function(e) e.auto_shoot_talent = e.T_SHOOT end), diff --git a/game/modules/tome/data/chats/command-staff.lua b/game/modules/tome/data/chats/command-staff.lua new file mode 100644 index 0000000000..afc5a16644 --- /dev/null +++ b/game/modules/tome/data/chats/command-staff.lua @@ -0,0 +1,269 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + + + +local Dialog = require "engine.ui.Dialog" +local DamageType = require "engine.DamageType" +local o = version +local src = game.player +if o.factory_settings then + print("Just started the chat, and we apparently have o.factory_settings.") +else + print("Just started the chat, and there's no o.factory_settings") + o.factory_settings = o.combat + o.unused_stats = 0 + o.factory_settings.mins = { + dam = math.max(o.factory_settings.dam - 5 * (o.material_level or 1), 1), + critical_power = math.max(o.factory_settings.critical_power - 0.5, 1), + max_acc = o.factory_settings.max_acc - 25, + } + o.factory_settings.maxes = { + dam = o.factory_settings.dam + 5 * (o.material_level or 1), + critical_power = math.min(o.factory_settings.critical_power + 0.5, 3), + max_acc = 100, + } +end + +local function intro(o) + local sentient_responses = { + default = [[Greetings. How can I help you?]], + aggressive = [[Hurry up and make with the foe-blasting.]], + fawning = [[O wise wielder, instruct me that I may better serve you.]], + penitent = [[Make amends, magic-user, for the harm ye have wrought is beyond compare.]], + telos = [[You really could have chosen a better home for me, you know. I was reasonably happy in my old crystal. This stick smells like armpit.]], + } + if o.no_command then + return [[It is not yet your place to command such a staff as this. To do so invites obliteration.]] + end + if o.combat.sentient then + return sentient_responses[o.combat.sentient] or sentient_responses["default"] + else + return [[Call on which aspect of the staff?]] + end +end + +local function how_speak(o) + if not o.combat.sentient then return [[error!]] end + local sentient_responses = { + default = [[Oh, I was once a mighty Eldritch Channeler. Mighty and absentminded, as it turns out. Had a bit of a mishap with an Inverted Kugala's Soul-infusion technique. Long story short, my soul is now stuck in this stick, and the soul I was working with... well, I don't rightly know where he got to. But I hope we never meet him.]], + aggressive = [[Argh! Bollocksed up a tricky bit of soul magic and the fool that I was supposed to be imprisoning for all eternity flitted away. My body, like all the targets of my spells, intended or otherwise, got reduced to elementary particles. Fortunately, I had this soul-cage of a staff all prepped and ready for a stray soul, so I'm not completely gone. But enough chit-chat. Let's fry somebody.]], + fawning = [[My old master-- who, though a powerful enchanter, did not compare to you and your glory-- saw fit to imprison me in this fine staff to aid him in his work. Alas, he is long gone, but I despair not, for I have found a mighty new master.]], + penitent = [[I am a portion of the very spirit of the world that was ripped free during the Spellblaze. I speak that I might enlighten those who bear me.]], + telos = [[What's the good of immortality if you can't even speak? No archmage worth his salt is going to concoct some immoral life-after-death scheme without including some sort of capacity for making his opinions known. And, by the way, your energy manipulation techniques are on the same level as those of my average pair of shoes. Best study up if you don't want to die forgotten and incompetent.]], + } + return sentient_responses[o.combat.sentient] or sentient_responses["default"] +end + +local function which_aspect(o) + if not o.combat.sentient then return [[error!]] end + local sentient_responses = { + default = [[Of course. Which aspect?]], + aggressive = [[I highly recommend the mage aspect and the fire element. You're not going to find anything better for turning a piece of meat into a cloud of vapor.]], + fawning = [[I live to serve-- though my use of the word 'live' is perhaps loose here.]], + penitent = [[Choose wisely. Powers beyond your comprehension will tolerate only so much interference in their carefully-laid natural order.]], + telos = [[Back in my day, we didn't need to go changing our staves around willy-nilly. We picked an element and stuck with it, by the gods.]], + } + return sentient_responses[o.combat.sentient] or sentient_responses["default"] +end + +--unused for now: +local function alter_combat(o) + if not o.combat.sentient then return [[error!]] end + local sentient_responses = { + default = [[Certainly. You should be impressed, by the way, that I can do such a thing. Most lesser practitioners of my art would have difficulties with this. What shall I change?]], + aggressive = [[Fine, as long as it leads to blasting something soon. What do you want me to change?]], + } + return sentient_responses[o.combat.sentient] or sentient_responses["default"] +end + +local function is_sentient() + return o.combat.sentient +end + +local function update_table(d_table_old, d_table_new, old_element, new_element, tab, v, is_greater) + if is_greater then + for i = 1, #d_table_old do + o.wielder[tab][d_table_old[i]] = o.wielder[tab][d_table_old[i]] - v + if o.wielder[tab][d_table_old[i]] == 0 then o.wielder[tab][d_table_old[i]] = nil end + end + for i = 1, #d_table_new do + o.wielder[tab][d_table_new[i]] = (o.wielder[tab][d_table_new[i]] or 0) + v + end + else + o.wielder[tab][old_element] = o.wielder[tab][old_element] - v + o.wielder[tab][new_element] = (o.wielder[tab][new_element] or 0) + v + if o.wielder[tab][old_element] == 0 then o.wielder[tab][old_element] = nil end + end + +end + +local function set_element(element, new_flavor, player) + state.set_element = true + local dam = o.combat.dam + local inven = player:getInven("MAINHAND") + local o = player:takeoffObject(inven, 1) + local dam_tables = { + magestaff = {engine.DamageType.FIRE, engine.DamageType.COLD, engine.DamageType.LIGHTNING, engine.DamageType.ARCANE}, + starstaff = {engine.DamageType.LIGHT, engine.DamageType.DARKNESS, engine.DamageType.TEMPORAL}, + earthstaff = {engine.DamageType.NATURE, engine.DamageType.BLIGHT, engine.DamageType.ACID}, + } + + update_table(dam_tables[o.flavor_name], dam_tables[new_flavor], o.combat.damtype, element, "inc_damage", dam, o.combat.is_greater) + if o.combat.of_warding then update_table(dam_tables[o.flavor_name], dam_tables[new_flavor], o.combat.damtype, element, "wards", 2, o.combat.is_greater) end + if o.combat.of_breaching then update_table(dam_tables[o.flavor_name], dam_tables[new_flavor], o.combat.damtype, element, "resists_pen", dam/2, o.combat.is_greater) end + if o.combat.of_retribution then update_table(dam_tables[o.flavor_name], dam_tables[new_flavor], o.combat.damtype, element, "elemental_retribution", 1, o.combat.is_greater) end + + o.combat.damtype = element + if not o.unique then o.name = o.name:gsub(o.flavor_name, new_flavor) end + o.flavor_name = new_flavor + o:resolve() + o:resolve(nil, true) + player:addObject(inven, o) + print("(in chat's set_element) state.set_element is ", state.set_element) + coroutine.resume(co, true) + +end + +newChat{ id="welcome", + text = intro(o), + answers = { + {"How is it that you speak?", cond = function() return is_sentient() and not o.no_command end, jump="how_speak"}, + {"I'd like you to bring forth a different aspect.", cond = function() return is_sentient() and not o.no_command end, jump="which_aspect"}, + {"I'd like to alter your basic properties.", cond = function() return is_sentient() and not o.no_command end, + action = function() + coroutine.resume(co, true) + local SentientWeapon = require "mod.dialogs.SentientWeapon" + local ds = SentientWeapon.new({actor=game.player, o=o}) + game:registerDialog(ds) + end, + }, + {"[Mage]", cond = function() return not is_sentient() and not o.no_command end, jump="element_mage"}, + {"[Star]", cond = function() return not is_sentient() and not o.no_command end, jump="element_star"}, + {"[Earth]", cond = function() return not is_sentient() and not o.no_command end, jump="element_earth"}, + {"Never mind"}, + } +} + +newChat{ id="element_mage", + text = [[Call forth which element?]], + answers = { + {"[Fire]", + action = function() + set_element(DamageType.FIRE, "magestaff", game.player) + game.level.map:particleEmitter(game.player.x, game.player.y, 1, "teleport") + end, + }, + {"[Lightning]", + action = function() + set_element(DamageType.LIGHTNING, "magestaff", game.player) + game.level.map:particleEmitter(game.player.x, game.player.y, 1, "teleport") + end, + }, + {"[Cold]", + action = function() + set_element(DamageType.COLD, "magestaff", game.player) + game.level.map:particleEmitter(game.player.x, game.player.y, 1, "teleport") + end, + }, + {"[Arcane]", + action = function() + set_element(DamageType.ARCANE, "magestaff", game.player) + game.level.map:particleEmitter(game.player.x, game.player.y, 1, "teleport") + end, + }, + {"[Choose different aspect]", jump="welcome"}, + {"Never mind"}, + } +} + + +newChat{ id="element_star", + text = [[Call forth which element?]], + answers = { + {"[Light]", + action = function() + set_element(DamageType.LIGHT, "starstaff", game.player) + game.level.map:particleEmitter(game.player.x, game.player.y, 1, "teleport") + end, + }, + {"[Darkness]", + action = function() + set_element(DamageType.DARKNESS, "starstaff", game.player) + game.level.map:particleEmitter(game.player.x, game.player.y, 1, "teleport") + end, + }, + {"[Temporal]", + action = function() + set_element(DamageType.TEMPORAL, "starstaff", game.player) + game.level.map:particleEmitter(game.player.x, game.player.y, 1, "teleport") + end, + }, + {"[Choose different aspect]", jump="welcome"}, + {"Never mind"}, + } +} + + +newChat{ id="element_earth", + text = [[Call forth which element?]], + answers = { + {"[Nature]", + action = function() + set_element(DamageType.NATURE, "earthstaff", game.player) + game.level.map:particleEmitter(game.player.x, game.player.y, 1, "teleport") + end, + }, + {"[Blight]", + action = function() + set_element(DamageType.BLIGHT, "earthstaff", game.player) + game.level.map:particleEmitter(game.player.x, game.player.y, 1, "teleport") + end, + }, + {"[Acid]", + action = function() + set_element(DamageType.ACID, "earthstaff", game.player) + game.level.map:particleEmitter(game.player.x, game.player.y, 1, "teleport") + end, + }, + {"[Choose different aspect]", jump="welcome"}, + {"Never mind"}, + } +} + +newChat{ id="how_speak", + text = how_speak(o), + answers = { + {"I see.", jump="welcome"}, + } +} + +newChat{ id="which_aspect", + text = which_aspect(o), + answers = { + {"[Mage]", jump="element_mage"}, + {"[Star]", jump="element_star"}, + {"[Earth]", jump="element_earth"}, + {"Back up a second.", jump="welcome"}, + {"Never mind"}, + } +} + +return "welcome" + diff --git a/game/modules/tome/data/chats/ward.lua b/game/modules/tome/data/chats/ward.lua new file mode 100644 index 0000000000..9c6054c58c --- /dev/null +++ b/game/modules/tome/data/chats/ward.lua @@ -0,0 +1,84 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +local DamageType = require "engine.DamageType" +local src = version + +local function has_ward(which) + if not src.wards then return false end + if src.wards[which] and src.wards[which] ~= 0 then return true end + return false +end + +local function set_ward(which, charges) + src:setEffect(src.EFF_WARD, 10, {nb=charges, d_type=which}) + state.set_ward = true + --print("(in chat's set_ward) state.set_ward is ", state.set_ward) +end + +newChat{ id="welcome", + text = [[Call forth which ward?]], + answers = { + {"Fire ["..(src.wards[DamageType.FIRE] or 0).."]", + cond = function() return has_ward(DamageType.FIRE) end, + action = function() return set_ward(DamageType.FIRE, (src.wards[DamageType.FIRE] or 0)) end, + }, + {"Lightning ["..(src.wards[DamageType.LIGHTNING] or 0).."]", + cond = function() return has_ward(DamageType.LIGHTNING) end, + action = function() return set_ward(DamageType.LIGHTNING, (src.wards[DamageType.LIGHTNING] or 0)) end, + }, + {"Cold ["..(src.wards[DamageType.COLD] or 0).."]", + cond = function(who) return has_ward(DamageType.COLD) end, + action = function() return set_ward(DamageType.COLD, (src.wards[DamageType.COLD] or 0)) end, + }, + {"Arcane ["..(src.wards[DamageType.ARCANE] or 0).."]", + cond = function(who) return has_ward(DamageType.ARCANE) end, + action = function() return set_ward(DamageType.ARCANE, (src.wards[DamageType.ARCANE] or 0)) end, + }, + {"Light ["..(src.wards[DamageType.LIGHT] or 0).."]", + cond = function() return has_ward(DamageType.LIGHT) end, + action = function() return set_ward(DamageType.LIGHT, (src.wards[DamageType.LIGHT] or 0)) end, + }, + {"Darkness ["..(src.wards[DamageType.DARKNESS] or 0).."]", + cond = function() return has_ward(DamageType.DARKNESS) end, + action = function() return set_ward(DamageType.DARKNESS, (src.wards[DamageType.DARKNESS] or 0)) end, + }, + {"Temporal ["..(src.wards[DamageType.TEMPORAL] or 0).."]", + cond = function() return has_ward(DamageType.TEMPORAL) end, + action = function() return set_ward(DamageType.TEMPORAL, (src.wards[DamageType.TEMPORAL] or 0)) end, + }, + {"Nature ["..(src.wards[DamageType.NATURE] or 0).."]", + cond = function() return has_ward(DamageType.NATURE) end, + action = function() return set_ward(DamageType.NATURE, (src.wards[DamageType.NATURE] or 0)) end, + }, + {"Blight ["..(src.wards[DamageType.BLIGHT] or 0).."]", + cond = function() return has_ward(DamageType.BLIGHT) end, + action = function() return set_ward(DamageType.BLIGHT, (src.wards[DamageType.BLIGHT] or 0)) end, + }, + {"Acid ["..(src.wards[DamageType.ACID] or 0).."]", + cond = function() return has_ward(DamageType.ACID) end, + action = function() return set_ward(DamageType.ACID, (src.wards[DamageType.ACID] or 0)) end, + }, + + {"Never mind"}, + } +} + +return "welcome" + diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 80864811de..7d0bccbccf 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -45,6 +45,19 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) t.on_damage(target, t, type) end + -- Item-granted damage ward talent + --if target:attr("ward") then + if target:hasEffect(target.EFF_WARD) then + local e = target.tempeffect_def[target.EFF_WARD] + dam = e.absorb(type, dam, target.tmp[target.EFF_WARD], target, src) + end + + -- Block talent from shields + if target:attr("block") then + local e = target.tempeffect_def[target.EFF_BLOCKING] + dam = e.do_block(type, dam, target.tmp[target.EFF_BLOCKING], target, src) + end + -- Increases damage if src.inc_damage then local inc = (src.inc_damage.all or 0) + (src.inc_damage[type] or 0) @@ -58,7 +71,6 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) print("[PROJECTOR] after inc_damage_actor_type", dam + (dam * inc / 100)) end end - dam = dam + (dam * inc / 100) end @@ -104,6 +116,12 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) end end + -- Elemental Retribution causes the target to get buffed when taking certain kinds of damage + if target:knowTalent(target.T_ELEMENTAL_RETRIBUTION) and target ~= src and target.elemental_retribution and target.elemental_retribution[type] and target.elemental_retribution[type] > 0 then + local t = target:getTalentFromId(target.T_ELEMENTAL_RETRIBUTION) + t.do_retribution(target, t) + end + -- Static reduce damage for psionic kinetic shield if target.isTalentActive and target:isTalentActive(target.T_KINETIC_SHIELD) then local t = target:getTalentFromId(target.T_KINETIC_SHIELD) @@ -283,7 +301,7 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) if dam > 0 and source_talent then local t = source_talent - if src:attr("spellshock_on_damage") and target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and not target:hasEffect(target.EFF_SPELLSHOCKED) then + if src:attr("spellshock_on_damage") and target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, src:getMaxAccuracy("spell"), 15) and not target:hasEffect(target.EFF_SPELLSHOCKED) then target:crossTierEffect(target.EFF_SPELLSHOCKED, src:combatSpellpower()) end @@ -328,19 +346,19 @@ local function tryDestroy(who, inven, dam, destroy_prop, proof_prop, msg) end newDamageType{ - name = "physical", type = "PHYSICAL", + name = "physical", type = "PHYSICAL", text_color = "#WHITE#", color = colors.WHITE, death_message = {"battered", "bludgeoned", "sliced", "maimed", "raked", "bled", "impaled", "dissected", "disembowelled", "decapitated", "stabbed", "pierced", "torn limb from limb", "crushed", "shattered", "smashed", "cleaved", "swiped", "struck", "mutilated", "tortured", "skewered", "squished", "mauled", "chopped into tiny pieces", "splattered", "ground", "minced", "punctured", "hacked apart", "eviscerated"}, } -- Arcane is basic (usually) unresistable damage newDamageType{ - name = "arcane", type = "ARCANE", text_color = "#PURPLE#", + name = "arcane", type = "ARCANE", text_color = "#PURPLE#", color = colors.PURPLE, antimagic_resolve = true, death_message = {"blasted", "energised", "mana-torn", "dweomered", "imploded"}, } -- The elemental damages newDamageType{ - name = "fire", type = "FIRE", text_color = "#LIGHT_RED#", + name = "fire", type = "FIRE", text_color = "#LIGHT_RED#", color = colors.LIGHT_RED, antimagic_resolve = true, projector = function(src, x, y, type, dam) if src.fire_convert_to then @@ -355,7 +373,7 @@ newDamageType{ death_message = {"burnt", "scorched", "blazed", "roasted", "flamed", "fried", "combusted", "toasted", "slowly cooked", "boiled"}, } newDamageType{ - name = "cold", type = "COLD", text_color = "#1133F3#", + name = "cold", type = "COLD", text_color = "#1133F3#", color = {r=0x11, g=0x33, b=0xF3}, antimagic_resolve = true, projector = function(src, x, y, type, dam) local realdam = DamageType.defaultProjector(src, x, y, type, dam) @@ -367,7 +385,7 @@ newDamageType{ death_message = {"frozen", "chilled", "iced", "cooled", "frozen and shattered into a million little shards"}, } newDamageType{ - name = "lightning", type = "LIGHTNING", text_color = "#ROYAL_BLUE#", + name = "lightning", type = "LIGHTNING", text_color = "#ROYAL_BLUE#", color = colors.ROYAL_BLUE, antimagic_resolve = true, projector = function(src, x, y, type, dam) local realdam = DamageType.defaultProjector(src, x, y, type, dam) @@ -377,7 +395,7 @@ newDamageType{ } -- Acid destroys potions newDamageType{ - name = "acid", type = "ACID", text_color = "#GREEN#", + name = "acid", type = "ACID", text_color = "#GREEN#", color = colors.GREEN, antimagic_resolve = true, projector = function(src, x, y, type, dam) local realdam = DamageType.defaultProjector(src, x, y, type, dam) @@ -388,12 +406,12 @@ newDamageType{ -- Nature & Blight: Opposing damage types newDamageType{ - name = "nature", type = "NATURE", text_color = "#LIGHT_GREEN#", + name = "nature", type = "NATURE", text_color = "#LIGHT_GREEN#", color = colors.LIGHT_GREEN, antimagic_resolve = true, death_message = {"slimed", "splurged", "treehugged", "naturalised"}, } newDamageType{ - name = "blight", type = "BLIGHT", text_color = "#DARK_GREEN#", + name = "blight", type = "BLIGHT", text_color = "#DARK_GREEN#", color = colors.DARK_GREEN, antimagic_resolve = true, projector = function(src, x, y, type, dam, extra) local realdam = DamageType.defaultProjector(src, x, y, type, dam) @@ -413,21 +431,21 @@ newDamageType{ -- Light damage newDamageType{ - name = "light", type = "LIGHT", text_color = "#YELLOW#", + name = "light", type = "LIGHT", text_color = "#YELLOW#", color = colors.YELLOW, antimagic_resolve = true, death_message = {"radiated", "seared", "purified", "sun baked", "jerkied", "tanned"}, } -- Darkness damage newDamageType{ - name = "darkness", type = "DARKNESS", text_color = "#GREY#", + name = "darkness", type = "DARKNESS", text_color = "#GREY#", color = colors.GREY, antimagic_resolve = true, death_message = {"shadowed", "darkened", "swallowed by the void"}, } -- Mind damage newDamageType{ - name = "mind", type = "MIND", text_color = "#YELLOW#", + name = "mind", type = "MIND", text_color = "#YELLOW#", color = colors.YELLOW, projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -452,7 +470,7 @@ newDamageType{ -- Temporal damage newDamageType{ - name = "temporal", type = "TEMPORAL", text_color = "#LIGHT_STEEL_BLUE#", + name = "temporal", type = "TEMPORAL", text_color = "#LIGHT_STEEL_BLUE#", color = colors.LIGHT_STEEL_BLUE, antimagic_resolve = true, death_message = {"timewarped", "temporally distorted", "spaghettified across the whole of space and time", "paradoxed", "replaced by a time clone (and no one ever knew the difference)", "grandfathered", "time dilated"}, } @@ -820,7 +838,7 @@ newDamageType{ DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam / 2) local target = game.level.map(x, y, Map.ACTOR) if target then - if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then + if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, src:getMaxAccuracy("spell"), 15) and target:canBe("knockback") then target:knockback(srcx, srcy, 1) target:crossTierEffect(target.EFF_OFFBALANCE, src:combatSpellpower()) game.logSeen(target, "%s is knocked back!", target.name:capitalize()) @@ -841,7 +859,7 @@ newDamageType{ if target and not tmp[target] then tmp[target] = true DamageType:get(DamageType.FIREBURN).projector(src, x, y, DamageType.FIREBURN, dam.dam) - if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then + if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, src:getMaxAccuracy("spell"), 15) and target:canBe("knockback") then target:knockback(src.x, src.y, dam.dist) target:crossTierEffect(target.EFF_OFFBALANCE, src:combatSpellpower()) game.logSeen(target, "%s is knocked back!", target.name:capitalize()) @@ -883,7 +901,7 @@ newDamageType{ if target and not tmp[target] then tmp[target] = true DamageType:get(DamageType.DARKNESS).projector(src, x, y, DamageType.DARKNESS, dam.dam) - if target:checkHit(src:combatSpellpower(), target:combatMentalResist(), 0, 95, 15) and target:canBe("knockback") then + if target:checkHit(src:combatSpellpower(), target:combatMentalResist(), 0, src:getMaxAccuracy("spell"), 15) and target:canBe("knockback") then target:knockback(src.x, src.y, dam.dist) target:crossTierEffect(target.EFF_BRAINLOCKED, src:combatSpellpower()) game.logSeen(target, "%s is knocked back!", target.name:capitalize()) @@ -904,7 +922,7 @@ newDamageType{ if target and not tmp[target] then tmp[target] = true realdam = DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam) - if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then + if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, src:getMaxAccuracy("spell"), 15) and target:canBe("knockback") then target:knockback(src.x, src.y, 3) target:crossTierEffect(target.EFF_OFFBALANCE, src:combatSpellpower()) game.logSeen(target, "%s is knocked back!", target.name:capitalize()) @@ -1122,7 +1140,7 @@ newDamageType{ if src == target then target:setEffect(target.EFF_TIME_PRISON, dam, {no_ct_effect=true}) target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=src:combatSpellpower(0.3), no_ct_effect=true}) - elseif target:checkHit(src:combatSpellpower() - (target:attr("continuum_destabilization") or 0), target:combatSpellResist(), 0, 95, 15) then + elseif target:checkHit(src:combatSpellpower() - (target:attr("continuum_destabilization") or 0), target:combatSpellResist(), 0, src:getMaxAccuracy("spell"), 15) then target:setEffect(target.EFF_TIME_PRISON, dam, {apply_power=src:combatSpellpower() - (target:attr("continuum_destabilization") or 0), apply_save="combatSpellResist", no_ct_effect=true}) target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=src:combatSpellpower(0.3), no_ct_effect=true}) else @@ -1149,9 +1167,10 @@ newDamageType{ -- Confusion newDamageType{ - name = "% chances to confuse", type = "RANDOM_CONFUSION", + name = "confusion", type = "RANDOM_CONFUSION", text_color = "#YELLOW#", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam} end + DamageType:get(DamageType.MIND).projector(src, x, y, DamageType.MIND, dam.dam) local target = game.level.map(x, y, Map.ACTOR) if target and rng.percent(dam.dam) then if target:canBe("confusion") then @@ -1256,6 +1275,26 @@ newDamageType{ end, } +-- Drain all resources +newDamageType{ + name = "soul drain", type = "SOUL_DRAIN", + projector = function(src, x, y, type, dam) + if _G.type(dam) == "number" then dam = {dam=dam, drain=0.5} end + local realdam = DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam.dam) + local target = game.level.map(x, y, Map.ACTOR) + if target and target ~= src and realdam > 0 then + target:incMana(-target:getMana()*0.5) + target:incVim(-target:getVim()*0.5) + target:incPositive(-target:getPositive()*0.5) + target:incNegative(-target:getNegative()*0.5) + target:incEquilibrium(target:getEquilibrium()*0.5) + target:incStamina(-target:getStamina()*0.5) + target:incHate(-target:getHate()*0.5) + target:incPsi(-target:getPsi()*0.5) + end + end, +} + -- Demonfire: heal demon; damage others newDamageType{ name = "demonfire", type = "DEMONFIRE", @@ -1445,7 +1484,7 @@ newDamageType{ -- check knockback if target and not target:attr("never_move") and not tmp[target] then tmp[target] = true - if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then + if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, src:getMaxAccuracy("spell"), 15) and target:canBe("knockback") then target:knockback(src.x, src.y, 2) target:crossTierEffect(target.EFF_OFFBALANCE, src:combatSpellpower()) game.logSeen(target, "%s is knocked back!", target.name:capitalize()) @@ -1529,7 +1568,7 @@ newDamageType{ elseif target ~= src then DamageType:get(DamageType.LIGHT).projector(src, x, y, DamageType.LIGHT, dam ) DamageType:get(DamageType.DARKNESS).projector(src, x, y, DamageType.DARKNESS, dam) - if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then + if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, src:getMaxAccuracy("spell"), 15) and target:canBe("knockback") then target:knockback(src.x, src.y, 1) target:crossTierEffect(target.EFF_OFFBALANCE, src:combatSpellpower()) game.logSeen(target, "%s is knocked back!", target.name:capitalize()) @@ -1669,7 +1708,7 @@ newDamageType{ game.logSeen(target, "%s resists the blindness!", target.name:capitalize()) end elseif chance == 3 then - if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("pin") then + if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, src:getMaxAccuracy("spell"), 15) and target:canBe("pin") then target:setEffect(target.EFF_PINNED, 3, {apply_power=src:combatSpellpower()}) else game.logSeen(target, "%s resists the pin!", target.name:capitalize()) diff --git a/game/modules/tome/data/general/npcs/ant.lua b/game/modules/tome/data/general/npcs/ant.lua index 9f0a7dee30..34ffdf965c 100644 --- a/game/modules/tome/data/general/npcs/ant.lua +++ b/game/modules/tome/data/general/npcs/ant.lua @@ -34,7 +34,7 @@ newEntity{ stats = { str=12, dex=10, mag=3, con=13 }, energy = { mod=1 }, combat_armor = 1, combat_def = 1, - combat = { dam=resolvers.levelup(resolvers.rngavg(5,5), 1, 1), atk=15, apr=7, dammod={str=0.6}, sound="creatures/ants/ant_hit" }, + combat = { dam=resolvers.levelup(resolvers.rngavg(5,5), 1, 1), atk=15, apr=7, dammod={str=resolvers.levelup(0.1, 5, 0.1, 0.6)}, sound="creatures/ants/ant_hit" }, infravision = 10, max_life = resolvers.rngavg(10,20), rank = 1, diff --git a/game/modules/tome/data/general/npcs/aquatic_critter.lua b/game/modules/tome/data/general/npcs/aquatic_critter.lua index d4161f3bd5..6501e4919a 100644 --- a/game/modules/tome/data/general/npcs/aquatic_critter.lua +++ b/game/modules/tome/data/general/npcs/aquatic_critter.lua @@ -30,7 +30,7 @@ newEntity{ ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=1, }, stats = { str=12, dex=10, mag=3, con=13 }, combat_armor = 1, combat_def = 1, - combat = { dam=resolvers.levelup(resolvers.mbonus(36, 10), 1, 1), atk=15, apr=7, dammod={str=0.6} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(36, 10), 1, 1), atk=15, apr=7, dammod={str=resolvers.levelup(0.2, 5, 0.1, 0.6)} }, max_life = resolvers.rngavg(10,20), life_rating = 6, infravision = 10, rank = 1, diff --git a/game/modules/tome/data/general/npcs/bear.lua b/game/modules/tome/data/general/npcs/bear.lua index 27fcdd4666..3763f54932 100644 --- a/game/modules/tome/data/general/npcs/bear.lua +++ b/game/modules/tome/data/general/npcs/bear.lua @@ -41,7 +41,7 @@ newEntity{ size_category = 4, combat_armor = 1, combat_def = 1, - combat = { dam=resolvers.levelup(resolvers.rngavg(12, 25), 1, 1), atk=10, apr=3, physspeed=2, dammod={str=0.8} }, + combat = { dam=resolvers.levelup(resolvers.rngavg(12, 25), 1, 1), atk=10, apr=3, physspeed=2, dammod={str=resolvers.levelup(0.2, 5, 0.1, 1.1)} }, life_rating = 12, resolvers.tmasteries{ ["technique/other"]=0.25 }, diff --git a/game/modules/tome/data/general/npcs/canine.lua b/game/modules/tome/data/general/npcs/canine.lua index 0ee72d2d57..03b3a9242f 100644 --- a/game/modules/tome/data/general/npcs/canine.lua +++ b/game/modules/tome/data/general/npcs/canine.lua @@ -39,7 +39,7 @@ newEntity{ ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=2, }, global_speed_base = 1.2, stats = { str=10, dex=17, mag=3, con=7 }, - combat = { dammod={str=0.6}, sound="creatures/wolves/wolf_attack_1" }, + combat = { dammod={str=resolvers.levelup(0.2, 5, 0.1, 0.6)}, sound="creatures/wolves/wolf_attack_1" }, combat_armor = 1, combat_def = 1, } diff --git a/game/modules/tome/data/general/npcs/cold-drake.lua b/game/modules/tome/data/general/npcs/cold-drake.lua index f506fa7bb0..289c26f98e 100644 --- a/game/modules/tome/data/general/npcs/cold-drake.lua +++ b/game/modules/tome/data/general/npcs/cold-drake.lua @@ -51,7 +51,7 @@ newEntity{ base = "BASE_NPC_COLD_DRAKE", rank = 1, size_category = 2, max_life = resolvers.rngavg(40,60), combat_armor = 5, combat_def = 0, - combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,50), apr=25, dammod={str=1.1} }, + combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,50), apr=25, dammod={str=resolvers.levelup(0.2, 5, 0.1, 1.1)} }, on_melee_hit = {[DamageType.COLD]=resolvers.mbonus(7, 2)}, make_escort = { diff --git a/game/modules/tome/data/general/npcs/feline.lua b/game/modules/tome/data/general/npcs/feline.lua index ecdec4d5c3..bfc2f06901 100644 --- a/game/modules/tome/data/general/npcs/feline.lua +++ b/game/modules/tome/data/general/npcs/feline.lua @@ -29,7 +29,7 @@ newEntity{ global_speed_base = 1.25, type = "animal", subtype="feline", ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=2, }, - + combat = {dammod={str=resolvers.levelup(0.1, 5, 0.1, 0.5), dex=resolvers.levelup(0.1, 5, 0.1, 0.5)}}, combat_physspeed = 2, -- Double attack per turn resolvers.sustains_at_birth(), @@ -44,7 +44,7 @@ newEntity{ base = "BASE_NPC_CAT", max_life = resolvers.rngavg(40,80), resists = { [DamageType.COLD] = 50 }, combat_armor = 0, combat_def = 8, - combat = { dam=resolvers.levelup(5, 1, 0.7), atk=12, apr=15, dammod={str=0.5, dex=0.5}}, + combat = { dam=resolvers.levelup(5, 1, 0.7), atk=12, apr=15}, resolvers.talents{ [Talents.T_STEALTH]={base=1, every=6, max=5}, [Talents.T_RUSH]={base=1, every=8, max=3}, @@ -60,7 +60,7 @@ newEntity{ base = "BASE_NPC_CAT", size_category=3, max_life = resolvers.rngavg(60,100), combat_armor = 3, combat_def = 8, - combat = { dam=resolvers.levelup(18, 1, 1), atk=12, apr=20, dammod={str=0.5, dex=0.5}}, + combat = { dam=resolvers.levelup(18, 1, 1), atk=12, apr=20}, resolvers.talents{ [Talents.T_STEALTH]={base=1, every=6, max=5}, [Talents.T_RUSH]={base=1, every=8, max=3}, @@ -76,7 +76,7 @@ newEntity{ base = "BASE_NPC_CAT", size_category=4, max_life = resolvers.rngavg(70,110), combat_armor = 3, combat_def = 8, - combat = { dam=resolvers.levelup(25, 1, 1), atk=12, apr=25, dammod={str=0.5, dex=0.5}}, + combat = { dam=resolvers.levelup(25, 1, 1), atk=12, apr=25}, resolvers.talents{ [Talents.T_STEALTH]={base=2, every=6, max=5}, [Talents.T_RUSH]={base=2, every=8, max=5}, @@ -93,7 +93,7 @@ newEntity{ base = "BASE_NPC_CAT", size_category=4, max_life = resolvers.rngavg(80,120), combat_armor = 3, combat_def = 8, - combat = { dam=resolvers.levelup(28, 1, 1), atk=12, apr=35, dammod={str=0.5, dex=0.5}}, + combat = { dam=resolvers.levelup(28, 1, 1), atk=12, apr=35}, resolvers.talents{ [Talents.T_STEALTH]={base=3, every=6, max=5}, [Talents.T_RUSH]={base=3, every=8, max=5}, diff --git a/game/modules/tome/data/general/npcs/fire-drake.lua b/game/modules/tome/data/general/npcs/fire-drake.lua index 6916668d37..5f763b21cb 100644 --- a/game/modules/tome/data/general/npcs/fire-drake.lua +++ b/game/modules/tome/data/general/npcs/fire-drake.lua @@ -51,7 +51,7 @@ newEntity{ base = "BASE_NPC_FIRE_DRAKE", rank = 1, size_category = 2, max_life = resolvers.rngavg(40,60), combat_armor = 5, combat_def = 0, - combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,60), apr=25, dammod={str=1.1} }, + combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,60), apr=25, dammod={str=resolvers.levelup(0.1, 5, 0.1, 1.1)} }, on_melee_hit = {[DamageType.FIRE]=resolvers.mbonus(7, 2)}, make_escort = { diff --git a/game/modules/tome/data/general/npcs/ghoul.lua b/game/modules/tome/data/general/npcs/ghoul.lua index d449de24ad..caf888b497 100644 --- a/game/modules/tome/data/general/npcs/ghoul.lua +++ b/game/modules/tome/data/general/npcs/ghoul.lua @@ -65,7 +65,7 @@ newEntity{ base = "BASE_NPC_GHOUL", }, ai_state = { talent_in=4, }, - combat = { dam=resolvers.levelup(10, 1, 1), atk=resolvers.levelup(5, 1, 1), apr=3, dammod={str=0.6} }, + combat = { dam=resolvers.levelup(10, 1, 1), atk=resolvers.levelup(5, 1, 1), apr=3, dammod={str=resolvers.levelup(0.1, 5, 0.1, 0.6)} }, } newEntity{ base = "BASE_NPC_GHOUL", @@ -77,7 +77,7 @@ newEntity{ base = "BASE_NPC_GHOUL", combat_armor = 2, combat_def = 8, ai_state = { talent_in=3, }, - combat = { dam=resolvers.levelup(17, 1, 1.1), atk=resolvers.levelup(6, 1, 1), apr=3, dammod={str=0.6} }, + combat = { dam=resolvers.levelup(17, 1, 1.1), atk=resolvers.levelup(6, 1, 1), apr=3, dammod={str=resolvers.levelup(0.1, 5, 0.1, 0.6)} }, summon = {{type="undead", subtype="ghoul", name="ghoul", number=1, hasxp=false}, }, resolvers.talents{ diff --git a/game/modules/tome/data/general/npcs/gwelgoroth.lua b/game/modules/tome/data/general/npcs/gwelgoroth.lua index b95c675fac..d927191631 100644 --- a/game/modules/tome/data/general/npcs/gwelgoroth.lua +++ b/game/modules/tome/data/general/npcs/gwelgoroth.lua @@ -25,7 +25,7 @@ newEntity{ blood_color = colors.AQUAMARINE, display = "E", color=colors.AQUAMARINE, - combat = { dam=resolvers.levelup(resolvers.mbonus(40, 15), 1, 1.2), atk=15, apr=15, dammod={mag=0.8}, damtype=DamageType.LIGHTNING }, + combat = { dam=resolvers.levelup(resolvers.mbonus(40, 15), 1, 1.2), atk=15, apr=15, dammod={mag=resolvers.levelup(0.1, 5, 0.1, 0.8)}, damtype=DamageType.LIGHTNING }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, diff --git a/game/modules/tome/data/general/npcs/multihued-drake.lua b/game/modules/tome/data/general/npcs/multihued-drake.lua index 76c292d82a..10b6bb9601 100644 --- a/game/modules/tome/data/general/npcs/multihued-drake.lua +++ b/game/modules/tome/data/general/npcs/multihued-drake.lua @@ -52,7 +52,7 @@ newEntity{ base = "BASE_NPC_MULTIHUED_DRAKE", max_life = resolvers.rngavg(60,80), combat_armor = 5, combat_def = 0, on_melee_hit = {[DamageType.FIRE]=resolvers.mbonus(7, 3), [DamageType.COLD]=resolvers.mbonus(7, 3)}, - combat = { dam=resolvers.levelup(resolvers.rngavg(25,70), 1, 0.6), atk=resolvers.rngavg(25,70), apr=25, dammod={str=1.1} }, + combat = { dam=resolvers.levelup(resolvers.rngavg(25,70), 1, 0.6), atk=resolvers.rngavg(25,70), apr=25, dammod={str=resolvers.levelup(0.2, 5, 0.1, 1.1)} }, resists = { [DamageType.PHYSICAL] = 20, [DamageType.FIRE] = 20, [DamageType.COLD] = 20, [DamageType.ACID] = 20, [DamageType.LIGHTNING] = 20, }, diff --git a/game/modules/tome/data/general/npcs/ritch.lua b/game/modules/tome/data/general/npcs/ritch.lua index 8cd2cb9047..1486a20250 100644 --- a/game/modules/tome/data/general/npcs/ritch.lua +++ b/game/modules/tome/data/general/npcs/ritch.lua @@ -27,7 +27,7 @@ newEntity{ desc = [[Ritches are giant insects native to the arid wastes of the southern parts of the Far East. Vicious predators, they inject corrupting diseases into their foes, and their sharp claws cut through most armours.]], - combat = { dam=resolvers.levelup(resolvers.rngavg(30,35), 1, 1), atk=16, apr=70, damtype=DamageType.BLIGHT, dammod={dex=1.2} }, + combat = { dam=resolvers.levelup(resolvers.rngavg(30,35), 1, 1), atk=16, apr=70, damtype=DamageType.BLIGHT, dammod={dex=resolvers.levelup(0.1, 5, 0.1, 1.2)} }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, diff --git a/game/modules/tome/data/general/npcs/sandworm.lua b/game/modules/tome/data/general/npcs/sandworm.lua index 9b65cafae3..4080ccb958 100644 --- a/game/modules/tome/data/general/npcs/sandworm.lua +++ b/game/modules/tome/data/general/npcs/sandworm.lua @@ -26,7 +26,7 @@ newEntity{ level_range = {7, nil}, body = { INVEN = 10 }, - combat = { dam=resolvers.levelup(resolvers.mbonus(25, 15), 1, 1), atk=15, apr=0, dammod={str=0.7} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(25, 15), 1, 1), atk=15, apr=0, dammod={str=resolvers.levelup(0.1, 5, 0.1, 0.7)} }, infravision = 10, max_life = 40, life_rating = 5, diff --git a/game/modules/tome/data/general/npcs/snow-giant.lua b/game/modules/tome/data/general/npcs/snow-giant.lua index 19d986455b..a3f903758e 100644 --- a/game/modules/tome/data/general/npcs/snow-giant.lua +++ b/game/modules/tome/data/general/npcs/snow-giant.lua @@ -24,7 +24,7 @@ newEntity{ type = "giant", subtype = "ice", display = "P", color=colors.WHITE, - combat = { dam=resolvers.levelup(resolvers.mbonus(50, 10), 1, 1), atk=15, apr=15, dammod={str=0.8} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(50, 10), 1, 1), atk=15, apr=15, dammod={str=resolvers.levelup(0.2, 5, 0.1, 0.8)} }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, resolvers.drops{chance=100, nb=1, {type="money"} }, diff --git a/game/modules/tome/data/general/npcs/spider.lua b/game/modules/tome/data/general/npcs/spider.lua index c1cf8cbb1b..6fc8df7550 100644 --- a/game/modules/tome/data/general/npcs/spider.lua +++ b/game/modules/tome/data/general/npcs/spider.lua @@ -25,7 +25,7 @@ newEntity{ display = "S", color=colors.WHITE, desc = [[Arachnophobia...]], - combat = { dam=resolvers.levelup(resolvers.mbonus(40, 70), 1, 0.9), atk=16, apr=9, damtype=DamageType.NATURE, dammod={dex=1.2} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(40, 70), 1, 0.9), atk=16, apr=9, damtype=DamageType.NATURE, dammod={dex=resolvers.levelup(0.2, 5, 0.1, 1.2)} }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, @@ -263,7 +263,7 @@ newEntity{ base = "BASE_NPC_SPIDER", size_category = 1, - combat = { dam=resolvers.levelup(resolvers.mbonus(40, 70), 1, 0.9), atk=16, apr=9, damtype=DamageType.WASTING, dammod={dex=1.2} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(40, 70), 1, 0.9), atk=16, apr=9, damtype=DamageType.WASTING}, combat_armor = 5, combat_def = 10, resists = { [DamageType.NATURE] = 20, [DamageType.LIGHT] = -20, [DamageType.TEMPORAL] = 20, }, @@ -285,7 +285,7 @@ newEntity{ base = "BASE_NPC_SPIDER", life_rating = 13, rank = 2, - combat = { dam=resolvers.levelup(resolvers.mbonus(40, 70), 1, 0.9), atk=16, apr=9, damtype=DamageType.WASTING, dammod={dex=1.2} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(40, 70), 1, 0.9), atk=16, apr=9, damtype=DamageType.WASTING}, combat_armor = 7, combat_def = 17, resists = { [DamageType.NATURE] = 20, [DamageType.LIGHT] = -20, [DamageType.TEMPORAL] = 20, }, @@ -316,7 +316,7 @@ newEntity{ base = "BASE_NPC_SPIDER", ai = "tactical", ai_tactic = resolvers.tactic"melee", ai_state = { ai_move="move_dmap", talent_in=2, }, - combat = { dam=resolvers.levelup(resolvers.mbonus(40, 70), 1, 0.9), atk=16, apr=9, damtype=DamageType.WASTING, dammod={dex=1.2} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(40, 70), 1, 0.9), atk=16, apr=9, damtype=DamageType.WASTING}, combat_armor = 7, combat_def = 17, resists = { [DamageType.NATURE] = 20, [DamageType.LIGHT] = -20, [DamageType.TEMPORAL] = 20, }, @@ -354,7 +354,7 @@ newEntity{ base = "BASE_NPC_SPIDER", ai = "tactical", ai_tactic = resolvers.tactic"melee", ai_state = { ai_move="move_dmap", talent_in=1, }, - combat = { dam=resolvers.levelup(resolvers.mbonus(100, 15), 1, 0.9), atk=16, apr=9, damtype=DamageType.WASTING, dammod={dex=1.2} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(100, 15), 1, 0.9), atk=16, apr=9, damtype=DamageType.WASTING}, combat_armor = 7, combat_def = 17, resists = { [DamageType.NATURE] = 20, [DamageType.LIGHT] = -20, [DamageType.TEMPORAL] = 20, }, diff --git a/game/modules/tome/data/general/npcs/storm-drake.lua b/game/modules/tome/data/general/npcs/storm-drake.lua index 5c812e0719..e6c324cfef 100644 --- a/game/modules/tome/data/general/npcs/storm-drake.lua +++ b/game/modules/tome/data/general/npcs/storm-drake.lua @@ -51,7 +51,7 @@ newEntity{ base = "BASE_NPC_STORM_DRAKE", rank = 1, size_category = 2, max_life = resolvers.rngavg(40,60), combat_armor = 5, combat_def = 0, - combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,60), apr=25, dammod={str=1.1} }, + combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,60), apr=25, dammod={str=resolvers.levelup(0.2, 5, 0.1, 1.1)} }, on_melee_hit = {[DamageType.LIGHTNING]=resolvers.mbonus(7, 2)}, make_escort = { diff --git a/game/modules/tome/data/general/npcs/telugoroth.lua b/game/modules/tome/data/general/npcs/telugoroth.lua index 96468426c9..244f948d4e 100644 --- a/game/modules/tome/data/general/npcs/telugoroth.lua +++ b/game/modules/tome/data/general/npcs/telugoroth.lua @@ -26,7 +26,7 @@ newEntity{ blood_color = colors.PURPLE, display = "E", color=colors.YELLOW, - combat = { dam=resolvers.levelup(resolvers.mbonus(40, 15), 1, 1.2), atk=15, apr=15, dammod={mag=0.8}, damtype=DamageType.TEMPORAL, }, + combat = { dam=resolvers.levelup(resolvers.mbonus(40, 15), 1, 1.2), atk=15, apr=15, dammod={mag=resolvers.levelup(0.1, 5, 0.1, 0.8)}, damtype=DamageType.TEMPORAL }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, @@ -44,7 +44,7 @@ newEntity{ resists = { [DamageType.TEMPORAL] = 100, }, negative_status_effect_immune = 1, - + } newEntity{ base = "BASE_NPC_TELUGOROTH", @@ -111,7 +111,7 @@ newEntity{ base = "BASE_NPC_TELUGOROTH", ai = "dumb_talented_simple", ai_state = { talent_in=2, ai_move="move_snake" }, talent_cd_reduction = {[Talents.T_DUST_TO_DUST]=-3}, - + resolvers.talents{ [Talents.T_ANOMALY_REARRANGE]=1, [Talents.T_DUST_TO_DUST]={base=3, every=10, max=7}, @@ -132,7 +132,7 @@ newEntity{ base = "BASE_NPC_TELUGOROTH", ai = "dumb_talented_simple", ai_state = { talent_in=2, ai_move="move_snake" }, talent_cd_reduction = {[Talents.T_DUST_TO_DUST]=-3}, - + resolvers.talents{ [Talents.T_DIMENSIONAL_STEP]={base=5, every=10, max=9}, [Talents.T_ANOMALY_REARRANGE]=1, @@ -156,7 +156,7 @@ newEntity{ base = "BASE_NPC_TELUGOROTH", ai = "tactical", ai_state = { talent_in=2, ai_move="move_snake" }, talent_cd_reduction = {[Talents.T_DUST_TO_DUST]=-3}, - + resolvers.talents{ [Talents.T_ANOMALY_TEMPORAL_STORM]=1, [Talents.T_DUST_TO_DUST]={base=4, every=7}, diff --git a/game/modules/tome/data/general/npcs/troll.lua b/game/modules/tome/data/general/npcs/troll.lua index fbffb3996e..b5f9a2a71d 100644 --- a/game/modules/tome/data/general/npcs/troll.lua +++ b/game/modules/tome/data/general/npcs/troll.lua @@ -27,7 +27,7 @@ newEntity{ sound_die = {"creatures/trolls/troll_die_%d", 1, 2}, sound_random = {"creatures/trolls/troll_growl_%d", 1, 4}, - combat = { dam=resolvers.levelup(resolvers.mbonus(45, 10), 1, 1), atk=2, apr=6, physspeed=2, dammod={str=0.8}, sound="creatures/trolls/stomp" }, + combat = { dam=resolvers.levelup(resolvers.mbonus(45, 10), 1, 1), atk=2, apr=6, physspeed=2, dammod={str=resolvers.levelup(0.2, 5, 0.1, 1.1)}, sound="creatures/trolls/stomp" }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, resolvers.drops{chance=20, nb=1, {} }, diff --git a/game/modules/tome/data/general/npcs/vampire.lua b/game/modules/tome/data/general/npcs/vampire.lua index 1add4ef128..54cf10644c 100644 --- a/game/modules/tome/data/general/npcs/vampire.lua +++ b/game/modules/tome/data/general/npcs/vampire.lua @@ -25,7 +25,7 @@ newEntity{ display = "V", color=colors.WHITE, desc = [[These ancient cursed beings often take the form of a bat and attack their prey.]], - combat = { dam=resolvers.levelup(resolvers.mbonus(30, 10), 1, 0.8), atk=10, apr=9, damtype=DamageType.DRAINLIFE, dammod={str=1.9} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(30, 10), 1, 0.8), atk=10, apr=9, damtype=DamageType.DRAINLIFE, dammod={str=resolvers.levelup(0.3, 5, 0.2, 1.9)} }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, drops = resolvers.drops{chance=20, nb=1, {} }, diff --git a/game/modules/tome/data/general/npcs/xorn.lua b/game/modules/tome/data/general/npcs/xorn.lua index 92f0022b9d..58005e7e1d 100644 --- a/game/modules/tome/data/general/npcs/xorn.lua +++ b/game/modules/tome/data/general/npcs/xorn.lua @@ -25,7 +25,7 @@ newEntity{ display = "X", color=colors.UMBER, blood_color = colors.UMBER, - combat = { dam=resolvers.levelup(resolvers.mbonus(46, 15), 1, 0.8), atk=15, apr=15, dammod={str=0.8} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(46, 15), 1, 0.8), atk=15, apr=15, dammod={str=resolvers.levelup(0.2, 5, 0.1, 0.8)} }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, resolvers.drops{chance=100, nb=1, {type="money"} }, diff --git a/game/modules/tome/data/general/objects/2haxes.lua b/game/modules/tome/data/general/objects/2haxes.lua index 8c926212fe..118c8b849e 100644 --- a/game/modules/tome/data/general/objects/2haxes.lua +++ b/game/modules/tome/data/general/objects/2haxes.lua @@ -17,8 +17,11 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +local Talents = require "engine.interface.ActorTalents" + newEntity{ define_as = "BASE_BATTLEAXE", + flavor_names = {"battleaxe", "greataxe", "bardiche", "warcleaver"}, slot = "MAINHAND", slot_forbid = "OFFHAND", type = "weapon", subtype="battleaxe", image = resolvers.image_material("2haxe", "metal"), @@ -28,7 +31,7 @@ newEntity{ encumber = 3, rarity = 5, metallic = true, - 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} }, + combat = { talented = "axe", damrange = 1, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2} }, desc = [[Massive two-handed battleaxes.]], twohanded = true, randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 }, @@ -42,10 +45,10 @@ newEntity{ base = "BASE_BATTLEAXE", cost = 5, material_level = 1, combat = { - dam = resolvers.rngavg(6,12), - apr = 1, - physcrit = 4.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(8), + max_acc = resolvers.cbonus(85, 100, 1, 3), + critical_power = resolvers.cbonus(17, 29, 0.1), + dammod = {str=0.25}, }, } @@ -53,13 +56,13 @@ newEntity{ base = "BASE_BATTLEAXE", name = "steel battleaxe", short_name = "steel", level_range = {10, 20}, require = { stat = { str=16 }, }, - cost = 10, + cost = 30, material_level = 2, combat = { - dam = resolvers.rngavg(15,23), - apr = 2, - physcrit = 5, - dammod = {str=1.2}, + dam = resolvers.cbonus(16), + max_acc = resolvers.cbonus(85, 100, 1, 3.5), + critical_power = resolvers.cbonus(17, 29, 0.1, 3.5), + dammod = {str=0.5}, }, } @@ -67,13 +70,13 @@ newEntity{ base = "BASE_BATTLEAXE", name = "dwarven-steel battleaxe", short_name = "d.steel", level_range = {20, 30}, require = { stat = { str=24 }, }, - cost = 15, + cost = 80, material_level = 3, combat = { - dam = resolvers.rngavg(28,35), - apr = 2, - physcrit = 6.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(32), + max_acc = resolvers.cbonus(85, 100, 1, 4), + critical_power = resolvers.cbonus(17, 29, 0.1, 4), + dammod = {str=0.75}, }, } @@ -81,13 +84,13 @@ newEntity{ base = "BASE_BATTLEAXE", name = "stralite battleaxe", short_name = "stralite", level_range = {30, 40}, require = { stat = { str=35 }, }, - cost = 25, + cost = 120, material_level = 4, combat = { - dam = resolvers.rngavg(40,48), - apr = 3, - physcrit = 7.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(56), + max_acc = resolvers.cbonus(85, 100, 1, 4.5), + critical_power = resolvers.cbonus(17, 29, 0.1, 4.5), + dammod = {str=1}, }, } @@ -95,12 +98,12 @@ newEntity{ base = "BASE_BATTLEAXE", name = "voratun battleaxe", short_name = "voratun", level_range = {40, 50}, require = { stat = { str=48 }, }, - cost = 35, + cost = 170, material_level = 5, combat = { - dam = resolvers.rngavg(54, 60), - apr = 4, - physcrit = 8, - dammod = {str=1.2}, + dam = resolvers.cbonus(80), + max_acc = resolvers.cbonus(85, 100, 1, 5), + critical_power = resolvers.cbonus(17, 29, 0.1, 5), + dammod = {str=1.25}, }, } diff --git a/game/modules/tome/data/general/objects/2hmaces.lua b/game/modules/tome/data/general/objects/2hmaces.lua index caa4e8eccc..e5586b418f 100644 --- a/game/modules/tome/data/general/objects/2hmaces.lua +++ b/game/modules/tome/data/general/objects/2hmaces.lua @@ -17,8 +17,11 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +local Talents = require "engine.interface.ActorTalents" + newEntity{ define_as = "BASE_GREATMAUL", + flavor_names = {"greatmaul", "sledge", "warhammer", "bonegrinder"}, slot = "MAINHAND", slot_forbid = "OFFHAND", type = "weapon", subtype="greatmaul", @@ -28,7 +31,7 @@ newEntity{ encumber = 5, rarity = 5, metallic = true, - 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} }, + combat = { talented = "mace", damrange = 1, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2} }, desc = [[Massive two-handed maul.]], twohanded = true, randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 }, @@ -42,10 +45,10 @@ newEntity{ base = "BASE_GREATMAUL", cost = 5, material_level = 1, combat = { - dam = resolvers.rngavg(10,16), - apr = 1, - physcrit = 0.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(12), + max_acc = resolvers.cbonus(80, 100, 1, 3), + critical_power = resolvers.cbonus(15, 27, 0.1, 3), + dammod = {str=0.25}, }, } @@ -53,13 +56,13 @@ newEntity{ base = "BASE_GREATMAUL", name = "steel greatmaul", short_name = "steel", level_range = {10, 20}, require = { stat = { str=16 }, }, - cost = 10, + cost = 30, material_level = 2, combat = { - dam = resolvers.rngavg(22,30), - apr = 2, - physcrit = 1, - dammod = {str=1.2}, + dam = resolvers.cbonus(24), + max_acc = resolvers.cbonus(80, 100, 1, 3.5), + critical_power = resolvers.cbonus(15, 27, 0.1, 3.5), + dammod = {str=0.5}, }, } @@ -67,13 +70,13 @@ newEntity{ base = "BASE_GREATMAUL", name = "dwarven-steel greatmaul", short_name = "d.steel", level_range = {20, 30}, require = { stat = { str=24 }, }, - cost = 15, + cost = 80, material_level = 3, combat = { - dam = resolvers.rngavg(38,45), - apr = 2, - physcrit = 1.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(48), + max_acc = resolvers.cbonus(80, 100, 1, 4), + critical_power = resolvers.cbonus(15, 27, 0.1, 4), + dammod = {str=0.75}, }, } @@ -81,13 +84,13 @@ newEntity{ base = "BASE_GREATMAUL", name = "stralite greatmaul", short_name = "stralite", level_range = {30, 40}, require = { stat = { str=35 }, }, - cost = 25, + cost = 120, material_level = 4, combat = { - dam = resolvers.rngavg(50,59), - apr = 3, - physcrit = 2.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(84), + max_acc = resolvers.cbonus(80, 100, 1, 4.5), + critical_power = resolvers.cbonus(15, 27, 0.1, 4.5), + dammod = {str=1}, }, } @@ -95,12 +98,12 @@ newEntity{ base = "BASE_GREATMAUL", name = "voratun greatmaul", short_name = "voratun", level_range = {40, 50}, require = { stat = { str=48 }, }, - cost = 35, + cost = 170, material_level = 5, combat = { - dam = resolvers.rngavg(62, 72), - apr = 4, - physcrit = 3, - dammod = {str=1.2}, + dam = resolvers.cbonus(120), + max_acc = resolvers.cbonus(80, 100, 1, 5), + critical_power = resolvers.cbonus(15, 27, 0.1, 5), + dammod = {str=1.25}, }, } diff --git a/game/modules/tome/data/general/objects/2hswords.lua b/game/modules/tome/data/general/objects/2hswords.lua index 1697ce0369..3c0915573b 100644 --- a/game/modules/tome/data/general/objects/2hswords.lua +++ b/game/modules/tome/data/general/objects/2hswords.lua @@ -19,6 +19,7 @@ newEntity{ define_as = "BASE_GREATSWORD", + flavor_names = {"greatsword", "broadsword", "claymore", "murderblade"}, slot = "MAINHAND", slot_forbid = "OFFHAND", type = "weapon", subtype="greatsword", @@ -27,7 +28,7 @@ newEntity{ moddable_tile = resolvers.moddable_tile("sword"), encumber = 3, rarity = 5, - combat = { talented = "sword", damrange = 1.6, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2} }, + combat = { talented = "sword", damrange = 1, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2} }, desc = [[Massive two-handed swords.]], twohanded = true, metallic = true, @@ -42,10 +43,10 @@ newEntity{ base = "BASE_GREATSWORD", cost = 5, material_level = 1, combat = { - dam = resolvers.rngavg(8,14), - apr = 1, - physcrit = 2.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(10), + max_acc = resolvers.cbonus(90, 100, 1, 3), + critical_power = resolvers.cbonus(13, 25, 0.1), + dammod = {str=0.25}, }, } @@ -53,13 +54,13 @@ newEntity{ base = "BASE_GREATSWORD", name = "steel greatsword", short_name = "steel", level_range = {10, 20}, require = { stat = { str=16 }, }, - cost = 10, + cost = 30, material_level = 2, combat = { - dam = resolvers.rngavg(18,26), - apr = 2, - physcrit = 3, - dammod = {str=1.2}, + dam = resolvers.cbonus(20), + max_acc = resolvers.cbonus(90, 100, 1, 3.5), + critical_power = resolvers.cbonus(13, 25, 0.1, 3.5), + dammod = {str=0.5}, }, } @@ -67,13 +68,13 @@ newEntity{ base = "BASE_GREATSWORD", name = "dwarven-steel greatsword", short_name = "d.steel", level_range = {20, 30}, require = { stat = { str=24 }, }, - cost = 15, + cost = 80, material_level = 3, combat = { - dam = resolvers.rngavg(32,40), - apr = 2, - physcrit = 3.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(40), + max_acc = resolvers.cbonus(90, 100, 1, 4), + critical_power = resolvers.cbonus(13, 25, 0.1, 4), + dammod = {str=0.75}, }, } @@ -81,13 +82,13 @@ newEntity{ base = "BASE_GREATSWORD", name = "stralite greatsword", short_name = "stralite", level_range = {30, 40}, require = { stat = { str=35 }, }, - cost = 25, + cost = 120, material_level = 4, combat = { - dam = resolvers.rngavg(45,52), - apr = 3, - physcrit = 4.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(70), + max_acc = resolvers.cbonus(90, 100, 1, 4.5), + critical_power = resolvers.cbonus(13, 25, 0.1, 4.5), + dammod = {str=1}, }, } @@ -95,12 +96,12 @@ newEntity{ base = "BASE_GREATSWORD", name = "voratun greatsword", short_name = "voratun", level_range = {40, 50}, require = { stat = { str=48 }, }, - cost = 35, + cost = 170, material_level = 5, combat = { - dam = resolvers.rngavg(58, 66), - apr = 4, - physcrit = 5, - dammod = {str=1.2}, + dam = resolvers.cbonus(100), + max_acc = resolvers.cbonus(90, 100, 1, 3, 5), + critical_power = resolvers.cbonus(13, 25, 0.1, 5), + dammod = {str=1.25}, }, } diff --git a/game/modules/tome/data/general/objects/2htridents.lua b/game/modules/tome/data/general/objects/2htridents.lua index 51c58e9b6f..daa94e32d7 100644 --- a/game/modules/tome/data/general/objects/2htridents.lua +++ b/game/modules/tome/data/general/objects/2htridents.lua @@ -29,7 +29,7 @@ newEntity{ trident_rarity = 5, -- Special rarity field, converted to "rarity" when needed metallic = true, no_rust = true, - combat = { talented = "trident", damrange = 1.6, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2} }, + combat = { talented = "trident", damrange = 1, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2} }, desc = [[A two-handed massive trident. Tridents require the exotic weapons mastery talent to use correctly.]], twohanded = true, @@ -44,10 +44,10 @@ newEntity{ base = "BASE_TRIDENT", cost = 5, material_level = 1, combat = { - dam = resolvers.rngavg(6,10), - apr = 6, - physcrit = 1.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(10), + max_acc = resolvers.cbonus(90, 100, 1, 3), + critical_power = resolvers.cbonus(13, 25, 0.1), + dammod = {str=0.25}, }, } @@ -55,13 +55,13 @@ newEntity{ base = "BASE_TRIDENT", name = "blue-steel trident", short_name = "b.steel", level_range = {10, 20}, require = { stat = { str=16 }, }, - cost = 10, + cost = 30, material_level = 2, combat = { - dam = resolvers.rngavg(11,19), - apr = 8, - physcrit = 2, - dammod = {str=1.2}, + dam = resolvers.cbonus(20), + max_acc = resolvers.cbonus(90, 100, 1, 3.5), + critical_power = resolvers.cbonus(13, 25, 0.1, 3.5), + dammod = {str=0.5}, }, } @@ -69,13 +69,13 @@ newEntity{ base = "BASE_TRIDENT", name = "deep-steel trident", short_name = "d.steel", level_range = {20, 30}, require = { stat = { str=24 }, }, - cost = 15, + cost = 80, material_level = 3, combat = { - dam = resolvers.rngavg(24,31), - apr = 10, - physcrit = 2.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(40), + max_acc = resolvers.cbonus(90, 100, 1, 4), + critical_power = resolvers.cbonus(13, 25, 0.1, 4), + dammod = {str=0.75}, }, } @@ -83,13 +83,13 @@ newEntity{ base = "BASE_TRIDENT", name = "orite trident", short_name = "orite", level_range = {30, 40}, require = { stat = { str=35 }, }, - cost = 25, + cost = 120, material_level = 4, combat = { - dam = resolvers.rngavg(36,44), - apr = 13, - physcrit = 3.5, - dammod = {str=1.2}, + dam = resolvers.cbonus(70), + max_acc = resolvers.cbonus(90, 100, 1, 4.5), + critical_power = resolvers.cbonus(13, 25, 0.1, 4.5), + dammod = {str=1}, }, } @@ -97,12 +97,12 @@ newEntity{ base = "BASE_TRIDENT", name = "orichalcum trident", short_name = "orichalcum", level_range = {40, 50}, require = { stat = { str=48 }, }, - cost = 35, + cost = 170, material_level = 5, combat = { - dam = resolvers.rngavg(50, 56), - apr = 16, - physcrit = 4, - dammod = {str=1.2}, + dam = resolvers.cbonus(100), + max_acc = resolvers.cbonus(90, 100, 1, 3, 5), + critical_power = resolvers.cbonus(13, 25, 0.1, 5), + dammod = {str=1.25}, }, } diff --git a/game/modules/tome/data/general/objects/axes.lua b/game/modules/tome/data/general/objects/axes.lua index d46ce2719c..172fef4502 100644 --- a/game/modules/tome/data/general/objects/axes.lua +++ b/game/modules/tome/data/general/objects/axes.lua @@ -19,6 +19,7 @@ newEntity{ define_as = "BASE_WARAXE", + flavor_names = {"handaxe", "waraxe", "broadaxe", "slaughteraxe"}, slot = "MAINHAND", dual_wieldable = true, type = "weapon", subtype="waraxe", add_name = " (#COMBAT#)", @@ -27,7 +28,7 @@ newEntity{ encumber = 3, rarity = 3, metallic = true, - combat = { talented = "axe", damrange = 1.4, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2}}, + combat = { talented = "axe", damrange = 1, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2}}, desc = [[One-handed war axes.]], randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 }, egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, @@ -40,10 +41,10 @@ newEntity{ base = "BASE_WARAXE", cost = 5, material_level = 1, combat = { - dam = resolvers.rngavg(5,8), - apr = 2, - physcrit = 3.5, - dammod = {str=1}, + dam = resolvers.cbonus(4), + max_acc = resolvers.cbonus(85, 100, 1, 3), + critical_power = resolvers.cbonus(17, 29, 0.1), + dammod = {str=0.2}, }, } @@ -51,13 +52,13 @@ newEntity{ base = "BASE_WARAXE", name = "steel waraxe", short_name = "steel", level_range = {10, 20}, require = { stat = { str=16 }, }, - cost = 10, + cost = 30, material_level = 2, combat = { - dam = resolvers.rngavg(8,14), - apr = 3, - physcrit = 4, - dammod = {str=1}, + dam = resolvers.cbonus(8), + max_acc = resolvers.cbonus(85, 100, 1, 3.5), + critical_power = resolvers.cbonus(17, 29, 0.1, 3.5), + dammod = {str=0.4}, }, } @@ -65,13 +66,13 @@ newEntity{ base = "BASE_WARAXE", name = "dwarven-steel waraxe", short_name = "d.steel", level_range = {20, 30}, require = { stat = { str=24 }, }, - cost = 15, + cost = 80, material_level = 3, combat = { - dam = resolvers.rngavg(17,23), - apr = 4, - physcrit = 4.5, - dammod = {str=1}, + dam = resolvers.cbonus(16), + max_acc = resolvers.cbonus(85, 100, 1, 4), + critical_power = resolvers.cbonus(17, 29, 0.1, 4), + dammod = {str=0.6}, }, } @@ -79,13 +80,13 @@ newEntity{ base = "BASE_WARAXE", name = "stralite waraxe", short_name = "stralite", level_range = {30, 40}, require = { stat = { str=35 }, }, - cost = 25, + cost = 120, material_level = 4, combat = { - dam = resolvers.rngavg(28,35), - apr = 5, - physcrit = 6.5, - dammod = {str=1}, + dam = resolvers.cbonus(28), + max_acc = resolvers.cbonus(85, 100, 1, 4.5), + critical_power = resolvers.cbonus(17, 29, 0.1, 4.5), + dammod = {str=0.8}, }, } @@ -93,12 +94,12 @@ newEntity{ base = "BASE_WARAXE", name = "voratun waraxe", short_name = "voratun", level_range = {40, 50}, require = { stat = { str=48 }, }, - cost = 35, + cost = 170, material_level = 5, combat = { - dam = resolvers.rngavg(38,42), - apr = 6, - physcrit = 7, + dam = resolvers.cbonus(40), + max_acc = resolvers.cbonus(85, 100, 1, 5), + critical_power = resolvers.cbonus(17, 29, 0.1, 5), dammod = {str=1}, }, } diff --git a/game/modules/tome/data/general/objects/boss-artifacts-far-east.lua b/game/modules/tome/data/general/objects/boss-artifacts-far-east.lua index b948cb7b1a..192aa0c4bc 100644 --- a/game/modules/tome/data/general/objects/boss-artifacts-far-east.lua +++ b/game/modules/tome/data/general/objects/boss-artifacts-far-east.lua @@ -34,10 +34,11 @@ newEntity{ base = "BASE_KNIFE", define_as = "LIFE_DRINKER", cost = 450, material_level = 5, combat = { + affects_spells = true, dam = 42, - apr = 11, - physcrit = 18, - dammod = {mag=0.55,str=0.35}, + max_acc = 100, + critical_power = 2.2, + dammod = {mag=0.6,str=0.4}, }, wielder = { inc_damage={ diff --git a/game/modules/tome/data/general/objects/boss-artifacts.lua b/game/modules/tome/data/general/objects/boss-artifacts.lua index 489843de2e..d845d40b54 100644 --- a/game/modules/tome/data/general/objects/boss-artifacts.lua +++ b/game/modules/tome/data/general/objects/boss-artifacts.lua @@ -34,11 +34,10 @@ It is said the Conclave created this weapon for their warmaster during the dark cost = 2000, material_level = 5, combat = { - dam = 45, - apr = 10, - physcrit = 10, + dam = 70, + max_acc = 95, + critical_power = 1.5, dammod = {str=1}, - damrange = 1.4, melee_project={[DamageType.ICE] = 45}, }, wielder = { @@ -200,11 +199,10 @@ Tridents require the exotic weapons mastery talent to use correctly.]], cost = 300, material_level = 4, combat = { - dam = 60, - apr = 4, - physcrit = 15, - dammod = {str=1.3}, - damrange = 1.4, + dam = 90, + max_acc = 100, + critical_power = 2, + dammod = {str=1.1}, melee_project={ [DamageType.COLD] = 15, [DamageType.NATURE] = 20, @@ -374,10 +372,11 @@ newEntity{ base = "BASE_SHIELD", cost = 350, material_level = 5, special_combat = { - dam = 45, - physcrit = 10, + dam = 55, + block = 250, + max_acc = 80, + critical_power = 1.5, dammod = {str=1}, - damrange = 1.4, damtype = DamageType.ARCANE, }, wielder = { @@ -411,9 +410,10 @@ newEntity{ base = "BASE_SHIELD", special_combat = { dam = resolvers.rngavg(20,30), - physcrit = 2, - dammod = {str=1.5}, - damrange = 1.4, + block = 60, + max_acc = 75, + critical_power = 1.5, + dammod = {str=0.4}, }, wielder = { combat_armor = 10, @@ -481,11 +481,10 @@ newEntity{ base = "BASE_WARAXE", rarity = 290, cost = 375, combat = { - dam = 55, - apr = 15, - physcrit = 10, + dam = 60, + max_acc = 90, + critical_power = 2.8, dammod = {str=1}, - damrange = 1.2, melee_project={[DamageType.BLIGHT] = 20}, }, wielder = { @@ -498,29 +497,33 @@ newEntity{ base = "BASE_STAFF", power_source = {arcane=true}, define_as = "STAFF_KOR", rarity=false, image = "object/artifact/staff_kors_fall.png", unided_name = "dark staff", + flavor_name = "starstaff", name = "Kor's Fall", unique=true, desc = [[Made from the bones of many creatures, this staff glows with power. You can feel its evilness even from a distance.]], require = { stat = { mag=25 }, }, + material_level = 1, level_range = {1, 10}, rarity = 200, cost = 60, + modes = {"light", "darkness", "temporal"}, combat = { + is_greater = true, dam = 10, - apr = 0, - physcrit = 1.5, - dammod = {mag=1.1}, + max_acc = 90, + critical_power = 1.6, + dammod = {mag=0.2}, + damtype = DamageType.DARKNESS, }, wielder = { see_invisible = 2, combat_spellpower = 7, combat_spellcrit = 8, inc_damage={ - [DamageType.FIRE] = 4, - [DamageType.COLD] = 4, - [DamageType.ACID] = 4, - [DamageType.LIGHTNING] = 4, - [DamageType.BLIGHT] = 4, + [DamageType.TEMPORAL] = 10, + [DamageType.DARKNESS] = 10, + [DamageType.LIGHT] = 10, }, + learn_talent = {[Talents.T_BLOODFLOW] = 2, [Talents.T_COMMAND_STAFF] = 2}, }, } @@ -550,23 +553,28 @@ newEntity{ base = "BASE_STAFF", twohanded = false, unided_name = "broken staff", name = "Telos's Staff (Top Half)", unique=true, + flavor_name = "magestaff", desc = [[The top part of Telos's broken staff.]], require = { stat = { mag=35 }, }, level_range = {40, 50}, rarity = 210, encumber = 2.5, cost = 500, + material_level = 5, + modes = {"fire", "cold", "lightning", "arcane"}, combat = { - dam = 35, - apr = 0, - physcrit = 1.5, - dammod = {mag=1.0}, + dam = 50, + max_acc = 85, + critical_power = 1.2, + dammod = {mag=0.3}, + damtype = DamageType.ARCANE, }, wielder = { - combat_spellpower = 30, - combat_spellcrit = 15, + combat_spellpower = 10, combat_mentalresist = 8, inc_stats = { [Stats.STAT_WIL] = 5, }, + inc_damage = {[DamageType.ARCANE] = 50}, + learn_talent = {[Talents.T_COMMAND_STAFF] = 5}, }, } @@ -675,11 +683,10 @@ newEntity{ base = "BASE_GREATMAUL", metallic = false, cost = 70, combat = { - dam = 30, - apr = 7, - physcrit = 1.5, - dammod = {str=1.3}, - damrange = 1.7, + dam = 40, + max_acc = 80, + critical_power = 1.5, + dammod = {str=0.5}, }, wielder = { @@ -699,9 +706,11 @@ newEntity{ base = "BASE_SHIELD", cost = 120, special_combat = { - dam = 40, - physcrit = 9, - dammod = {str=1.2}, + dam = 60, + block = 290, + max_acc = 95, + critical_power = 1.5, + dammod = {str=1}, }, wielder = { combat_armor = 4, @@ -726,9 +735,9 @@ newEntity{ base = "BASE_WHIP", cost = 250, material_level = 5, combat = { - dam = resolvers.rngavg(40,45), - apr = 0, - physcrit = 9, + dam = resolvers.rngavg(50,55), + max_acc = 75, + critical_power = 3, dammod = {dex=1}, damtype = DamageType.FIREKNOCKBACK, }, @@ -755,10 +764,10 @@ newEntity{ base = "BASE_GREATSWORD", cost = 300, material_level = 5, combat = { - dam = 60, - apr = 19, - physcrit = 4.5, - dammod = {str=1.2}, + dam = 121, + max_acc = 100, + critical_power = 2, + dammod = {str=1.25}, special_on_hit = {desc="10% chance to send the wielder into a killing frenzy", fct=function(combat, who) if not rng.percent(10) then return end who:setEffect(who.EFF_FRENZY, 3, {crit=10, power=0.3, dieat=0.2}) @@ -820,11 +829,10 @@ newEntity{ base = "BASE_GLOVES", define_as = "FLAMEWROUGHT", inc_damage = { [DamageType.FIRE]= 5, }, combat_armor = 2, combat = { - dam = 5, - apr = 7, - physcrit = 1, - physspeed = -0.4, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, + dam = 8, + max_acc = 13, + critical_power = 0.4, + dammod = {dex=0.1, str=0, cun=0.1 }, melee_project={[DamageType.FIRE] = 10}, }, }, @@ -1005,9 +1013,9 @@ newEntity{ base = "BASE_WARAXE", cost = 50, combat = { dam = 16, - apr = 3, - physcrit = 12, - dammod = {str=1}, + max_acc = 85, + critical_power = 2.6, + dammod = {str=0.4}, talent_on_hit = { [Talents.T_GREATER_WEAPON_FOCUS] = {level=2, chance=10} }, melee_project={[DamageType.DRAINLIFE] = 10}, }, @@ -1071,10 +1079,10 @@ newEntity{ base = "BASE_BATTLEAXE", cost = 650, material_level = 4, combat = { - dam = 72, - apr = 4, - physcrit = 8, - dammod = {str=1.2}, + dam = 120, + max_acc = 80, + critical_power = 2, + dammod = {str=1}, melee_project={[DamageType.SLIME] = 50, [DamageType.ACID] = 50}, }, wielder = { diff --git a/game/modules/tome/data/general/objects/bows.lua b/game/modules/tome/data/general/objects/bows.lua index edd4a6c510..cf69ae4ea9 100644 --- a/game/modules/tome/data/general/objects/bows.lua +++ b/game/modules/tome/data/general/objects/bows.lua @@ -21,18 +21,19 @@ local Talents = require "engine.interface.ActorTalents" newEntity{ define_as = "BASE_LONGBOW", + flavor_names = {"shortbow", "longbow", "warbow", "warbow"}, slot = "MAINHAND", slot_forbid = "OFFHAND", type = "weapon", subtype="longbow", + add_name = " (#COMBAT_RANGED#)", display = "}", color=colors.UMBER, image = resolvers.image_material("longbow", "wood"), moddable_tile = resolvers.moddable_tile("bow"), encumber = 4, rarity = 5, - combat = { talented = "bow", sound = "actions/arrow", sound_miss = "actions/arrow",}, + combat = { talented = "bow", sound = "actions/arrow", sound_miss = "actions/arrow", physspeed = 0.8,}, require = { talent = { Talents.T_SHOOT }, }, archery = "bow", proj_image = resolvers.image_material("arrow", "wood"), - basic_ammo = { talented = "bow", damrange = 1.4 }, desc = [[Longbows are used to shoot arrows at your foes.]], randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 }, egos = "/data/general/objects/egos/bow.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, @@ -45,14 +46,10 @@ newEntity{ base = "BASE_LONGBOW", cost = 5, material_level = 1, combat = { + dam = resolvers.cbonus(3, 6, 1, 1), + critical_power = resolvers.cbonus(18, 30, 0.1, 3), range = 6, - physspeed = 0.8, - }, - basic_ammo = { - dam = resolvers.rngavg(7,12), - apr = 5, - physcrit = 1, - dammod = {dex=0.7, str=0.5}, + dammod = {dex=0.1}, }, } @@ -60,17 +57,13 @@ newEntity{ base = "BASE_LONGBOW", name = "ash longbow", short_name = "ash", level_range = {10, 20}, require = { stat = { dex=16 }, }, - cost = 10, + cost = 30, material_level = 2, combat = { + dam = resolvers.cbonus(6), + critical_power = resolvers.cbonus(18, 30, 0.1, 3.5), range = 7, - physspeed = 0.8, - }, - basic_ammo = { - dam = resolvers.rngavg(15,22), - apr = 7, - physcrit = 1.5, - dammod = {dex=0.7, str=0.5}, + dammod = {dex=0.2}, }, } @@ -78,17 +71,13 @@ newEntity{ base = "BASE_LONGBOW", name = "yew longbow", short_name = "yew", level_range = {20, 30}, require = { stat = { dex=24 }, }, - cost = 15, + cost = 80, material_level = 3, combat = { + dam = resolvers.cbonus(12), + critical_power = resolvers.cbonus(18, 30, 0.1, 4), range = 8, - physspeed = 0.8, - }, - basic_ammo = { - dam = resolvers.rngavg(28,37), - apr = 10, - physcrit = 2, - dammod = {dex=0.7, str=0.5}, + dammod = {dex=0.3}, }, } @@ -96,17 +85,13 @@ newEntity{ base = "BASE_LONGBOW", name = "elven-wood longbow", short_name = "e.wood", level_range = {30, 40}, require = { stat = { dex=35 }, }, - cost = 25, + cost = 120, material_level = 4, combat = { + dam = resolvers.cbonus(21), + critical_power = resolvers.cbonus(18, 30, 0.1, 4.5), range = 9, - physspeed = 0.8, - }, - basic_ammo = { - dam = resolvers.rngavg(40,47), - apr = 14, - physcrit = 2.5, - dammod = {dex=0.7, str=0.5}, + dammod = {dex=0.4}, }, } @@ -114,105 +99,106 @@ newEntity{ base = "BASE_LONGBOW", name = "dragonbone longbow", short_name = "dragonbone", level_range = {40, 50}, require = { stat = { dex=48 }, }, - cost = 35, + cost = 170, material_level = 5, combat = { + dam = resolvers.cbonus(30), + critical_power = resolvers.cbonus(18, 30, 0.1, 5), range = 10, - physspeed = 0.8, - }, - basic_ammo = { - dam = resolvers.rngavg(50, 57), - apr = 18, - physcrit = 3, - dammod = {dex=0.7, str=0.5}, + dammod = {dex=0.5}, }, } - ------------------- AMMO ------------------- +------------------ QUIVERS ------------------- newEntity{ - define_as = "BASE_ARROW", + define_as = "BASE_QUIVER", slot = "QUIVER", type = "ammo", subtype="arrow", - add_name = " (#COMBAT#)", + add_name = " (#COMBAT_QUIVER#)", display = "{", color=colors.UMBER, image = resolvers.image_material("arrow", "wood"), - encumber = 0.03, + encumber = 3, rarity = 11, - combat = { talented = "bow", damrange = 1.4}, + combat = { talented = "bow", damrange = 1}, proj_image = resolvers.image_material("arrow", "wood"), archery_ammo = "bow", - desc = [[Arrows are used with bows to pierce your foes to death.]], - generate_stack = resolvers.rngavg(100,200), - egos = "/data/general/objects/egos/ammo.lua", egos_chance = {100, resolvers.mbonus(30, 5)}, - stacking = true, + desc = [[Arrows are used with bows to pierce your foes.]], + egos = "/data/general/objects/egos/ammo.lua", + egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, } -newEntity{ base = "BASE_ARROW", - name = "elm arrow", short_name = "elm", +newEntity{ base = "BASE_QUIVER", define_as = "TEST_ELM_QUIVER", + name = "quiver of elm arrows", short_name = "elm", level_range = {1, 10}, require = { stat = { dex=11 }, }, - cost = 0.05, + cost = 5, material_level = 1, combat = { - dam = resolvers.rngavg(7,12), - apr = 5, - physcrit = 1, - dammod = {dex=0.7, str=0.5}, + capacity = resolvers.cbonus(10), + dam = resolvers.cbonus(3, 6, 1, 1), + max_acc = resolvers.cbonus(85, 100, 1, 3), + dammod = {dex=0.1}, + shots_left = 20, }, + --wielder = {learn_talent = {[Talents.T_RELOAD] = 1}}, } -newEntity{ base = "BASE_ARROW", - name = "ash arrow", short_name = "ash", +newEntity{ base = "BASE_QUIVER", + name = "quiver of ash arrows", short_name = "ash", level_range = {10, 20}, require = { stat = { dex=16 }, }, - cost = 0.1, + cost = 30, material_level = 2, combat = { - dam = resolvers.rngavg(15,22), - apr = 7, - physcrit = 1.5, - dammod = {dex=0.7, str=0.5}, + capacity = resolvers.cbonus(10, nil, nil, 3), + dam = resolvers.cbonus(6), + max_acc = resolvers.cbonus(85, 100, 1, 3.5), + dammod = {dex=0.2}, + shots_left = 20, }, } -newEntity{ base = "BASE_ARROW", - name = "yew arrow", short_name = "yew", +newEntity{ base = "BASE_QUIVER", + name = "quiver of yew arrows", short_name = "yew", level_range = {20, 30}, require = { stat = { dex=24 }, }, - cost = 0.15, + cost = 80, material_level = 3, combat = { - dam = resolvers.rngavg(28,37), - apr = 10, - physcrit = 2, - dammod = {dex=0.7, str=0.5}, + capacity = resolvers.cbonus(10, nil, nil, 3.5), + dam = resolvers.cbonus(12), + max_acc = resolvers.cbonus(85, 100, 1, 4), + dammod = {dex=0.3}, + shots_left = 20, }, } -newEntity{ base = "BASE_ARROW", - name = "elven-wood arrow", short_name = "e.wood", +newEntity{ base = "BASE_QUIVER", + name = "quiver of elven-wood arrows", short_name = "e.wood", level_range = {30, 40}, require = { stat = { dex=35 }, }, - cost = 0.25, + cost = 120, material_level = 4, combat = { - dam = resolvers.rngavg(40,47), - apr = 14, - physcrit = 2.5, - dammod = {dex=0.7, str=0.5}, + capacity = resolvers.cbonus(10, nil, nil, 4), + dam = resolvers.cbonus(21), + max_acc = resolvers.cbonus(85, 100, 1, 4.5), + dammod = {dex=0.4}, + shots_left = 20, }, } -newEntity{ base = "BASE_ARROW", - name = "dragonbone arrow", short_name = "dragonbone", +newEntity{ base = "BASE_QUIVER", + name = "quiver of dragonbone arrows", short_name = "dragonbone", level_range = {40, 50}, require = { stat = { dex=48 }, }, - cost = 0.35, + cost = 170, material_level = 5, combat = { - dam = resolvers.rngavg(50, 57), - apr = 18, - physcrit = 3, - dammod = {dex=0.7, str=0.5}, + capacity = resolvers.cbonus(10, nil, nil, 4.5), + dam = resolvers.cbonus(30), + max_acc = resolvers.cbonus(85, 100, 1, 5), + dammod = {dex=0.5}, + shots_left = 20, }, } + diff --git a/game/modules/tome/data/general/objects/egos/ammo.lua b/game/modules/tome/data/general/objects/egos/ammo.lua index e8dc03eef8..9548117691 100644 --- a/game/modules/tome/data/general/objects/egos/ammo.lua +++ b/game/modules/tome/data/general/objects/egos/ammo.lua @@ -17,81 +17,181 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +local Talents = require("engine.interface.ActorTalents") + newEntity{ - power_source = {arcane=true}, - name = "flaming ", prefix=true, instant_resolve=true, - keywords = {flaming=true}, + power_source = {technique=true}, + name = "quick-loading ", prefix=true, instant_resolve=true, + keywords = {quick=true}, level_range = {1, 50}, rarity = 5, wielder = { - ranged_project={[DamageType.FIRE] = resolvers.mbonus_material(25, 4, function(e, v) return v * 0.1 * 0.64 end)}, + learn_talent = { + [Talents.T_RELOAD] = resolvers.mbonus_material("learn_talent"), + } }, } + +newEntity{ + power_source = {technique=true}, + name = "high-capacity ", prefix=true, instant_resolve=true, + keywords = {capacity=true}, + level_range = {1, 50}, + rarity = 5, + combat = { + capacity = resolvers.mbonus_material("capacity"), + }, + resolvers.genericlast(function(e) + e.combat.shots_left = e.combat.capacity end), +} + newEntity{ power_source = {arcane=true}, - name = "icy ", prefix=true, instant_resolve=true, - keywords = {icy=true}, - level_range = {15, 50}, + name = "self-loading ", prefix=true, instant_resolve=true, + keywords = {self=true}, + level_range = {1, 50}, rarity = 5, - wielder = { - ranged_project={[DamageType.ICE] = resolvers.mbonus_material(15, 4, function(e, v) return v * 0.1 * 0.7 end)}, + combat = { + ammo_regen = resolvers.mbonus_material("ammo_regen"), }, + resolvers.genericlast(function(e) + e.combat.ammo_every = 6 - e.combat.ammo_regen + end), } + newEntity{ - power_source = {nature=true}, - name = "acidic ", prefix=true, instant_resolve=true, - keywords = {acidic=true}, + power_source = {technique=true}, + name = "battle-ranger's ", prefix=true, instant_resolve=true, + keywords = {ranger=true}, level_range = {1, 50}, rarity = 5, + greater_ego = 1, + combat = { + capacity = resolvers.mbonus_material("capacity"), + }, wielder = { - ranged_project={[DamageType.ACID] = resolvers.mbonus_material(25, 4, function(e, v) return v * 0.1 * 0.7 end)}, + learn_talent = { + [Talents.T_RELOAD] = resolvers.mbonus_material("learn_talent"), + } }, + resolvers.genericlast(function(e) + e.combat.shots_left = e.combat.capacity end), } + newEntity{ power_source = {arcane=true}, - name = "shocking ", prefix=true, instant_resolve=true, - keywords = {shocking=true}, + name = "enchanted ", prefix=true, instant_resolve=true, + keywords = {enchanted=true}, level_range = {1, 50}, rarity = 5, + greater_ego = 1, + combat = { + ammo_regen = resolvers.mbonus_material("ammo_regen"), + }, wielder = { - ranged_project={[DamageType.LIGHTNING] = resolvers.mbonus_material(25, 4, function(e, v) return v * 0.1 * 0.7 end)}, + learn_talent = { + [Talents.T_RELOAD] = resolvers.mbonus_material("learn_talent"), + } + }, + resolvers.genericlast(function(e) + e.combat.ammo_every = 6 - e.combat.ammo_regen + end), +} + +newEntity{ + power_source = {arcane=true}, + name = "sentry's ", prefix=true, instant_resolve=true, + keywords = {sentry=true}, + level_range = {1, 50}, + rarity = 5, + greater_ego = 1, + combat = { + ammo_regen = resolvers.mbonus_material("ammo_regen"), + capacity = resolvers.mbonus_material("capacity"), }, + resolvers.genericlast(function(e) + e.combat.ammo_every = 6 - e.combat.ammo_regen + end), + resolvers.genericlast(function(e) + e.combat.shots_left = e.combat.capacity end), } + newEntity{ power_source = {nature=true}, - name = "poisonous ", prefix=true, instant_resolve=true, - keywords = {poisonous=true}, + name = " of fire", suffix=true, instant_resolve=true, + keywords = {fire=true}, level_range = {1, 50}, rarity = 5, - wielder = { - ranged_project={[DamageType.POISON] = resolvers.mbonus_material(45, 6, function(e, v) return v * 0.1 * 0.5 end)}, + combat = { + ranged_project={[DamageType.FIRE] = resolvers.mbonus_material("ranged_project", 1)}, + }, +} +newEntity{ + power_source = {nature=true}, + name = " of ice", suffix=true, instant_resolve=true, + keywords = {ice=true}, + level_range = {15, 50}, + rarity = 5, + combat = { + ranged_project={[DamageType.ICE] = resolvers.mbonus_material("ranged_project", 0.5)}, + }, +} +newEntity{ + power_source = {nature=true}, + name = " of acid", suffix=true, instant_resolve=true, + keywords = {cunning=true}, + level_range = {1, 50}, + rarity = 5, + combat = { + ranged_project={[DamageType.ACID] = resolvers.mbonus_material("ranged_project", 1)}, + }, +} +newEntity{ + power_source = {nature=true}, + name = " of lightning", suffix=true, instant_resolve=true, + keywords = {lightning=true}, + level_range = {1, 50}, + rarity = 5, + combat = { + ranged_project={[DamageType.LIGHTNING] = resolvers.mbonus_material("ranged_project", 1)}, }, } newEntity{ power_source = {nature=true}, - name = "slime-covered ", prefix=true, instant_resolve=true, + name = " of slime", suffix=true, instant_resolve=true, keywords = {slime=true}, level_range = {10, 50}, rarity = 5, - wielder = { - ranged_project={[DamageType.SLIME] = resolvers.mbonus_material(45, 6, function(e, v) return v * 0.1 * 0.9 end)}, + combat = { + ranged_project={[DamageType.SLIME] = resolvers.mbonus_material("ranged_project", 0.5)}, }, } newEntity{ - power_source = {arcane=true}, - name = "elemental ", prefix=true, instant_resolve=true, - keywords = {elemental=true}, + power_source = {technique=true}, + name = " of accuracy", suffix=true, instant_resolve=true, + keywords = {accuracy=true}, + level_range = {1, 50}, + rarity = 3, + cost = 4, + combat = {max_acc = resolvers.mbonus_material("max_acc")}, +} + +newEntity{ + power_source = {nature=true}, + name = " of the elements", suffix=true, instant_resolve=true, + keywords = {elements=true}, level_range = {35, 50}, greater_ego = 1, rarity = 25, - wielder = { + cost = 35, + combat = { ranged_project={ - [DamageType.FIRE] = resolvers.mbonus_material(25, 4, function(e, v) return v * 0.1 * 0.7 * 0.3 end), - [DamageType.ICE] = resolvers.mbonus_material(15, 4, function(e, v) return v * 0.1 * 0.7 * 0.3 end), - [DamageType.ACID] = resolvers.mbonus_material(25, 4, function(e, v) return v * 0.1 * 0.7 * 0.3 end), - [DamageType.LIGHTNING] = resolvers.mbonus_material(25, 4, function(e, v) return v * 0.1 * 0.7 * 0.3 end), + [DamageType.FIRE] = resolvers.mbonus_material("ranged_project", 0.5), + [DamageType.ICE] = resolvers.mbonus_material("ranged_project", 0.5), + [DamageType.ACID] = resolvers.mbonus_material("ranged_project", 0.5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("ranged_project", 0.5), }, }, } @@ -104,40 +204,78 @@ newEntity{ rarity = 7, combat = { travel_speed = 200, - atk = resolvers.mbonus_material(10, 3, function(e, v) return v * 0.1 * 0.5 end), }, } newEntity{ power_source = {technique=true}, - name = " of annihilation", suffix=true, - keywords = {['annihil.']=true}, + name = " of annihilation", suffix=true, instant_resolve=true, + keywords = {annihilation=true}, level_range = {1, 50}, greater_ego = 1, cost = 1, rarity = 15, combat = { - physcrit = 100, + dam = resolvers.mbonus_material("dam", 4), + max_acc = resolvers.mbonus_material("max_acc", 3), + travel_speed = 200, }, - -- Powerful but does not come in much quantity + -- Powerful but comes in a small quiver/pouch resolvers.generic(function(e) - e.generate_stack = rng.range(5, 10) + e.combat.capacity = math.ceil(e.combat.capacity/4) + e.combat.shots_left = e.combat.capacity end), } newEntity{ - power_source = {technique=true}, - name = " of unerring flight", suffix=true, - keywords = {unerring=true}, + power_source = {arcane=true}, + name = " of corruption", suffix=true, instant_resolve=true, + keywords = {corruption=true}, + level_range = {35, 50}, + greater_ego = 1, + rarity = 20, + cost = 35, + combat = { + ranged_project={ + [DamageType.BLIGHT] = resolvers.mbonus_material("ranged_project", 1, true), + [DamageType.DARKNESS] = resolvers.mbonus_material("ranged_project", 1, true), + }, + }, +} + +newEntity{ + power_source = {arcane=true}, + name = " of paradox", suffix=true, instant_resolve=true, + keywords = {paradox=true}, level_range = {1, 50}, greater_ego = 1, - cost = 1, + rarity = 15, + cost = 30, + combat = { + ranged_project = { + [DamageType.TEMPORAL] = resolvers.mbonus_material("ranged_project", 2, true), + [DamageType.RANDOM_CONFUSION] = resolvers.mbonus_material("ranged_project", 1, true), + }, + }, +} + +newEntity{ + power_source = {nature=true}, + name = " of sunrise", suffix=true, + keywords = {sunrise=true}, + level_range = {1, 50}, + greater_ego = 1, + cost = 30, rarity = 15, combat = { - atk = 500, + tg_type = "beam", + damtype = DamageType.LIGHT, + travel_speed = 300, + lite = true, }, - -- Powerful but does not come in much quantity + -- Powerful but comes in a small quiver/pouch resolvers.generic(function(e) - e.generate_stack = rng.range(5, 10) + e.combat.capacity = math.ceil(e.combat.capacity/4) + e.combat.shots_left = e.combat.capacity end), } diff --git a/game/modules/tome/data/general/objects/egos/amulets.lua b/game/modules/tome/data/general/objects/egos/amulets.lua index 0380a809f4..f920c3309a 100644 --- a/game/modules/tome/data/general/objects/egos/amulets.lua +++ b/game/modules/tome/data/general/objects/egos/amulets.lua @@ -33,7 +33,7 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_CUN] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats") }, }, } newEntity{ @@ -44,7 +44,7 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_WIL] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats") }, }, } newEntity{ @@ -122,8 +122,8 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -137,9 +137,9 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), }, - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), }, } @@ -152,9 +152,9 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), + [DamageType.TEMPORAL] = resolvers.mbonus_material("resists"), }, - teleport_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + teleport_immune = resolvers.mbonus_material("immunity"), }, } @@ -166,8 +166,8 @@ newEntity{ rarity = 6, cost = 5, wielder = { - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), }, } @@ -179,8 +179,8 @@ newEntity{ rarity = 6, cost = 5, wielder = { - blind_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + blind_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), }, } @@ -193,10 +193,10 @@ newEntity{ cost = 9, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), }, - poison_immune = resolvers.mbonus_material(10, 5, function(e, v) return 0, v/100 end), - disease_immune = resolvers.mbonus_material(10, 5, function(e, v) return 0, v/100 end), + poison_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), }, } @@ -209,7 +209,7 @@ newEntity{ rarity = 6, cost = 10, wielder = { - fatigue = resolvers.mbonus_material(6, 4, function(e, v) return 0, -v end), + fatigue = resolvers.mbonus_material("fatigue"), }, } @@ -223,15 +223,15 @@ newEntity{ cost = 30, wielder = { resists={ - [DamageType.BLIGHT] = resolvers.mbonus_material(10, 5), + [DamageType.BLIGHT] = resolvers.mbonus_material("resists"), }, inc_stats={ - [Stats.STAT_CON] = resolvers.mbonus_material(4, 2), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - combat_physresist = resolvers.mbonus_material(5, 5), - max_life = resolvers.mbonus_material(50, 30), - life_regen = resolvers.mbonus_material(12, 3, function(e, v) v=v/10 return 0, v end), - max_stamina = resolvers.mbonus_material(20, 10), + combat_physresist = resolvers.mbonus_material("rare_resists"), + max_life = resolvers.mbonus_material("max_life"), + life_regen = resolvers.mbonus_material("life_regen"), + max_stamina = resolvers.mbonus_material("max_stamina"), }, } @@ -245,10 +245,10 @@ newEntity{ rarity = 16, cost = 40, wielder = { - combat_physcrit = resolvers.mbonus_material(3, 3), - combat_critical_power = resolvers.mbonus_material(10, 10), - combat_atk = resolvers.mbonus_material(5, 5), - combat_apr = resolvers.mbonus_material(4, 4), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), + -- combat_critical_power = resolvers.mbonus_material("combat_critical_power"), + combat_atk = resolvers.mbonus_material("combat_atk", 2), + combat_apr = resolvers.mbonus_material("combat_apr"), }, } @@ -262,10 +262,10 @@ newEntity{ rarity = 15, cost = 30, wielder = { - see_invisible = resolvers.mbonus_material(10, 5), - blind_immune = resolvers.mbonus_material(30, 10, function(e, v) v=v/100 return 0, v end), - infravision = resolvers.mbonus_material(2, 1), - trap_detect_power = resolvers.mbonus_material(15, 5), + see_invisible = resolvers.mbonus_material("see_invisible"), + blind_immune = resolvers.mbonus_material("immunity"), + infravision = resolvers.mbonus_material("infravision"), + trap_detect_power = resolvers.mbonus_material("trap_detect_power"), }, } @@ -279,8 +279,8 @@ newEntity{ rarity = 18, cost = 60, wielder = { - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - cut_immune = resolvers.mbonus_material(4, 4, function(e, v) v=v/10 return 0, v end), + healing_factor = resolvers.mbonus_material("healing_factor"), + cut_immune = resolvers.mbonus_material("immunity"), }, max_power = 80, power_regen = 1, use_talent = { id = Talents.T_HEAL, level = 3, power = 80 }, @@ -295,9 +295,9 @@ newEntity{ rarity = 16, cost = 40, wielder = { - combat_armor = resolvers.mbonus_material(3, 2), - combat_def = resolvers.mbonus_material(4, 4), - combat_physresist = resolvers.mbonus_material(20, 7), + combat_armor = resolvers.mbonus_material("combat_armor"), + combat_def = resolvers.mbonus_material("combat_def"), + combat_physresist = resolvers.mbonus_material("save"), }, } @@ -310,9 +310,9 @@ newEntity{ rarity = 20, cost = 90, wielder = { - combat_dam = resolvers.mbonus_material(5, 5), - inc_damage = { [DamageType.PHYSICAL] = resolvers.mbonus_material(5, 5) }, - combat_physspeed = 0.1, + combat_dam = resolvers.mbonus_material("combat_dam", 2), + --inc_damage = { [DamageType.PHYSICAL] = resolvers.mbonus_material("inc_damage") }, + combat_physspeed = resolvers.mbonus_material("combat_physspeed"), }, } @@ -326,13 +326,13 @@ newEntity{ rarity = 16, cost = 40, wielder = { - combat_spellpower = resolvers.mbonus_material(3, 3), - combat_spellcrit = resolvers.mbonus_material(3, 3), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), inc_damage = { - [DamageType.FIRE] = resolvers.mbonus_material(4, 4), - [DamageType.COLD] = resolvers.mbonus_material(4, 4), - [DamageType.ACID] = resolvers.mbonus_material(4, 4), - [DamageType.LIGHTNING] = resolvers.mbonus_material(4, 4), + [DamageType.FIRE] = resolvers.mbonus_material("inc_damage"), + [DamageType.COLD] = resolvers.mbonus_material("inc_damage"), + [DamageType.ACID] = resolvers.mbonus_material("inc_damage"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("inc_damage"), }, }, } @@ -348,14 +348,14 @@ newEntity{ wielder = { resists={ - [DamageType.ARCANE] = resolvers.mbonus_material(20, 10, function(e, v) return 0, -v end), + [DamageType.ARCANE] = resolvers.mbonus_material("rare_resists", -1), }, inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(6, 4), - [Stats.STAT_DEX] = resolvers.mbonus_material(6, 4), - [Stats.STAT_WIL] = resolvers.mbonus_material(6, 4), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats", 2), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats", 2), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats", 2), }, - combat_spellresist = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), + combat_spellresist = resolvers.mbonus_material("save", -1), }, } @@ -370,12 +370,10 @@ newEntity{ cost = 30, wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - combat_mentalresist = resolvers.mbonus_material(10, 5), - combat_spellresist = resolvers.mbonus_material(10, 5), - + confusion_immune = resolvers.mbonus_material("immunity"), + combat_mentalresist = resolvers.mbonus_material("save"), }, } @@ -388,10 +386,10 @@ newEntity{ rarity = 15, cost = 30, wielder = { - combat_mentalresist = resolvers.mbonus_material(10, 5), - combat_physresist = resolvers.mbonus_material(10, 5), - combat_spellresist = resolvers.mbonus_material(10, 5), - combat_def = resolvers.mbonus_material(10, 5), + combat_mentalresist = resolvers.mbonus_material("save"), + combat_physresist = resolvers.mbonus_material("save"), + combat_spellresist = resolvers.mbonus_material("save"), + combat_def = resolvers.mbonus_material("combat_def"), }, } @@ -405,10 +403,10 @@ newEntity{ cost = 30, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(7, 3), - [Stats.STAT_CUN] = resolvers.mbonus_material(7, 3), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - combat_armor = resolvers.mbonus_material(7, 3), + combat_armor = resolvers.mbonus_material("combat_armor"), }, } @@ -422,7 +420,7 @@ newEntity{ cost = 30, wielder = { inc_stats = { - [Stats.STAT_LCK] = resolvers.mbonus_material(12, 8), + [Stats.STAT_LCK] = resolvers.mbonus_material("inc_stats", 2), }, }, } @@ -437,18 +435,35 @@ newEntity{ cost = 90, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), - [DamageType.MIND] = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), + [DamageType.FIRE] = resolvers.mbonus_material("resists", -1), + [DamageType.MIND] = resolvers.mbonus_material("rare_resists", -1), }, - combat_spellpower = resolvers.mbonus_material(10, 5), - combat_critical_power = resolvers.mbonus_material(30, 10), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), + --combat_critical_power = resolvers.mbonus_material("combat_critical_power"), inc_damage = { - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.MIND] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("inc_damage", 2), + [DamageType.MIND] = resolvers.mbonus_material("inc_damage", 2), }, }, } - +--[=[ +newEntity{ + power_source = {nature=true}, + name = " of lifeblood", suffix=true, instant_resolve=true, + level_range = {40, 50}, + greater_ego = 1, + rarity = 30, + cost = 100, + wielder = { + resists={ + [DamageType.LIGHT] = resolvers.mbonus_material("resists", -1), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), + }, + resource_leech_chance = resolvers.mbonus_material("resource_leech_chance"), + resource_leech_value = resolvers.mbonus_material("resource_leech_value"), + }, +} +]=] newEntity{ power_source = {technique=true}, name = " of seduction", suffix=true, instant_resolve=true, @@ -459,10 +474,10 @@ newEntity{ cost = 50, wielder = { inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(5, 1), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, - max_stamina = resolvers.mbonus_material(30, 10), - stamina_regen_on_hit = resolvers.mbonus_material(23, 7, function(e, v) v=v/10 return 0, v end), + max_stamina = resolvers.mbonus_material("max_stamina"), + stamina_regen_on_hit = resolvers.mbonus_material("stamina_regen_on_hit"), }, } @@ -476,10 +491,10 @@ newEntity{ cost = 70, wielder = { inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(5, 1), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), }, - max_mana = resolvers.mbonus_material(40, 20), - mana_regen = resolvers.mbonus_material(50, 10, function(e, v) v=v/100 return 0, v end), + max_mana = resolvers.mbonus_material("max_mana"), + mana_regen = resolvers.mbonus_material("mana_regen"), }, } @@ -494,13 +509,10 @@ newEntity{ cost = 40, wielder = { resists={ - [DamageType.LIGHT] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHT] = resolvers.mbonus_material("resists"), }, on_melee_hit = { - [DamageType.LIGHT] = resolvers.mbonus_material(10, 5), - }, - melee_project={ - [DamageType.LIGHT] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHT] = resolvers.mbonus_material("on_melee_hit", 2), }, }, -} \ No newline at end of file +} diff --git a/game/modules/tome/data/general/objects/egos/armor.lua b/game/modules/tome/data/general/objects/egos/armor.lua index 577c3228e3..0d637cab4b 100644 --- a/game/modules/tome/data/general/objects/egos/armor.lua +++ b/game/modules/tome/data/general/objects/egos/armor.lua @@ -28,7 +28,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - resists={[DamageType.FIRE] = resolvers.mbonus_material(30, 10)}, + resists={[DamageType.FIRE] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -39,7 +39,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - resists={[DamageType.COLD] = resolvers.mbonus_material(30, 10)}, + resists={[DamageType.COLD] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -50,7 +50,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - resists={[DamageType.ACID] = resolvers.mbonus_material(30, 10)}, + resists={[DamageType.ACID] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -61,7 +61,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - resists={[DamageType.LIGHTNING] = resolvers.mbonus_material(30, 10)}, + resists={[DamageType.LIGHTNING] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -72,7 +72,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - resists={[DamageType.NATURE] = resolvers.mbonus_material(30, 10)}, + resists={[DamageType.NATURE] = resolvers.mbonus_material("nature")}, }, } @@ -84,8 +84,8 @@ newEntity{ rarity = 7, cost = 6, wielder = { - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(20, 20, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), }, } @@ -98,8 +98,8 @@ newEntity{ cost = 7, wielder = { resists={ - [DamageType.LIGHT] = resolvers.mbonus_material(10, 10), - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 10), + [DamageType.LIGHT] = resolvers.mbonus_material("resists"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, }, } @@ -112,22 +112,7 @@ newEntity{ rarity = 6, cost = 7, wielder = { - on_melee_hit={[DamageType.PHYSICAL] = resolvers.mbonus_material(10, 10)}, - }, -} - -newEntity{ - power_source = {arcane=true}, - name = "searing ", prefix=true, instant_resolve=true, - keywords = {searing=true}, - level_range = {10, 50}, - rarity = 10, - cost = 7, - wielder = { - melee_project={ - [DamageType.FIRE] = resolvers.mbonus_material(8, 8), - [DamageType.ACID] = resolvers.mbonus_material(8, 8), - }, + on_melee_hit={[DamageType.PHYSICAL] = resolvers.mbonus_material("on_melee_hit")}, }, } @@ -139,7 +124,7 @@ newEntity{ rarity = 10, cost = 15, wielder = { - stamina_regen = resolvers.mbonus_material(50, 20, function(e, v) v=v/100 return 0, v end), + stamina_regen = resolvers.mbonus_material("stamina_regen", 2), }, } @@ -152,14 +137,13 @@ newEntity{ rarity = 18, cost = 15, wielder = { - melee_project={[DamageType.LIGHT] = resolvers.mbonus_material(10, 4),}, resists={ - [DamageType.BLIGHT] = resolvers.mbonus_material(20, 10), - [DamageType.DARKNESS] = resolvers.mbonus_material(20, 10), + [DamageType.BLIGHT] = resolvers.mbonus_material("resists"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(5, 1), - [Stats.STAT_LCK] = resolvers.mbonus_material(10, 1), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_LCK] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -173,8 +157,8 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -190,9 +174,9 @@ newEntity{ cost = 10, wielder = { resists={ - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), }, - stun_immune = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), }, } @@ -205,9 +189,9 @@ newEntity{ cost = 10, wielder = { resists={ - [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), + [DamageType.TEMPORAL] = resolvers.mbonus_material("resists"), }, - teleport_immune = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), + teleport_immune = resolvers.mbonus_material("immunity"), }, } @@ -220,8 +204,8 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - [DamageType.POISON] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.POISON] = resolvers.mbonus_material("resists"), }, }, } @@ -236,10 +220,10 @@ newEntity{ cost = 35, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 2), - [Stats.STAT_STR] = resolvers.mbonus_material(5, 2), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), }, - max_life=resolvers.mbonus_material(70, 30), + max_life=resolvers.mbonus_material("max_life"), }, } @@ -254,13 +238,11 @@ newEntity{ cost = 47, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(8, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(8, 5), - [DamageType.FIRE] = resolvers.mbonus_material(8, 5), - [DamageType.COLD] = resolvers.mbonus_material(8, 5), - [DamageType.PHYSICAL] = resolvers.mbonus_material(8, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, - combat_armor = resolvers.mbonus_material(5, 5), + combat_armor = resolvers.mbonus_material("combat_armor"), }, } @@ -274,7 +256,7 @@ newEntity{ rarity = 9, cost = 10, wielder = { - max_life = resolvers.mbonus_material(40, 40), + max_life = resolvers.mbonus_material("max_life", 2), }, } @@ -290,13 +272,12 @@ newEntity{ cost = 35, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(8, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(8, 5), - [DamageType.FIRE] = resolvers.mbonus_material(8, 5), - [DamageType.COLD] = resolvers.mbonus_material(8, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(6, 2), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -310,9 +291,9 @@ newEntity{ rarity = 16, cost = 30, wielder = { - max_life=resolvers.mbonus_material(60, 40), - life_regen = resolvers.mbonus_material(15, 5, function(e, v) v=v/10 return 0, v end), - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + max_life=resolvers.mbonus_material("max_life"), + life_regen = resolvers.mbonus_material("life_regen"), + healing_factor = resolvers.mbonus_material("healing_factor"), }, } @@ -325,9 +306,9 @@ newEntity{ rarity = 16, cost = 30, wielder = { - combat_dam = resolvers.mbonus_material(5, 5), - combat_physcrit = resolvers.mbonus_material(3, 3), - combat_critical_power = resolvers.mbonus_material(10, 10), + combat_dam = resolvers.mbonus_material("combat_dam", 2), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), + --combat_critical_power = resolvers.mbonus_material("combat_critical_power"), }, } @@ -340,10 +321,10 @@ newEntity{ rarity = 16, cost = 30, wielder = { - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - pin_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - combat_armor = resolvers.mbonus_material(6, 4), - fatigue = resolvers.mbonus_material(6, 4, function(e, v) return 0, -v end), + stun_immune = resolvers.mbonus_material("immunity"), + pin_immune = resolvers.mbonus_material("immunity"), + combat_armor = resolvers.mbonus_material("combat_armor"), + fatigue = resolvers.mbonus_material("fatigue"), }, } @@ -357,11 +338,11 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(7, 3), - [Stats.STAT_DEX] = resolvers.mbonus_material(7, 3), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), }, - disarm_immune = resolvers.mbonus_material(25, 15, function(e, v) v=v/100 return 0, v end), - combat_physresist = resolvers.mbonus_material(15, 5), + disarm_immune = resolvers.mbonus_material("immunity"), + combat_physresist = resolvers.mbonus_material("save"), }, } @@ -375,12 +356,12 @@ newEntity{ cost = 30, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - poison_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - disease_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - life_regen = resolvers.mbonus_material(30, 5, function(e, v) v=v/10 return 0, v end), - fatigue = resolvers.mbonus_material(6, 4, function(e, v) return 0, -v end), + poison_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), + life_regen = resolvers.mbonus_material("life_regen"), + fatigue = resolvers.mbonus_material("fatigue"), }, } @@ -394,12 +375,12 @@ newEntity{ cost = 80, wielder = { inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(7, 3), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, - combat_armor = resolvers.mbonus_material(7, 3), - combat_physcrit = resolvers.mbonus_material(5, 1), - combat_spellcrit = resolvers.mbonus_material(5, 1), - combat_atk = resolvers.mbonus_material(10, 5), + combat_armor = resolvers.mbonus_material("combat_armor"), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), + combat_atk = resolvers.mbonus_material("combat_atk"), }, } @@ -413,12 +394,12 @@ newEntity{ cost = 30, wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - blind_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - combat_mentalresist = resolvers.mbonus_material(10, 5), - combat_spellresist = resolvers.mbonus_material(10, 5), + blind_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), + combat_mentalresist = resolvers.mbonus_material("save"), + combat_spellresist = resolvers.mbonus_material("save"), }, } @@ -433,12 +414,12 @@ newEntity{ max_power = 80, power_regen = 1, use_talent = { id = Talents.T_SECOND_WIND, level = 5, power = 80 }, wielder = { - max_life = resolvers.mbonus_material(60, 40, function(e, v) return 0, -v end), - combat_armor = resolvers.mbonus_material(7, 3, function(e, v) return 0, -v end), + max_life = resolvers.mbonus_material("max_life", -1), + combat_armor = resolvers.mbonus_material("combat_armor", -1), - combat_physcrit = resolvers.mbonus_material(7, 3), - combat_apr = resolvers.mbonus_material(15, 5), - combat_def = resolvers.mbonus_material(10, 5), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), + combat_apr = resolvers.mbonus_material("combat_apr"), + combat_def = resolvers.mbonus_material("combat_def", 2), }, } @@ -452,11 +433,11 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - combat_mentalresist = resolvers.mbonus_material(10, 5), - combat_armor = resolvers.mbonus_material(7, 3), - combat_def = resolvers.mbonus_material(10, 5), + combat_mentalresist = resolvers.mbonus_material("save"), + combat_armor = resolvers.mbonus_material("combat_armor"), + combat_def = resolvers.mbonus_material("combat_def"), }, } @@ -472,9 +453,9 @@ newEntity{ use_talent = { id = Talents.T_TRACK, level = 2, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(6, 4), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), }, - lite = resolvers.mbonus_material(1, 1), + lite = resolvers.mbonus_material("lite"), }, } @@ -488,10 +469,10 @@ newEntity{ cost = 20, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, - combat_armor = resolvers.mbonus_material(5, 1), + combat_armor = resolvers.mbonus_material("combat_armor"), can_breath = {water=1}, }, } @@ -506,11 +487,11 @@ newEntity{ cost = 100, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(7, 3), - [Stats.STAT_MAG] = resolvers.mbonus_material(7, 3), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), }, - combat_physcrit = resolvers.mbonus_material(3, 2), - combat_spellcrit = resolvers.mbonus_material(3, 2), - combat_dam = resolvers.mbonus_material(7, 3), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), + combat_dam = resolvers.mbonus_material("combat_dam"), }, } diff --git a/game/modules/tome/data/general/objects/egos/belt.lua b/game/modules/tome/data/general/objects/egos/belt.lua index cf60d94297..68fef5634b 100644 --- a/game/modules/tome/data/general/objects/egos/belt.lua +++ b/game/modules/tome/data/general/objects/egos/belt.lua @@ -30,8 +30,8 @@ newEntity{ rarity = 5, cost = 6, wielder = { - max_encumber = resolvers.mbonus_material(40, 20), - fatigue = resolvers.mbonus_material(6, 4, function(e, v) return 0, -v end), + max_encumber = resolvers.mbonus_material("max_encumber"), + fatigue = resolvers.mbonus_material("fatigue"), }, } @@ -43,7 +43,7 @@ newEntity{ rarity = 10, cost = 40, wielder = { - combat_def = resolvers.mbonus_material(10, 5), + combat_def = resolvers.mbonus_material("combat_def"), }, max_power = 120, power_regen = 1, use_power = { name = "create a temporary shield that absorbs damage", power = 100, use = function(self, who) @@ -62,7 +62,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - combat_spellpower = resolvers.mbonus_material(10, 2), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), }, } @@ -74,7 +74,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - combat_dam = resolvers.mbonus_material(10, 2), + combat_dam = resolvers.mbonus_material("combat_dam"), }, } @@ -86,7 +86,7 @@ newEntity{ rarity = 8, cost = 6, wielder = { - life_regen = resolvers.mbonus_material(10, 2, function(e, v) return 0, v/10 end), + life_regen = resolvers.mbonus_material("life_regen"), }, } @@ -98,7 +98,7 @@ newEntity{ rarity = 6, cost = 5, wielder = { - max_life = resolvers.mbonus_material(40, 30), + max_life = resolvers.mbonus_material("max_life"), }, } @@ -110,8 +110,8 @@ newEntity{ rarity = 9, cost = 10, wielder = { - combat_def_ranged = resolvers.mbonus_material(8, 2), - inc_stealth = resolvers.mbonus_material(10, 5), + combat_def_ranged = resolvers.mbonus_material("combat_def_ranged"), + inc_stealth = resolvers.mbonus_material("inc_stealth"), }, } @@ -124,8 +124,8 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -139,9 +139,9 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), }, - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), }, } @@ -154,9 +154,9 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), + [DamageType.TEMPORAL] = resolvers.mbonus_material("resists"), }, - teleport_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + teleport_immune = resolvers.mbonus_material("immunity"), }, } @@ -168,8 +168,8 @@ newEntity{ rarity = 6, cost = 5, wielder = { - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), }, } @@ -182,10 +182,10 @@ newEntity{ cost = 9, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), }, - poison_immune = resolvers.mbonus_material(10, 5, function(e, v) return 0, v/100 end), - disease_immune = resolvers.mbonus_material(10, 5, function(e, v) return 0, v/100 end), + poison_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), }, } @@ -197,7 +197,7 @@ newEntity{ rarity = 9, cost = 9, wielder = { - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), + confusion_immune = resolvers.mbonus_material("immunity"), }, } @@ -211,10 +211,10 @@ newEntity{ cost = 50, wielder = { inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(3, 3), - [Stats.STAT_WIL] = resolvers.mbonus_material(3, 3), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, - combat_spellcrit = resolvers.mbonus_material(3, 3), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), }, } @@ -227,11 +227,11 @@ newEntity{ rarity = 15, cost = 30, wielder = { - disarm_bonus = resolvers.mbonus_material(25, 5), - trap_detect_power = resolvers.mbonus_material(25, 5), - infravision = resolvers.mbonus_material(2, 2), + disarm_bonus = resolvers.mbonus_material("disarm_bonus"), + trap_detect_power = resolvers.mbonus_material("trap_detect_power"), + infravision = resolvers.mbonus_material("infravision"), inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(3, 3), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -246,10 +246,10 @@ newEntity{ cost = 50, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(5, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(5, 5), - [DamageType.FIRE] = resolvers.mbonus_material(5, 5), - [DamageType.COLD] = resolvers.mbonus_material(5, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -264,10 +264,10 @@ newEntity{ cost = 50, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(3, 3), - [Stats.STAT_CON] = resolvers.mbonus_material(3, 3), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - pin_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + pin_immune = resolvers.mbonus_material("immunity"), }, } @@ -282,8 +282,8 @@ newEntity{ cost = 60, wielder = { size_category = 1, - combat_dam = resolvers.mbonus_material(5, 5), - combat_critical_power = resolvers.mbonus_material(10, 10), + combat_dam = resolvers.mbonus_material("combat_dam", 2), + -- combat_critical_power = resolvers.mbonus_material("combat_critical_power"), }, } @@ -298,10 +298,10 @@ newEntity{ cost = 60, wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(3, 3), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - combat_atk = resolvers.mbonus_material(5, 5), - combat_physcrit = resolvers.mbonus_material(3, 3), + combat_atk = resolvers.mbonus_material("combat_atk"), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), }, } @@ -315,9 +315,9 @@ newEntity{ rarity = 20, cost = 60, wielder = { - combat_armor = resolvers.mbonus_material(6, 4), - combat_def = resolvers.mbonus_material(4, 4), - combat_physresist = resolvers.mbonus_material(20, 7), + combat_armor = resolvers.mbonus_material("combat_armor"), + combat_def = resolvers.mbonus_material("combat_def"), + combat_physresist = resolvers.mbonus_material("save", 2), }, } @@ -330,18 +330,29 @@ newEntity{ rarity = 40, cost = 100, wielder = { - resists={ - [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 5, function(e, v) return 0, -v end), - }, - inc_damage = { - [DamageType.PHYSICAL] = resolvers.mbonus_material(20, 5), - }, + combat_dam = resolvers.mbonus_material("combat_dam"), resists_pen = { - [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 5), + [DamageType.PHYSICAL] = resolvers.mbonus_material("resists_pen", 2), }, }, } - +--[=[ +newEntity{ + power_source = {nature=true}, + name = "draining ", prefix=true, instant_resolve=true, + level_range = {45, 50}, + greater_ego = 1, + rarity = 40, + cost = 100, + wielder = { + resource_leech_chance = resolvers.mbonus_material("resource_leech_chance"), + resource_leech_value = resolvers.mbonus_material("resource_leech_value"), + on_melee_hit = { + [DamageType.BLIGHT] = resolvers.mbonus_material("on_melee_hit"), + }, + }, +} +]=] newEntity{ power_source = {arcane=true}, name = "nightruned ", prefix=true, instant_resolve=true, @@ -352,11 +363,11 @@ newEntity{ cost = 60, wielder = { resists={ - [DamageType.LIGHT] = resolvers.mbonus_material(10, 5), - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHT] = resolvers.mbonus_material("resists"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, - blind_immune = resolvers.mbonus_material(20, 15, function(e, v) v=v/100 return 0, v end), - see_invisible = resolvers.mbonus_material(20, 5), + blind_immune = resolvers.mbonus_material("immunity"), + see_invisible = resolvers.mbonus_material("immunity"), }, } @@ -369,16 +380,13 @@ newEntity{ rarity = 35, cost = 70, wielder = { - inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(3, 1), - [Stats.STAT_DEX] = resolvers.mbonus_material(3, 1), - [Stats.STAT_WIL] = resolvers.mbonus_material(3, 1), - [Stats.STAT_CUN] = resolvers.mbonus_material(3, 1), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - combat_mentalresist = resolvers.mbonus_material(3, 3), - combat_physresist = resolvers.mbonus_material(3, 3), - combat_spellresist = resolvers.mbonus_material(3, 3), + combat_spellresist = resolvers.mbonus_material("save"), }, } @@ -392,10 +400,10 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(5, 1), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), }, - max_mana = resolvers.mbonus_material(40, 20), - mana_regen = resolvers.mbonus_material(50, 10, function(e, v) v=v/100 return 0, v end), + max_mana = resolvers.mbonus_material("max_mana"), + mana_regen = resolvers.mbonus_material("mana_regen"), }, } @@ -409,14 +417,14 @@ newEntity{ cost = 70, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(6, 4), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - stun_immune = resolvers.mbonus_material(17, 5, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(17, 5, function(e, v) v=v/100 return 0, v end), - pin_immune = resolvers.mbonus_material(17, 5, function(e, v) v=v/100 return 0, -v end), - blind_immune = resolvers.mbonus_material(17, 5, function(e, v) v=v/100 return 0, -v end), - confusion_immune = resolvers.mbonus_material(17, 5, function(e, v) v=v/100 return 0, v end), - max_stamina = resolvers.mbonus_material(30, 10), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), + pin_immune = resolvers.mbonus_material("immunity", -1), + blind_immune = resolvers.mbonus_material("immunity", -1), + confusion_immune = resolvers.mbonus_material("immunity"), + max_stamina = resolvers.mbonus_material("max_stamina"), }, } @@ -429,10 +437,10 @@ newEntity{ rarity = 15, cost = 40, wielder = { - disarm_immune = resolvers.mbonus_material(15, 5, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(15, 5, function(e, v) v=v/100 return 0, v end), - combat_critical_power = resolvers.mbonus_material(10, 5), - combat_dam = resolvers.mbonus_material(3, 3), + disarm_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), + --combat_critical_power = resolvers.mbonus_material("combat_critical_power"), + combat_dam = resolvers.mbonus_material("combat_dam"), }, } @@ -446,12 +454,12 @@ newEntity{ cost = 60, wielder = { resists={ - [DamageType.PHYSICAL] = resolvers.mbonus_material(7, 3), + [DamageType.PHYSICAL] = resolvers.mbonus_material("resists"), }, inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(5, 1), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, - max_life = resolvers.mbonus_material(70, 40), + max_life = resolvers.mbonus_material("max_life"), }, } @@ -465,10 +473,10 @@ newEntity{ cost = 30, wielder = { resists={ - [DamageType.BLIGHT] = resolvers.mbonus_material(10, 5), + [DamageType.BLIGHT] = resolvers.mbonus_material("resists"), }, inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(5, 1), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), }, can_breath = {water=1}, }, @@ -484,10 +492,8 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats", 2), }, - combat_mentalresist = resolvers.mbonus_material(7, 3), - combat_physresist = resolvers.mbonus_material(7, 3), - combat_spellresist = resolvers.mbonus_material(7, 3), + combat_physresist = resolvers.mbonus_material("save", 2), }, } diff --git a/game/modules/tome/data/general/objects/egos/boots.lua b/game/modules/tome/data/general/objects/egos/boots.lua index 0895bbaeb9..728542497f 100644 --- a/game/modules/tome/data/general/objects/egos/boots.lua +++ b/game/modules/tome/data/general/objects/egos/boots.lua @@ -52,7 +52,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - combat_def_ranged = resolvers.mbonus_material(8, 2), + combat_def_ranged = resolvers.mbonus_material("combat_def_ranged"), }, } @@ -65,7 +65,7 @@ newEntity{ rarity = 20, cost = 60, wielder = { - movement_speed = 0.2, + movement_speed = resolvers.mbonus_material("movement_speed"), }, } @@ -81,8 +81,8 @@ newEntity{ use_talent = { id = Talents.T_RUSH, level = 2, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(2, 2), - [Stats.STAT_CON] = resolvers.mbonus_material(2, 2), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -100,8 +100,8 @@ newEntity{ use_talent = { id = Talents.T_DISENGAGE, level = 2, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(2, 2), - [Stats.STAT_CUN] = resolvers.mbonus_material(2, 2), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -114,8 +114,8 @@ newEntity{ rarity = 12, cost = 12, wielder = { - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), }, } @@ -127,8 +127,8 @@ newEntity{ rarity = 9, cost = 7, wielder = { - max_stamina = resolvers.mbonus_material(30, 10), - stamina_regen = resolvers.mbonus_material(10, 3, function(e, v) v=v/10 return 0, v end), + max_stamina = resolvers.mbonus_material("max_stamina"), + stamina_regen = resolvers.mbonus_material("stamina_regen"), }, } @@ -140,7 +140,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - max_encumber = resolvers.mbonus_material(30, 20), + max_encumber = resolvers.mbonus_material("max_encumber"), }, } @@ -153,7 +153,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - combat_spellpower = resolvers.mbonus_material(3, 3), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), }, } @@ -165,7 +165,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - combat_armor = resolvers.mbonus_material(6, 4), + combat_armor = resolvers.mbonus_material("combat_armor"), }, } @@ -176,7 +176,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - infravision = resolvers.mbonus_material(2, 1), + infravision = resolvers.mbonus_material("infravision"), }, } @@ -189,10 +189,10 @@ newEntity{ rarity = 18, cost = 60, wielder = { - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - cut_immune = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), - life_regen = resolvers.mbonus_material(10, 5, function(e, v) v=v/10 return 0, v end), - poison_immune = resolvers.mbonus_material(10, 10, function(e, v) return 0, v/100 end), + healing_factor = resolvers.mbonus_material("healing_factor"), + cut_immune = resolvers.mbonus_material("immunity"), + life_regen = resolvers.mbonus_material("life_regen"), + poison_immune = resolvers.mbonus_material("immunity"), }, } @@ -206,9 +206,9 @@ newEntity{ rarity = 20, cost = 70, wielder = { - fatigue = resolvers.mbonus_material(6, 4, function(e, v) return 0, -v end), - max_life=resolvers.mbonus_material(30, 30), - movement_speed = 0.1, + fatigue = resolvers.mbonus_material("fatigue"), + max_life = resolvers.mbonus_material("max_life"), + movement_speed = resolvers.mbonus_material("movement_speed"), }, } @@ -221,9 +221,9 @@ newEntity{ rarity = 15, cost = 20, wielder = { - combat_dam = resolvers.mbonus_material(3, 3), - combat_apr = resolvers.mbonus_material(3, 3), - pin_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + combat_dam = resolvers.mbonus_material("combat_dam"), + combat_apr = resolvers.mbonus_material("combat_apr"), + pin_immune = resolvers.mbonus_material("immunity"), }, } @@ -238,14 +238,14 @@ newEntity{ max_power = 80, power_regen = 1, wielder = { resists={ - [DamageType.NATURE] = resolvers.mbonus_material(20, 10, function(e, v) return 0, -v end), - [DamageType.LIGHT] = resolvers.mbonus_material(20, 10, function(e, v) return 0, -v end), + [DamageType.NATURE] = resolvers.mbonus_material("resists", -1), + [DamageType.LIGHT] = resolvers.mbonus_material("resists", -1), }, inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(7, 3), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats", 2), }, - pin_immune = resolvers.mbonus_material(50, 40, function(e, v) v=v/100 return 0, v end), - combat_spellpower = resolvers.mbonus_material(7, 3), + pin_immune = resolvers.mbonus_material("immunity", 2), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), }, } @@ -259,11 +259,11 @@ newEntity{ cost = 30, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - blind_immune = resolvers.mbonus_material(15, 5, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(15, 5, function(e, v) v=v/100 return 0, v end), - disease_immune = resolvers.mbonus_material(15, 5, function(e, v) v=v/100 return 0, v end), + blind_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), }, } @@ -277,12 +277,12 @@ newEntity{ cost = 60, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, - combat_armor = resolvers.mbonus_material(7, 3), + combat_armor = resolvers.mbonus_material("combat_armor"), }, } @@ -295,9 +295,9 @@ newEntity{ rarity = 30, cost = 60, wielder = { - max_mana = resolvers.mbonus_material(40, 20), - mana_regen = resolvers.mbonus_material(50, 10, function(e, v) v=v/100 return 0, v end), - combat_spellcrit = resolvers.mbonus_material(4, 1), + max_mana = resolvers.mbonus_material("max_mana"), + mana_regen = resolvers.mbonus_material("mana_regen"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), }, } @@ -311,11 +311,11 @@ newEntity{ cost = 70, wielder = { resists={ - [DamageType.LIGHTNING] = resolvers.mbonus_material(15, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), }, - stun_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - pin_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), + pin_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), }, } @@ -331,15 +331,29 @@ newEntity{ use_talent = { id = Talents.T_HEAVE, level = 4, power = 40 }, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(7, 3), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats", 2), }, - knockback_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - pin_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - poison_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, -v end), - disease_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, -v end), + knockback_immune = resolvers.mbonus_material("immunity"), + pin_immune = resolvers.mbonus_material("immunity"), + poison_immune = resolvers.mbonus_material("immunity", -1), + disease_immune = resolvers.mbonus_material("immunity", -1), }, } - +--[=[ +newEntity{ + power_source = {nature=true}, + name = " of voracity", suffix=true, instant_resolve=true, + level_range = {20, 50}, + greater_ego = 1, + rarity = 20, + cost = 40, + wielder = { + resource_leech_chance = resolvers.mbonus_material("resource_leech_chance"), + resource_leech_value = resolvers.mbonus_material("resource_leech_value"), + max_life = resolvers.mbonus_material("max_life", -1), + }, +} +]=] newEntity{ power_source = {technique=true}, name = " of invasion", suffix=true, instant_resolve=true, @@ -349,11 +363,11 @@ newEntity{ rarity = 30, cost = 40, wielder = { - disarm_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - combat_physcrit = resolvers.mbonus_material(4, 1), - combat_dam = resolvers.mbonus_material(3, 3), + disarm_immune = resolvers.mbonus_material("immunity"), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), + combat_dam = resolvers.mbonus_material("combat_dam"), resists_pen = { - [DamageType.PHYSICAL] = resolvers.mbonus_material(10, 5), + [DamageType.PHYSICAL] = resolvers.mbonus_material("resists"), }, }, } @@ -370,7 +384,7 @@ newEntity{ use_talent = { id = Talents.T_METAFLOW, level = 2, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(5, 1), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -386,8 +400,8 @@ newEntity{ max_power = 80, power_regen = 1, use_talent = { id = Talents.T_EVASION, level = 2, power = 80 }, wielder = { - combat_mentalresist = resolvers.mbonus_material(7, 1), - combat_physresist = resolvers.mbonus_material(7, 1), - combat_spellresist = resolvers.mbonus_material(7, 1), + combat_mentalresist = resolvers.mbonus_material("save"), + combat_physresist = resolvers.mbonus_material("save"), + combat_spellresist = resolvers.mbonus_material("save"), }, } diff --git a/game/modules/tome/data/general/objects/egos/bow.lua b/game/modules/tome/data/general/objects/egos/bow.lua index 04fc09a96c..8fd7b1f26d 100644 --- a/game/modules/tome/data/general/objects/egos/bow.lua +++ b/game/modules/tome/data/general/objects/egos/bow.lua @@ -19,74 +19,7 @@ local Talents = require("engine.interface.ActorTalents") local Stats = require("engine.interface.ActorStats") ---load("/data/general/objects/egos/charged-attack.lua") - -newEntity{ - power_source = {technique=true}, - name = " of power", suffix=true, instant_resolve=true, - keywords = {power=true}, - level_range = {1, 50}, - rarity = 3, - cost = 6, - combat={apr = resolvers.mbonus_material(15, 1)}, -} - -newEntity{ - power_source = {technique=true}, - name = "mighty ", prefix=true, instant_resolve=true, - keywords = {mighty=true}, - level_range = {1, 50}, - rarity = 3, - cost = 4, - wielder = { - inc_damage={ [DamageType.PHYSICAL] = resolvers.mbonus_material(25, 8), }, - }, -} - -newEntity{ - power_source = {technique=true}, - name = "steady ", prefix=true, instant_resolve=true, - keywords = {steady=true}, - level_range = {20, 50}, - rarity = 9, - cost = 10, - wielder = { - talent_cd_reduction={[Talents.T_STEADY_SHOT]=1}, - }, -} - -newEntity{ - power_source = {technique=true}, - name = " of dexterity (#STATBONUS#)", suffix=true, instant_resolve=true, - keywords = {dexterity=true}, - level_range = {20, 50}, - rarity = 7, - cost = 7, - wielder = { - inc_stats = { [Stats.STAT_DEX] = resolvers.mbonus_material(6, 2) }, - }, -} - -newEntity{ - power_source = {technique=true}, - name = " of speed", suffix=true, instant_resolve=true, - keywords = {speed=true}, - level_range = {20, 50}, - rarity = 7, - cost = 7, - combat={physspeed = -0.1}, -} - -newEntity{ - power_source = {technique=true}, - name = " of great speed", suffix=true, instant_resolve=true, - keywords = {['g.speed']=true}, - level_range = {40, 50}, - greater_ego = 1, - rarity = 10, - cost = 60, - combat={physspeed = -0.2}, -} +load("/data/general/objects/egos/ranged.lua") newEntity{ power_source = {technique=true}, @@ -96,12 +29,14 @@ newEntity{ greater_ego = 1, rarity = 24, cost = 40, + combat = { + critical_power = resolvers.mbonus_material("critical_power"), + }, wielder = { - talent_cd_reduction={ - [Talents.T_STEADY_SHOT]=1, - [Talents.T_PINNING_SHOT]=1, - [Talents.T_VOLLEY_OF_ARROWS]=2, + learn_talent = { + [Talents.T_STEADY_SHOT] = resolvers.mbonus_material("learn_talent"), + [Talents.T_PINNING_SHOT] = resolvers.mbonus_material("learn_talent"), + [Talents.T_VOLLEY_OF_ARROWS] = resolvers.mbonus_material("learn_talent"), }, - inc_damage={ [DamageType.PHYSICAL] = resolvers.mbonus_material(14, 8), }, }, } diff --git a/game/modules/tome/data/general/objects/egos/cloak.lua b/game/modules/tome/data/general/objects/egos/cloak.lua index 7319200a4c..72cee57b24 100644 --- a/game/modules/tome/data/general/objects/egos/cloak.lua +++ b/game/modules/tome/data/general/objects/egos/cloak.lua @@ -30,7 +30,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - inc_stealth = resolvers.mbonus_material(20, 5), + inc_stealth = resolvers.mbonus_material("inc_stealth"), }, } @@ -42,7 +42,7 @@ newEntity{ rarity = 6, cost = 7, wielder = { - resists={[DamageType.COLD] = resolvers.mbonus_material(20, 10)}, + resists={[DamageType.COLD] = resolvers.mbonus_material("resists")}, }, } @@ -54,7 +54,7 @@ newEntity{ rarity = 6, cost = 7, wielder = { - combat_armor = resolvers.mbonus_material(8, 5), + combat_armor = resolvers.mbonus_material("combat_armor"), }, } @@ -67,8 +67,8 @@ newEntity{ cost = 10, wielder = { inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(3, 1), - [Stats.STAT_CUN] = resolvers.mbonus_material(3, 1), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats", 0.5), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats", 0.5), }, }, } @@ -82,8 +82,8 @@ newEntity{ cost = 10, wielder = { inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(3, 1), - [Stats.STAT_WIL] = resolvers.mbonus_material(3, 1), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats", 0.5), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats", 0.5), }, }, } @@ -97,8 +97,8 @@ newEntity{ cost = 10, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(3, 1), - [Stats.STAT_CON] = resolvers.mbonus_material(3, 1), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats", 0.5), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats", 0.5), }, }, } @@ -111,7 +111,7 @@ newEntity{ rarity = 6, cost = 7, wielder = { - resists={[DamageType.ACID] = resolvers.mbonus_material(15, 10)}, + resists={[DamageType.ACID] = resolvers.mbonus_material("resists")}, }, } @@ -126,13 +126,13 @@ newEntity{ cost = 25, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(15, 10), - [DamageType.LIGHT] = resolvers.mbonus_material(15, 10), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.LIGHT] = resolvers.mbonus_material("resists"), }, - confusion_immune = -0.2, - combat_def = resolvers.mbonus_material(6, 4), + confusion_immune = resolvers.mbonus_material("immunity", -1), + combat_def = resolvers.mbonus_material("combat_def"), lite = -1, - inc_stealth = resolvers.mbonus_material(10, 5), + inc_stealth = resolvers.mbonus_material("inc_stealth"), }, } @@ -145,7 +145,7 @@ newEntity{ rarity = 7, cost = 6, wielder = { - max_life=resolvers.mbonus_material(30, 30), + max_life=resolvers.mbonus_material("max_life"), }, } @@ -157,8 +157,8 @@ newEntity{ rarity = 7, cost = 6, wielder = { - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), }, } @@ -170,7 +170,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - combat_def = resolvers.mbonus_material(4, 4), + combat_def = resolvers.mbonus_material("combat_def"), }, } @@ -182,7 +182,7 @@ newEntity{ rarity = 10, cost = 10, wielder = { - fatigue = resolvers.mbonus_material(5, 2, function(e, v) return 0, -v end), + fatigue = resolvers.mbonus_material("fatigue"), }, } @@ -196,11 +196,11 @@ newEntity{ cost = 50, wielder = { inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(2, 2), - [Stats.STAT_WIL] = resolvers.mbonus_material(2, 2), - [Stats.STAT_CUN] = resolvers.mbonus_material(2, 2), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats", 0.5), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats", 0.5), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats", 0.5), }, - combat_spellcrit = resolvers.mbonus_material(3, 3), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), }, } @@ -213,9 +213,9 @@ newEntity{ rarity = 16, cost = 50, wielder = { - pin_immune = resolvers.mbonus_material(3, 2, function(e, v) v=v/10 return 0, v end), - knockback_immune = resolvers.mbonus_material(3, 2, function(e, v) v=v/10 return 0, v end), - confusion_immune = resolvers.mbonus_material(3, 2, function(e, v) v=v/10 return 0, v end), + pin_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), }, } @@ -228,10 +228,10 @@ newEntity{ rarity = 18, cost = 60, wielder = { - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - cut_immune = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), - life_regen = resolvers.mbonus_material(10, 5, function(e, v) v=v/10 return 0, v end), - poison_immune = resolvers.mbonus_material(10, 10, function(e, v) return 0, v/100 end), + healing_factor = resolvers.mbonus_material("healing_factor"), + --cut_immune = resolvers.mbonus_material("immunity"), + life_regen = resolvers.mbonus_material("life_regen"), + poison_immune = resolvers.mbonus_material("immunity"), }, } @@ -246,10 +246,10 @@ newEntity{ cost = 20, wielder = { inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(2, 2), - [Stats.STAT_CUN] = resolvers.mbonus_material(2, 2), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - silence_immune = resolvers.mbonus_material(3, 2, function(e, v) v=v/10 return 0, v end), + silence_immune = resolvers.mbonus_material("immunity"), }, } @@ -263,10 +263,10 @@ newEntity{ cost = 60, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(5, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(5, 5), - [DamageType.FIRE] = resolvers.mbonus_material(5, 5), - [DamageType.COLD] = resolvers.mbonus_material(5, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -281,15 +281,15 @@ newEntity{ cost = 80, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(5, 1), - [Stats.STAT_DEX] = resolvers.mbonus_material(5, 1), - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - combat_spellresist = resolvers.mbonus_material(20, 10, function(e, v) return 0, -v end), - stamina_regen = resolvers.mbonus_material(12, 3, function(e, v) v=v/10 return 0, -v end), - mana_regen = resolvers.mbonus_material(50, 10, function(e, v) v=v/100 return 0, -v end), + combat_spellresist = resolvers.mbonus_material("save", -1), + stamina_regen = resolvers.mbonus_material("stamina_regen", -1), + mana_regen = resolvers.mbonus_material("mana_regen", -1), talents_types_mastery = { - ["technique/combat-training"] = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), + ["technique/combat-training"] = resolvers.mbonus_material("talent_types_mastery"), }, }, } @@ -303,11 +303,11 @@ newEntity{ rarity = 15, cost = 30, wielder = { - blind_immune = resolvers.mbonus_material(10, 5, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(10, 5, function(e, v) v=v/100 return 0, v end), - combat_mentalresist = resolvers.mbonus_material(4, 1), - combat_physresist = resolvers.mbonus_material(4, 1), - combat_spellresist = resolvers.mbonus_material(4, 1), + blind_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), + combat_mentalresist = resolvers.mbonus_material("save"), + combat_physresist = resolvers.mbonus_material("save"), + combat_spellresist = resolvers.mbonus_material("save"), }, } @@ -321,13 +321,13 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(5, 1), - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - combat_mentalresist = resolvers.mbonus_material(4, 1), - combat_physresist = resolvers.mbonus_material(4, 1), - combat_spellresist = resolvers.mbonus_material(4, 1), - max_life = resolvers.mbonus_material(70, 40), + combat_mentalresist = resolvers.mbonus_material("save"), + combat_physresist = resolvers.mbonus_material("save"), + combat_spellresist = resolvers.mbonus_material("save"), + max_life = resolvers.mbonus_material("max_life"), }, } @@ -341,14 +341,31 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(5, 1), - [Stats.STAT_CUN] = resolvers.mbonus_material(5, 1), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - combat_atk = resolvers.mbonus_material(7, 3), - combat_apr = resolvers.mbonus_material(7, 3), + combat_atk = resolvers.mbonus_material("combat_atk"), + combat_apr = resolvers.mbonus_material("combat_apr"), }, } - +--[=[ +newEntity{ + power_source = {nature=true}, + name = "parasitic ", prefix=true, instant_resolve=true, + level_range = {30, 50}, + greater_ego = 1, + rarity = 30, + cost = 60, + wielder = { + inc_stats = { + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats", -2), + }, + poison_immune = resolvers.mbonus_material("immunity"), + resource_leech_chance = resolvers.mbonus_material("resource_leech_chance"), + resource_leech_value = resolvers.mbonus_material("resource_leech_value"), + }, +} +]=] newEntity{ power_source = {technique=true}, name = " of the guardian", suffix=true, instant_resolve=true, @@ -358,11 +375,11 @@ newEntity{ rarity = 35, cost = 40, wielder = { - combat_mentalresist = resolvers.mbonus_material(10, 5), - combat_physresist = resolvers.mbonus_material(10, 5), - combat_spellresist = resolvers.mbonus_material(10, 5), - combat_armor = resolvers.mbonus_material(7, 3), - combat_def = resolvers.mbonus_material(10, 5), + combat_mentalresist = resolvers.mbonus_material("save"), + combat_physresist = resolvers.mbonus_material("save"), + combat_spellresist = resolvers.mbonus_material("save"), + combat_armor = resolvers.mbonus_material("combat_armor"), + combat_def = resolvers.mbonus_material("combat_def"), }, } @@ -375,9 +392,9 @@ newEntity{ rarity = 35, cost = 70, wielder = { - max_mana = resolvers.mbonus_material(80, 20), - combat_spellpower = resolvers.mbonus_material(7, 3), - combat_spellcrit = resolvers.mbonus_material(3, 3), + max_mana = resolvers.mbonus_material("max_mana"), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), }, } @@ -390,10 +407,10 @@ newEntity{ rarity = 15, cost = 30, wielder = { - disarm_immune = resolvers.mbonus_material(15, 5, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(15, 5, function(e, v) v=v/100 return 0, v end), - combat_physcrit = resolvers.mbonus_material(4, 1), - combat_dam = resolvers.mbonus_material(4, 1), + disarm_immune = resolvers.mbonus_material("immunity"), + --confusion_immune = resolvers.mbonus_material("immunity"), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), + combat_dam = resolvers.mbonus_material("combat_dam"), }, } @@ -408,8 +425,8 @@ newEntity{ max_power = 80, power_regen = 1, use_talent = { id = Talents.T_BLINDING_SPEED, level = 3, power = 80 }, wielder = { - max_life = resolvers.mbonus_material(70, 40), - fatigue = resolvers.mbonus_material(6, 4, function(e, v) return 0, -v end), + max_life = resolvers.mbonus_material("max_life"), + fatigue = resolvers.mbonus_material("fatigue"), }, } @@ -422,9 +439,9 @@ newEntity{ rarity = 35, cost = 70, wielder = { - combat_critical_power = resolvers.mbonus_material(30, 10), - combat_atk = resolvers.mbonus_material(10, 5), - combat_apr = resolvers.mbonus_material(10, 5), - inc_stealth = resolvers.mbonus_material(10, 5), + --combat_critical_power = resolvers.mbonus_material("combat_critical_power"), + combat_atk = resolvers.mbonus_material("combat_atk"), + combat_apr = resolvers.mbonus_material("combat_apr"), + inc_stealth = resolvers.mbonus_material("inc_stealth"), }, } \ No newline at end of file diff --git a/game/modules/tome/data/general/objects/egos/digger.lua b/game/modules/tome/data/general/objects/egos/digger.lua index 1c41b21e1d..b35121137b 100644 --- a/game/modules/tome/data/general/objects/egos/digger.lua +++ b/game/modules/tome/data/general/objects/egos/digger.lua @@ -38,7 +38,7 @@ newEntity{ rarity = 6, cost = 10, wielder = { - inc_stats = { [Stats.STAT_STR] = resolvers.mbonus_material(4, 1) }, + inc_stats = { [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats") }, }, } @@ -51,10 +51,10 @@ newEntity{ rarity = 20, cost = 20, wielder = { - lite = 1, + lite = resolvers.mbonus_material("lite"), inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(3, 1), - [Stats.STAT_CON] = resolvers.mbonus_material(3, 1), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -67,7 +67,7 @@ newEntity{ rarity = 6, cost = 5, wielder = { - fatigue = resolvers.mbonus_material(6, 4, function(e, v) return 0, -v end), + fatigue = resolvers.mbonus_material("fatigue"), }, } @@ -79,7 +79,7 @@ newEntity{ rarity = 6, cost = 5, wielder = { - infravision = resolvers.mbonus_material(2, 1), + infravision = resolvers.mbonus_material("infravision"), }, } @@ -91,7 +91,7 @@ newEntity{ rarity = 6, cost = 5, wielder = { - resists = { [DamageType.NATURE] = resolvers.mbonus_material(5, 10), }, + resists = { [DamageType.NATURE] = resolvers.mbonus_material("resists"), }, }, } @@ -104,8 +104,8 @@ newEntity{ rarity = 15, cost = 15, wielder = { - max_life = resolvers.mbonus_material(20, 20), - max_stamina = resolvers.mbonus_material(15, 15), + max_life = resolvers.mbonus_material("max_life"), + max_stamina = resolvers.mbonus_material("max_stamina"), }, resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 3) end), } @@ -120,8 +120,8 @@ newEntity{ cost = 15, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(5, 5), - [DamageType.DARKNESS] = resolvers.mbonus_material(5, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, }, resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 3) end), @@ -136,9 +136,9 @@ newEntity{ rarity = 20, cost = 70, wielder = { - combat_dam = resolvers.mbonus_material(5, 5), - combat_apr = resolvers.mbonus_material(4, 4), - combat_critical_power = resolvers.mbonus_material(10, 10), + combat_dam = resolvers.mbonus_material("combat_dam", 2), + combat_apr = resolvers.mbonus_material("combat_apr"), + --combat_critical_power = resolvers.mbonus_material("combat_critical_power"), }, resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 3) end), } @@ -153,9 +153,9 @@ newEntity{ cost = 15, wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(2, 2), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - confusion_immune = resolvers.mbonus_material(3, 2, function(e, v) v=v/10 return 0, v end), + confusion_immune = resolvers.mbonus_material("immunity"), }, resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 3) end), } @@ -169,8 +169,8 @@ newEntity{ rarity = 15, cost = 15, wielder = { - combat_def = resolvers.mbonus_material(4, 4), - combat_armor = resolvers.mbonus_material(3, 2), + combat_def = resolvers.mbonus_material("combat_def"), + combat_armor = resolvers.mbonus_material("combat_armor"), }, resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 3) end), } @@ -186,10 +186,10 @@ newEntity{ resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 2) end), wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(7, 3), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats", 2), }, - combat_physcrit = resolvers.mbonus_material(5, 1), - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, -v end), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), + healing_factor = resolvers.mbonus_material("healing_factor", -1), }, } @@ -203,10 +203,10 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - max_mana = resolvers.mbonus_material(40, 20), - combat_spellcrit = resolvers.mbonus_material(4, 1), + max_mana = resolvers.mbonus_material("max_mana"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), }, } @@ -221,7 +221,7 @@ newEntity{ resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 3) end), wielder = { resists_pen = { - [DamageType.PHYSICAL] = resolvers.mbonus_material(10, 5), + [DamageType.PHYSICAL] = resolvers.mbonus_material("resists_pen"), }, }, } @@ -237,10 +237,10 @@ newEntity{ resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 2) end), wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - combat_atk = resolvers.mbonus_material(7, 3), - infravision = resolvers.mbonus_material(2, 1), + combat_atk = resolvers.mbonus_material("combat_atk"), + infravision = resolvers.mbonus_material("infravision"), }, } @@ -254,13 +254,29 @@ newEntity{ cost = 60, resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 2) end), wielder = { - combat_mentalresist = resolvers.mbonus_material(7, 3), - combat_physresist = resolvers.mbonus_material(7, 3), - combat_spellresist = resolvers.mbonus_material(7, 3), - max_life = resolvers.mbonus_material(70, 40), + combat_mentalresist = resolvers.mbonus_material("save"), + --combat_physresist = resolvers.mbonus_material("save"), + --combat_spellresist = resolvers.mbonus_material("save"), + max_life = resolvers.mbonus_material("max_life"), }, } - +--[=[ +newEntity{ + power_source = {technique=true}, + name = " of avarice", suffix=true, instant_resolve=true, + level_range = {40, 50}, + greater_ego = 1, + rarity = 45, + cost = 60, + resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 2) end), + wielder = { + blind_immune = resolvers.mbonus_material("immunity", -1), + combat_mentalresist = resolvers.mbonus_material("save", -1), + resource_leech_chance = resolvers.mbonus_material("resource_leech_chance"), + resource_leech_value = resolvers.mbonus_material("resource_leech_value"), + }, +} +]=] newEntity{ power_source = {arcane=true}, name = " of quickening", suffix=true, instant_resolve=true, @@ -285,10 +301,10 @@ newEntity{ resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 2) end), wielder = { inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(5, 1), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), }, - pin_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - combat_dam = resolvers.mbonus_material(7, 3), + pin_immune = resolvers.mbonus_material("immunity"), + combat_dam = resolvers.mbonus_material("combat_dam"), }, } @@ -303,11 +319,11 @@ newEntity{ resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 2) end), wielder = { resists={ - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, - blind_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - infravision = resolvers.mbonus_material(2, 1), + blind_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), + infravision = resolvers.mbonus_material("infravision"), }, } @@ -324,8 +340,8 @@ newEntity{ resolvers.generic(function(e) e.digspeed = math.ceil(e.digspeed / 2) end), wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(5, 1), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), }, - combat_apr = resolvers.mbonus_material(10, 5), + combat_apr = resolvers.mbonus_material("combat_apr"), }, } diff --git a/game/modules/tome/data/general/objects/egos/gloves.lua b/game/modules/tome/data/general/objects/egos/gloves.lua index b0f5000ae9..a971768b67 100644 --- a/game/modules/tome/data/general/objects/egos/gloves.lua +++ b/game/modules/tome/data/general/objects/egos/gloves.lua @@ -28,7 +28,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - disarm_bonus = resolvers.mbonus_material(25, 5), + disarm_bonus = resolvers.mbonus_material("disarm_bonus"), combat = { talent_on_hit = { [Talents.T_DISARM] = {level=2, chance=10} }, }, @@ -43,27 +43,25 @@ newEntity{ rarity = 9, cost = 15, wielder = { - combat_spellcrit = resolvers.mbonus_material(15, 5), - combat_physcrit = resolvers.mbonus_material(15, 5), - combat = { - physcrit = resolvers.mbonus_material(10, 4), - }, + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), + combat_mindcrit = resolvers.mbonus_material("combat_mindcrit"), }, } newEntity{ power_source = {technique=true}, - name = " of mighty criticals", suffix=true, instant_resolve=true, + name = " of might", suffix=true, instant_resolve=true, keywords = {critical=true}, level_range = {30, 50}, greater_ego = 1, rarity = 12, cost = 25, wielder = { - combat_critical_power = resolvers.mbonus_material(35, 5), + combat_dam = resolvers.mbonus_material("combat_dam"), combat = { - physcrit = resolvers.mbonus_material(10, 4), - dam = resolvers.mbonus_material(7, 3), + critical_power = resolvers.mbonus_material("critical_power"), + dam = resolvers.mbonus_material("dam"), talent_on_hit = { [Talents.T_HAYMAKER] = {level=1, chance=10} }, }, }, @@ -71,30 +69,30 @@ newEntity{ newEntity{ power_source = {technique=true}, - name = " of attack", suffix=true, instant_resolve=true, - keywords = {attack=true}, + name = " of precision", suffix=true, instant_resolve=true, + keywords = {precision=true}, level_range = {1, 50}, rarity = 5, cost = 5, wielder = { - combat_atk = resolvers.mbonus_material(15, 10), + combat_atk = resolvers.mbonus_material("combat_atk"), combat = { - atk = resolvers.mbonus_material(10, 4), + max_acc = resolvers.mbonus_material("max_acc"), }, }, } newEntity{ power_source = {technique=true}, - name = " of damage", suffix=true, instant_resolve=true, - keywords = {damage=true}, + name = " of power", suffix=true, instant_resolve=true, + keywords = {power=true}, level_range = {10, 50}, rarity = 7, cost = 10, wielder = { - combat_dam = resolvers.mbonus_material(15, 5), + combat_dam = resolvers.mbonus_material("combat_dam"), combat = { - dam = resolvers.mbonus_material(7, 3), + dam = resolvers.mbonus_material("dam"), }, }, } @@ -107,10 +105,10 @@ newEntity{ rarity = 3, cost = 5, wielder = { - inc_damage={ [DamageType.FIRE] = resolvers.mbonus_material(8, 3), }, - resists = { [DamageType.FIRE] = resolvers.mbonus_material(5, 5), }, + inc_damage={ [DamageType.FIRE] = resolvers.mbonus_material("inc_damage"), }, + resists = { [DamageType.FIRE] = resolvers.mbonus_material("resists"), }, combat = { - melee_project={[ DamageType.FIRE] = resolvers.mbonus_material(25, 4) }, + melee_project={[ DamageType.FIRE] = resolvers.mbonus_material("melee_project") }, }, }, } @@ -123,10 +121,10 @@ newEntity{ rarity = 3, cost = 5, wielder = { - inc_damage={ [DamageType.COLD] = resolvers.mbonus_material(8, 3), }, - resists = { [DamageType.COLD] = resolvers.mbonus_material(5, 5), }, + inc_damage={ [DamageType.COLD] = resolvers.mbonus_material("inc_damage"), }, + resists = { [DamageType.COLD] = resolvers.mbonus_material("resists"), }, combat = { - melee_project={ [DamageType.ICE] = resolvers.mbonus_material(15, 4) }, + melee_project={ [DamageType.ICE] = resolvers.mbonus_material("melee_project") }, }, }, } @@ -139,10 +137,10 @@ newEntity{ rarity = 3, cost = 5, wielder = { - inc_damage={ [DamageType.ACID] = resolvers.mbonus_material(8, 3), }, - resists = { [DamageType.ACID] = resolvers.mbonus_material(5, 5), }, + inc_damage={ [DamageType.ACID] = resolvers.mbonus_material("inc_damage"), }, + resists = { [DamageType.ACID] = resolvers.mbonus_material("resists"), }, combat = { - melee_project={ [DamageType.ACID] = resolvers.mbonus_material(25, 4) }, + melee_project={ [DamageType.ACID] = resolvers.mbonus_material("melee_project") }, }, }, } @@ -155,10 +153,10 @@ newEntity{ rarity = 3, cost = 5, wielder = { - inc_damage={ [DamageType.LIGHTNING] = resolvers.mbonus_material(8, 3), }, - resists = { [DamageType.LIGHTNING] = resolvers.mbonus_material(5, 5), }, + inc_damage={ [DamageType.LIGHTNING] = resolvers.mbonus_material("inc_damage"), }, + resists = { [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), }, combat = { - melee_project={ [DamageType.LIGHTNING] = resolvers.mbonus_material(25, 4) }, + melee_project={ [DamageType.LIGHTNING] = resolvers.mbonus_material("melee_project") }, }, }, } @@ -171,10 +169,10 @@ newEntity{ rarity = 3, cost = 5, wielder = { - inc_damage={ [DamageType.TEMPORAL] = resolvers.mbonus_material(8, 3), }, - resists = { [DamageType.TEMPORAL] = resolvers.mbonus_material(5, 5), }, + inc_damage={ [DamageType.TEMPORAL] = resolvers.mbonus_material("inc_damage"), }, + resists = { [DamageType.TEMPORAL] = resolvers.mbonus_material("resists"), }, combat = { - melee_project={ [DamageType.TEMPORAL] = resolvers.mbonus_material(15, 4) }, + melee_project={ [DamageType.TEMPORAL] = resolvers.mbonus_material("melee_project") }, }, }, } @@ -187,10 +185,10 @@ newEntity{ rarity = 3, cost = 5, wielder = { - inc_damage={ [DamageType.NATURE] = resolvers.mbonus_material(8, 3), }, - resists = { [DamageType.NATURE] = resolvers.mbonus_material(5, 5), }, + inc_damage={ [DamageType.NATURE] = resolvers.mbonus_material("inc_damage"), }, + resists = { [DamageType.NATURE] = resolvers.mbonus_material("resists"), }, combat = { - melee_project={ [DamageType.SLIME] = resolvers.mbonus_material(25, 4) }, + melee_project={ [DamageType.SLIME] = resolvers.mbonus_material("melee_project") }, }, }, } @@ -203,25 +201,10 @@ newEntity{ rarity = 3, cost = 5, wielder = { - inc_damage={ [DamageType.BLIGHT] = resolvers.mbonus_material(8, 3), }, - resists = { [DamageType.BLIGHT] = resolvers.mbonus_material(5, 5), }, - combat = { - melee_project={ [DamageType.BLIGHT] = resolvers.mbonus_material(25, 4) }, - }, - }, -} - -newEntity{ - power_source = {technique=true}, - name = "powerful ", prefix=true, instant_resolve=true, - keywords = {powerful=true}, - level_range = {1, 50}, - rarity = 3, - cost = 5, - wielder = { - inc_damage={ [DamageType.PHYSICAL] = resolvers.mbonus_material(8, 3), }, + inc_damage={ [DamageType.BLIGHT] = resolvers.mbonus_material("inc_damage"), }, + resists = { [DamageType.BLIGHT] = resolvers.mbonus_material("resists"), }, combat = { - melee_project={ [DamageType.PHYSICAL] = resolvers.mbonus_material(25, 4) }, + melee_project={ [DamageType.BLIGHT] = resolvers.mbonus_material("melee_project") }, }, }, } @@ -234,10 +217,9 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_STR] = resolvers.mbonus_material(4, 2) }, + inc_stats = { [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats") }, combat = { - dam = resolvers.mbonus_material(5, 1), - melee_project={ [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 4) }, + dam = resolvers.mbonus_material("dam"), }, }, } @@ -250,10 +232,9 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_DEX] = resolvers.mbonus_material(4, 2) }, + inc_stats = { [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats") }, combat = { - physcrit = resolvers.mbonus_material(8, 4), - atk = resolvers.mbonus_material(8, 4), + max_acc = resolvers.mbonus_material("max_acc"), }, }, } @@ -266,9 +247,9 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_MAG] = resolvers.mbonus_material(4, 2) }, + inc_stats = { [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats") }, combat = { - melee_project={ [DamageType.ARCANE] = resolvers.mbonus_material(15, 4) }, + melee_project={ [DamageType.ARCANE] = resolvers.mbonus_material("melee_project") }, }, }, } @@ -281,9 +262,9 @@ newEntity{ rarity = 9, cost = 15, wielder = { - talents_types_mastery = { ["technique/grappling"] = 0.2}, - inc_stats = { [Stats.STAT_STR] = resolvers.mbonus_material(2, 2) }, - disarm_immune = resolvers.mbonus_material(4, 4, function(e, v) v=v/10 return 0, v end), + talents_types_mastery = { ["technique/grappling"] = resolvers.mbonus_material("talents_types_mastery")}, + inc_stats = { [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats") }, + disarm_immune = resolvers.mbonus_material("immunity"), combat = { talent_on_hit = { [Talents.T_MAIM] = {level=2, chance=10} }, }, @@ -300,11 +281,9 @@ newEntity{ cost = 25, wielder = { resists={ - [DamageType.NATURE] = resolvers.mbonus_material(5, 5), + [DamageType.NATURE] = resolvers.mbonus_material("resists"), }, - combat_mentalresist = resolvers.mbonus_material(7, 3), - combat_physresist = resolvers.mbonus_material(7, 3), - combat_spellresist = resolvers.mbonus_material(7, 3), + combat_physresist = resolvers.mbonus_material("save", 2), combat = { talent_on_hit = { [Talents.T_HEALING_NEXUS] = {level=1, chance=10} }, }, @@ -321,13 +300,12 @@ newEntity{ cost = 35, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(3, 2), - [Stats.STAT_DEX] = resolvers.mbonus_material(3, 2), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), }, - combat_apr = resolvers.mbonus_material(4, 4), + combat_apr = resolvers.mbonus_material("combat_apr"), combat = { - physcrit = resolvers.mbonus_material(10, 4), - melee_project={ [DamageType.PHYSICAL] = resolvers.mbonus_material(25, 4) }, + critical_power = resolvers.mbonus_material("critical_power"), talent_on_hit = { [Talents.T_BATTLE_CALL] = {level=1, chance=10} }, }, }, @@ -343,9 +321,9 @@ newEntity{ rarity = 18, cost = 25, wielder = { - life_regen = resolvers.mbonus_material(15, 5, function(e, v) v=v/10 return 0, v end), - mana_regen = resolvers.mbonus_material(30, 10, function(e, v) v=v/100 return 0, v end), - stamina_regen = resolvers.mbonus_material(10, 3, function(e, v) v=v/10 return 0, v end), + life_regen = resolvers.mbonus_material("life_regen"), + mana_regen = resolvers.mbonus_material("mana_regen"), + stamina_regen = resolvers.mbonus_material("stamina_regen"), combat = { talent_on_hit = { [Talents.T_SECOND_WIND] = {level=1, chance=10} }, }, @@ -362,14 +340,13 @@ newEntity{ cost = 75, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, - max_life=resolvers.mbonus_material(40, 40), - combat_armor = resolvers.mbonus_material(3, 3), + max_life=resolvers.mbonus_material("max_life"), + combat_armor = resolvers.mbonus_material("combat_armor"), combat = { - dam = resolvers.mbonus_material(7, 3), - atk = resolvers.mbonus_material(10, 2), + dam = resolvers.mbonus_material("combat_dam"), talent_on_hit = { [Talents.T_BATTLE_SHOUT] = {level=1, chance=10} }, }, }, @@ -385,17 +362,17 @@ newEntity{ cost = 35, wielder = { inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(3, 2), - [Stats.STAT_WIL] = resolvers.mbonus_material(3, 2), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, - blind_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), + blind_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), combat = { melee_project={ - [DamageType.FIRE] = resolvers.mbonus_material(25, 4), - [DamageType.ICE] = resolvers.mbonus_material(15, 4), - [DamageType.ACID] = resolvers.mbonus_material(25, 4), - [DamageType.LIGHTNING] = resolvers.mbonus_material(25, 4), + [DamageType.FIRE] = resolvers.mbonus_material("melee_project", 0.5), + [DamageType.ICE] = resolvers.mbonus_material("melee_project", 0.5), + [DamageType.ACID] = resolvers.mbonus_material("melee_project", 0.5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("melee_project", 0.5), }, talent_on_hit = { [Talents.T_STONE_TOUCH] = {level=1, chance=10} }, }, @@ -413,13 +390,12 @@ newEntity{ cost = 35, wielder = { inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(3, 2), - [Stats.STAT_CUN] = resolvers.mbonus_material(3, 2), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - combat_atk = resolvers.mbonus_material(5, 5), + combat_atk = resolvers.mbonus_material("combat_atk"), combat = { - apr = resolvers.mbonus_material(8, 1), - atk = resolvers.mbonus_material(10, 2), + max_acc = resolvers.mbonus_material("max_acc"), }, }, } @@ -435,14 +411,13 @@ newEntity{ wielder = { talent_cd_reduction={ [Talents.T_DOUBLE_STRIKE]=1, }, inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(3, 2), - [Stats.STAT_DEX] = resolvers.mbonus_material(3, 2), - [Stats.STAT_CUN] = resolvers.mbonus_material(3, 2), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, combat = { - physcrit = resolvers.mbonus_material(10, 4), - atk = resolvers.mbonus_material(10, 2), - physspeed = -0.1, + critical_power = resolvers.mbonus_material("critical_power"), + physspeed = resolvers.mbonus_material("combat_physspeed"), }, }, } @@ -457,14 +432,14 @@ newEntity{ cost = 90, wielder = { resists={ - [DamageType.PHYSICAL] = resolvers.mbonus_material(7, 3), + [DamageType.PHYSICAL] = resolvers.mbonus_material("rare_resists"), }, inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(5, 1, function(e, v) return 0, -v end), - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats", -1), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - combat_armor = resolvers.mbonus_material(7, 3), - combat_atk = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), + combat_armor = resolvers.mbonus_material("combat_armor"), + combat_atk = resolvers.mbonus_material("combat_atk", -1), combat = { talent_on_hit = { [Talents.T_UNSTOPPABLE] = {level=1, chance=5} }, }, @@ -483,13 +458,13 @@ newEntity{ use_talent = { id = Talents.T_DISPERSE_MAGIC, level = 3, power = 80 }, wielder = { resists={ - [DamageType.ARCANE] = resolvers.mbonus_material(7, 3), + [DamageType.ARCANE] = resolvers.mbonus_material("rare_resists"), }, inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(7, 3), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), }, combat = { - melee_project={ [DamageType.ARCANE] = resolvers.mbonus_material(15, 4), }, + melee_project={ [DamageType.ARCANE] = resolvers.mbonus_material("melee_project"), }, talent_on_hit = { [Talents.T_MANATHRUST] = {level=3, chance=10} }, }, }, @@ -505,16 +480,15 @@ newEntity{ cost = 60, wielder = { resists={ - [DamageType.BLIGHT] = resolvers.mbonus_material(10, 5), + [DamageType.BLIGHT] = resolvers.mbonus_material("resists"), }, - poison_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - disease_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - combat_atk = resolvers.mbonus_material(7, 3), - combat_dam = resolvers.mbonus_material(7, 1), + poison_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), + combat_dam = resolvers.mbonus_material("combat_dam"), combat = { melee_project={ - [DamageType.SLIME] = resolvers.mbonus_material(15, 3), - [DamageType.ACID] = resolvers.mbonus_material(24, 4), + [DamageType.SLIME] = resolvers.mbonus_material("melee_project"), + [DamageType.ACID] = resolvers.mbonus_material("melee_project"), }, }, }, @@ -532,13 +506,11 @@ newEntity{ use_talent = { id = Talents.T_JUGGERNAUT, level = 4, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - combat_mentalresist = resolvers.mbonus_material(7, 3), - combat_physresist = resolvers.mbonus_material(7, 3), - combat_spellresist = resolvers.mbonus_material(7, 3), + combat_physresist = resolvers.mbonus_material("save"), + combat_spellresist = resolvers.mbonus_material("save"), combat = { - melee_project={ [DamageType.PHYSICAL] = resolvers.mbonus_material(25, 4), }, talent_on_hit = { [Talents.T_JUGGERNAUT] = {level=1, chance=10} }, }, }, @@ -556,13 +528,12 @@ newEntity{ use_talent = { id = Talents.T_TRACK, level = 2, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(5, 1), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), }, - combat_atk = resolvers.mbonus_material(7, 3), + combat_atk = resolvers.mbonus_material("combat_atk"), combat = { - physcrit = resolvers.mbonus_material(8, 4), - atk = resolvers.mbonus_material(8, 4), - inc_damage_type = {animal=25}, + max_acc = resolvers.mbonus_material("max_acc"), + inc_damage_type = {animal=resolvers.mbonus_material("inc_damage_type"),}, }, }, } @@ -577,15 +548,15 @@ newEntity{ cost = 40, wielder = { resists={ - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - blind_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - infravision = resolvers.mbonus_material(1, 1), + blind_immune = resolvers.mbonus_material("immunity"), + infravision = resolvers.mbonus_material("infravision"), combat = { - melee_project={ [DamageType.DARKNESS] = resolvers.mbonus_material(25, 4), }, + melee_project={ [DamageType.DARKNESS] = resolvers.mbonus_material("melee_project"), }, talent_on_hit = { [Talents.T_SHADOWSTEP] = {level=3, chance=10} }, }, }, @@ -601,12 +572,12 @@ newEntity{ cost = 30, wielder = { inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(5, 1), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, - combat_spellpower = resolvers.mbonus_material(7, 1), - combat_spellcrit = resolvers.mbonus_material(4, 1), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), combat = { - melee_project={ [DamageType.ARCANE] = resolvers.mbonus_material(15, 4), }, + melee_project={ [DamageType.ARCANE] = resolvers.mbonus_material("melee_project"), }, talent_on_hit = { [Talents.T_ELEMENTAL_BOLT] = {level=3, chance=10} }, }, }, @@ -621,18 +592,21 @@ newEntity{ rarity = 50, cost = 100, wielder = { - melee_project = { - [DamageType.ACID] = resolvers.mbonus_material(7, 3), - [DamageType.LIGHTNING] = resolvers.mbonus_material(7, 3), - [DamageType.FIRE] = resolvers.mbonus_material(7, 3), - [DamageType.COLD] = resolvers.mbonus_material(7, 3), + learn_talent = { + [Talents.T_WARD] = resolvers.mbonus_material("learn_talent"), + }, + wards = { + [DamageType.ACID] = resolvers.mbonus_material("wards"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("wards"), + [DamageType.FIRE] = resolvers.mbonus_material("wards"), + [DamageType.COLD] = resolvers.mbonus_material("wards"), }, combat = { melee_project={ - [DamageType.FIRE] = resolvers.mbonus_material(25, 4), - [DamageType.ICE] = resolvers.mbonus_material(15, 4), - [DamageType.ACID] = resolvers.mbonus_material(25, 4), - [DamageType.LIGHTNING] = resolvers.mbonus_material(25, 4), + [DamageType.FIRE] = resolvers.mbonus_material("melee_project"), + [DamageType.ICE] = resolvers.mbonus_material("melee_project"), + [DamageType.ACID] = resolvers.mbonus_material("melee_project"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("melee_project"), }, }, }, @@ -648,13 +622,13 @@ newEntity{ cost = 60, wielder = { inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(7, 3), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), }, - stun_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - pin_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), + pin_immune = resolvers.mbonus_material("immunity"), combat = { - melee_project={ [DamageType.PHYSICAL] = resolvers.mbonus_material(25, 4), }, + critical_power = resolvers.mbonus_material("critical_power"), talent_on_hit = { [Talents.T_SET_UP] = {level=1, chance=10} }, }, }, diff --git a/game/modules/tome/data/general/objects/egos/heavy-armor.lua b/game/modules/tome/data/general/objects/egos/heavy-armor.lua index 610797ba9d..b6c5080b4d 100644 --- a/game/modules/tome/data/general/objects/egos/heavy-armor.lua +++ b/game/modules/tome/data/general/objects/egos/heavy-armor.lua @@ -30,7 +30,7 @@ newEntity{ rarity = 8, cost = 7, wielder = { - combat_armor = resolvers.mbonus_material(12, 3), + combat_armor = resolvers.mbonus_material("combat_armor"), }, } @@ -44,16 +44,16 @@ newEntity{ cost = 80, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.LIGHT] = resolvers.mbonus_material(10, 10, function(e, v) return 0, -v end), - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.LIGHT] = resolvers.mbonus_material("resists", -1), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 5), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats", 2), }, - combat_mentalresist = resolvers.mbonus_material(5, 5), - combat_physresist = resolvers.mbonus_material(5, 5), - combat_spellresist = resolvers.mbonus_material(5, 5), - fatigue = resolvers.mbonus_material(10, 5), - }, -} \ No newline at end of file + combat_mentalresist = resolvers.mbonus_material("save", 2), + --combat_physresist = resolvers.mbonus_material(5, 5), + --combat_spellresist = resolvers.mbonus_material(5, 5), + fatigue = resolvers.mbonus_material("fatigue", -1), + }, +} diff --git a/game/modules/tome/data/general/objects/egos/helm.lua b/game/modules/tome/data/general/objects/egos/helm.lua index 20bec90f79..3324c1431a 100644 --- a/game/modules/tome/data/general/objects/egos/helm.lua +++ b/game/modules/tome/data/general/objects/egos/helm.lua @@ -33,7 +33,7 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_STR] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats") }, }, } newEntity{ @@ -44,7 +44,7 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_CON] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats") }, }, } newEntity{ @@ -55,7 +55,7 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_DEX] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats") }, }, } newEntity{ @@ -78,9 +78,9 @@ newEntity{ rarity = 10, cost = 10, wielder = { - inc_stats = { [Stats.STAT_WIL] = resolvers.mbonus_material(2, 1) }, - disease_immune = resolvers.mbonus_material(15, 10, function(e, v) return 0, v/100 end), - stun_immune = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), + inc_stats = { [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats") }, + disease_immune = resolvers.mbonus_material("immunity"), + stun_immune = resolvers.mbonus_material("immunity"), }, } newEntity{ @@ -92,8 +92,8 @@ newEntity{ cost = 7, wielder = { resists={ - [DamageType.LIGHT] = resolvers.mbonus_material(10, 10), - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 10), + [DamageType.LIGHT] = resolvers.mbonus_material("resists"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, }, } @@ -107,9 +107,9 @@ newEntity{ rarity = 18, cost = 25, wielder = { - combat_atk = resolvers.mbonus_material(4, 2), - combat_def = resolvers.mbonus_material(4, 2), - inc_stats = { [Stats.STAT_CUN] = 4, }, + combat_atk = resolvers.mbonus_material("combat_atk"), + combat_def = resolvers.mbonus_material("combat_def"), + inc_stats = { [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats") }, }, } @@ -133,9 +133,9 @@ newEntity{ rarity = 10, cost = 20, wielder = { - stamina_regen_on_hit = resolvers.mbonus_material(23, 7, function(e, v) v=v/10 return 0, v end), - equilibrium_regen_on_hit = resolvers.mbonus_material(23, 7, function(e, v) v=v/10 return 0, v end), - mana_regen_on_hit = resolvers.mbonus_material(23, 7, function(e, v) v=v/10 return 0, v end), + stamina_regen_on_hit = resolvers.mbonus_material("stamina_regen_on_hit"), + equilibrium_regen_on_hit = resolvers.mbonus_material("equilibrium_regen_on_hit"), + mana_regen_on_hit = resolvers.mbonus_material("mana_regen_on_hit"), }, } @@ -147,8 +147,8 @@ newEntity{ rarity = 6, cost = 5, wielder = { - infravision = resolvers.mbonus_material(3, 1), - combat_armor = resolvers.mbonus_material(5, 1), + infravision = resolvers.mbonus_material("infravision"), + combat_armor = resolvers.mbonus_material("combat_armor"), }, } @@ -161,8 +161,8 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -176,9 +176,9 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), }, - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), }, } @@ -191,9 +191,9 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), + [DamageType.TEMPORAL] = resolvers.mbonus_material("resists"), }, - teleport_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + teleport_immune = resolvers.mbonus_material("immunity"), }, } @@ -205,8 +205,8 @@ newEntity{ rarity = 6, cost = 5, wielder = { - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), }, } @@ -219,10 +219,10 @@ newEntity{ cost = 9, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), }, - poison_immune = resolvers.mbonus_material(10, 5, function(e, v) return 0, v/100 end), - disease_immune = resolvers.mbonus_material(10, 5, function(e, v) return 0, v/100 end), + poison_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), }, } @@ -236,10 +236,10 @@ newEntity{ rarity = 15, cost = 20, wielder = { - combat_spellcrit = resolvers.mbonus_material(3, 3), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(3, 2), - [Stats.STAT_WIL] = resolvers.mbonus_material(3, 2), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -254,10 +254,10 @@ newEntity{ rarity = 15, cost = 20, wielder = { - combat_physcrit = resolvers.mbonus_material(3, 3), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(3, 2), - [Stats.STAT_CON] = resolvers.mbonus_material(3, 2), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -271,10 +271,10 @@ newEntity{ rarity = 13, cost = 20, wielder = { - combat_apr = resolvers.mbonus_material(4, 4), + combat_apr = resolvers.mbonus_material("combat_apr"), inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(3, 2), - [Stats.STAT_CUN] = resolvers.mbonus_material(3, 2), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -288,10 +288,10 @@ newEntity{ rarity = 17, cost = 50, wielder = { - combat_dam = resolvers.mbonus_material(6, 6), - pin_immune = resolvers.mbonus_material(3, 3, function(e, v) v=v/10 return 0, v end), + combat_dam = resolvers.mbonus_material("combat_dam"), + pin_immune = resolvers.mbonus_material("immunity"), inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(4, 3), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -305,9 +305,9 @@ newEntity{ rarity = 17, cost = 50, wielder = { - combat_armor = resolvers.mbonus_material(5, 4), - combat_def = resolvers.mbonus_material(4, 4), - combat_physresist = resolvers.mbonus_material(7, 3), + combat_armor = resolvers.mbonus_material("combat_armor"), + combat_def = resolvers.mbonus_material("combat_def"), + combat_physresist = resolvers.mbonus_material("save"), }, } @@ -321,10 +321,10 @@ newEntity{ cost = 50, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -339,15 +339,15 @@ newEntity{ cost = 80, wielder = { resists={ - [DamageType.LIGHT] = resolvers.mbonus_material(25, 15, function(e, v) return 0, -v end), + [DamageType.LIGHT] = resolvers.mbonus_material("resists", -1), }, inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(4, 1), - [Stats.STAT_DEX] = resolvers.mbonus_material(4, 1), - [Stats.STAT_CON] = resolvers.mbonus_material(4, 1), - [Stats.STAT_CUN] = resolvers.mbonus_material(4, 1), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - life_regen = resolvers.mbonus_material(30, 5, function(e, v) v=v/10 return 0, v end), + life_regen = resolvers.mbonus_material("life_regen"), }, } @@ -361,11 +361,11 @@ newEntity{ cost = 40, wielder = { resists={ - [DamageType.MIND] = resolvers.mbonus_material(15, 5), + [DamageType.MIND] = resolvers.mbonus_material("rare_resists"), }, - blind_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - combat_mentalresist = resolvers.mbonus_material(7, 3), + blind_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), + combat_mentalresist = resolvers.mbonus_material("save"), }, } @@ -379,11 +379,11 @@ newEntity{ cost = 30, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(5, 1), - [Stats.STAT_WIL] = resolvers.mbonus_material(5, 1), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - lite = resolvers.mbonus_material(1, 1), + confusion_immune = resolvers.mbonus_material("immunity"), + lite = resolvers.mbonus_material("lite"), }, } @@ -397,12 +397,12 @@ newEntity{ cost = 80, wielder = { resists={ - [DamageType.NATURE] = resolvers.mbonus_material(10, 5), + [DamageType.NATURE] = resolvers.mbonus_material("resists"), }, - poison_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - disease_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - max_life = resolvers.mbonus_material(70, 40), - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + poison_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), + max_life = resolvers.mbonus_material("max_life"), + healing_factor = resolvers.mbonus_material("healing_factor"), }, } @@ -416,12 +416,12 @@ newEntity{ cost = 40, wielder = { resists={ - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(7, 3), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), }, - infravision = resolvers.mbonus_material(3, 1), + infravision = resolvers.mbonus_material("infravision"), }, } @@ -435,16 +435,16 @@ newEntity{ cost = 100, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), - [Stats.STAT_MAG] = resolvers.mbonus_material(5, 3), - [Stats.STAT_WIL] = resolvers.mbonus_material(5, 3), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats", -1), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, - combat_spellcrit = resolvers.mbonus_material(4, 1), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), inc_damage = { - [DamageType.BLIGHT] = resolvers.mbonus_material(15, 5), - [DamageType.ARCANE] = resolvers.mbonus_material(15, 5), + [DamageType.BLIGHT] = resolvers.mbonus_material("inc_damage"), + [DamageType.ARCANE] = resolvers.mbonus_material("inc_damage"), }, - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, -v end), + healing_factor = resolvers.mbonus_material("healing_factor", -1), }, } @@ -458,10 +458,10 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_LCK] = resolvers.mbonus_material(7, 3), + [Stats.STAT_LCK] = resolvers.mbonus_material("inc_stats"), }, - combat_physcrit = resolvers.mbonus_material(4, 1), - combat_spellcrit = resolvers.mbonus_material(4, 1), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), }, } @@ -477,10 +477,10 @@ newEntity{ use_talent = { id = Talents.T_CIRCLE_OF_SANCTITY, level = 4, power = 80 }, wielder = { resists={ - [DamageType.BLIGHT] = resolvers.mbonus_material(10, 5), - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + [DamageType.BLIGHT] = resolvers.mbonus_material("resists"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), + confusion_immune = resolvers.mbonus_material("immunity"), }, } @@ -496,9 +496,26 @@ newEntity{ use_talent = { id = Talents.T_BATTLE_CRY, level = 2, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(5, 1), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats", 2), }, - combat_mentalresist = resolvers.mbonus_material(7, 3), - combat_physresist = resolvers.mbonus_material(7, 3), + --combat_mentalresist = resolvers.mbonus_material("save"), + combat_physresist = resolvers.mbonus_material("save"), }, } +--[=[ +newEntity{ + power_source = {technique=true}, + name = " of hoarding", suffix=true, instant_resolve=true, + level_range = {40, 50}, + greater_ego = 1, + rarity = 40, + cost = 40, + wielder = { + inc_stats = { + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), + }, + resource_leech_chance = resolvers.mbonus_material("resource_leech_chance"), + resource_leech_value = resolvers.mbonus_material("resource_leech_value"), + }, +} +]=] diff --git a/game/modules/tome/data/general/objects/egos/light-armor.lua b/game/modules/tome/data/general/objects/egos/light-armor.lua index 085bded9bc..4384612ca7 100644 --- a/game/modules/tome/data/general/objects/egos/light-armor.lua +++ b/game/modules/tome/data/general/objects/egos/light-armor.lua @@ -31,7 +31,7 @@ newEntity{ rarity = 12, cost = 14, wielder = { - life_regen = resolvers.mbonus_material(60, 15, function(e, v) v=v/10 return 0, v end), + life_regen = resolvers.mbonus_material("life_regen", 4), }, } @@ -44,8 +44,8 @@ newEntity{ rarity = 22, cost = 35, wielder = { - combat_def_ranged = resolvers.mbonus_material(8, 2), - movement_speed = 0.1, - inc_stats = { [Stats.STAT_DEX] = resolvers.mbonus_material(3, 2), }, + --combat_def_ranged = resolvers.mbonus_material("combat_def_ranged"), + movement_speed = resolvers.mbonus_material("movement_speed"), + inc_stats = { [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), }, }, } diff --git a/game/modules/tome/data/general/objects/egos/light-boots.lua b/game/modules/tome/data/general/objects/egos/light-boots.lua index caa2757e28..b4b517c9bd 100644 --- a/game/modules/tome/data/general/objects/egos/light-boots.lua +++ b/game/modules/tome/data/general/objects/egos/light-boots.lua @@ -31,6 +31,6 @@ newEntity{ rarity = 5, cost = 6, wielder = { - inc_stealth = resolvers.mbonus_material(10, 5), + inc_stealth = resolvers.mbonus_material("inc_stealth"), }, } diff --git a/game/modules/tome/data/general/objects/egos/lite.lua b/game/modules/tome/data/general/objects/egos/lite.lua index a8063f571c..98746e115e 100644 --- a/game/modules/tome/data/general/objects/egos/lite.lua +++ b/game/modules/tome/data/general/objects/egos/lite.lua @@ -30,7 +30,7 @@ newEntity{ rarity = 5, cost = 1, wielder = { - lite=1, + lite = resolvers.mbonus_material("lite"), }, } @@ -42,7 +42,7 @@ newEntity{ rarity = 5, cost = 1, wielder = { - blind_immune=resolvers.mbonus_material(3, 3, function(e, v) v=v/10 return 0, v end), + blind_immune = resolvers.mbonus_material("immunity"), }, } @@ -55,9 +55,9 @@ newEntity{ rarity = 9, cost = 10, wielder = { - blind_immune=resolvers.mbonus_material(3, 3, function(e, v) v=v/10 return 0, v end), - combat_spellresist = 15, - lite=1, + blind_immune = resolvers.mbonus_material("immunity"), + combat_spellresist = resolvers.mbonus_material("save"), + lite = resolvers.mbonus_material("lite"), }, } @@ -69,7 +69,7 @@ newEntity{ rarity = 5, cost = 4, wielder = { - on_melee_hit={[DamageType.FIRE] = resolvers.mbonus_material(20, 10)}, + on_melee_hit={[DamageType.FIRE] = resolvers.mbonus_material("on_melee_hit")}, }, } @@ -81,9 +81,9 @@ newEntity{ rarity = 7, cost = 10, wielder = { - lite = 1, - see_invisible = resolvers.mbonus_material(20, 5), - trap_detect_power = resolvers.mbonus_material(15, 10), + lite = resolvers.mbonus_material("lite"), + see_invisible = resolvers.mbonus_material("see_invisible"), + trap_detect_power = resolvers.mbonus_material("trap_detect_power"), }, } @@ -95,7 +95,7 @@ newEntity{ rarity = 7, cost = 10, wielder = { - confusion_immune = resolvers.mbonus_material(3, 2, function(e, v) v=v/10 return 0, v end), + confusion_immune = resolvers.mbonus_material("immunity"), }, } @@ -107,7 +107,7 @@ newEntity{ rarity = 7, cost = 10, wielder = { - max_life=resolvers.mbonus_material(40, 40), + max_life=resolvers.mbonus_material("max_life"), }, } @@ -120,7 +120,7 @@ newEntity{ cost = 10, wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(4, 3), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -133,8 +133,8 @@ newEntity{ rarity = 9, cost = 12, wielder = { - lite = -2, - infravision = resolvers.mbonus_material(2, 1), + lite = resolvers.mbonus_material("lite", -1), + infravision = resolvers.mbonus_material("infravision"), }, } @@ -146,7 +146,7 @@ newEntity{ rarity = 9, cost = 12, wielder = { - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), }, } @@ -158,7 +158,7 @@ newEntity{ rarity = 9, cost = 12, wielder = { - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + healing_factor = resolvers.mbonus_material("healing_factor"), }, } @@ -170,7 +170,7 @@ newEntity{ rarity = 9, cost = 12, wielder = { - combat_mentalresist = resolvers.mbonus_material(15, 5), + combat_mentalresist = resolvers.mbonus_material("save"), }, } @@ -184,10 +184,10 @@ newEntity{ cost = 30, wielder = { resists={ - [DamageType.LIGHT] = resolvers.mbonus_material(10, 5), - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHT] = resolvers.mbonus_material("resists"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, - blind_immune = resolvers.mbonus_material(30, 10, function(e, v) v=v/100 return 0, v end), + blind_immune = resolvers.mbonus_material("immunity"), }, } @@ -200,10 +200,10 @@ newEntity{ rarity = 10, cost = 50, wielder = { - combat_dam = resolvers.mbonus_material(5, 5), - combat_physcrit = resolvers.mbonus_material(3, 3), + combat_dam = resolvers.mbonus_material("combat_dam"), + combat_physcrit = resolvers.mbonus_material("combat_physcrit"), inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(4, 3), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -218,9 +218,9 @@ newEntity{ cost = 50, encumber = -1, wielder = { - lite = 2, + lite = resolvers.mbonus_material("lite"), inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(3, 3), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -234,10 +234,10 @@ newEntity{ rarity = 10, cost = 50, wielder = { - combat_def = resolvers.mbonus_material(4, 4), - combat_mentalresist = resolvers.mbonus_material(10, 5), - combat_physresist = resolvers.mbonus_material(10, 5), - combat_spellresist = resolvers.mbonus_material(10, 5), + combat_def = resolvers.mbonus_material("combat_def", 2), + --combat_mentalresist = resolvers.mbonus_material("save"), + combat_physresist = resolvers.mbonus_material("save"), + --combat_spellresist = resolvers.mbonus_material("save"), }, } @@ -250,9 +250,9 @@ newEntity{ rarity = 10, cost = 50, wielder = { - combat_spellpower = resolvers.mbonus_material(3, 3), - combat_spellcrit = resolvers.mbonus_material(3, 3), - see_invisible = resolvers.mbonus_material(10, 5), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), + see_invisible = resolvers.mbonus_material("see_invisible"), }, } @@ -266,11 +266,11 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_LCK] = resolvers.mbonus_material(5, 5, function(e, v) return 0, -v end), - [Stats.STAT_DEX] = resolvers.mbonus_material(9, 1), - [Stats.STAT_CON] = resolvers.mbonus_material(9, 1), - [Stats.STAT_WIL] = resolvers.mbonus_material(5, 5, function(e, v) return 0, -v end), - [Stats.STAT_CUN] = resolvers.mbonus_material(9, 1), + [Stats.STAT_LCK] = resolvers.mbonus_material("inc_stats", -1), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats", 2), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats", -1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats", 2), }, }, } @@ -284,10 +284,10 @@ newEntity{ rarity = 30, cost = 40, wielder = { - stun_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - pin_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - lite = resolvers.mbonus_material(1, 1), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), + pin_immune = resolvers.mbonus_material("immunity"), + lite = resolvers.mbonus_material("lite"), }, } @@ -300,10 +300,10 @@ newEntity{ rarity = 20, cost = 40, wielder = { - combat_spellpower = resolvers.mbonus_material(6, 1), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), inc_damage = { - [DamageType.LIGHT] = resolvers.mbonus_material(10, 5), - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHT] = resolvers.mbonus_material("inc_damage"), + [DamageType.DARKNESS] = resolvers.mbonus_material("inc_damage"), }, }, } @@ -317,11 +317,11 @@ newEntity{ rarity = 20, cost = 40, wielder = { - combat_apr = resolvers.mbonus_material(10, 5), + combat_apr = resolvers.mbonus_material("combat_apr"), resists_pen = { - [DamageType.PHYSICAL] = resolvers.mbonus_material(10, 5), + [DamageType.PHYSICAL] = resolvers.mbonus_material("resists_pen"), }, - lite = resolvers.mbonus_material(1, 1), + lite = resolvers.mbonus_material("lite"), }, } @@ -335,11 +335,11 @@ newEntity{ cost = 20, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - poison_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - disease_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - life_regen = resolvers.mbonus_material(27, 3, function(e, v) v=v/10 return 0, v end), + poison_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), + life_regen = resolvers.mbonus_material("life_regen"), }, } @@ -354,11 +354,11 @@ newEntity{ max_power = 80, power_regen = 1, use_talent = { id = Talents.T_ARCANE_EYE, level = 2, power = 80 }, wielder = { - blind_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, -v end), - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, -v end), + blind_immune = resolvers.mbonus_material("immunity", -1), + confusion_immune = resolvers.mbonus_material("immunity", -1), inc_damage = { - [DamageType.LIGHTNING] = resolvers.mbonus_material(15, 5), - [DamageType.FIRE] = resolvers.mbonus_material(15, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("inc_damage"), + [DamageType.FIRE] = resolvers.mbonus_material("inc_damage"), }, }, } @@ -385,13 +385,13 @@ newEntity{ cost = 40, wielder = { resists={ - [DamageType.LIGHT] = resolvers.mbonus_material(7, 3), - [DamageType.DARKNESS] = resolvers.mbonus_material(7, 3), + [DamageType.LIGHT] = resolvers.mbonus_material("resists"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, resists_pen = { - [DamageType.LIGHT] = resolvers.mbonus_material(7, 3), - [DamageType.DARKNESS] = resolvers.mbonus_material(7, 3), + [DamageType.LIGHT] = resolvers.mbonus_material("resists_pen"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists_pen"), }, }, } @@ -407,7 +407,7 @@ newEntity{ max_power = 80, power_regen = 1, use_talent = { id = Talents.T_MOONLIGHT_RAY, level = 4, power = 80 }, wielder = { - combat_spellpower = resolvers.mbonus_material(7, 3), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), }, } @@ -423,7 +423,7 @@ newEntity{ use_talent = { id = Talents.T_GLYPH_OF_REPULSION, level = 3, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(5, 1), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), }, }, } diff --git a/game/modules/tome/data/general/objects/egos/massive-armor.lua b/game/modules/tome/data/general/objects/egos/massive-armor.lua index 3e132f18a0..eb7f0abe49 100644 --- a/game/modules/tome/data/general/objects/egos/massive-armor.lua +++ b/game/modules/tome/data/general/objects/egos/massive-armor.lua @@ -29,23 +29,23 @@ newEntity{ keywords = {dragon=true}, level_range = {20, 50}, greater_ego = 1, - rarity = 20, + rarity = 40, cost = 60, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), - [DamageType.PHYSICAL] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), + [DamageType.PHYSICAL] = resolvers.mbonus_material("resists"), }, inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), - [Stats.STAT_STR] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), }, - stun_immune = resolvers.mbonus_material(20, 20, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(20, 20, function(e, v) v=v/100 return 0, v end), - disarm_immune = resolvers.mbonus_material(20, 20, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), + disarm_immune = resolvers.mbonus_material("immunity"), talent_cd_reduction={[Talents.T_RUSH]=5}, }, } @@ -59,6 +59,6 @@ newEntity{ rarity = 8, cost = 7, wielder = { - combat_armor = resolvers.mbonus_material(12, 3), + combat_armor = resolvers.mbonus_material("combat_armor"), }, } diff --git a/game/modules/tome/data/general/objects/egos/ranged.lua b/game/modules/tome/data/general/objects/egos/ranged.lua new file mode 100644 index 0000000000..fb579a3551 --- /dev/null +++ b/game/modules/tome/data/general/objects/egos/ranged.lua @@ -0,0 +1,277 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org +local Talents = require("engine.interface.ActorTalents") +local Stats = require("engine.interface.ActorStats") + + + +newEntity{ + power_source = {technique=true}, + name = " of power", suffix=true, instant_resolve=true, + keywords = {power=true}, + level_range = {1, 50}, + rarity = 3, + cost = 6, + combat={apr = resolvers.mbonus_material("combat_apr", 4)}, +} + +newEntity{ + power_source = {technique=true}, + name = "mighty ", prefix=true, instant_resolve=true, + keywords = {mighty=true}, + level_range = {1, 50}, + rarity = 3, + cost = 4, + combat = { + dam = resolvers.mbonus_material("dam"), + }, +} + +newEntity{ + power_source = {technique=true}, + name = "steady ", prefix=true, instant_resolve=true, + keywords = {steady=true}, + level_range = {1, 50}, + rarity = 9, + cost = 10, + wielder = { + learn_talent = { + [Talents.T_STEADY_SHOT] = resolvers.mbonus_material("learn_talent"), + }, + }, +} + +newEntity{ + power_source = {technique=true}, + name = " of crippling", suffix=true, instant_resolve=true, + keywords = {crippling=true}, + level_range = {1, 50}, + rarity = 7, + cost = 7, + combat = { + critical_power = resolvers.mbonus_material("critical_power"), + } +} + +newEntity{ + power_source = {technique=true}, + name = " of speed", suffix=true, instant_resolve=true, + keywords = {speed=true}, + level_range = {20, 50}, + rarity = 7, + cost = 7, + combat = { + physspeed = resolvers.mbonus_material("physspeed", -1), + }, +} + +newEntity{ + power_source = {technique=true}, + name = "tracker's ", prefix=true, instant_resolve=true, + keywords = {tracker=true}, + level_range = {1, 50}, + rarity = 9, + cost = 10, + wielder = { + learn_talent = { + [Talents.T_TRACK] = resolvers.mbonus_material("learn_talent"), + }, + }, +} + +newEntity{ + power_source = {technique=true}, + name = " of range", suffix=true, instant_resolve=true, + keywords = {range=true}, + level_range = {1, 50}, + rarity = 9, + cost = 10, + resolvers.generic(function(e) + e.combat.range = e.combat.range + 1 + end), +} + +newEntity{ + power_source = {technique=true}, + name = "swiftstrike ", prefix=true, instant_resolve=true, + keywords = {swiftstrike=true}, + level_range = {1, 50}, + rarity = 9, + cost = 10, + combat = {travel_speed = 200,}, +} + +newEntity{ + power_source = {technique=true}, + name = " of true flight", suffix=true, instant_resolve=true, + keywords = {flight=true}, + level_range = {30, 50}, + greater_ego = 1, + rarity = 20, + cost = 40, + combat = { + critical_power = resolvers.mbonus_material("critical_power"), + travel_speed = 200 + }, + resolvers.generic(function(e) + e.combat.range = e.combat.range + 1 + end), +} + +newEntity{ + power_source = {technique=true}, + name = "penetrating ", prefix=true, instant_resolve=true, + keywords = {penetrating=true}, + level_range = {30, 50}, + greater_ego = 1, + rarity = 20, + cost = 40, + combat = { + apr = resolvers.mbonus_material("combat_apr", 4), + }, + wielder = { + resists_pen = { + [DamageType.PHYSICAL] = resolvers.mbonus_material("resists_pen", 2), + }, + learn_talent = { + [Talents.T_PIERCING_ARROW] = resolvers.mbonus_material("learn_talent"), + }, + }, +} + +newEntity{ + power_source = {technique=true}, + name = "phase-shifting ", prefix=true, instant_resolve=true, + keywords = {phase=true}, + level_range = {10, 50}, + greater_ego = 1, + rarity = 30, + cost = 80, + combat = { + tg_type = "beam", + }, + resolvers.generic(function(e) + e.combat.dam = 0 + e.combat.dammod = {dex=0} + end), +} + +newEntity{ + power_source = {technique=true}, + name = " of concussion", suffix=true, instant_resolve=true, + keywords = {concussion=true}, + level_range = {10, 50}, + greater_ego = 1, + rarity = 40, + cost = 40, + resolvers.generic(function(e) + e.combat.concussion = (e.combat.critical_power - 1) * 100 + end), +} + +newEntity{ + power_source = {arcane=true}, + name = " of spellstriking", suffix=true, instant_resolve=true, + keywords = {spellstrike=true}, + level_range = {20, 50}, + greater_ego = 1, + rarity = 20, + cost = 30, + combat = { + affects_spells = true, + talent_on_hit = { + [Talents.T_DISPERSE_MAGIC] = { + level=3, + chance = resolvers.mbonus_material("talent_on_hit_chance"), + } , + }, + }, + resolvers.generic(function(e) + e.combat.dammod.mag = e.combat.dammod.dex + end), +} + +newEntity{ + power_source = {arcane=true}, + name = " of torment", suffix=true, instant_resolve=true, + keywords = {torment=true}, + level_range = {1, 50}, + rarity = 18, + cost = 22, + combat = { + special_on_hit = {desc="30% chance to torment the target", fct=function(combat, who, target) + if not rng.percent(30) then return end + local eff = rng.table{"stun", "blind", "pin", "confusion", "silence"} + if not target:canBe(eff) then return end + if not target:checkHit(who:combatAttack(combat), target:combatPhysicalResist(), 15) then return end + if eff == "stun" then target:setEffect(target.EFF_STUNNED, 3, {}) + elseif eff == "blind" then target:setEffect(target.EFF_BLINDED, 3, {}) + elseif eff == "pin" then target:setEffect(target.EFF_PINNED, 3, {}) + elseif eff == "confusion" then target:setEffect(target.EFF_CONFUSED, 3, {power=60}) + elseif eff == "silence" then target:setEffect(target.EFF_SILENCED, 3, {}) + end + end}, + }, +} + +newEntity{ + power_source = {nature=true}, + name = "voracious ", prefix=true, instant_resolve=true, + keywords = {voracious=true}, + level_range = {1, 50}, + greater_ego = 1, + rarity = 60, + cost = 40, + wielder = { + resource_leech_chance = resolvers.mbonus_material("resource_leech_chance"), + resource_leech_value = resolvers.mbonus_material("resource_leech_value", 2), + }, + max_power = 20, power_regen = 1, + use_talent = { id = Talents.T_THERMAL_LEECH, level = 5, power = 20 }, +} + +newEntity{ + power_source = {technique=true}, + name = " of savagery", suffix=true, instant_resolve=true, + keywords = {savage=true}, + level_range = {30, 50}, + greater_ego = 1, + rarity = 20, + cost = 40, + wielder = { + learn_talent = { + [Talents.T_SAVAGERY] = resolvers.mbonus_material("learn_talent_5"), + }, + }, +} + +newEntity{ + power_source = {technique=true}, + name = " of sacrifice", suffix=true, instant_resolve=true, + keywords = {sacrifice=true}, + level_range = {20, 50}, + greater_ego = 1, + rarity = 20, + cost = 40, + max_power = 30, power_regen = 1, + use_talent = { id = Talents.T_LIFE_TAP, level = 5, power = 30 }, + combat = { + dam = resolvers.mbonus_material("dam", 2, true), + }, +} diff --git a/game/modules/tome/data/general/objects/egos/rings.lua b/game/modules/tome/data/general/objects/egos/rings.lua index 5da83654c7..242b818378 100644 --- a/game/modules/tome/data/general/objects/egos/rings.lua +++ b/game/modules/tome/data/general/objects/egos/rings.lua @@ -33,7 +33,7 @@ newEntity{ rarity = 4, cost = 2, wielder = { - see_invisible = resolvers.mbonus_material(20, 5), + see_invisible = resolvers.mbonus_material("see_invisible"), }, } @@ -45,7 +45,7 @@ newEntity{ rarity = 10, cost = 8, wielder = { - life_regen = resolvers.mbonus_material(30, 5, function(e, v) v=v/10 return 0, v end), + life_regen = resolvers.mbonus_material("life_regen"), }, } @@ -57,117 +57,120 @@ newEntity{ rarity = 8, cost = 3, wielder = { - mana_regen = resolvers.mbonus_material(30, 10, function(e, v) v=v/100 return 0, v end), + mana_regen = resolvers.mbonus_material("mana_regen"), }, } newEntity{ power_source = {arcane=true}, - name = " of fire (#RESIST#)", suffix=true, instant_resolve=true, + name = " of fire (#DAMBONUS#)", suffix=true, instant_resolve=true, keywords = {fire=true}, level_range = {10, 40}, rarity = 6, cost = 2, wielder = { - inc_damage = { [DamageType.FIRE] = resolvers.mbonus_material(10, 10) }, - resists = {}, + inc_damage = { [DamageType.FIRE] = resolvers.mbonus_material("inc_damage") }, + wards = {[DamageType.FIRE] = resolvers.mbonus_material("wards")}, + learn_talent = {[Talents.T_WARD] = resolvers.mbonus_material("learn_talent")}, }, - resolvers.genericlast(function(e) e.wielder.resists[engine.DamageType.FIRE] = (e.wielder.resists[engine.DamageType.FIRE] or 0) + e.wielder.inc_damage[engine.DamageType.FIRE] end), } newEntity{ power_source = {arcane=true}, - name = " of time (#RESIST#)", suffix=true, instant_resolve=true, + name = " of time (#DAMBONUS#)", suffix=true, instant_resolve=true, keywords = {time=true}, level_range = {10, 40}, rarity = 6, cost = 2, wielder = { - inc_damage = { [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 10) }, - resists = {}, + inc_damage = { [DamageType.TEMPORAL] = resolvers.mbonus_material("inc_damage") }, + wards = {[DamageType.TEMPORAL] = resolvers.mbonus_material("wards")}, + learn_talent = {[Talents.T_WARD] = resolvers.mbonus_material("learn_talent")}, }, - resolvers.genericlast(function(e) e.wielder.resists[engine.DamageType.TEMPORAL] = (e.wielder.resists[engine.DamageType.TEMPORAL] or 0) + e.wielder.inc_damage[engine.DamageType.TEMPORAL] end), } newEntity{ power_source = {arcane=true}, - name = " of frost (#RESIST#)", suffix=true, instant_resolve=true, + name = " of frost (#DAMBONUS#)", suffix=true, instant_resolve=true, keywords = {frost=true}, level_range = {10, 40}, rarity = 6, cost = 2, wielder = { - inc_damage = { [DamageType.COLD] = resolvers.mbonus_material(10, 10) }, - resists = {}, + inc_damage = { [DamageType.COLD] = resolvers.mbonus_material("inc_damage") }, + wards = {[DamageType.COLD] = resolvers.mbonus_material("wards")}, + learn_talent = {[Talents.T_WARD] = resolvers.mbonus_material("learn_talent")}, }, - resolvers.genericlast(function(e) e.wielder.resists[engine.DamageType.COLD] = (e.wielder.resists[engine.DamageType.COLD] or 0) + e.wielder.inc_damage[engine.DamageType.COLD] end), } newEntity{ power_source = {nature=true}, - name = " of nature (#RESIST#)", suffix=true, instant_resolve=true, + name = " of nature (#DAMBONUS#)", suffix=true, instant_resolve=true, keywords = {nature=true}, level_range = {10, 40}, rarity = 6, cost = 2, wielder = { - inc_damage = { [DamageType.NATURE] = resolvers.mbonus_material(10, 10) }, - resists = {}, + inc_damage = { [DamageType.NATURE] = resolvers.mbonus_material("inc_damage") }, + wards = {[DamageType.NATURE] = resolvers.mbonus_material("wards")}, + learn_talent = {[Talents.T_WARD] = resolvers.mbonus_material("learn_talent")}, }, - resolvers.genericlast(function(e) e.wielder.resists[engine.DamageType.NATURE] = (e.wielder.resists[engine.DamageType.NATURE] or 0) + e.wielder.inc_damage[engine.DamageType.NATURE] end), } newEntity{ power_source = {arcane=true}, - name = " of lightning (#RESIST#)", suffix=true, instant_resolve=true, + name = " of lightning (#DAMBONUS#)", suffix=true, instant_resolve=true, keywords = {lightning=true}, level_range = {10, 40}, rarity = 6, cost = 2, wielder = { - inc_damage = { [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 10) }, - resists = {}, + inc_damage = { [DamageType.LIGHTNING] = resolvers.mbonus_material("inc_damage") }, + wards = {[DamageType.LIGHTNING] = resolvers.mbonus_material("wards")}, + learn_talent = {[Talents.T_WARD] = resolvers.mbonus_material("learn_talent")}, }, - resolvers.genericlast(function(e) e.wielder.resists[engine.DamageType.LIGHTNING] = (e.wielder.resists[engine.DamageType.LIGHTNING] or 0) + e.wielder.inc_damage[engine.DamageType.LIGHTNING] end), + } newEntity{ power_source = {nature=true}, - name = " of corrosion (#RESIST#)", suffix=true, instant_resolve=true, + name = " of corrosion (#DAMBONUS#)", suffix=true, instant_resolve=true, keywords = {corrosion=true}, level_range = {10, 40}, rarity = 6, cost = 2, wielder = { - inc_damage = { [DamageType.ACID] = resolvers.mbonus_material(10, 10) }, - resists = {}, + inc_damage = { [DamageType.ACID] = resolvers.mbonus_material("inc_damage") }, + wards = {[DamageType.ACID] = resolvers.mbonus_material("wards")}, + learn_talent = {[Talents.T_WARD] = resolvers.mbonus_material("learn_talent")}, }, - resolvers.genericlast(function(e) e.wielder.resists[engine.DamageType.ACID] = (e.wielder.resists[engine.DamageType.ACID] or 0) + e.wielder.inc_damage[engine.DamageType.ACID] end), + } newEntity{ power_source = {arcane=true}, - name = " of blight (#RESIST#)", suffix=true, instant_resolve=true, + name = " of blight (#DAMBONUS#)", suffix=true, instant_resolve=true, keywords = {blight=true}, level_range = {10, 40}, rarity = 6, cost = 2, wielder = { - inc_damage = { [DamageType.BLIGHT] = resolvers.mbonus_material(10, 10) }, - resists = {}, + inc_damage = { [DamageType.BLIGHT] = resolvers.mbonus_material("inc_damage") }, + wards = {[DamageType.BLIGHT] = resolvers.mbonus_material("wards")}, + learn_talent = {[Talents.T_WARD] = resolvers.mbonus_material("learn_talent")}, }, - resolvers.genericlast(function(e) e.wielder.resists[engine.DamageType.BLIGHT] = (e.wielder.resists[engine.DamageType.BLIGHT] or 0) + e.wielder.inc_damage[engine.DamageType.BLIGHT] end), } newEntity{ power_source = {nature=true}, - name = " of massacre (#DAMBONUS#)", suffix=true, instant_resolve=true, + name = " of massacre", suffix=true, instant_resolve=true, keywords = {massacre=true}, level_range = {6, 50}, rarity = 4, cost = 4, wielder = { - inc_damage = { [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 5) }, + combat_dam = resolvers.mbonus_material("combat_dam", 2), + --inc_damage = { [DamageType.PHYSICAL] = resolvers.mbonus_material("inc_damage") }, }, } @@ -179,7 +182,9 @@ newEntity{ define_as = "RING_ARCANE_POWER", rarity = 4, cost = 4, wielder = { - inc_damage = { [DamageType.ARCANE] = resolvers.mbonus_material(15, 5) }, + inc_damage = { [DamageType.ARCANE] = resolvers.mbonus_material("inc_damage") }, + wards = {[DamageType.ARCANE] = resolvers.mbonus_material("wards")}, + learn_talent = {[Talents.T_WARD] = resolvers.mbonus_material("learn_talent")}, }, } @@ -187,13 +192,14 @@ newEntity{ power_source = {technique=true}, name = "savior's ", prefix=true, instant_resolve=true, keywords = {savior=true}, + greater_ego = 1, level_range = {1, 50}, rarity = 10, cost = 10, wielder = { - combat_mentalresist = resolvers.mbonus_material(10, 5), - combat_physresist = resolvers.mbonus_material(10, 5), - combat_spellresist = resolvers.mbonus_material(10, 5), + combat_mentalresist = resolvers.mbonus_material("save"), + combat_physresist = resolvers.mbonus_material("save"), + combat_spellresist = resolvers.mbonus_material("save"), }, } @@ -205,7 +211,7 @@ newEntity{ rarity = 7, cost = 6, wielder = { - inc_stats = { [Stats.STAT_STR] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats") }, }, resolvers.genericlast(function(e) e.wielder.combat_def = (e.wielder.combat_def or 0) + e.wielder.inc_stats[engine.interface.ActorStats.STAT_STR] end), } @@ -218,7 +224,7 @@ newEntity{ rarity = 7, cost = 6, wielder = { - inc_stats = { [Stats.STAT_CON] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats") }, }, resolvers.genericlast(function(e) e.wielder.combat_physresist = (e.wielder.combat_physresist or 0) + e.wielder.inc_stats[engine.interface.ActorStats.STAT_CON] end), } @@ -231,7 +237,7 @@ newEntity{ rarity = 7, cost = 6, wielder = { - inc_stats = { [Stats.STAT_DEX] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats") }, }, resolvers.genericlast(function(e) e.wielder.combat_atk = (e.wielder.combat_atk or 0) + e.wielder.inc_stats[engine.interface.ActorStats.STAT_DEX] end), } @@ -244,7 +250,7 @@ newEntity{ define_as = "RING_MAGIC", rarity = 7, cost = 6, wielder = { - inc_stats = { [Stats.STAT_MAG] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats") }, }, resolvers.genericlast(function(e) e.wielder.combat_spellresist = (e.wielder.combat_spellresist or 0) + e.wielder.inc_stats[engine.interface.ActorStats.STAT_MAG] end), } @@ -257,8 +263,8 @@ newEntity{ rarity = 7, cost = 6, wielder = { - max_encumber = resolvers.mbonus_material(20, 20), - fatigue = resolvers.mbonus_material(6, 4, function(e, v) return 0, -v end), + max_encumber = resolvers.mbonus_material("max_encumber"), + fatigue = resolvers.mbonus_material("fatigue"), }, } @@ -271,10 +277,10 @@ newEntity{ rarity = 12, cost = 20, wielder = { - lite = -2, + lite = resolvers.mbonus_material("lite", -1), inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(6, 4), - [Stats.STAT_CUN] = resolvers.mbonus_material(6, 4), + [Stats.STAT_DEX] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -288,10 +294,10 @@ newEntity{ rarity = 12, cost = 20, wielder = { - combat_dam = resolvers.mbonus_material(10, 5), + combat_dam = resolvers.mbonus_material("combat_dam"), inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(6, 4), - [Stats.STAT_CON] = resolvers.mbonus_material(6, 4), + [Stats.STAT_STR] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -305,10 +311,10 @@ newEntity{ rarity = 12, cost = 20, wielder = { - mana_regen = resolvers.mbonus_material(30, 10, function(e, v) v=v/100 return 0, v end), + mana_regen = resolvers.mbonus_material("mana_regen"), inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(4, 4), - [Stats.STAT_WIL] = resolvers.mbonus_material(4, 4), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -322,9 +328,9 @@ newEntity{ rarity = 12, cost = 50, wielder = { - pin_immune = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), - knockback_immune = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), - disarm_immune = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), + pin_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), + disarm_immune = resolvers.mbonus_material("immunity"), }, } @@ -338,9 +344,9 @@ newEntity{ rarity = 12, cost = 50, wielder = { - combat_spellpower = resolvers.mbonus_material(3, 3), - combat_spellcrit = resolvers.mbonus_material(3, 3), - inc_damage = { [DamageType.ARCANE] = resolvers.mbonus_material(15, 5) }, + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), + inc_damage = { [DamageType.ARCANE] = resolvers.mbonus_material("inc_damage") }, }, } @@ -353,9 +359,9 @@ newEntity{ rarity = 12, cost = 50, wielder = { - max_life=resolvers.mbonus_material(60, 40), - life_regen = resolvers.mbonus_material(15, 5, function(e, v) v=v/10 return 0, v end), - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + max_life=resolvers.mbonus_material("max_life"), + life_regen = resolvers.mbonus_material("life_regen"), + healing_factor = resolvers.mbonus_material("healing_factor"), }, } @@ -364,12 +370,13 @@ newEntity{ name = "painweaver's ", prefix=true, instant_resolve=true, keywords = {painweaver=true}, level_range = {5, 35}, + greater_ego = 1, rarity = 20, cost = 60, wielder = { - healing_factor = resolvers.mbonus_material(30, 5, function(e, v) v=v/10 return 0, -v end), - combat_spellpower = resolvers.mbonus_material(15, 5), - combat_dam = resolvers.mbonus_material(15, 5), + healing_factor = resolvers.mbonus_material("healing_factor", -1), + combat_spellpower = resolvers.mbonus_material("combat_spellpower", 2), + combat_dam = resolvers.mbonus_material("combat_dam", 2), }, } @@ -383,13 +390,10 @@ newEntity{ cost = 60, wielder = { inc_damage = { - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - }, - melee_project = { - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("inc_damage"), }, resists_pen = { - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists_pen"), }, }, } @@ -404,12 +408,12 @@ newEntity{ cost = 40, wielder = { resists={ - [DamageType.ARCANE] = resolvers.mbonus_material(7, 3), + [DamageType.ARCANE] = resolvers.mbonus_material("rare_resists"), }, inc_damage = { - [DamageType.ARCANE] = resolvers.mbonus_material(20, 5), + [DamageType.ARCANE] = resolvers.mbonus_material("inc_damage"), }, - lite = resolvers.mbonus_material(1, 1), + lite = resolvers.mbonus_material("lite"), }, } @@ -423,10 +427,10 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - combat_spellresist = resolvers.mbonus_material(7, 3), - max_stamina = resolvers.mbonus_material(30, 10), + combat_spellresist = resolvers.mbonus_material("combat_spellresist"), + max_stamina = resolvers.mbonus_material("max_stamina"), }, } @@ -440,11 +444,11 @@ newEntity{ cost = 40, wielder = { resists={ - [DamageType.NATURE] = resolvers.mbonus_material(10, 5), + [DamageType.NATURE] = resolvers.mbonus_material("resists"), }, - poison_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - disease_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - combat_physresist = resolvers.mbonus_material(7, 3), + poison_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), + combat_physresist = resolvers.mbonus_material("save"), }, } @@ -458,13 +462,10 @@ newEntity{ cost = 60, wielder = { inc_damage = { - [DamageType.COLD] = resolvers.mbonus_material(10, 5), - }, - melee_project = { - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.COLD] = resolvers.mbonus_material("inc_damage"), }, resists_pen = { - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.COLD] = resolvers.mbonus_material("resists_pen"), }, }, } @@ -481,11 +482,11 @@ newEntity{ use_talent = { id = Talents.T_BLEEDING_EDGE, level = 4, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(9, 1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats", 2), }, - combat_mentalresist = resolvers.mbonus_material(5, 5, function(e, v) return 0, -v end), - combat_physresist = resolvers.mbonus_material(5, 5, function(e, v) return 0, -v end), - combat_spellresist = resolvers.mbonus_material(5, 5, function(e, v) return 0, -v end), + combat_mentalresist = resolvers.mbonus_material("save", -1), + combat_physresist = resolvers.mbonus_material("save", -1), + combat_spellresist = resolvers.mbonus_material("save", -1), }, } @@ -499,10 +500,10 @@ newEntity{ cost = 60, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -519,7 +520,7 @@ newEntity{ use_talent = { id = Talents.T_GREATER_WEAPON_FOCUS, level = 4, power = 80 }, wielder = { resists_pen = { - [DamageType.PHYSICAL] = resolvers.mbonus_material(10, 5), + [DamageType.PHYSICAL] = resolvers.mbonus_material("resists_pen"), }, }, } @@ -535,8 +536,8 @@ newEntity{ max_power = 80, power_regen = 1, use_talent = { id = Talents.T_DISENGAGE, level = 2, power = 40 }, wielder = { - combat_apr = resolvers.mbonus_material(7, 3), - combat_def = resolvers.mbonus_material(7, 3), + combat_apr = resolvers.mbonus_material("combat_apr"), + combat_def = resolvers.mbonus_material("combat_def"), }, } @@ -551,10 +552,10 @@ newEntity{ max_power = 80, power_regen = 1, use_talent = { id = Talents.T_BLINDING_SPEED, level = 4, power = 80 }, wielder = { - movement_speed = resolvers.mbonus_material(12, 3, function(e, v) v=v/100 return 0, v end), + movement_speed = resolvers.mbonus_material("movement_speed"), }, } - +--[=[ newEntity{ power_source = {arcane=true}, name = " of blasting", suffix=true, instant_resolve=true, @@ -565,9 +566,9 @@ newEntity{ cost = 60, wielder = { melee_project = { - [DamageType.LIGHTNING] = resolvers.mbonus_material(12, 3), - [DamageType.PHYSICAL] = resolvers.mbonus_material(12, 3), + [DamageType.LIGHTNING] = resolvers.mbonus_material("melee_project"), + [DamageType.PHYSICAL] = resolvers.mbonus_material("melee_project"), }, }, } - +]=] diff --git a/game/modules/tome/data/general/objects/egos/robe.lua b/game/modules/tome/data/general/objects/egos/robe.lua index d56fb14041..527b88a027 100644 --- a/game/modules/tome/data/general/objects/egos/robe.lua +++ b/game/modules/tome/data/general/objects/egos/robe.lua @@ -31,7 +31,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - resists={[DamageType.FIRE] = resolvers.mbonus_material(30, 10)}, + resists={[DamageType.FIRE] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -42,7 +42,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - resists={[DamageType.COLD] = resolvers.mbonus_material(30, 10)}, + resists={[DamageType.COLD] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -53,7 +53,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - resists={[DamageType.ACID] = resolvers.mbonus_material(30, 10)}, + resists={[DamageType.ACID] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -64,7 +64,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - resists={[DamageType.LIGHTNING] = resolvers.mbonus_material(30, 10)}, + resists={[DamageType.LIGHTNING] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -75,7 +75,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - resists={[DamageType.NATURE] = resolvers.mbonus_material(30, 10)}, + resists={[DamageType.NATURE] = resolvers.mbonus_material("resists")}, }, } @@ -87,7 +87,7 @@ newEntity{ rarity = 7, cost = 6, wielder = { - max_mana = resolvers.mbonus_material(100, 10), + max_mana = resolvers.mbonus_material("max_mana", 2), }, } @@ -99,7 +99,7 @@ newEntity{ rarity = 7, cost = 6, wielder = { - on_melee_hit={[DamageType.SLIME] = resolvers.mbonus_material(7, 3)}, + on_melee_hit={[DamageType.SLIME] = resolvers.mbonus_material("on_hit_melee")}, }, } @@ -113,16 +113,15 @@ newEntity{ cost = 15, wielder = { inc_damage = { - [DamageType.ARCANE] = resolvers.mbonus_material(15, 5), - [DamageType.FIRE] = resolvers.mbonus_material(15, 5), - [DamageType.COLD] = resolvers.mbonus_material(15, 5), - [DamageType.ACID] = resolvers.mbonus_material(15, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(15, 5), - [DamageType.NATURE] = resolvers.mbonus_material(15, 5), - [DamageType.BLIGHT] = resolvers.mbonus_material(15, 5), - [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 5), + [DamageType.ARCANE] = resolvers.mbonus_material("inc_damage"), + [DamageType.FIRE] = resolvers.mbonus_material("inc_damage"), + [DamageType.COLD] = resolvers.mbonus_material("inc_damage"), + [DamageType.ACID] = resolvers.mbonus_material("inc_damage"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("inc_damage"), + [DamageType.NATURE] = resolvers.mbonus_material("inc_damage"), + [DamageType.BLIGHT] = resolvers.mbonus_material("inc_damage"), }, - combat_spellpower = resolvers.mbonus_material(4, 3), + --combat_spellpower = resolvers.mbonus_material("combat_spellpower"), }, } @@ -134,7 +133,7 @@ newEntity{ rarity = 7, cost = 6, wielder = { - combat_spellpower = resolvers.mbonus_material(4, 2), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), }, } @@ -146,7 +145,7 @@ newEntity{ rarity = 7, cost = 6, wielder = { - combat_armor = resolvers.mbonus_material(6, 2), + combat_armor = resolvers.mbonus_material("combat_armor"), }, } @@ -158,7 +157,7 @@ newEntity{ rarity = 7, cost = 6, wielder = { - combat_spellcrit = resolvers.mbonus_material(4, 2), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), }, } @@ -170,7 +169,7 @@ newEntity{ rarity = 10, cost = 10, wielder = { - mana_regen = resolvers.mbonus_material(30, 10, function(e, v) v=v/100 return 0, v end), + mana_regen = resolvers.mbonus_material("mana_regen"), }, } @@ -184,15 +183,15 @@ newEntity{ cost = 50, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.ACID] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.ACID] = resolvers.mbonus_material("resists"), }, - inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(4, 4), - }, +-- inc_stats = { +-- [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), +-- }, inc_damage = { - [DamageType.FIRE] = resolvers.mbonus_material(15, 5), - [DamageType.ACID] = resolvers.mbonus_material(15, 5), + [DamageType.FIRE] = resolvers.mbonus_material("inc_damage"), + [DamageType.ACID] = resolvers.mbonus_material("inc_damage"), }, }, } @@ -207,15 +206,15 @@ newEntity{ cost = 50, wielder = { resists={ - [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), - [DamageType.PHYSICAL] = resolvers.mbonus_material(10, 5), + [DamageType.TEMPORAL] = resolvers.mbonus_material("resists"), + [DamageType.PHYSICAL] = resolvers.mbonus_material("rare_resists"), }, inc_stats = { [Stats.STAT_MAG] = resolvers.mbonus_material(4, 4), }, inc_damage = { - [DamageType.TEMPORAL] = resolvers.mbonus_material(15, 5), - [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 5), + [DamageType.TEMPORAL] = resolvers.mbonus_material("inc_damage"), + --[DamageType.PHYSICAL] = resolvers.mbonus_material("inc_damage"), }, }, } @@ -230,15 +229,15 @@ newEntity{ cost = 50, wielder = { resists={ - [DamageType.COLD] = resolvers.mbonus_material(10, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), + [DamageType.COLD] = resolvers.mbonus_material("resists"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), }, - inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(4, 4), - }, +-- inc_stats = { +-- [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), +-- }, inc_damage = { - [DamageType.COLD] = resolvers.mbonus_material(15, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(15, 5), + [DamageType.COLD] = resolvers.mbonus_material("inc_damage"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("inc_damage"), }, }, } @@ -253,13 +252,13 @@ newEntity{ cost = 50, wielder = { resists={ - [DamageType.LIGHT] = resolvers.mbonus_material(10, 5), - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHT] = resolvers.mbonus_material("resists"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, - lite = 1, + lite = resolvers.mbonus_material("lite"), inc_damage = { - [DamageType.LIGHT] = resolvers.mbonus_material(15, 5), - [DamageType.DARKNESS] = resolvers.mbonus_material(15, 5), + [DamageType.LIGHT] = resolvers.mbonus_material("inc_damage"), + [DamageType.DARKNESS] = resolvers.mbonus_material("inc_damage"), }, }, } @@ -273,12 +272,11 @@ newEntity{ rarity = 20, cost = 60, wielder = { - inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(4, 2), - [Stats.STAT_WIL] = resolvers.mbonus_material(4, 2), - [Stats.STAT_CUN] = resolvers.mbonus_material(4, 2), - [Stats.STAT_CON] = resolvers.mbonus_material(4, 2), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), + --[Stats.STAT_CON] = resolvers.mbonus_material(4, 2), }, }, @@ -293,10 +291,10 @@ newEntity{ rarity = 20, cost = 60, wielder = { - combat_spellpower = resolvers.mbonus_material(3, 3), - combat_spellcrit = resolvers.mbonus_material(3, 3), - max_mana = resolvers.mbonus_material(60, 40), - mana_regen = resolvers.mbonus_material(30, 10, function(e, v) v=v/100 return 0, v end), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), + max_mana = resolvers.mbonus_material("max_mana"), + mana_regen = resolvers.mbonus_material("mana_regen"), }, } @@ -310,11 +308,11 @@ newEntity{ rarity = 20, cost = 60, wielder = { - max_life=resolvers.mbonus_material(60, 40), - life_regen = resolvers.mbonus_material(15, 5, function(e, v) v=v/10 return 0, v end), - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + max_life=resolvers.mbonus_material("max_life"), + life_regen = resolvers.mbonus_material("life_regen"), + healing_factor = resolvers.mbonus_material("healing_factor"), resists={ - [DamageType.BLIGHT] = resolvers.mbonus_material(15, 5), + [DamageType.BLIGHT] = resolvers.mbonus_material("resists"), }, }, @@ -330,21 +328,37 @@ newEntity{ cost = 40, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), - [DamageType.BLIGHT] = resolvers.mbonus_material(10, 5), - [DamageType.NATURE] = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), - [DamageType.PHYSICAL] = resolvers.mbonus_material(10, 5), - [DamageType.ARCANE] = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists", -1), + [DamageType.BLIGHT] = resolvers.mbonus_material("resists"), + [DamageType.NATURE] = resolvers.mbonus_material("resists", -1), + [DamageType.PHYSICAL] = resolvers.mbonus_material("rare_resists"), + [DamageType.ARCANE] = resolvers.mbonus_material("resists", -1), }, - resists_pen = { - [DamageType.FIRE] = resolvers.mbonus_material(15, 5), - [DamageType.BLIGHT] = resolvers.mbonus_material(15, 5), - [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 5), + resists_pen = { + [DamageType.FIRE] = resolvers.mbonus_material("resists_pen", 2), + [DamageType.BLIGHT] = resolvers.mbonus_material("resists_pen", 2), + [DamageType.PHYSICAL] = resolvers.mbonus_material("resists_pen", 2), }, - }, + }, } - +--[=[ +newEntity{ + power_source = {nature=true}, + name = " of gathering", suffix=true, instant_resolve=true, + level_range = {20, 50}, + greater_ego = 1, + rarity = 40, + cost = 80, + wielder = { + resists={ + [DamageType.NATURE] = resolvers.mbonus_material("resists"), + }, + resource_leech_chance = resolvers.mbonus_material("resource_leech_chance"), + resource_leech_value = resolvers.mbonus_material("resource_leech_value"), + }, +} +]=] newEntity{ power_source = {arcane=true}, name = " of explosions", suffix=true, instant_resolve=true, @@ -357,10 +371,10 @@ newEntity{ use_talent = { id = Talents.T_GLYPH_OF_EXPLOSION, level = 4, power = 80 }, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), }, - combat_armor = resolvers.mbonus_material(7, 3), - }, + combat_armor = resolvers.mbonus_material("combat_armor"), + }, } newEntity{ @@ -373,12 +387,12 @@ newEntity{ cost = 40, wielder = { on_melee_hit = { - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("on_melee_hit"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("on_melee_hit"), + [DamageType.FIRE] = resolvers.mbonus_material("on_melee_hit"), + [DamageType.COLD] = resolvers.mbonus_material("on_melee_hit"), }, - }, + }, } newEntity{ @@ -393,9 +407,9 @@ newEntity{ use_talent = { id = Talents.T_NOVA, level = 4, power = 6 }, wielder = { resists={ - [DamageType.LIGHTNING] = resolvers.mbonus_material(20, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), }, - }, + }, } newEntity{ @@ -408,16 +422,16 @@ newEntity{ cost = 60, wielder = { resists={ - [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 5, function(e, v) return 0, -v end), - [DamageType.ARCANE] = resolvers.mbonus_material(7, 3), + [DamageType.PHYSICAL] = resolvers.mbonus_material("rare_resists", -1), + [DamageType.ARCANE] = resolvers.mbonus_material("rara_resists"), }, inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(7, 3), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), }, - combat_mentalresist = resolvers.mbonus_material(10, 5), - combat_physresist = resolvers.mbonus_material(10, 5), - combat_spellresist = resolvers.mbonus_material(10, 5), - }, + combat_mentalresist = resolvers.mbonus_material("save"), + --combat_physresist = resolvers.mbonus_material(10, 5), + combat_spellresist = resolvers.mbonus_material("save"), + }, } newEntity{ @@ -430,11 +444,11 @@ newEntity{ cost = 30, wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats"), }, - blind_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - combat_spellpower = resolvers.mbonus_material(7, 3), - }, + blind_immune = resolvers.mbonus_material("immunity"), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), + }, } newEntity{ @@ -447,13 +461,13 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(9, 1), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), }, - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - melee_project = { - [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), + confusion_immune = resolvers.mbonus_material("immunity"), + on_melee_hit = { + [DamageType.TEMPORAL] = resolvers.mbonus_material("on_melee_hit"), }, - }, + }, } newEntity{ @@ -466,12 +480,12 @@ newEntity{ cost = 80, wielder = { resists={ - [DamageType.BLIGHT] = resolvers.mbonus_material(35, 5), + [DamageType.BLIGHT] = resolvers.mbonus_material("resists"), }, - combat_mentalresist = resolvers.mbonus_material(15, 5), - combat_armor = resolvers.mbonus_material(7, 3), - combat_spellpower = resolvers.mbonus_material(7, 3), - }, + combat_mentalresist = resolvers.mbonus_material("save", 2), + --combat_armor = resolvers.mbonus_material("combat_armor"), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), + }, } newEntity{ @@ -484,9 +498,9 @@ newEntity{ cost = 60, wielder = { inc_stats = { - [Stats.STAT_CUN] = resolvers.mbonus_material(9, 1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats", 2), }, - combat_spellcrit = resolvers.mbonus_material(4, 1), - combat_critical_power = resolvers.mbonus_material(30, 10), - }, -} \ No newline at end of file + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), + --combat_critical_power = resolvers.mbonus_material("combat_critical_power"), + }, +} diff --git a/game/modules/tome/data/general/objects/egos/shield.lua b/game/modules/tome/data/general/objects/egos/shield.lua index cd021b5019..2a021d0819 100644 --- a/game/modules/tome/data/general/objects/egos/shield.lua +++ b/game/modules/tome/data/general/objects/egos/shield.lua @@ -32,7 +32,7 @@ newEntity{ rarity = 5, cost = 4, wielder = { - resists={[DamageType.FIRE] = resolvers.mbonus_material(20, 10)}, + resists={[DamageType.FIRE] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -43,7 +43,7 @@ newEntity{ rarity = 5, cost = 4, wielder = { - resists={[DamageType.COLD] = resolvers.mbonus_material(20, 10)}, + resists={[DamageType.COLD] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -54,7 +54,7 @@ newEntity{ rarity = 5, cost = 4, wielder = { - resists={[DamageType.ACID] = resolvers.mbonus_material(20, 10)}, + resists={[DamageType.ACID] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -65,7 +65,7 @@ newEntity{ rarity = 5, cost = 4, wielder = { - resists={[DamageType.LIGHTNING] = resolvers.mbonus_material(20, 10)}, + resists={[DamageType.LIGHTNING] = resolvers.mbonus_material("resists")}, }, } newEntity{ @@ -76,11 +76,10 @@ newEntity{ rarity = 5, cost = 4, wielder = { - resists={[DamageType.NATURE] = resolvers.mbonus_material(20, 10)}, + resists={[DamageType.NATURE] = resolvers.mbonus_material("resists")}, }, } - newEntity{ power_source = {arcane=true}, name = "flaming ", prefix=true, instant_resolve=true, @@ -89,7 +88,7 @@ newEntity{ rarity = 8, cost = 8, wielder = { - on_melee_hit={[DamageType.FIRE] = resolvers.mbonus_material(10, 10)}, + on_melee_hit={[DamageType.FIRE] = resolvers.mbonus_material("on_melee_hit")}, }, } newEntity{ @@ -100,7 +99,7 @@ newEntity{ rarity = 8, cost = 10, wielder = { - on_melee_hit={[DamageType.ICE] = resolvers.mbonus_material(10, 10)}, + on_melee_hit={[DamageType.COLD] = resolvers.mbonus_material("on_melee_hit")}, }, } newEntity{ @@ -111,7 +110,7 @@ newEntity{ rarity = 8, cost = 8, wielder = { - on_melee_hit={[DamageType.ACID] = resolvers.mbonus_material(10, 10)}, + on_melee_hit={[DamageType.ACID] = resolvers.mbonus_material("on_melee_hit")}, }, } newEntity{ @@ -122,7 +121,7 @@ newEntity{ rarity = 8, cost = 8, wielder = { - on_melee_hit={[DamageType.LIGHTNING] = resolvers.mbonus_material(10, 10)}, + on_melee_hit={[DamageType.LIGHTNING] = resolvers.mbonus_material("on_melee_hit")}, }, } @@ -134,7 +133,7 @@ newEntity{ rarity = 10, cost = 10, wielder = { - max_life=resolvers.mbonus_material(60, 40), + max_life=resolvers.mbonus_material("max_life"), }, } @@ -146,7 +145,7 @@ newEntity{ rarity = 10, cost = 10, wielder = { - combat_def=resolvers.mbonus_material(11, 4), + combat_def=resolvers.mbonus_material("combat_def", 2), }, } @@ -154,13 +153,14 @@ newEntity{ power_source = {nature=true}, name = "reflective ", prefix=true, instant_resolve=true, keywords = {reflective=true}, - level_range = {10, 50}, - rarity = 10, - cost = 10, + level_range = {1, 50}, + greater_ego = 1, + rarity = 30, + cost = 50, + special_combat = {reflective=true}, wielder = { resists={ - [DamageType.LIGHT] = resolvers.mbonus_material(10, 10), - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 10), + [DamageType.LIGHT] = resolvers.mbonus_material("resists"), }, }, } @@ -173,7 +173,7 @@ newEntity{ rarity = 8, cost = 8, wielder = { - on_melee_hit={[DamageType.LIGHT] = resolvers.mbonus_material(10, 10)}, + on_melee_hit={[DamageType.LIGHT] = resolvers.mbonus_material("on_melee_hit")}, }, } @@ -185,10 +185,56 @@ newEntity{ greater_ego = 1, rarity = 16, cost = 20, + special_combat = { + critical_power = resolvers.mbonus_material("critical_power"), + dam = resolvers.mbonus_material("dam"), + }, wielder = { - pin_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - combat_dam = resolvers.mbonus_material(5, 5), - combat_physcrit = resolvers.mbonus_material(3, 3), + combat_dam = resolvers.mbonus_material("combat_dam"), + }, +} + +newEntity{ + power_source = {technique=true}, + name = "spiked ", prefix=true, instant_resolve=true, + keywords = {spiked=true}, + level_range = {1, 50}, + rarity = 5, + cost = 4, + special_combat = { + dam = resolvers.mbonus_material("dam"), + }, + wielder = { + on_melee_hit={[DamageType.PHYSICAL] = resolvers.mbonus_material("on_melee_hit")}, + }, +} + +newEntity{ + power_source = {technique=true}, + name = "reinforced ", prefix=true, instant_resolve=true, + keywords = {reinforced=true}, + level_range = {1, 50}, + rarity = 5, + cost = 4, + special_combat = { + block = resolvers.mbonus_material("block"), + }, +} + +newEntity{ + power_source = {technique=true}, + name = "brutal ", prefix=true, instant_resolve=true, + keywords = {brutal=true}, + greater_ego = 1, + level_range = {1, 50}, + rarity = 16, + cost = 20, + special_combat = { + dam = resolvers.mbonus_material("dam"), + block = resolvers.mbonus_material("block"), + }, + wielder = { + on_melee_hit={[DamageType.PHYSICAL] = resolvers.mbonus_material("on_melee_hit")}, }, } @@ -202,10 +248,10 @@ newEntity{ cost = 20, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(8, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(8, 5), - [DamageType.FIRE] = resolvers.mbonus_material(8, 5), - [DamageType.COLD] = resolvers.mbonus_material(8, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -220,10 +266,10 @@ newEntity{ cost = 20, wielder = { resists={ - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 10), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, - on_melee_hit={[DamageType.DARKNESS] = resolvers.mbonus_material(10, 10)}, - infravision = resolvers.mbonus_material(2, 1), + on_melee_hit={[DamageType.DARKNESS] = resolvers.mbonus_material("on_melee_hit", 2)}, + infravision = resolvers.mbonus_material("infravision"), }, } @@ -235,12 +281,12 @@ newEntity{ greater_ego = 1, rarity = 18, cost = 40, + special_combat = { + block = resolvers.mbonus_material("block"), + }, wielder = { - combat_armor = resolvers.mbonus_material(8, 4), - stun_immune = resolvers.mbonus_material(3, 2, function(e, v) v=v/10 return 0, v end), - inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(4, 3), - }, + combat_armor = resolvers.mbonus_material("combat_armor"), + stun_immune = resolvers.mbonus_material("immunity"), }, } @@ -252,11 +298,12 @@ newEntity{ greater_ego = 1, rarity = 15, cost = 18, + special_combat = {spellplated = true}, wielder = { - combat_mentalresist = resolvers.mbonus_material(10, 5), - combat_spellresist = resolvers.mbonus_material(10, 5), + combat_mentalresist = resolvers.mbonus_material("save"), + combat_spellresist = resolvers.mbonus_material("save"), inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(4, 2), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -269,12 +316,10 @@ newEntity{ greater_ego = 1, rarity = 17, cost = 30, + special_combat = {bloodruned = true}, wielder = { - life_regen = resolvers.mbonus_material(15, 5, function(e, v) v=v/10 return 0, v end), - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(4, 3), - }, + life_regen = resolvers.mbonus_material("life_regen"), + healing_factor = resolvers.mbonus_material("healing_factor"), }, } @@ -287,20 +332,15 @@ newEntity{ rarity = 30, cost = 60, encumber = 15, + special_combat = {block = resolvers.mbonus_material("block")}, wielder = { resists={ - [DamageType.ARCANE] = resolvers.mbonus_material(7, 3), - }, - inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(5, 1), + [DamageType.ARCANE] = resolvers.mbonus_material("rare_resists"), }, on_melee_hit = { - [DamageType.ARCANE] = resolvers.mbonus_material(10, 5), + [DamageType.ARCANE] = resolvers.mbonus_material("on_melee_hit"), }, - melee_project = { - [DamageType.ARCANE] = resolvers.mbonus_material(10, 5), - }, - fatigue = resolvers.mbonus_material(6, 4, function(e, v) return 0, v end), + fatigue = resolvers.mbonus_material("fatigue"), }, } @@ -312,14 +352,16 @@ newEntity{ greater_ego = 1, rarity = 15, cost = 30, + special_combat = { + melee_project = { + [DamageType.NATURE] = resolvers.mbonus_material("melee_project"), + }, + }, wielder = { resists={ - [DamageType.NATURE] = resolvers.mbonus_material(10, 5), - }, - max_life = resolvers.mbonus_material(70, 40), - melee_project = { - [DamageType.NATURE] = resolvers.mbonus_material(10, 5), + [DamageType.NATURE] = resolvers.mbonus_material("resists"), }, + max_life = resolvers.mbonus_material("max_life", 2), }, } @@ -331,90 +373,90 @@ newEntity{ greater_ego = 1, rarity = 30, cost = 60, + special_combat = { + dam = resolvers.mbonus_material("dam"), + melee_project = { + [DamageType.FIRE] = resolvers.mbonus_material("melee_project"), + }, + }, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - }, - inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(5, 1), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), }, on_melee_hit = { - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - }, - melee_project = { - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("on_melee_hit"), }, }, } newEntity{ - power_source = {technique=true}, + power_source = {nature=true}, name = "crackling ", prefix=true, instant_resolve=true, keywords = {crackling=true}, level_range = {30, 50}, greater_ego = 1, rarity = 30, cost = 60, + special_combat = { + dam = resolvers.mbonus_material("dam"), + melee_project = { + [DamageType.LIGHTNING] = resolvers.mbonus_material("melee_project"), + }, + }, wielder = { resists={ - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), - }, - inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(5, 1), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), }, on_melee_hit = { - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), - }, - melee_project = { - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("on_melee_hit"), }, }, } newEntity{ - power_source = {technique=true}, + power_source = {nature=true}, name = "corrosive ", prefix=true, instant_resolve=true, keywords = {corrosive=true}, level_range = {30, 50}, greater_ego = 1, rarity = 30, cost = 60, + special_combat = { + dam = resolvers.mbonus_material("dam"), + melee_project = { + [DamageType.ACID] = resolvers.mbonus_material("melee_project"), + }, + }, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - }, - inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [DamageType.ACID] = resolvers.mbonus_material("resists"), }, on_melee_hit = { - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - }, - melee_project = { - [DamageType.ACID] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("on_melee_hit"), }, }, } newEntity{ - power_source = {technique=true}, + power_source = {nature=true}, name = "wintry ", prefix=true, instant_resolve=true, keywords = {wintry=true}, level_range = {30, 50}, greater_ego = 1, rarity = 30, cost = 60, + special_combat = { + dam = resolvers.mbonus_material("dam"), + melee_project = { + [DamageType.COLD] = resolvers.mbonus_material("melee_project"), + }, + }, wielder = { resists={ - [DamageType.COLD] = resolvers.mbonus_material(10, 5), - }, - inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(5, 1), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, on_melee_hit = { - [DamageType.COLD] = resolvers.mbonus_material(10, 5), - }, - melee_project = { - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.COLD] = resolvers.mbonus_material("on_melee_hit"), }, }, } @@ -427,10 +469,10 @@ newEntity{ greater_ego = 1, rarity = 25, cost = 40, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_DISPLACEMENT_SHIELD, level = 5, power = 80 }, + max_power = 40, power_regen = 1, + use_talent = { id = Talents.T_DISPLACEMENT_SHIELD, level = resolvers.mbonus_material("learn_talent_5"), power = 40 }, wielder = { - combat_def = resolvers.mbonus_material(10, 5), + combat_def = resolvers.mbonus_material("combat_def", 2), }, } @@ -442,11 +484,9 @@ newEntity{ greater_ego = 1, rarity = 25, cost = 40, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_EARTHEN_BARRIER, level = 5, power = 80 }, - wielder = { - combat_armor = resolvers.mbonus_material(7, 3), - }, + special_combat = {block = resolvers.mbonus_material("block")}, + max_power = 30, power_regen = 1, + use_talent = { id = Talents.T_EARTHEN_BARRIER, level = resolvers.mbonus_material("learn_talent_5"), power = 30 }, } newEntity{ @@ -458,11 +498,11 @@ newEntity{ rarity = 10, cost = 20, max_power = 10, power_regen = 1, - use_talent = { id = Talents.T_ILLUMINATE, level = 2, power = 6 }, + use_talent = { id = Talents.T_ILLUMINATE, level = resolvers.mbonus_material("learn_talent_5"), power = 10 }, wielder = { resists={ - [DamageType.LIGHT] = resolvers.mbonus_material(10, 5), - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHT] = resolvers.mbonus_material("resists"), + [DamageType.DARKNESS] = resolvers.mbonus_material("resists"), }, }, } @@ -475,14 +515,17 @@ newEntity{ greater_ego = 1, rarity = 20, cost = 40, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_TIME_SHIELD, level = 5, power = 80 }, + max_power = 20, power_regen = 1, + use_talent = { id = Talents.T_TIME_SHIELD, level = resolvers.mbonus_material("learn_talent_5"), power = 20 }, + special_combat = { + dam = resolvers.mbonus_material("dam"), + melee_project = { + [DamageType.TEMPORAL] = resolvers.mbonus_material("melee_project"), + }, + }, wielder = { resists={ - [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), - }, - melee_project = { - [DamageType.TEMPORAL] = resolvers.mbonus_material(7, 3), + [DamageType.TEMPORAL] = resolvers.mbonus_material("resists"), }, }, } @@ -491,17 +534,11 @@ newEntity{ power_source = {nature=true}, name = " of harmony", suffix=true, instant_resolve=true, keywords = {harmony=true}, - level_range = {30, 50}, - greater_ego = 1, - rarity = 30, - cost = 60, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_WATERS_OF_LIFE, level = 4, power = 80 }, - wielder = { - talents_types_mastery = { - ["wild-gift/harmony"] = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), - }, - }, + level_range = {1, 50}, + rarity = 5, + cost = 5, + max_power = 30, power_regen = 1, + use_talent = { id = Talents.T_WATERS_OF_LIFE, level = resolvers.mbonus_material("learn_talent_5"), power = 30 }, } newEntity{ @@ -512,11 +549,6 @@ newEntity{ greater_ego = 1, rarity = 10, cost = 20, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_BARRIER, level = 4, power = 80 }, - wielder = { - inc_stats = { - [Stats.STAT_WIL] = resolvers.mbonus_material(5, 1), - }, - }, -} \ No newline at end of file + max_power = 20, power_regen = 1, + use_talent = { id = Talents.T_BARRIER, level = resolvers.mbonus_material("learn_talent_5"), power = 20 }, +} diff --git a/game/modules/tome/data/general/objects/egos/sling.lua b/game/modules/tome/data/general/objects/egos/sling.lua index 8e541d87d6..a76eb05a9e 100644 --- a/game/modules/tome/data/general/objects/egos/sling.lua +++ b/game/modules/tome/data/general/objects/egos/sling.lua @@ -19,74 +19,7 @@ local Talents = require("engine.interface.ActorTalents") local Stats = require("engine.interface.ActorStats") ---load("/data/general/objects/egos/charged-attack.lua") - -newEntity{ - power_source = {technique=true}, - name = " of power", suffix=true, instant_resolve=true, - keywords = {power=true}, - level_range = {1, 50}, - rarity = 3, - cost = 6, - combat={apr = resolvers.mbonus_material(15, 1)}, -} - -newEntity{ - power_source = {technique=true}, - name = "mighty ", prefix=true, instant_resolve=true, - keywords = {mighty=true}, - level_range = {1, 50}, - rarity = 3, - cost = 4, - wielder = { - inc_damage={ [DamageType.PHYSICAL] = resolvers.mbonus_material(25, 8), }, - }, -} - -newEntity{ - power_source = {technique=true}, - name = "steady ", prefix=true, instant_resolve=true, - keywords = {steady=true}, - level_range = {20, 50}, - rarity = 9, - cost = 10, - wielder = { - talent_cd_reduction={[Talents.T_STEADY_SHOT]=1}, - }, -} - -newEntity{ - power_source = {technique=true}, - name = " of dexterity (#STATBONUS#)", suffix=true, instant_resolve=true, - keywords = {dex=true}, - level_range = {20, 50}, - rarity = 7, - cost = 7, - wielder = { - inc_stats = { [Stats.STAT_DEX] = resolvers.mbonus_material(6, 2) }, - }, -} - -newEntity{ - power_source = {technique=true}, - name = " of speed", suffix=true, instant_resolve=true, - keywords = {speed=true}, - level_range = {20, 50}, - rarity = 7, - cost = 7, - combat={physspeed = -0.1}, -} - -newEntity{ - power_source = {technique=true}, - name = " of great speed", suffix=true, instant_resolve=true, - keywords = {SPEED=true}, - level_range = {40, 50}, - greater_ego = 1, - rarity = 10, - cost = 60, - combat={physspeed = -0.2}, -} +load("/data/general/objects/egos/ranged.lua") newEntity{ power_source = {technique=true}, @@ -96,12 +29,14 @@ newEntity{ greater_ego = 1, rarity = 24, cost = 40, + combat = { + dam = resolvers.mbonus_material("dam"), + }, wielder = { - talent_cd_reduction={ - [Talents.T_STEADY_SHOT]=1, - [Talents.T_PINNING_SHOT]=1, - [Talents.T_MULTISHOT]=2, + learn_talent={ + [Talents.T_STEADY_SHOT] = resolvers.mbonus_material("learn_talent"), + [Talents.T_PINNING_SHOT] = resolvers.mbonus_material("learn_talent"), + [Talents.T_MULTISHOT] = resolvers.mbonus_material("learn_talent"), }, - inc_damage={ [DamageType.PHYSICAL] = resolvers.mbonus_material(14, 8), }, }, } diff --git a/game/modules/tome/data/general/objects/egos/staves.lua b/game/modules/tome/data/general/objects/egos/staves.lua index 0f6b6ed8cf..eb1395d2f8 100644 --- a/game/modules/tome/data/general/objects/egos/staves.lua +++ b/game/modules/tome/data/general/objects/egos/staves.lua @@ -26,488 +26,437 @@ local Talents = require "engine.interface.ActorTalents" newEntity{ power_source = {arcane=true}, - name = " of power", suffix=true, instant_resolve=true, - keywords = {power=true}, + name = " of warding", suffix=true, instant_resolve=true, + keywords = {warding=true}, level_range = {1, 50}, - rarity = 4, - cost = 8, + rarity = 10, + cost = 20, wielder = { - combat_spellpower = resolvers.mbonus_material(30, 3), + learn_talent = { + [Talents.T_WARD] = resolvers.mbonus_material("learn_talent"), + }, + wards = {}, }, + combat = {of_warding = true}, + resolvers.genericlast(function(e) + for d, v in pairs(e.wielder.inc_damage) do + e.wielder.wards[d] = 2 + end + end), } newEntity{ - power_source = {arcane=true}, - name = "shimmering ", prefix=true, instant_resolve=true, - keywords = {shimmering=true}, - level_range = {1, 50}, - rarity = 3, - cost = 8, + power_source = {technique=true}, + name = " of savagery", suffix=true, instant_resolve=true, + keywords = {savagery=true}, + level_range = {30, 50}, + greater_ego = 1, + rarity = 20, + cost = 40, wielder = { - max_mana = resolvers.mbonus_material(70, 40), + learn_talent = { + [Talents.T_SAVAGERY] = resolvers.mbonus_material("learn_talent_5"), + }, }, } - newEntity{ power_source = {arcane=true}, - name = " of might", suffix=true, instant_resolve=true, - keywords = {might=true}, - level_range = {1, 50}, - rarity = 3, - cost = 8, + name = " of draining", suffix=true, instant_resolve=true, + keywords = {draining=true}, + level_range = {30, 50}, + greater_ego = 1, + rarity = 20, + cost = 40, wielder = { - combat_spellcrit = resolvers.mbonus_material(15, 4), + learn_talent = { + [Talents.T_SOUL_DRAIN] = resolvers.mbonus_material("learn_talent_5"), + }, }, } newEntity{ power_source = {arcane=true}, - name = " of wizardry", suffix=true, instant_resolve=true, - keywords = {wizardry=true}, - level_range = {30, 50}, - greater_ego = 1, - rarity = 18, - cost = 45, + name = " of retribution", suffix=true, instant_resolve=true, + keywords = {retribution=true}, + level_range = {1, 50}, + rarity = 10, + cost = 20, wielder = { - combat_spellpower = resolvers.mbonus_material(30, 3), - max_mana = resolvers.mbonus_material(100, 10), - inc_stats = { [Stats.STAT_MAG] = resolvers.mbonus_material(5, 1), [Stats.STAT_WIL] = resolvers.mbonus_material(5, 1) }, + learn_talent = { + [Talents.T_ELEMENTAL_RETRIBUTION] = resolvers.mbonus_material("learn_talent_5"), + }, + elemental_retribution = {}, }, + combat = {of_retribution = true}, + resolvers.genericlast(function(e) + for d, v in pairs(e.wielder.inc_damage) do + e.wielder.elemental_retribution[d] = 1 + end + end), } newEntity{ power_source = {arcane=true}, - name = "magma ", prefix=true, instant_resolve=true, - keywords = {magma=true}, + name = " of breaching", suffix=true, instant_resolve=true, + keywords = {breaching=true}, level_range = {1, 50}, - rarity = 3, - cost = 5, + greater_ego = 1, + rarity = 20, + cost = 40, wielder = { - inc_damage={ [DamageType.FIRE] = resolvers.mbonus_material(25, 8), }, + resists_pen = {}, }, + combat = {of_breaching = true}, + resolvers.genericlast(function(e) + for d, v in pairs(e.wielder.inc_damage) do + e.wielder.resists_pen[d] = v/2 + end + end), } newEntity{ power_source = {arcane=true}, - name = "temporal ", prefix=true, instant_resolve=true, - keywords = {temporal=true}, + name = "potent ", prefix=true, instant_resolve=true, + keywords = {potent=true}, level_range = {1, 50}, rarity = 3, - cost = 5, - wielder = { - inc_damage={ [DamageType.TEMPORAL] = resolvers.mbonus_material(25, 8), }, + cost = 4, + combat = { + dam = resolvers.mbonus_material("dam"), }, + resolvers.genericlast(function(e) + e.wielder.inc_damage[e.combat.damtype] = e.combat.dam + if e.combat.of_breaching then + for d, v in pairs(e.wielder.inc_damage) do + e.wielder.resists_pen[d] = math.ceil(e.combat.dam/2) + end + end + end), } newEntity{ - power_source = {arcane=true}, - name = "icy ", prefix=true, instant_resolve=true, - keywords = {icy=true}, + power_source = {technique=true}, + name = "cruel ", prefix=true, instant_resolve=true, + keywords = {cruel=true}, level_range = {1, 50}, rarity = 3, - cost = 5, - wielder = { - inc_damage={ [DamageType.COLD] = resolvers.mbonus_material(25, 8), }, + cost = 4, + combat = { + critical_power = resolvers.mbonus_material("critical_power"), }, } newEntity{ power_source = {arcane=true}, - name = "acidic ", prefix=true, instant_resolve=true, - keywords = {acidic=true}, + name = "tuned ", prefix=true, instant_resolve=true, + keywords = {tuned=true}, level_range = {1, 50}, rarity = 3, - cost = 5, - wielder = { - inc_damage={ [DamageType.ACID] = resolvers.mbonus_material(25, 8), }, + cost = 4, + combat = { + max_acc = resolvers.mbonus_material("max_acc"), }, } newEntity{ power_source = {arcane=true}, - name = "crackling ", prefix=true, instant_resolve=true, - keywords = {crackling=true}, + name = "evoker's ", prefix=true, instant_resolve=true, + keywords = {evoker=true}, level_range = {1, 50}, - rarity = 3, - cost = 5, - wielder = { - inc_damage={ [DamageType.LIGHTNING] = resolvers.mbonus_material(25, 8), }, + greater_ego = 1, + rarity = 20, + cost = 25, + combat = { + dam = resolvers.mbonus_material("dam"), + critical_power = resolvers.mbonus_material("critical_power"), }, + resolvers.genericlast(function(e) + e.wielder.inc_damage[e.combat.damtype] = e.combat.dam + if e.combat.of_breaching then + for d, v in pairs(e.wielder.inc_damage) do + e.wielder.resists_pen[d] = math.ceil(e.combat.dam/2) + end + end + end), } newEntity{ - power_source = {nature=true}, - name = "naturalist's ", prefix=true, instant_resolve=true, - keywords = {naturalist=true}, + power_source = {arcane=true}, + name = "ritualist's ", prefix=true, instant_resolve=true, + keywords = {ritualist=true}, level_range = {1, 50}, - rarity = 3, - cost = 5, - wielder = { - inc_damage={ [DamageType.NATURE] = resolvers.mbonus_material(25, 8), }, + greater_ego = 1, + rarity = 20, + cost = 25, + combat = { + dam = resolvers.mbonus_material("dam"), + max_acc = resolvers.mbonus_material("max_acc"), }, + resolvers.genericlast(function(e) + e.wielder.inc_damage[e.combat.damtype] = e.combat.dam + if e.combat.of_breaching then + for d, v in pairs(e.wielder.inc_damage) do + e.wielder.resists_pen[d] = math.ceil(e.combat.dam/2) + end + end + end), } newEntity{ - power_source = {arcane=true}, - name = "blighted ", prefix=true, instant_resolve=true, - keywords = {blighted=true}, + power_source = {technique=true}, + name = "sadist's ", prefix=true, instant_resolve=true, + keywords = {sadist=true}, level_range = {1, 50}, - rarity = 3, - cost = 5, - wielder = { - inc_damage={ [DamageType.BLIGHT] = resolvers.mbonus_material(25, 8), }, + greater_ego = 1, + rarity = 20, + cost = 25, + combat = { + max_acc = resolvers.mbonus_material("max_acc"), + critical_power = resolvers.mbonus_material("critical_power"), }, } newEntity{ - power_source = {nature=true}, - name = "sunbathed ", prefix=true, instant_resolve=true, - keywords = {sunbathed=true}, + power_source = {arcane=true}, + name = "greater ", prefix=true, instant_resolve=true, + keywords = {greater=true}, level_range = {1, 50}, - rarity = 3, - cost = 5, - wielder = { - inc_damage={ [DamageType.LIGHT] = resolvers.mbonus_material(25, 8), }, - }, + greater_ego = 1, + rarity = 20, + cost = 25, + combat = {is_greater = true,}, + resolvers.generic(function(e) + local dam_tables = { + magestaff = {engine.DamageType.FIRE, engine.DamageType.COLD, engine.DamageType.LIGHTNING, engine.DamageType.ARCANE}, + starstaff = {engine.DamageType.LIGHT, engine.DamageType.DARKNESS, engine.DamageType.TEMPORAL}, + earthstaff = {engine.DamageType.NATURE, engine.DamageType.BLIGHT, engine.DamageType.ACID}, + } + local d_table = dam_tables[e.flavor_name] + for i = 1, #d_table do + e.wielder.inc_damage[d_table[i]] = e.combat.dam + end + end), } newEntity{ power_source = {nature=true}, - name = "shadow ", prefix=true, instant_resolve=true, - keywords = {shadow=true}, + name = " of blood", suffix=true, instant_resolve=true, + keywords = {blood=true}, level_range = {1, 50}, - rarity = 3, - cost = 5, + rarity = 10, + cost = 10, wielder = { - inc_damage={ [DamageType.DARKNESS] = resolvers.mbonus_material(25, 8), }, + learn_talent = { + [Talents.T_BLOODFLOW] = resolvers.mbonus_material("learn_talent_5"), + }, }, } newEntity{ - power_source = {arcane=true}, - name = " of divination", suffix=true, instant_resolve=true, - keywords = {divination=true}, + power_source = {nature=true}, + name = "parasitic ", prefix=true, instant_resolve=true, + keywords = {parasitic=true}, level_range = {1, 50}, - rarity = 8, - cost = 8, + greater_ego = 1, + rarity = 60, + cost = 40, wielder = { - talents_types_mastery = { - ["spell/divination"] = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), - }, + resource_leech_chance = resolvers.mbonus_material("resource_leech_chance"), + resource_leech_value = resolvers.mbonus_material("resource_leech_value"), }, } newEntity{ power_source = {arcane=true}, - name = " of conveyance", suffix=true, instant_resolve=true, - keywords = {conveyance=true}, + name = " of channeling", suffix=true, instant_resolve=true, + keywords = {channeling=true}, level_range = {1, 50}, rarity = 10, - cost = 10, + cost = 20, wielder = { - talents_types_mastery = { - ["spell/conveyance"] = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), + learn_talent = { + [Talents.T_CHANNEL_STAFF] = resolvers.mbonus_material("learn_talent"), }, }, - max_power = 120, power_regen = 1, - use_power = { name = "teleport you anywhere on the level, randomly", power = 70, use = function(self, who) - game.level.map:particleEmitter(who.x, who.y, 1, "teleport") - who:teleportRandom(who.x, who.y, 200) - game.level.map:particleEmitter(who.x, who.y, 1, "teleport") - game.logSeen(who, "%s uses %s!", who.name:capitalize(), self:getName{no_count=true}) - return {id=true, used=true} - end} } newEntity{ power_source = {nature=true}, - name = " of illumination", suffix=true, instant_resolve=true, - keywords = {illumination=true}, + name = "sentient ", prefix=true, instant_resolve=true, + keywords = {sentient=true}, level_range = {1, 50}, - rarity = 8, - cost = 8, - wielder = { - lite = 1, + greater_ego = 1, + rarity = 60, + cost = 200, + combat = { + sentient = resolvers.rngtable{"default", "aggressive", "fawning"}, }, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_ILLUMINATE, level = 2, power = 10 }, } newEntity{ power_source = {arcane=true}, - name = " of blasting", suffix=true, instant_resolve=true, - keywords = {blasting=true}, + name = " of wizardry", suffix=true, instant_resolve=true, + keywords = {wizardry=true}, level_range = {30, 50}, greater_ego = 1, rarity = 18, cost = 45, wielder = { - combat_spellpower = resolvers.mbonus_material(12, 3), - combat_spellcrit = resolvers.mbonus_material(4, 2), - inc_damage = { - [DamageType.FIRE] = resolvers.mbonus_material(15, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(15, 5), + learn_talent = { + [Talents.T_ELEMENTAL_RETRIBUTION] = resolvers.mbonus_material("learn_talent_5"), + [Talents.T_METAFLOW] = resolvers.mbonus_material("learn_talent"), + [Talents.T_COMMAND_STAFF] = resolvers.mbonus_material("learn_talent"), }, + elemental_retribution = {}, }, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_BLASTWAVE, level = 2, power = 80 }, + combat = { + of_retribution = true, + max_acc = resolvers.mbonus_material("max_acc"), + }, + resolvers.genericlast(function(e) + for d, v in pairs(e.wielder.inc_damage) do + e.wielder.elemental_retribution[d] = 1 + end + end), } - newEntity{ power_source = {arcane=true}, - name = " of warding", suffix=true, instant_resolve=true, - keywords = {warding=true}, - level_range = {30, 50}, - greater_ego = 1, + name = "shadowy ", prefix=true, instant_resolve=true, + keywords = {shadowy=true}, + level_range = {1, 50}, rarity = 20, - cost = 45, + cost = 20, wielder = { - combat_spellpower = resolvers.mbonus_material(12, 3), - stun_immune = resolvers.mbonus_material(3, 3, function(e, v) v=v/10 return 0, v end), - combat_def = resolvers.mbonus_material(16, 4), - resists={ - [DamageType.ARCANE] = resolvers.mbonus_material(5, 5), + learn_talent = { + [Talents.T_FEARSCAPE_FOG] = resolvers.mbonus_material("learn_talent"), }, }, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_DISPLACEMENT_SHIELD, level = 4, power = 80 }, -} - --- TODO: Make into an artifact effect and remove -newEntity{ - power_source = {arcane=true}, - name = " of channeling", suffix=true, instant_resolve=true, - keywords = {channeling=true}, - level_range = {30, 50}, - greater_ego = 1, - rarity = 38, - cost = 45, - wielder = { - combat_spellpower = resolvers.mbonus_material(12, 3), - mana_regen = resolvers.mbonus_material(30, 10, function(e, v) v=v/100 return 0, v end), - }, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_METAFLOW, level = 3, power = 80 }, } newEntity{ power_source = {nature=true}, - name = "lifebinding ", prefix=true, instant_resolve=true, - keywords = {lifebinding=true}, - level_range = {30, 50}, - greater_ego = 1, - rarity = 16, - cost = 35, - wielder = { - combat_spellpower = resolvers.mbonus_material(7, 3), - life_regen = resolvers.mbonus_material(15, 5, function(e, v) v=v/10 return 0, v end), - healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(4, 3), - }, - }, -} - -newEntity{ - power_source = {arcane=true}, - name = "infernal ", prefix=true, instant_resolve=true, - keywords = {infernal=true}, - level_range = {30, 50}, - greater_ego = 1, - rarity = 16, - cost = 35, + name = " of perception", suffix=true, instant_resolve=true, + keywords = {perception=true}, + level_range = {1, 50}, + rarity = 3, + cost = 4, wielder = { - combat_spellpower = resolvers.mbonus_material(7, 3), - see_invisible = resolvers.mbonus_material(15, 5), - inc_damage = { - [DamageType.FIRE] = resolvers.mbonus_material(20, 5), - [DamageType.BLIGHT] = resolvers.mbonus_material(20, 5), + learn_talent = { + [Talents.T_PERCEPTION] = resolvers.mbonus_material("learn_talent_5"), }, }, } newEntity{ power_source = {arcane=true}, - name = "chronomancer's ", prefix=true, instant_resolve=true, - keywords = {chronomancer=true}, - level_range = {30, 50}, - greater_ego = 1, - rarity = 16, - cost = 35, + name = " of conveyance", suffix=true, instant_resolve=true, + keywords = {conveyance=true}, + level_range = {1, 50}, + rarity = 10, + cost = 10, wielder = { - combat_spellpower = resolvers.mbonus_material(7, 3), - movement_speed = 0.1, - inc_damage = { - [DamageType.TEMPORAL] = resolvers.mbonus_material(20, 5), + talents_types_mastery = { + ["spell/conveyance"] = resolvers.mbonus_material("talents_types_mastery"), }, }, - + max_power = 120, power_regen = 1, + use_power = { name = "teleport you anywhere on the level, randomly", power = 70, use = function(self, who) + game.level.map:particleEmitter(who.x, who.y, 1, "teleport") + who:teleportRandom(who.x, who.y, 200) + game.level.map:particleEmitter(who.x, who.y, 1, "teleport") + game.logSeen(who, "%s uses %s!", who.name:capitalize(), self:getName{no_count=true}) + return {id=true, used=true} + end} } newEntity{ power_source = {nature=true}, - name = "abyssal ", prefix=true, instant_resolve=true, - keywords = {abyssal=true}, - level_range = {30, 50}, - greater_ego = 1, - rarity = 40, - cost = 80, + name = " of illumination", suffix=true, instant_resolve=true, + keywords = {illumination=true}, + level_range = {1, 50}, + rarity = 3, + cost = 4, wielder = { - inc_damage = { - [DamageType.COLD] = resolvers.mbonus_material(25, 5), - [DamageType.DARKNESS] = resolvers.mbonus_material(25, 5), - }, - resists_pen = { - [DamageType.COLD] = resolvers.mbonus_material(15, 5), - [DamageType.DARKNESS] = resolvers.mbonus_material(15, 5), - }, + lite = resolvers.mbonus_material("lite"), }, + max_power = 20, power_regen = 1, + use_talent = { id = Talents.T_ILLUMINATE, level = resolvers.mbonus_material("learn_talent_5"), power = 10 }, } newEntity{ power_source = {arcane=true}, - name = "magelord's ", prefix=true, instant_resolve=true, - keywords = {magelord=true}, - level_range = {10, 50}, + name = " of blasting", suffix=true, instant_resolve=true, + keywords = {blasting=true}, + level_range = {30, 50}, greater_ego = 1, - rarity = 40, - cost = 60, - wielder = { - max_mana = resolvers.mbonus_material(100, 20), - combat_spellpower = resolvers.mbonus_material(20, 5), + rarity = 18, + cost = 45, + combat = { + critical_power = resolvers.mbonus_material("critical_power"), }, + max_power = 80, power_regen = 1, + use_talent = { id = Talents.T_BLASTWAVE, level = resolvers.mbonus_material("learn_talent_5"), power = 50 }, } -newEntity{ - power_source = {arcane=true}, - name = "polar ", prefix=true, instant_resolve=true, - keywords = {polar=true}, - level_range = {10, 50}, - greater_ego = 1, - rarity = 15, - cost = 30, - wielder = { - combat_spellpower = resolvers.mbonus_material(12, 3), - inc_damage = { - [DamageType.COLD] = resolvers.mbonus_material(15, 5), - }, - on_melee_hit = { - [DamageType.ICE] = resolvers.mbonus_material(10, 5), - }, - }, -} newEntity{ power_source = {arcane=true}, - name = "ethereal ", prefix=true, instant_resolve=true, - keywords = {ethereal=true}, + name = " of displacement", suffix=true, instant_resolve=true, + keywords = {displacement=true}, level_range = {1, 50}, - greater_ego = 1, rarity = 10, cost = 20, - wielder = { - inc_damage = { - [DamageType.ARCANE] = resolvers.mbonus_material(10, 5), - }, - mana_regen = resolvers.mbonus_material(50, 10, function(e, v) v=v/100 return 0, v end), - combat_spellpower = resolvers.mbonus_material(12, 3), - }, + max_power = 30, power_regen = 1, + use_talent = { id = Talents.T_DISPLACEMENT_SHIELD, level = resolvers.mbonus_material("learn_talent_5"), power = 20 }, } newEntity{ power_source = {arcane=true}, - name = "bloodlich's ", prefix=true, instant_resolve=true, - keywords = {bloodlich=true}, - level_range = {40, 50}, - greater_ego = 1, - rarity = 40, - cost = 90, - wielder = { - inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(9, 1), - }, - inc_damage = { - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), - }, - }, -} - -newEntity{ - power_source = {arcane=true}, - name = " of conflagration", suffix=true, instant_resolve=true, - keywords = {conflagration=true}, + name = " of renewal", suffix=true, instant_resolve=true, + keywords = {renewal=true}, level_range = {30, 50}, greater_ego = 1, - rarity = 30, - cost = 60, - wielder = { - mana_regen = resolvers.mbonus_material(50, 10, function(e, v) v=v/100 return 0, -v end), - combat_spellpower = resolvers.mbonus_material(12, 3), - inc_damage = { - [DamageType.FIRE] = resolvers.mbonus_material(20, 5), - }, - resists_pen = { - [DamageType.FIRE] = resolvers.mbonus_material(20, 5), - }, - }, + rarity = 18, + cost = 45, + max_power = 50, power_regen = 1, + use_talent = { id = Talents.T_METAFLOW, level = resolvers.mbonus_material("learn_talent_5"), power = 50 }, } newEntity{ - power_source = {arcane=true}, - name = " of the stars", suffix=true, instant_resolve=true, - keywords = {stars=true}, + power_source = {nature=true}, + name = "lifebinding ", prefix=true, instant_resolve=true, + keywords = {lifebinding=true}, level_range = {1, 50}, greater_ego = 1, - rarity = 15, - cost = 30, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_STARFALL, level = 2, power = 50 }, + rarity = 30, + cost = 80, wielder = { - combat_spellpower = resolvers.mbonus_material(12, 3), - inc_damage = { - [DamageType.DARKNESS] = resolvers.mbonus_material(10, 5), + learn_talent = { + [Talents.T_LIFEBIND] = resolvers.mbonus_material("learn_talent_5"), }, }, } newEntity{ - power_source = {arcane=true}, - name = " of ruination", suffix=true, instant_resolve=true, - keywords = {ruination=true}, + power_source = {nature=true}, + name = "ghostly ", prefix=true, instant_resolve=true, + keywords = {ghostly=true}, level_range = {1, 50}, - greater_ego = 1, rarity = 15, - cost = 30, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_CORRUPTED_NEGATION, level = 2, power = 80 }, - wielder = { - combat_spellpower = resolvers.mbonus_material(12, 3), - inc_damage = { - [DamageType.BLIGHT] = resolvers.mbonus_material(10, 5), - [DamageType.NATURE] = resolvers.mbonus_material(10, 5), - }, - }, + cost = 15, + max_power = 50, power_regen = 1, + use_talent = { id = Talents.T_WRAITHFORM, level = resolvers.mbonus_material("learn_talent_5"), power = 50 }, } newEntity{ power_source = {arcane=true}, - name = " of lightning", suffix=true, instant_resolve=true, - keywords = {lightning=true}, - level_range = {30, 50}, - greater_ego = 1, - rarity = 30, - cost = 60, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_CHAIN_LIGHTNING, level = 5, power = 60 }, - wielder = { - combat_spellpower = resolvers.mbonus_material(12, 3), - resists_pen = { - [DamageType.LIGHTNING] = resolvers.mbonus_material(25, 5), - }, - }, + name = " of negation", suffix=true, instant_resolve=true, + keywords = {negation=true}, + level_range = {1, 50}, + rarity = 10, + cost = 20, + max_power = 40, power_regen = 1, + use_talent = { id = Talents.T_CORRUPTED_NEGATION, level = resolvers.mbonus_material("learn_talent_5"), power = 40 }, } diff --git a/game/modules/tome/data/general/objects/egos/weapon.lua b/game/modules/tome/data/general/objects/egos/weapon.lua index c9bbff5918..3e5d610985 100644 --- a/game/modules/tome/data/general/objects/egos/weapon.lua +++ b/game/modules/tome/data/general/objects/egos/weapon.lua @@ -29,7 +29,7 @@ newEntity{ level_range = {1, 50}, rarity = 5, combat = { - melee_project={[DamageType.FIRE] = resolvers.mbonus_material(25, 4)}, + melee_project={[DamageType.FIRE] = resolvers.mbonus_material("melee_project", 1, true)}, }, } newEntity{ @@ -39,7 +39,7 @@ newEntity{ level_range = {15, 50}, rarity = 5, combat = { - melee_project={[DamageType.ICE] = resolvers.mbonus_material(15, 4)}, + melee_project={[DamageType.ICE] = resolvers.mbonus_material("melee_project", 0.5, true)}, }, } newEntity{ @@ -49,7 +49,7 @@ newEntity{ level_range = {1, 50}, rarity = 5, combat = { - melee_project={[DamageType.ACID] = resolvers.mbonus_material(25, 4)}, + melee_project={[DamageType.ACID] = resolvers.mbonus_material("melee_project", 1, true)}, }, } newEntity{ @@ -59,18 +59,7 @@ newEntity{ level_range = {1, 50}, rarity = 5, combat = { - melee_project={[DamageType.LIGHTNING] = resolvers.mbonus_material(25, 4)}, - }, -} - -newEntity{ - power_source = {nature=true}, - name = "poisonous ", prefix=true, instant_resolve=true, - keywords = {poisonous=true}, - level_range = {1, 50}, - rarity = 5, - combat = { - melee_project={[DamageType.POISON] = resolvers.mbonus_material(45, 6)}, + melee_project={[DamageType.LIGHTNING] = resolvers.mbonus_material("melee_project", 1, true)}, }, } @@ -81,7 +70,7 @@ newEntity{ level_range = {10, 50}, rarity = 5, combat = { - melee_project={[DamageType.SLIME] = resolvers.mbonus_material(45, 6)}, + melee_project={[DamageType.SLIME] = resolvers.mbonus_material("melee_project", 0.5, true)}, }, } @@ -92,7 +81,7 @@ newEntity{ level_range = {1, 50}, rarity = 3, cost = 4, - wielder={combat_atk = resolvers.mbonus_material(20, 5)}, + combat = {max_acc = resolvers.mbonus_material("max_acc")}, } newEntity{ @@ -102,7 +91,7 @@ newEntity{ level_range = {1, 50}, rarity = 3, cost = 6, - combat={apr = resolvers.mbonus_material(20, 5)}, + combat = {apr = resolvers.mbonus_material("combat_apr", 4)}, } newEntity{ @@ -115,10 +104,10 @@ newEntity{ cost = 35, combat = { melee_project={ - [DamageType.FIRE] = resolvers.mbonus_material(25, 4), - [DamageType.ICE] = resolvers.mbonus_material(15, 4), - [DamageType.ACID] = resolvers.mbonus_material(25, 4), - [DamageType.LIGHTNING] = resolvers.mbonus_material(25, 4), + [DamageType.FIRE] = resolvers.mbonus_material("melee_project", 0.5, true), + [DamageType.ICE] = resolvers.mbonus_material("melee_project", 0.5, true), + [DamageType.ACID] = resolvers.mbonus_material("melee_project", 0.5, true), + [DamageType.LIGHTNING] = resolvers.mbonus_material("melee_project", 0.5, true), }, }, } @@ -131,7 +120,7 @@ newEntity{ rarity = 3, cost = 4, combat = { - dam = resolvers.mbonus_material(15, 5), + dam = resolvers.mbonus_material("dam", 1, true), }, } @@ -139,13 +128,13 @@ newEntity{ power_source = {arcane=true}, name = " of torment", suffix=true, instant_resolve=true, keywords = {torment=true}, - level_range = {15, 50}, + level_range = {1, 50}, rarity = 18, cost = 22, combat = { - special_on_hit = {desc="10% chance to torment the target", fct=function(combat, who, target) - if not rng.percent(10) then return end - local eff = rng.table{"stun", "blind", "pin", "teleport", "stone", "confusion", "silence", "knockback"} + special_on_hit = {desc="30% chance to torment the target", fct=function(combat, who, target) + if not rng.percent(30) then return end + local eff = rng.table{"stun", "blind", "pin", "confusion", "silence"} if not target:canBe(eff) then return end if not target:checkHit(who:combatAttack(combat), target:combatPhysicalResist(), 15) then return end if eff == "stun" then target:setEffect(target.EFF_STUNNED, 3, {}) @@ -153,8 +142,6 @@ newEntity{ elseif eff == "pin" then target:setEffect(target.EFF_PINNED, 3, {}) elseif eff == "confusion" then target:setEffect(target.EFF_CONFUSED, 3, {power=60}) elseif eff == "silence" then target:setEffect(target.EFF_SILENCED, 3, {}) - elseif eff == "knockback" then target:knockback(who.x, who.y, 3) - elseif eff == "teleport" then target:teleportRandom(target.x, target.y, 10) end end}, }, @@ -169,18 +156,30 @@ newEntity{ rarity = 25, cost = 35, wielder = { - combat_atk = resolvers.mbonus_material(10, 2), - inc_damage = { - [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 4), - }, - inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(4, 3), - [Stats.STAT_STR] = resolvers.mbonus_material(4, 3), - }, - stamina_regen_on_hit = resolvers.mbonus_material(23, 7, function(e, v) v=v/10 return 0, v end), + stamina_regen_on_hit = resolvers.mbonus_material("stamina_regen_on_hit"), + }, + combat = { + apr = resolvers.mbonus_material("combat_apr", 3), + dam = resolvers.mbonus_material("dam", 1, true), + }, +} + +newEntity{ + power_source = {nature=true}, + name = "insatiable ", prefix=true, instant_resolve=true, + keywords = {insatiable=true}, + level_range = {1, 50}, + greater_ego = 1, + rarity = 60, + cost = 40, + wielder = { + resource_leech_chance = resolvers.mbonus_material("resource_leech_chance"), + resource_leech_value = resolvers.mbonus_material("resource_leech_value", 2), }, combat = { - apr = resolvers.mbonus_material(8, 1), + melee_project = { + [DamageType.NATURE] = resolvers.mbonus_material("melee_project", 1, true), + }, }, } @@ -194,14 +193,11 @@ newEntity{ cost = 35, combat = { melee_project={ - [DamageType.BLIGHT] = resolvers.mbonus_material(25, 4), - [DamageType.DARKNESS] = resolvers.mbonus_material(25, 4), + [DamageType.BLIGHT] = resolvers.mbonus_material("melee_project", 1, true), + [DamageType.DARKNESS] = resolvers.mbonus_material("melee_project", 1, true), }, }, - wielder = { - see_invisible = resolvers.mbonus_material(20, 5), - combat_physcrit = resolvers.mbonus_material(10, 4), - }, + } newEntity{ @@ -211,8 +207,8 @@ newEntity{ level_range = {1, 50}, rarity = 3, cost = 4, - wielder = { - combat_physcrit = resolvers.mbonus_material(7, 3), + combat = { + critical_power = resolvers.mbonus_material("critical_power"), }, } @@ -224,10 +220,10 @@ newEntity{ rarity = 3, cost = 4, combat = { - melee_project={[DamageType.LIGHT] = resolvers.mbonus_material(45, 6)}, + melee_project={[DamageType.LIGHT] = resolvers.mbonus_material("melee_project", 1, true)}, }, } - +--[=[ newEntity{ power_source = {technique=true}, name = " of defense", suffix=true, instant_resolve=true, @@ -239,7 +235,7 @@ newEntity{ combat_def = resolvers.mbonus_material(7, 3), }, } - +]=] newEntity{ power_source = {technique=true}, name = " of ruin", suffix=true, instant_resolve=true, @@ -248,15 +244,11 @@ newEntity{ greater_ego = 1, rarity = 20, cost = 25, - wielder = { - inc_stats = { - [Stats.STAT_STR] = resolvers.mbonus_material(4, 3), - }, - combat_physcrit = resolvers.mbonus_material(7, 3), - combat_critical_power = resolvers.mbonus_material(10, 10), - combat_apr = resolvers.mbonus_material(7, 3), + combat = { + max_acc = resolvers.mbonus_material("max_acc"), + critical_power = resolvers.mbonus_material("critical_power"), + melee_project={[DamageType.TEMPORAL] = resolvers.mbonus_material("melee_project", 1, true)}, }, - } newEntity{ @@ -267,13 +259,9 @@ newEntity{ greater_ego = 1, rarity = 25, cost = 30, - combat = { physspeed = -0.1 }, - wielder = { - combat_atk = resolvers.mbonus_material(20, 2), - inc_stats = { - [Stats.STAT_DEX] = resolvers.mbonus_material(4, 3), - [Stats.STAT_CUN] = resolvers.mbonus_material(4, 3), - }, + combat = { + physspeed = resolvers.mbonus_material("physspeed"), + max_acc = resolvers.mbonus_material("max_acc"), }, } @@ -285,12 +273,9 @@ newEntity{ greater_ego = 1, rarity = 20, cost = 30, - wielder = { - combat_spellcrit = resolvers.mbonus_material(7, 3), - inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(4, 3), - [Stats.STAT_WIL] = resolvers.mbonus_material(4, 3), - }, + combat = { + affects_spells = true, + melee_project={[DamageType.ARCANE] = resolvers.mbonus_material("melee_project", 1, true)}, }, } @@ -303,16 +288,13 @@ newEntity{ rarity = 35, cost = 40, wielder = { - on_melee_hit = { - [DamageType.FIRE] = resolvers.mbonus_material(20, 5), - }, resists_pen = { - [DamageType.FIRE] = resolvers.mbonus_material(20, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists_pen", 2), }, }, combat = { melee_project = { - [DamageType.FIRE] = resolvers.mbonus_material(46, 5), + [DamageType.FIRE] = resolvers.mbonus_material("melee_project", 2, true), }, }, } @@ -326,16 +308,13 @@ newEntity{ rarity = 45, cost = 40, wielder = { - on_melee_hit = { - [DamageType.ICE] = resolvers.mbonus_material(20, 5), - }, resists_pen = { - [DamageType.COLD] = resolvers.mbonus_material(20, 5), + [DamageType.COLD] = resolvers.mbonus_material("resists_pen", 2), }, }, combat = { melee_project = { - [DamageType.COLD] = resolvers.mbonus_material(46, 5), + [DamageType.COLD] = resolvers.mbonus_material("melee_project", 2, true), }, }, } @@ -349,16 +328,13 @@ newEntity{ rarity = 35, cost = 40, wielder = { - on_melee_hit = { - [DamageType.LIGHTNING] = resolvers.mbonus_material(20, 5), - }, resists_pen = { - [DamageType.LIGHTNING] = resolvers.mbonus_material(20, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists_pen", 2), }, }, combat = { melee_project = { - [DamageType.LIGHTNING] = resolvers.mbonus_material(46, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("melee_project", 2, true), }, }, } @@ -372,16 +348,13 @@ newEntity{ rarity = 35, cost = 40, wielder = { - on_melee_hit = { - [DamageType.ACID] = resolvers.mbonus_material(20, 5), - }, resists_pen = { - [DamageType.ACID] = resolvers.mbonus_material(20, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists_pen", 2), }, }, combat = { melee_project = { - [DamageType.ACID] = resolvers.mbonus_material(46, 5), + [DamageType.ACID] = resolvers.mbonus_material("melee_project", 2, true), }, }, } @@ -395,16 +368,13 @@ newEntity{ rarity = 45, cost = 40, wielder = { - on_melee_hit = { - [DamageType.SLIME] = resolvers.mbonus_material(20, 5), - }, resists_pen = { - [DamageType.NATURE] = resolvers.mbonus_material(20, 5), + [DamageType.NATURE] = resolvers.mbonus_material("resists_pen", 2), }, }, combat = { melee_project = { - [DamageType.SLIME] = resolvers.mbonus_material(46, 5), + [DamageType.SLIME] = resolvers.mbonus_material("melee_project", 1, true), }, }, } @@ -418,15 +388,14 @@ newEntity{ rarity = 30, cost = 40, wielder = { - inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(9, 1), + talents_types_mastery = { + ["technique/combat-training"] = resolvers.mbonus_material("talents_types_mastery"), }, - disarm_immune = resolvers.mbonus_material(25, 10, function(e, v) v=v/100 return 0, v end), - combat_dam = resolvers.mbonus_material(15, 5), - resists_pen = { - [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 5), + learn_talent = { + [Talents.T_GREATER_WEAPON_FOCUS] = resolvers.mbonus_material("learn_talent"), }, }, + } newEntity{ @@ -437,13 +406,12 @@ newEntity{ greater_ego = 1, rarity = 20, cost = 40, + combat = { + apr = resolvers.mbonus_material("combat_apr", 5), + }, wielder = { - combat_apr = resolvers.mbonus_material(15, 5), - inc_damage = { - [DamageType.PHYSICAL] = resolvers.mbonus_material(10, 5), - }, resists_pen = { - [DamageType.PHYSICAL] = resolvers.mbonus_material(15, 5), + [DamageType.PHYSICAL] = resolvers.mbonus_material("resists_pen", 1, true), }, }, } @@ -456,18 +424,11 @@ newEntity{ greater_ego = 1, rarity = 30, cost = 60, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_EPIDEMIC, level = 4, power = 80 }, - wielder = { - inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), - [Stats.STAT_MAG] = resolvers.mbonus_material(5, 1), - }, - disease_immune = resolvers.mbonus_material(55, 10, function(e, v) v=v/100 return 0, v end), - }, + max_power = 20, power_regen = 1, + use_talent = { id = Talents.T_EPIDEMIC, level = 5, power = 10 }, combat = { melee_project = { - [DamageType.BLIGHT] = resolvers.mbonus_material(46, 5), + [DamageType.BLIGHT] = resolvers.mbonus_material("melee_project", 2, true), }, }, } @@ -481,7 +442,7 @@ newEntity{ rarity = 30, cost = 60, max_power = 20, power_regen = 1, - use_talent = { id = Talents.T_WAVE_OF_POWER, level = 4, power = 12 }, + use_talent = { id = Talents.T_WAVE_OF_POWER, level = 4, power = 10 }, } newEntity{ @@ -492,11 +453,10 @@ newEntity{ greater_ego = 1, rarity = 20, cost = 40, - max_power = 80, power_regen = 1, - use_talent = { id = Talents.T_LIFE_TAP, level = 3, power = 80 }, - wielder = { - combat_physcrit = resolvers.mbonus_material(4, 3), - combat_dam = resolvers.mbonus_material(12, 3), + max_power = 30, power_regen = 1, + use_talent = { id = Talents.T_LIFE_TAP, level = 5, power = 30 }, + combat = { + dam = resolvers.mbonus_material("dam", 2, true), }, } @@ -508,37 +468,39 @@ newEntity{ greater_ego = 1, rarity = 15, cost = 30, - wielder = { - resists={ - [DamageType.TEMPORAL] = resolvers.mbonus_material(15, 5), - }, - on_melee_hit = { - [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), - }, - }, combat = { melee_project = { - [DamageType.TEMPORAL] = resolvers.mbonus_material(46, 5), + [DamageType.TEMPORAL] = resolvers.mbonus_material("melee_project", 2, true), + [DamageType.RANDOM_CONFUSION] = resolvers.mbonus_material("melee_project", 0.5, true), }, }, } --[[ Todo: make it balanced newEntity{ - power_source = {nature=true}, - name = "insatiable ", prefix=true, instant_resolve=true, - keywords = {insatiable=true}, - level_range = {1, 50}, + power_source = {technique=true}, + name = " of concussion", suffix=true, instant_resolve=true, + keywords = {concussion=true}, + level_range = {10, 50}, greater_ego = 1, - rarity = 60, + rarity = 40, + cost = 40, + resolvers.generic(function(e) + e.combat.concussion = (e.combat.critical_power - 1) * 100 + end), +} + +newEntity{ + power_source = {technique=true}, + name = " of savagery", suffix=true, instant_resolve=true, + keywords = {savagery=true}, + level_range = {30, 50}, + greater_ego = 1, + rarity = 20, cost = 40, wielder = { - resource_leech_chance = resolvers.mbonus_material(4, 1, function(e, v) v=v*10 return 0, v end), - resource_leech_value = resolvers.mbonus_material(15, 5), - }, - combat = { - melee_project = { - [DamageType.NATURE] = resolvers.mbonus_material(25, 5), + learn_talent = { + [Talents.T_SAVAGERY] = resolvers.mbonus_material("learn_talent_5"), }, }, } diff --git a/game/modules/tome/data/general/objects/egos/wizard-hat.lua b/game/modules/tome/data/general/objects/egos/wizard-hat.lua index 4bbfe27cb6..c3fcb53539 100644 --- a/game/modules/tome/data/general/objects/egos/wizard-hat.lua +++ b/game/modules/tome/data/general/objects/egos/wizard-hat.lua @@ -32,9 +32,9 @@ newEntity{ rarity = 10, cost = 20, wielder = { - stamina_regen_on_hit = resolvers.mbonus_material(23, 7, function(e, v) v=v/10 return 0, v end), - equilibrium_regen_on_hit = resolvers.mbonus_material(23, 7, function(e, v) v=v/10 return 0, v end), - mana_regen_on_hit = resolvers.mbonus_material(23, 7, function(e, v) v=v/10 return 0, v end), + stamina_regen_on_hit = resolvers.mbonus_material("stamina_regen_on_hit"), + equilibrium_regen_on_hit = resolvers.mbonus_material("equilibrium_regen_on_hit"), + mana_regen_on_hit = resolvers.mbonus_material("mana_regen_on_hit"), }, } @@ -46,7 +46,7 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_MAG] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats") }, }, } newEntity{ @@ -57,7 +57,7 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_WIL] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats") }, }, } newEntity{ @@ -68,7 +68,7 @@ newEntity{ rarity = 6, cost = 4, wielder = { - inc_stats = { [Stats.STAT_CUN] = resolvers.mbonus_material(8, 2) }, + inc_stats = { [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats") }, }, } newEntity{ @@ -90,7 +90,7 @@ newEntity{ rarity = 10, cost = 4, wielder = { - max_mana = resolvers.mbonus_material(70, 40), + max_mana = resolvers.mbonus_material("max_mana"), }, } @@ -102,7 +102,7 @@ newEntity{ rarity = 5, cost = 6, wielder = { - blind_immune = resolvers.mbonus_material(3, 3, function(e, v) v=v/10 return 0, v end), + blind_immune = resolvers.mbonus_material("immunity"), }, } @@ -117,9 +117,9 @@ newEntity{ cost = 20, wielder = { resists={ - [DamageType.ARCANE] = resolvers.mbonus_material(5, 5), + [DamageType.ARCANE] = resolvers.mbonus_material("rare_resists"), }, - combat_spellpower = resolvers.mbonus_material(5, 3), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), }, max_power = 80, power_regen = 1, use_talent = { id = Talents.T_MANAFLOW, level = 1, power = 80 }, @@ -134,8 +134,8 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.FIRE] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.FIRE] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -149,9 +149,9 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.LIGHTNING] = resolvers.mbonus_material(10, 5), + [DamageType.LIGHTNING] = resolvers.mbonus_material("resists"), }, - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), }, } @@ -164,9 +164,9 @@ newEntity{ cost = 5, wielder = { resists={ - [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), + [DamageType.TEMPORAL] = resolvers.mbonus_material("resists"), }, - teleport_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + teleport_immune = resolvers.mbonus_material("immunity"), }, } @@ -178,8 +178,8 @@ newEntity{ rarity = 6, cost = 5, wielder = { - stun_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), - knockback_immune = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end), + stun_immune = resolvers.mbonus_material("immunity"), + knockback_immune = resolvers.mbonus_material("immunity"), }, } @@ -192,10 +192,10 @@ newEntity{ cost = 9, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), }, - poison_immune = resolvers.mbonus_material(10, 5, function(e, v) return 0, v/100 end), - disease_immune = resolvers.mbonus_material(10, 5, function(e, v) return 0, v/100 end), + poison_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), }, } @@ -207,7 +207,7 @@ newEntity{ rarity = 10, cost = 10, wielder = { - mana_regen = resolvers.mbonus_material(30, 10, function(e, v) v=v/100 return 0, v end), + mana_regen = resolvers.mbonus_material("mana_regen"), }, } @@ -220,10 +220,10 @@ newEntity{ rarity = 13, cost = 20, wielder = { - combat_spellcrit = resolvers.mbonus_material(3, 3), + combat_spellcrit = resolvers.mbonus_material("combat_spellcrit"), inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(3, 2), - [Stats.STAT_WIL] = resolvers.mbonus_material(3, 2), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats"), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats"), }, }, } @@ -238,10 +238,10 @@ newEntity{ cost = 20, wielder = { inc_damage = { - [DamageType.FIRE] = resolvers.mbonus_material(7, 5), - [DamageType.COLD] = resolvers.mbonus_material(7, 5), - [DamageType.ACID] = resolvers.mbonus_material(7, 5), - [DamageType.LIGHTNING] = resolvers.mbonus_material(7, 5), + [DamageType.FIRE] = resolvers.mbonus_material("inc_damage"), + [DamageType.COLD] = resolvers.mbonus_material("inc_damage"), + [DamageType.ACID] = resolvers.mbonus_material("inc_damage"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("inc_damage"), }, }, } @@ -255,10 +255,10 @@ newEntity{ rarity = 11, cost = 15, wielder = { - max_life=resolvers.mbonus_material(30, 30), - life_regen = resolvers.mbonus_material(15, 5, function(e, v) v=v/10 return 0, v end), + max_life=resolvers.mbonus_material("max_life"), + life_regen = resolvers.mbonus_material("life_regen"), talents_types_mastery = { - ["spell/aegis"] = resolvers.mbonus_material(30, 10, function(e, v) v=v/100 return 0, v end), + ["spell/aegis"] = resolvers.mbonus_material("talents_types_mastery"), }, }, } @@ -272,9 +272,9 @@ newEntity{ rarity = 17, cost = 20, wielder = { - disease_immune = resolvers.mbonus_material(30, 20, function(e, v) v=v/100 return 0, v end), - confusion_immune = resolvers.mbonus_material(30, 20, function(e, v) v=v/100 return 0, v end), - poison_immune = resolvers.mbonus_material(30, 10, function(e, v) return 0, v/100 end), + disease_immune = resolvers.mbonus_material("immunity"), + confusion_immune = resolvers.mbonus_material("immunity"), + poison_immune = resolvers.mbonus_material("immunity"), }, } @@ -288,16 +288,16 @@ newEntity{ cost = 40, wielder = { resists={ - [DamageType.TEMPORAL] = resolvers.mbonus_material(10, 5), + [DamageType.TEMPORAL] = resolvers.mbonus_material("resists"), }, inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(7, 1), - [Stats.STAT_WIL] = resolvers.mbonus_material(5, 1, function(e, v) return 0, -v end), - [Stats.STAT_CUN] = resolvers.mbonus_material(7, 1), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats", 2), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats", -1), + [Stats.STAT_CUN] = resolvers.mbonus_material("inc_stats", 2), }, - confusion_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, -v end), + confusion_immune = resolvers.mbonus_material("immunity", -1), talents_types_mastery = { - ["spell/temporal"] = resolvers.mbonus_material(2, 2, function(e, v) v=v/10 return 0, v end), + ["spell/temporal"] = resolvers.mbonus_material("talents_types_mastery"), }, }, } @@ -312,10 +312,10 @@ newEntity{ cost = 40, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - mana_regen = resolvers.mbonus_material(50, 10, function(e, v) v=v/100 return 0, v end), - combat_spellpower = resolvers.mbonus_material(7, 1), + mana_regen = resolvers.mbonus_material("mana_regen"), + combat_spellpower = resolvers.mbonus_material("combat_spellpower"), }, } @@ -329,11 +329,11 @@ newEntity{ cost = 60, wielder = { inc_damage = { - [DamageType.ACID] = resolvers.mbonus_material(7, 3), - [DamageType.LIGHTNING] = resolvers.mbonus_material(7, 3), - [DamageType.FIRE] = resolvers.mbonus_material(7, 3), - [DamageType.COLD] = resolvers.mbonus_material(7, 3), - [DamageType.ARCANE] = resolvers.mbonus_material(7, 3), + [DamageType.ACID] = resolvers.mbonus_material("inc_damage"), + [DamageType.LIGHTNING] = resolvers.mbonus_material("inc_damage"), + [DamageType.FIRE] = resolvers.mbonus_material("inc_damage"), + [DamageType.COLD] = resolvers.mbonus_material("inc_damage"), + [DamageType.ARCANE] = resolvers.mbonus_material("inc_damage"), }, }, } @@ -348,11 +348,11 @@ newEntity{ cost = 20, wielder = { resists={ - [DamageType.BLIGHT] = resolvers.mbonus_material(10, 5), + [DamageType.BLIGHT] = resolvers.mbonus_material("resists"), }, - poison_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - disease_immune = resolvers.mbonus_material(15, 10, function(e, v) v=v/100 return 0, v end), - combat_physresist = resolvers.mbonus_material(7, 3), + poison_immune = resolvers.mbonus_material("immunity"), + disease_immune = resolvers.mbonus_material("immunity"), + combat_physresist = resolvers.mbonus_material("save"), }, } @@ -365,10 +365,10 @@ newEntity{ rarity = 10, cost = 20, wielder = { - max_mana = resolvers.mbonus_material(40, 20), + max_mana = resolvers.mbonus_material("max_mana"), talents_types_mastery = { - ["spell/arcane"] = resolvers.mbonus_material(3, 1, function(e, v) v=v/10 return 0, v end), - ["spell/arcane-shield"] = resolvers.mbonus_material(3, 1, function(e, v) v=v/10 return 0, v end), + ["spell/arcane"] = resolvers.mbonus_material("talents_types_mastery"), + ["spell/arcane-shield"] = resolvers.mbonus_material("talents_types_mastery"), }, }, } @@ -385,13 +385,13 @@ newEntity{ use_talent = { id = Talents.T_HATEFUL_WHISPER, level = 4, power = 80 }, wielder = { resists={ - [DamageType.MIND] = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), + [DamageType.MIND] = resolvers.mbonus_material("rare_resists", -1), }, inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(9, 1), - [Stats.STAT_WIL] = resolvers.mbonus_material(9, 1), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats", 2), + [Stats.STAT_WIL] = resolvers.mbonus_material("inc_stats", 2), }, - combat_mentalresist = resolvers.mbonus_material(10, 5, function(e, v) return 0, -v end), + combat_mentalresist = resolvers.mbonus_material("save", -1), }, } @@ -407,9 +407,9 @@ newEntity{ use_talent = { id = Talents.T_STONE_WALL, level = 3, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_CON] = resolvers.mbonus_material(5, 1), + [Stats.STAT_CON] = resolvers.mbonus_material("inc_stats"), }, - combat_armor = resolvers.mbonus_material(5, 1), + combat_armor = resolvers.mbonus_material("combat_armor"), }, } @@ -425,8 +425,8 @@ newEntity{ use_talent = { id = Talents.T_CORROSIVE_VAPOUR, level = 3, power = 80 }, wielder = { resists={ - [DamageType.ACID] = resolvers.mbonus_material(10, 5), - [DamageType.COLD] = resolvers.mbonus_material(10, 5), + [DamageType.ACID] = resolvers.mbonus_material("resists"), + [DamageType.COLD] = resolvers.mbonus_material("resists"), }, }, } @@ -443,7 +443,7 @@ newEntity{ use_talent = { id = Talents.T_ARCANE_EYE, level = 5, power = 80 }, wielder = { inc_stats = { - [Stats.STAT_MAG] = resolvers.mbonus_material(9, 1), + [Stats.STAT_MAG] = resolvers.mbonus_material("inc_stats", 2), }, }, } diff --git a/game/modules/tome/data/general/objects/gauntlets.lua b/game/modules/tome/data/general/objects/gauntlets.lua index 124ff654eb..7b29063330 100644 --- a/game/modules/tome/data/general/objects/gauntlets.lua +++ b/game/modules/tome/data/general/objects/gauntlets.lua @@ -23,7 +23,7 @@ newEntity{ define_as = "BASE_GAUNTLETS", slot = "HANDS", type = "armor", subtype="hands", - add_name = " (#ARMOR#)", + add_name = " (#GLOVES#)", display = "[", color=colors.SLATE, image = resolvers.image_material("hgloves", "metal"), moddable_tile = resolvers.moddable_tile("gauntlets"), @@ -31,6 +31,7 @@ newEntity{ encumber = 1.5, rarity = 9, metallic = true, + wielder = {combat = {physspeed = -0.2}}, desc = [[Metal gloves protecting the hands up to the middle of the lower arm.]], randart_able = { attack=10, physical=10, spell=10, def=40, misc=30 }, egos = "/data/general/objects/egos/gloves.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, @@ -44,12 +45,10 @@ newEntity{ base = "BASE_GAUNTLETS", wielder = { combat_armor = 1, combat = { - dam = resolvers.rngavg(7, 12), - apr = 4, - physcrit = 1, - physspeed = -0.2, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, - damrange = 0.3, + dam = resolvers.cbonus(4, 10, 1, 2), + max_acc = resolvers.cbonus(10, 25, 1, 3), + critical_power = resolvers.cbonus(4, 14, 0.1, 3), + dammod = {dex=0.1, str=0, cun=0.1 }, }, }, } @@ -57,17 +56,15 @@ newEntity{ base = "BASE_GAUNTLETS", newEntity{ base = "BASE_GAUNTLETS", name = "dwarven-steel gauntlets", short_name = "d.steel", level_range = {20, 40}, - cost = 7, + cost = 25, material_level = 3, wielder = { combat_armor = 2, combat = { - dam = resolvers.rngavg(16, 22), - apr = 7, - physcrit = 1, - physspeed = -0.2, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, - damrange = 0.3, + dam = resolvers.cbonus(16), + max_acc = resolvers.cbonus(10, 25, 1, 4), + critical_power = resolvers.cbonus(4, 14, 0.1, 4), + dammod = {dex=0.2, str=0.1, cun=0.2 }, }, }, } @@ -75,17 +72,15 @@ newEntity{ base = "BASE_GAUNTLETS", newEntity{ base = "BASE_GAUNTLETS", name = "voratun gauntlets", short_name = "voratun", level_range = {40, 50}, - cost = 10, + cost = 35, material_level = 5, wielder = { combat_armor = 3, combat = { - dam = resolvers.rngavg(25, 32), - apr = 10, - physcrit = 3, - physspeed = -0.2, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, - damrange = 0.3, + dam = resolvers.cbonus(40), + max_acc = resolvers.cbonus(10, 25, 1, 5), + critical_power = resolvers.cbonus(4, 14, 0.1, 5), + dammod = {dex=0.4, str=0.3, cun=0.4 }, }, }, } diff --git a/game/modules/tome/data/general/objects/gloves.lua b/game/modules/tome/data/general/objects/gloves.lua index ffadd86d8c..d2b79c644b 100644 --- a/game/modules/tome/data/general/objects/gloves.lua +++ b/game/modules/tome/data/general/objects/gloves.lua @@ -23,12 +23,13 @@ newEntity{ define_as = "BASE_GLOVES", slot = "HANDS", type = "armor", subtype="hands", - add_name = " (#ARMOR#)", + add_name = " (#GLOVES#)", display = "[", color=colors.UMBER, image = resolvers.image_material("gloves", "leather"), moddable_tile = resolvers.moddable_tile("gloves"), encumber = 1, rarity = 9, + wielder = {combat = {physspeed = -0.333}}, desc = [[Light gloves which do not seriously hinder finger movements, while still protecting the hands somewhat.]], randart_able = { attack=10, physical=10, spell=10, def=30, misc=10 }, egos = "/data/general/objects/egos/gloves.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, @@ -42,11 +43,10 @@ newEntity{ base = "BASE_GLOVES", wielder = { combat_armor = 1, combat = { - dam = resolvers.rngavg(5, 8), - apr = 1, - physcrit = 4, - physspeed = -0.4, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, + dam = resolvers.cbonus(3, 10, 1, 2), + max_acc = resolvers.cbonus(10, 25, 1, 3), + critical_power = resolvers.cbonus(2, 12, 0.1, 3), + dammod = {dex=0.1, str=0, cun=0.1 }, }, }, } @@ -54,16 +54,15 @@ newEntity{ base = "BASE_GLOVES", newEntity{ base = "BASE_GLOVES", name = "hardened leather gloves", short_name = "hardened", level_range = {20, 40}, - cost = 7, + cost = 25, material_level = 3, wielder = { combat_armor = 2, combat = { - dam = resolvers.rngavg(14, 18), - apr = 1, - physcrit = 7, - physspeed = -0.4, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, + dam = resolvers.cbonus(12), + max_acc = resolvers.cbonus(10, 25, 1, 4), + critical_power = resolvers.cbonus(2, 12, 0.1, 4), + dammod = {dex=0.2, str=0.1, cun=0.2 }, }, }, } @@ -71,16 +70,15 @@ newEntity{ base = "BASE_GLOVES", newEntity{ base = "BASE_GLOVES", name = "drakeskin leather gloves", short_name = "drakeskin", level_range = {40, 50}, - cost = 10, + cost = 35, material_level = 5, wielder = { combat_armor = 3, combat = { - dam = resolvers.rngavg(23, 28), - apr = 3, - physcrit = 10, - physspeed = -0.4, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, + dam = resolvers.cbonus(30), + max_acc = resolvers.cbonus(10, 25, 1, 5), + critical_power = resolvers.cbonus(2, 12, 0.1, 5), + dammod = {dex=0.4, str=0.3, cun=0.4 }, }, }, } diff --git a/game/modules/tome/data/general/objects/knifes.lua b/game/modules/tome/data/general/objects/knifes.lua index da79b57621..b980e4c091 100644 --- a/game/modules/tome/data/general/objects/knifes.lua +++ b/game/modules/tome/data/general/objects/knifes.lua @@ -17,8 +17,11 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +local Talents = require "engine.interface.ActorTalents" + newEntity{ define_as = "BASE_KNIFE", + flavor_names = {"dagger", "dirk", "stiletto", "baselard"}, slot = "MAINHAND", offslot = "OFFHAND", type = "weapon", subtype="dagger", add_name = " (#COMBAT#)", @@ -27,7 +30,7 @@ newEntity{ encumber = 1, rarity = 5, metallic = true, - combat = { talented = "knife", damrange = 1.3, physspeed = 1, sound = {"actions/melee", pitch=1.2, vol=1.2}, sound_miss = {"actions/melee", pitch=1.2, vol=1.2} }, + combat = { talented = "knife", damrange = 1, physspeed = 0.666, sound = {"actions/melee", pitch=1.2, vol=1.2}, sound_miss = {"actions/melee", pitch=1.2, vol=1.2} }, desc = [[Sharp, short and deadly.]], randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 }, egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, @@ -40,10 +43,10 @@ newEntity{ base = "BASE_KNIFE", cost = 5, material_level = 1, combat = { - dam = resolvers.rngavg(4,6), - apr = 5, - physcrit = 4, - dammod = {dex=0.45,str=0.45}, + dam = resolvers.cbonus(3, 5, 1, 1.5), + max_acc = resolvers.cbonus(95, 100, 1, 1.5), + critical_power = resolvers.cbonus(16, 25, 0.1), + dammod = {dex=0.1, str=0.1}, }, } @@ -51,13 +54,13 @@ newEntity{ base = "BASE_KNIFE", name = "steel dagger", short_name = "steel", level_range = {10, 20}, require = { stat = { dex=16 }, }, - cost = 10, + cost = 30, material_level = 2, combat = { - dam = resolvers.rngavg(8,12), - apr = 6, - physcrit = 5, - dammod = {dex=0.45,str=0.45}, + dam = resolvers.cbonus(6, 10, 1, 2), + max_acc = resolvers.cbonus(95, 100, 1, 2), + critical_power = resolvers.cbonus(16, 25, 0.1, 2.5), + dammod = {dex=0.2, str=0.2}, }, } @@ -65,13 +68,13 @@ newEntity{ base = "BASE_KNIFE", name = "dwarven-steel dagger", short_name = "d.steel", level_range = {20, 30}, require = { stat = { dex=24 }, }, - cost = 15, + cost = 80, material_level = 3, combat = { - dam = resolvers.rngavg(14,22), - apr = 7, - physcrit = 6, - dammod = {dex=0.45,str=0.45}, + dam = resolvers.cbonus(12), + max_acc = resolvers.cbonus(95, 100, 1, 2.5), + critical_power = resolvers.cbonus(16, 25, 0.1, 3), + dammod = {dex=0.3, str=0.3}, }, } @@ -79,13 +82,13 @@ newEntity{ base = "BASE_KNIFE", name = "stralite dagger", short_name = "stralite", level_range = {30, 40}, require = { stat = { dex=35 }, }, - cost = 25, + cost = 120, material_level = 4, combat = { - dam = resolvers.rngavg(25,32), - apr = 9, - physcrit = 8, - dammod = {dex=0.45,str=0.45}, + dam = resolvers.cbonus(21), + max_acc = resolvers.cbonus(95, 100, 1, 3), + critical_power = resolvers.cbonus(16, 25, 0.1, 3.5), + dammod = {dex=0.4, str=0.4}, }, } @@ -93,12 +96,12 @@ newEntity{ base = "BASE_KNIFE", name = "voratun dagger", short_name = "voratun", level_range = {40, 50}, require = { stat = { dex=48 }, }, - cost = 35, + cost = 170, material_level = 5, combat = { - dam = resolvers.rngavg(36,40), - apr = 9, - physcrit = 10, - dammod = {dex=0.45,str=0.45}, + dam = resolvers.cbonus(30), + max_acc = resolvers.cbonus(95, 100, 1, 3.5), + critical_power = resolvers.cbonus(16, 25, 0.1, 4), + dammod = {dex=0.5, str=0.5}, }, } diff --git a/game/modules/tome/data/general/objects/maces.lua b/game/modules/tome/data/general/objects/maces.lua index 3dae70e3c6..b7db1c6fd6 100644 --- a/game/modules/tome/data/general/objects/maces.lua +++ b/game/modules/tome/data/general/objects/maces.lua @@ -19,6 +19,7 @@ newEntity{ define_as = "BASE_MACE", + flavor_names = {"cudgel", "mace", "flail", "dreadmace"}, slot = "MAINHAND", dual_wieldable = true, type = "weapon", subtype="mace", add_name = " (#COMBAT#)", @@ -27,7 +28,7 @@ newEntity{ encumber = 3, rarity = 5, metallic = true, - combat = { talented = "mace", damrange = 1.4, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2}}, + combat = { talented = "mace", damrange = 1, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2}}, desc = [[Blunt and deadly.]], randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 }, egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, @@ -40,10 +41,10 @@ newEntity{ base = "BASE_MACE", cost = 5, material_level = 1, combat = { - dam = resolvers.rngavg(6,9), - apr = 2, - physcrit = 0.5, - dammod = {str=1}, + dam = resolvers.cbonus(6), + max_acc = resolvers.cbonus(80, 100, 1, 3), + critical_power = resolvers.cbonus(15, 27, 0.1, 3), + dammod = {str=0.2}, }, } @@ -51,13 +52,13 @@ newEntity{ base = "BASE_MACE", name = "steel mace", short_name = "steel", level_range = {10, 20}, require = { stat = { str=16 }, }, - cost = 10, + cost = 30, material_level = 2, combat = { - dam = resolvers.rngavg(11,17), - apr = 3, - physcrit = 1, - dammod = {str=1}, + dam = resolvers.cbonus(12), + max_acc = resolvers.cbonus(80, 100, 1, 3.5), + critical_power = resolvers.cbonus(15, 27, 0.1, 3.5), + dammod = {str=0.4}, }, } @@ -65,13 +66,13 @@ newEntity{ base = "BASE_MACE", name = "dwarven-steel mace", short_name = "d.steel", level_range = {20, 30}, require = { stat = { str=24 }, }, - cost = 15, + cost = 80, material_level = 3, combat = { - dam = resolvers.rngavg(22,28), - apr = 4, - physcrit = 1.5, - dammod = {str=1}, + dam = resolvers.cbonus(24), + max_acc = resolvers.cbonus(80, 100, 1, 4), + critical_power = resolvers.cbonus(15, 27, 0.1, 4), + dammod = {str=0.6}, }, } @@ -79,13 +80,13 @@ newEntity{ base = "BASE_MACE", name = "stralite mace", short_name = "stralite", level_range = {30, 40}, require = { stat = { str=35 }, }, - cost = 25, + cost = 120, material_level = 4, combat = { - dam = resolvers.rngavg(33,40), - apr = 5, - physcrit = 2.5, - dammod = {str=1}, + dam = resolvers.cbonus(42), + max_acc = resolvers.cbonus(80, 100, 1, 4.5), + critical_power = resolvers.cbonus(15, 27, 0.1, 4.5), + dammod = {str=0.8}, }, } @@ -93,12 +94,12 @@ newEntity{ base = "BASE_MACE", name = "voratun mace", short_name = "voratun", level_range = {40, 50}, require = { stat = { str=48 }, }, - cost = 35, + cost = 170, material_level = 5, combat = { - dam = resolvers.rngavg(43,48), - apr = 6, - physcrit = 3, + dam = resolvers.cbonus(60), + max_acc = resolvers.cbonus(80, 100, 1, 5), + critical_power = resolvers.cbonus(15, 27, 0.1, 5), dammod = {str=1}, }, } diff --git a/game/modules/tome/data/general/objects/quest-artifacts.lua b/game/modules/tome/data/general/objects/quest-artifacts.lua index f3477f9a6a..049d45ad92 100644 --- a/game/modules/tome/data/general/objects/quest-artifacts.lua +++ b/game/modules/tome/data/general/objects/quest-artifacts.lua @@ -18,6 +18,7 @@ -- darkgod@te4.org local Stats = require "engine.interface.ActorStats" +local Talents = require "engine.interface.ActorTalents" -- The staff of absorption, the reason the game exists! newEntity{ define_as = "STAFF_ABSORPTION", @@ -26,8 +27,12 @@ newEntity{ define_as = "STAFF_ABSORPTION", slot = "MAINHAND", slot_forbid = "OFFHAND", type = "weapon", subtype="staff", + twohanded = true, unided_name = "dark runed staff", name = "Staff of Absorption", + flavor_name = "magestaff", + no_command = true, + material_level = 5, level_range = {30, 30}, display = "\\", color=colors.VIOLET, image = "object/artifact/staff_absorption.png", encumber = 7, @@ -35,17 +40,24 @@ newEntity{ define_as = "STAFF_ABSORPTION", Light around it seems to dim and you can feel its tremendous power simply by touching it.]], require = { stat = { mag=60 }, }, + modes = {"fire", "cold", "lightning", "arcane"}, combat = { - dam = 30, - apr = 4, - dammod = {mag=1}, + dam = 40, + max_acc = 100, + critical_power = 2, + dammod = {mag=0.6}, damtype = DamageType.ARCANE, + affects_spells = true, talented = "staff", + physspeed = 1, + damrange = 1, + sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2}, }, wielder = { combat_atk = 20, combat_spellpower = 20, combat_spellcrit = 10, + learn_talent = {[Talents.T_COMMAND_STAFF] = 1}, }, max_power = 1000, power_regen = 1, diff --git a/game/modules/tome/data/general/objects/shields.lua b/game/modules/tome/data/general/objects/shields.lua index 36f370fca1..8a70b824e8 100644 --- a/game/modules/tome/data/general/objects/shields.lua +++ b/game/modules/tome/data/general/objects/shields.lua @@ -23,7 +23,7 @@ newEntity{ define_as = "BASE_SHIELD", slot = "OFFHAND", type = "armor", subtype="shield", - add_name = " (#ARMOR#)", + add_name = " (#SHIELD#)", display = ")", color=colors.UMBER, image = resolvers.image_material("shield", "metal"), moddable_tile = resolvers.moddable_tile("shield"), rarity = 5, @@ -32,7 +32,7 @@ newEntity{ desc = [[Handheld deflection devices]], require = { talent = { {Talents.T_ARMOUR_TRAINING,3} }, }, randart_able = { attack=20, physical=10, spell=10, def=50, misc=10 }, - special_combat = { damrange = 1.2 }, + special_combat = { damrange = 1 }, egos = "/data/general/objects/egos/shield.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, } @@ -46,15 +46,17 @@ newEntity{ base = "BASE_SHIELD", cost = 5, material_level = 1, special_combat = { - dam = resolvers.rngavg(7,11), - physcrit = 2.5, - dammod = {str=1}, + dam = resolvers.cbonus(5), + block = resolvers.cbonus(20), + max_acc = 75, + critical_power = 1.1, + dammod = {str=0.2}, }, wielder = { - combat_armor = 2, - combat_def = 4, - combat_def_ranged = 4, fatigue = 6, + learn_talent = { + [Talents.T_BLOCK] = 1, + }, }, } @@ -62,17 +64,19 @@ newEntity{ base = "BASE_SHIELD", name = "steel shield", short_name = "steel", level_range = {10, 20}, require = { stat = { str=16 }, }, - cost = 10, + cost = 30, material_level = 2, special_combat = { - dam = resolvers.rngavg(10,20), - physcrit = 3, - dammod = {str=1}, + dam = resolvers.cbonus(10), + block = resolvers.cbonus(40), + max_acc = 75, + critical_power = 1.1, + dammod = {str=0.4}, }, wielder = { - combat_armor = 2, - combat_def = 6, - combat_def_ranged = 6, + learn_talent = { + [Talents.T_BLOCK] = 2, + }, fatigue = 8, }, } @@ -81,17 +85,19 @@ newEntity{ base = "BASE_SHIELD", name = "dwarven-steel shield", short_name = "d.steel", level_range = {20, 30}, require = { stat = { str=24 }, }, - cost = 15, + cost = 80, material_level = 3, special_combat = { - dam = resolvers.rngavg(25,35), - physcrit = 3.5, - dammod = {str=1}, + dam = resolvers.cbonus(20), + block = resolvers.cbonus(80), + max_acc = 75, + critical_power = 1.1, + dammod = {str=0.6}, }, wielder = { - combat_armor = 2, - combat_def = 8, - combat_def_ranged = 8, + learn_talent = { + [Talents.T_BLOCK] = 3, + }, fatigue = 12, }, } @@ -100,17 +106,19 @@ newEntity{ base = "BASE_SHIELD", name = "stralite shield", short_name = "stralite", level_range = {30, 40}, require = { stat = { str=35 }, }, - cost = 25, + cost = 120, material_level = 4, special_combat = { - dam = resolvers.rngavg(40,55), - physcrit = 4.5, - dammod = {str=1}, + dam = resolvers.cbonus(35), + block = resolvers.cbonus(140), + max_acc = 75, + critical_power = 1.1, + dammod = {str=0.8}, }, wielder = { - combat_armor = 2, - combat_def = 10, - combat_def_ranged = 10, + learn_talent = { + [Talents.T_BLOCK] = 4, + }, fatigue = 14, }, } @@ -119,17 +127,19 @@ newEntity{ base = "BASE_SHIELD", name = "voratun shield", short_name = "voratun", level_range = {40, 50}, require = { stat = { str=48 }, }, - cost = 35, + cost = 170, material_level = 5, special_combat = { - dam = resolvers.rngavg(60,75), - physcrit = 5, + dam = resolvers.cbonus(50), + block = resolvers.cbonus(200), + max_acc = 75, + critical_power = 1.1, dammod = {str=1}, }, wielder = { - combat_armor = 3, - combat_def = 12, - combat_def_ranged = 12, + learn_talent = { + [Talents.T_BLOCK] = 5, + }, fatigue = 14, }, } diff --git a/game/modules/tome/data/general/objects/slings.lua b/game/modules/tome/data/general/objects/slings.lua index 243f66d1c1..c66d3323c8 100644 --- a/game/modules/tome/data/general/objects/slings.lua +++ b/game/modules/tome/data/general/objects/slings.lua @@ -23,6 +23,7 @@ newEntity{ define_as = "BASE_SLING", slot = "MAINHAND", type = "weapon", subtype="sling", + add_name = " (#COMBAT_RANGED#)", display = "}", color=colors.UMBER, image = resolvers.image_material("sling", "leather"), moddable_tile = resolvers.moddable_tile("sling"), encumber = 4, @@ -31,7 +32,6 @@ newEntity{ archery = "sling", require = { talent = { Talents.T_SHOOT }, }, proj_image = resolvers.image_material("shot_s", "metal"), - basic_ammo = { talented = "sling", damrange = 1.2}, desc = [[Slings are used to hurl stones or metal shots at your foes.]], randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 }, egos = "/data/general/objects/egos/sling.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, @@ -41,17 +41,13 @@ newEntity{ base = "BASE_SLING", name = "rough leather sling", short_name = "rough", level_range = {1, 10}, require = { stat = { dex=11 }, }, - cost = 5, + cost = 1, material_level = 1, combat = { + dam = resolvers.cbonus(2, 4, 1, 1), + critical_power = resolvers.cbonus(15, 27, 0.1, 3), range = 6, - physspeed = 0.8, - }, - basic_ammo = { - dam = resolvers.rngavg(7,12), - apr = 1, - physcrit = 4, - dammod = {dex=0.7, cun=0.5}, + dammod = {dex=0.1, cun=0.1}, }, } @@ -62,14 +58,10 @@ newEntity{ base = "BASE_SLING", cost = 10, material_level = 2, combat = { + dam = resolvers.cbonus(4, 8, 1, 1), + critical_power = resolvers.cbonus(15, 27, 0.1, 3.5), range = 7, - physspeed = 0.8, - }, - basic_ammo = { - dam = resolvers.rngavg(15,22), - apr = 2, - physcrit = 4.5, - dammod = {dex=0.7, cun=0.5}, + dammod = {dex=0.2, cun=0.2}, }, } @@ -80,14 +72,10 @@ newEntity{ base = "BASE_SLING", cost = 15, material_level = 3, combat = { + dam = resolvers.cbonus(8), + critical_power = resolvers.cbonus(15, 27, 0.1, 4), range = 8, - physspeed = 0.8, - }, - basic_ammo = { - dam = resolvers.rngavg(28,37), - apr = 3, - physcrit = 5, - dammod = {dex=0.7, cun=0.5}, + dammod = {dex=0.3, cun=0.3}, }, } @@ -98,14 +86,10 @@ newEntity{ base = "BASE_SLING", cost = 25, material_level = 4, combat = { + dam = resolvers.cbonus(14), + critical_power = resolvers.cbonus(15, 27, 0.1, 4.5), range = 9, - physspeed = 0.8, - }, - basic_ammo = { - dam = resolvers.rngavg(40,47), - apr = 5, - physcrit = 5.5, - dammod = {dex=0.7, cun=0.5}, + dammod = {dex=0.4, cun=0.4}, }, } @@ -116,102 +100,112 @@ newEntity{ base = "BASE_SLING", cost = 35, material_level = 5, combat = { + dam = resolvers.cbonus(20), + critical_power = resolvers.cbonus(15, 27, 0.1, 5), range = 10, - physspeed = 0.8, - }, - basic_ammo = { - dam = resolvers.rngavg(50, 57), - apr = 6, - physcrit = 7, - dammod = {dex=0.7, cun=0.5}, + dammod = {dex=0.5, cun=0.5}, }, } ------------------ AMMO ------------------- newEntity{ - define_as = "BASE_SHOT", + define_as = "BASE_SHOT_POUCH", slot = "QUIVER", type = "ammo", subtype="shot", - add_name = " (#COMBAT#)", + add_name = " (#COMBAT_QUIVER#)", display = "{", color=colors.UMBER, image = resolvers.image_material("shot", "metal"), - encumber = 0.03, + encumber = 3, rarity = 11, - combat = { talented = "sling", damrange = 1.2}, + combat = { talented = "sling", damrange = 1}, proj_image = resolvers.image_material("shot_s", "metal"), archery_ammo = "sling", - desc = [[Shots are used with slings to pummel your foes to death.]], - generate_stack = resolvers.rngavg(100,200), - egos = "/data/general/objects/egos/ammo.lua", egos_chance = {100, resolvers.mbonus(30, 5)}, - stacking = true, + desc = [[Shots are used with slings to pummel your foes.]], + egos = "/data/general/objects/egos/ammo.lua", + egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, } -newEntity{ base = "BASE_SHOT", - name = "iron shot", short_name = "iron", +newEntity{ base = "BASE_SHOT_POUCH", + name = "pouch of iron shot", short_name = "iron", level_range = {1, 10}, require = { stat = { dex=11 }, }, - cost = 0.05, + cost = 1, material_level = 1, combat = { - dam = resolvers.rngavg(7,12), - apr = 1, - physcrit = 4, - dammod = {dex=0.7, cun=0.5}, + capacity = resolvers.cbonus(40), + dam = resolvers.cbonus(2, 4, 1, 1), + max_acc = resolvers.cbonus(80, 100, 1, 3), + dammod = {dex=0.1}, + shots_left = 40, }, + wielder = {}, + --learn_talent = {[Talents.T_RELOAD] = 1}, } -newEntity{ base = "BASE_SHOT", - name = "steel shot", short_name = "steel", +newEntity{ base = "BASE_SHOT_POUCH", + name = "pouch of steel shot", short_name = "steel", level_range = {10, 20}, require = { stat = { dex=16 }, }, - cost = 0.10, + cost = 10, material_level = 2, combat = { - dam = resolvers.rngavg(15,22), - apr = 2, - physcrit = 4.5, - dammod = {dex=0.7, cun=0.5}, + capacity = resolvers.cbonus(40), + dam = resolvers.cbonus(4, 8, 1, 1), + max_acc = resolvers.cbonus(80, 100, 1, 3.5), + dammod = {dex=0.2}, + shots_left = 40, }, + wielder = {}, + learn_talent = {[Talents.T_RELOAD] = 1}, } -newEntity{ base = "BASE_SHOT", - name = "dwarven-steel shot", short_name = "d.steel", +newEntity{ base = "BASE_SHOT_POUCH", + name = "pouch of dwarven-steel shot", short_name = "d.steel", level_range = {20, 30}, require = { stat = { dex=24 }, }, - cost = 0.15, + cost = 15, material_level = 3, combat = { - dam = resolvers.rngavg(28,37), - apr = 3, - physcrit = 5, - dammod = {dex=0.7, cun=0.5}, + capacity = resolvers.cbonus(40), + dam = resolvers.cbonus(8), + max_acc = resolvers.cbonus(80, 100, 1, 4), + dammod = {dex=0.3}, + shots_left = 40, }, + wielder = {}, + learn_talent = {[Talents.T_RELOAD] = 1}, } -newEntity{ base = "BASE_SHOT", - name = "stralite shot", short_name = "stralite", +newEntity{ base = "BASE_SHOT_POUCH", + name = "pouch of stralite shot", short_name = "stralite", level_range = {30, 40}, require = { stat = { dex=35 }, }, - cost = 0.25, + cost = 25, material_level = 4, combat = { - dam = resolvers.rngavg(40,47), - apr = 5, - physcrit = 5.5, - dammod = {dex=0.7, cun=0.5}, + capacity = resolvers.cbonus(40), + dam = resolvers.cbonus(14), + max_acc = resolvers.cbonus(80, 100, 1, 4.5), + dammod = {dex=0.4}, + shots_left = 40, }, + wielder = {}, + learn_talent = {[Talents.T_RELOAD] = 2}, } -newEntity{ base = "BASE_SHOT", - name = "voratun shot", short_name = "voratun", +newEntity{ base = "BASE_SHOT_POUCH", + name = "pouch of voratun shot", short_name = "voratun", level_range = {40, 50}, require = { stat = { dex=48 }, }, - cost = 0.35, + cost = 35, material_level = 5, combat = { - dam = resolvers.rngavg(50, 57), - apr = 6, - physcrit = 7, - dammod = {dex=0.7, cun=0.5}, + capacity = resolvers.cbonus(40), + dam = resolvers.cbonus(20), + max_acc = resolvers.cbonus(80, 100, 1, 5), + dammod = {dex=0.5}, + shots_left = 40, }, + wielder = {}, + learn_talent = {[Talents.T_RELOAD] = 2}, } diff --git a/game/modules/tome/data/general/objects/staves.lua b/game/modules/tome/data/general/objects/staves.lua index 5aca68510f..46996e9a98 100644 --- a/game/modules/tome/data/general/objects/staves.lua +++ b/game/modules/tome/data/general/objects/staves.lua @@ -17,27 +17,30 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +local Talents = require "engine.interface.ActorTalents" + newEntity{ define_as = "BASE_STAFF", + flavor_names = {"staff", "magestaff", "starstaff", "earthstaff"}, slot = "MAINHAND", slot_forbid = "OFFHAND", type = "weapon", subtype="staff", twohanded = true, - add_name = " (#COMBAT_DAMTYPE#)", + add_name = " (#COMBAT_STAFF#)", display = "\\", color=colors.LIGHT_RED, image = resolvers.image_material("staff", "wood"), moddable_tile = resolvers.moddable_tile("staff"), randart_able = { attack=10, physical=40, spell=80, def=10, misc=10 }, encumber = 5, rarity = 4, combat = { + affects_spells = true, talented = "staff", physspeed = 1, - damrange = 1.2, + damrange = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2}, - damtype = resolvers.rngtable{DamageType.FIRE, DamageType.COLD, DamageType.ACID, DamageType.LIGHTNING, DamageType.LIGHT, DamageType.DARKNESS, DamageType.NATURE, DamageType.BLIGHT}, }, desc = [[Staves designed for wielders of magic, by the greats of the art.]], - egos = "/data/general/objects/egos/staves.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, + egos = "/data/general/objects/egos/weapon-test.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, } newEntity{ base = "BASE_STAFF", @@ -47,85 +50,70 @@ newEntity{ base = "BASE_STAFF", cost = 5, material_level = 1, combat = { - dam = resolvers.rngavg(3,5), - apr = 2, - physcrit = 2.5, - dammod = {mag=1}, - }, - wielder = { - combat_spellpower = 1, - combat_spellcrit = 1, + dam = resolvers.cbonus(5, 10, 1, 2), + max_acc = resolvers.cbonus(90, 100, 1, 3), + critical_power = resolvers.cbonus(15, 25, 0.1), + dammod = {mag=0.1}, }, + wielder = resolvers.staff_wielder(), } newEntity{ base = "BASE_STAFF", name = "ash staff", short_name = "ash", level_range = {10, 20}, require = { stat = { mag=16 }, }, - cost = 10, + cost = 30, material_level = 2, combat = { - dam = resolvers.rngavg(7,11), - apr = 3, - physcrit = 3, - dammod = {mag=1}, - }, - wielder = { - combat_spellpower = 2, - combat_spellcrit = 2, + dam = resolvers.cbonus(10, 20, 1, 3), + max_acc = resolvers.cbonus(90, 100, 1, 3.5), + critical_power = resolvers.cbonus(15, 25, 0.1, 3), + dammod = {mag=0.2}, }, + wielder = resolvers.staff_wielder(), } newEntity{ base = "BASE_STAFF", name = "yew staff", short_name = "yew", level_range = {20, 30}, require = { stat = { mag=24 }, }, - cost = 15, + cost = 80, material_level = 3, combat = { - dam = resolvers.rngavg(14,22), - apr = 4, - physcrit = 3.5, - dammod = {mag=1}, - }, - wielder = { - combat_spellpower = 3, - combat_spellcrit = 3, + dam = resolvers.cbonus(20, 30, 1, 3), + max_acc = resolvers.cbonus(90, 100, 1, 4), + critical_power = resolvers.cbonus(15, 25, 0.1, 3.5), + dammod = {mag=0.3}, }, + wielder = resolvers.staff_wielder(), } newEntity{ base = "BASE_STAFF", name = "elven-wood staff", short_name = "e.wood", level_range = {30, 40}, require = { stat = { mag=35 }, }, - cost = 25, + cost = 120, material_level = 4, combat = { - dam = resolvers.rngavg(24,28), - apr = 5, - physcrit = 4.5, - dammod = {mag=1}, - }, - wielder = { - combat_spellpower = 4, - combat_spellcrit = 4, + dam = resolvers.cbonus(30, 40, 1, 3), + max_acc = resolvers.cbonus(90, 100, 1, 4.5), + critical_power = resolvers.cbonus(15, 25, 0.1, 4), + dammod = {mag=0.4}, }, + wielder = resolvers.staff_wielder(), } newEntity{ base = "BASE_STAFF", name = "dragonbone staff", short_name = "dragonbone", level_range = {40, 50}, require = { stat = { mag=48 }, }, - cost = 35, + cost = 170, material_level = 5, combat = { - dam = resolvers.rngavg(32,38), - apr = 6, - physcrit = 5, - dammod = {mag=1}, - }, - wielder = { - combat_spellpower = 7, - combat_spellcrit = 5, + dam = resolvers.cbonus(40, 50, 1, 4), + max_acc = resolvers.cbonus(90, 100, 1, 5), + critical_power = resolvers.cbonus(15, 25, 0.1, 4.5), + dammod = {mag=0.5}, }, + wielder = resolvers.staff_wielder(), } diff --git a/game/modules/tome/data/general/objects/swords.lua b/game/modules/tome/data/general/objects/swords.lua index d39d1c15e8..103a97676d 100644 --- a/game/modules/tome/data/general/objects/swords.lua +++ b/game/modules/tome/data/general/objects/swords.lua @@ -19,6 +19,7 @@ newEntity{ define_as = "BASE_LONGSWORD", + flavor_names = {"shortsword", "longsword", "scimitar", "warsword"}, slot = "MAINHAND", dual_wieldable = true, type = "weapon", subtype="longsword", add_name = " (#COMBAT#)", @@ -27,7 +28,7 @@ newEntity{ encumber = 3, rarity = 5, metallic = true, - combat = { talented = "sword", damrange = 1.4, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2}}, + combat = { talented = "sword", damrange = 1, physspeed = 1, sound = {"actions/melee", pitch=0.6, vol=1.2}, sound_miss = {"actions/melee", pitch=0.6, vol=1.2}}, desc = [[Sharp, long, and deadly.]], randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 }, egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, @@ -40,10 +41,10 @@ newEntity{ base = "BASE_LONGSWORD", cost = 5, material_level = 1, combat = { - dam = resolvers.rngavg(5,8), - apr = 2, - physcrit = 2.5, - dammod = {str=1}, + dam = resolvers.cbonus(5), + max_acc = resolvers.cbonus(90, 100, 1, 3), + critical_power = resolvers.cbonus(13, 25, 0.1), + dammod = {str=0.2}, }, } @@ -51,13 +52,13 @@ newEntity{ base = "BASE_LONGSWORD", name = "steel longsword", short_name = "steel", level_range = {10, 20}, require = { stat = { str=16 }, }, - cost = 10, + cost = 30, material_level = 2, combat = { - dam = resolvers.rngavg(10,16), - apr = 3, - physcrit = 3, - dammod = {str=1}, + dam = resolvers.cbonus(10), + max_acc = resolvers.cbonus(90, 100, 1, 3.5), + critical_power = resolvers.cbonus(13, 25, 0.1, 3.5), + dammod = {str=0.4}, }, } @@ -65,13 +66,13 @@ newEntity{ base = "BASE_LONGSWORD", name = "dwarven-steel longsword", short_name = "d.steel", level_range = {20, 30}, require = { stat = { str=24 }, }, - cost = 15, + cost = 80, material_level = 3, combat = { - dam = resolvers.rngavg(20,26), - apr = 4, - physcrit = 3.5, - dammod = {str=1}, + dam = resolvers.cbonus(20), + max_acc = resolvers.cbonus(90, 100, 1, 4), + critical_power = resolvers.cbonus(13, 25, 0.1, 4), + dammod = {str=0.6}, }, } @@ -79,13 +80,13 @@ newEntity{ base = "BASE_LONGSWORD", name = "stralite longsword", short_name = "stralite", level_range = {30, 40}, require = { stat = { str=35 }, }, - cost = 25, + cost = 120, material_level = 4, combat = { - dam = resolvers.rngavg(30,37), - apr = 5, - physcrit = 4.5, - dammod = {str=1}, + dam = resolvers.cbonus(35), + max_acc = resolvers.cbonus(90, 100, 1, 4.5), + critical_power = resolvers.cbonus(13, 25, 0.1, 4.5), + dammod = {str=0.8}, }, } @@ -93,12 +94,12 @@ newEntity{ base = "BASE_LONGSWORD", name = "voratun longsword", short_name = "voratun", level_range = {40, 50}, require = { stat = { str=48 }, }, - cost = 35, + cost = 170, material_level = 5, combat = { - dam = resolvers.rngavg(40,45), - apr = 6, - physcrit = 5, + dam = resolvers.cbonus(50), + max_acc = resolvers.cbonus(90, 100, 1, 5), + critical_power = resolvers.cbonus(13, 25, 0.1, 5), dammod = {str=1}, }, } diff --git a/game/modules/tome/data/general/objects/whips.lua b/game/modules/tome/data/general/objects/whips.lua index 9aa0a4bdc5..de5541427d 100644 --- a/game/modules/tome/data/general/objects/whips.lua +++ b/game/modules/tome/data/general/objects/whips.lua @@ -19,6 +19,7 @@ newEntity{ define_as = "BASE_WHIP", + flavor_names = {"whip", "horsewhip", "bullwhip", "warlash"}, slot = "MAINHAND", offslot = "OFFHAND", type = "weapon", subtype="whip", add_name = " (#COMBAT#)", @@ -27,7 +28,7 @@ newEntity{ encumber = 3, rarity = 5, metallic = true, - combat = { talented = "whip", damrange = 1.1, sound = "actions/melee", sound_miss = "actions/melee_miss",}, + combat = { talented = "whip", damrange = 1, sound = "actions/melee", sound_miss = "actions/melee_miss",}, desc = [[Sharp, long and deadly.]], randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 }, egos = "/data/general/objects/egos/weapon.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) }, diff --git a/game/modules/tome/data/general/objects/world-artifacts-far-east.lua b/game/modules/tome/data/general/objects/world-artifacts-far-east.lua index 2d770903f0..3660a164c2 100644 --- a/game/modules/tome/data/general/objects/world-artifacts-far-east.lua +++ b/game/modules/tome/data/general/objects/world-artifacts-far-east.lua @@ -89,8 +89,10 @@ newEntity{ base = "BASE_SHIELD", cost = 400, material_level = 5, special_combat = { - dam = 50, - physcrit = 4.5, + dam = 60, + block = 280, + max_acc = 90, + critical_power = 1.1, dammod = {str=1}, damtype = DamageType.LIGHT, }, diff --git a/game/modules/tome/data/general/objects/world-artifacts.lua b/game/modules/tome/data/general/objects/world-artifacts.lua index 5ff7ceec52..3237bf96ad 100644 --- a/game/modules/tome/data/general/objects/world-artifacts.lua +++ b/game/modules/tome/data/general/objects/world-artifacts.lua @@ -27,10 +27,11 @@ for def, e in pairs(game.state:getWorldArtifacts()) do end -- This file describes artifacts not bound to a special location, they can be found anywhere -newEntity{ base = "BASE_STAFF", +newEntity{ base = "BASE_STAFF", define_as = "STAFF_DESTRUCTION", power_source = {arcane=true}, unique = true, name = "Staff of Destruction", + flavor_name = "magestaff", unided_name = "darkness infused staff", image = "object/artifact/staff_of_destruction.png", level_range = {20, 25}, color=colors.VIOLET, @@ -40,26 +41,32 @@ newEntity{ base = "BASE_STAFF", material_level = 3, require = { stat = { mag=24 }, }, + modes = {"fire", "cold", "lightning", "arcane"}, combat = { - dam = 15, - apr = 4, - dammod = {mag=1.5}, + dam = 25, + max_acc = 95, + critical_power = 2, + dammod = {mag=0.4}, damtype = DamageType.ARCANE, + is_greater = true, }, wielder = { combat_spellpower = 10, - combat_spellcrit = 15, inc_damage={ - [DamageType.FIRE] = resolvers.mbonus(25, 8), - [DamageType.LIGHTNING] = resolvers.mbonus(25, 8), + [DamageType.FIRE] = 25, + [DamageType.LIGHTNING] = 25, + [DamageType.COLD] = 25, + [DamageType.ARCANE] = 25, }, + learn_talent = {[Talents.T_COMMAND_STAFF] = 4}, }, } -newEntity{ base = "BASE_STAFF", +newEntity{ base = "BASE_STAFF", define_as = "STAFF_PENITENCE", power_source = {arcane=true}, unique = true, name = "Penitence", + flavor_name = "earthstaff", unided_name = "glowing staff", image = "object/artifact/staff_penitence.png", level_range = {10, 18}, color=colors.VIOLET, @@ -69,18 +76,22 @@ newEntity{ base = "BASE_STAFF", material_level = 2, require = { stat = { mag=24 }, }, + modes = {"acid", "blight", "nature"}, combat = { - dam = 10, - apr = 4, - dammod = {mag=1.2}, - damtype = DamageType.ARCANE, + sentient = "penitent", + dam = 15, + max_acc = 98, + critical_power = 1.5, + dammod = {mag=0.2}, + damtype = DamageType.NATURE, }, wielder = { combat_spellpower = 15, - combat_spellcrit = 10, resists = { [DamageType.BLIGHT] = 30, }, + inc_damage = {[DamageType.NATURE] = 15}, + learn_talent = {[Talents.T_COMMAND_STAFF] = 3}, }, max_power = 60, power_regen = 1, use_power = { name = "cure diseases", power = 10, @@ -113,9 +124,10 @@ newEntity{ base = "BASE_STAFF", } newEntity{ base = "BASE_STAFF", - power_source = {arcane=true}, + power_source = {arcane=true}, define_as = "STAFF_TARELION", unique = true, name = "Lost Staff of Archmage Tarelion", image = "object/artifact/staff_lost_staff_archmage_tarelion.png", + flavor_name = "magestaff", unided_name = "shining staff", level_range = {37, 50}, color=colors.VIOLET, @@ -125,18 +137,21 @@ newEntity{ base = "BASE_STAFF", material_level = 5, require = { stat = { mag=48 }, }, + modes = {"fire", "cold", "lightning", "arcane"}, combat = { - dam = 38, - apr = 4, - dammod = {mag=1.5}, + is_greater = true, + of_retribution = true, + dam = 40, + max_acc = 90, + critical_power = 1.8, + dammod = {mag=0.7}, damtype = DamageType.ARCANE, }, wielder = { inc_stats = { [Stats.STAT_WIL] = 7, [Stats.STAT_MAG] = 8 }, max_mana = 40, - combat_spellpower = 40, - combat_spellcrit = 25, - inc_damage = { [DamageType.ARCANE] = 24, [DamageType.FIRE] = 24, [DamageType.COLD] = 24, [DamageType.LIGHTNING] = 24, }, + combat_spellpower = 20, + inc_damage = { [DamageType.ARCANE] = 40, [DamageType.FIRE] = 40, [DamageType.COLD] = 40, [DamageType.LIGHTNING] = 40}, silence_immune = 0.4, mana_on_crit = 12, talent_cd_reduction={ @@ -144,10 +159,12 @@ newEntity{ base = "BASE_STAFF", [Talents.T_FIREFLASH] = 2, [Talents.T_CHAIN_LIGHTNING] = 2, }, + learn_talent = {[Talents.T_COMMAND_STAFF] = 5, [Talents.T_ELEMENTAL_RETRIBUTION] = 5}, + elemental_retribution = {[DamageType.ARCANE] = 1, [DamageType.FIRE] = 1, [DamageType.COLD] = 1, [DamageType.LIGHTNING] = 1}, }, } -newEntity{ base = "BASE_STAFF", +newEntity{ base = "BASE_STAFF", define_as = "STAFF_BOLBUM", power_source = {arcane=true}, unique = true, name = "Bolbum's Big Knocker", image = "object/artifact/staff_bolbums_big_knocker.png", @@ -161,9 +178,11 @@ newEntity{ base = "BASE_STAFF", require = { stat = { mag=38 }, }, combat = { - dam = 64, - apr = 10, - dammod = {mag=1.4}, + of_retribution = true, + dam = 50, + max_acc = 90, + critical_power = 1.8, + dammod = {mag=0.7}, damtype = DamageType.PHYSICAL, }, wielder = { @@ -171,11 +190,13 @@ newEntity{ base = "BASE_STAFF", combat_spellpower = 12, combat_spellcrit = 18, inc_damage={ - [DamageType.PHYSICAL] = resolvers.mbonus(20, 8), + [DamageType.PHYSICAL] = 50, }, talents_types_mastery = { ["spell/staff-combat"] = 0.2, - } + }, + learn_talent = {[Talents.T_ELEMENTAL_RETRIBUTION] = 4}, + elemental_retribution = {[DamageType.PHYSICAL] = 1}, }, } @@ -507,21 +528,18 @@ newEntity{ base = "BASE_LONGBOW", cost = 800, material_level = 5, combat = { + dam = 35, + critical_power = 2, range = 10, + dammod = {dex=0.5}, + apr = 30, physspeed = 0.7, - apr = 12, - }, - basic_ammo = { - dam = 57, - apr = 18, - physcrit = 3, - dammod = {dex=0.7, str=0.5}, + ranged_project={[DamageType.LIGHT] = 30}, }, wielder = { inc_damage={ [DamageType.PHYSICAL] = 12, }, lite = 1, - inc_stats = { [Stats.STAT_DEX] = 5, [Stats.STAT_WIL] = 4, }, - ranged_project={[DamageType.LIGHT] = 30}, + inc_stats = { [Stats.STAT_DEX] = 5, [Stats.STAT_WIL] = 4, }, }, } @@ -535,18 +553,15 @@ newEntity{ base = "BASE_LONGBOW", cost = 50, material_level = 2, combat = { + dam = 10, + critical_power = 1.8, range = 7, - physspeed = 0.8, - }, - basic_ammo = { - dam = 20, + dammod = {dex=0.2}, apr = 7, - physcrit = 1.5, - dammod = {dex=0.7, str=0.5}, + ranged_project = {[DamageType.CORRUPTED_BLOOD] = 15}, }, wielder = { disease_immune = 0.5, - ranged_project = {[DamageType.CORRUPTED_BLOOD] = 15}, }, } @@ -562,14 +577,13 @@ newEntity{ base = "BASE_SLING", cost = 350, material_level = 3, combat = { + dam = 10, + critical_power = 1.5, range = 10, + dammod = {dex=0.2, cun=0.2}, physspeed = 0.7, - }, - basic_ammo = { - dam = 36, apr = 3, physcrit = 5, - dammod = {dex=0.7, cun=0.5}, }, wielder = { inc_stats = { [Stats.STAT_DEX] = 4, [Stats.STAT_CUN] = 3, }, @@ -593,9 +607,10 @@ newEntity{ base = "BASE_LONGSWORD", require = { stat = { mag=28, str=28, dex=28 }, }, material_level = 5, combat = { - dam = 50, - apr = 2, - physcrit = 5, + affects_spells = true, + dam = 65, + max_acc = 90, + critical_power = 2, dammod = {str=1}, }, wielder = { @@ -603,7 +618,6 @@ newEntity{ base = "BASE_LONGSWORD", combat_spellpower = 20, combat_spellcrit = 9, inc_damage={ - [DamageType.PHYSICAL] = 18, [DamageType.FIRE] = 18, [DamageType.LIGHT] = 18, }, @@ -624,10 +638,10 @@ newEntity{ base = "BASE_GREATSWORD", require = { stat = { str=40, wil=20 }, }, material_level = 5, combat = { - dam = 42, - apr = 4, - physcrit = 18, - dammod = {str=1.2}, + dam = 100, + max_acc = 95, + critical_power = 2.5, + dammod = {str=1.25}, }, wielder = { stamina_regen = 1, @@ -650,9 +664,9 @@ newEntity{ base = "BASE_KNIFE", material_level = 3, combat = { dam = 15, - apr = 10, - physcrit = 0, - dammod = {dex=0.55, str=0.45}, + max_acc = 100, + critical_power = 2.8, + dammod = {dex=0.4, str=0.2}, }, wielder = {combat_atk=20}, } @@ -701,7 +715,9 @@ newEntity{ base = "BASE_SHIELD", material_level = 5, special_combat = { dam = 58, - physcrit = 4.5, + block = 220, + max_acc = 80, + critical_power = 2, dammod = {str=1}, damtype = DamageType.FIRE, }, @@ -729,8 +745,10 @@ newEntity{ base = "BASE_SHIELD", material_level = 4, special_combat = { dam = 48, - physcrit = 4.5, - dammod = {str=1}, + block = 300, + max_acc = 75, + critical_power = 1.1, + dammod = {str=0.8,}, }, wielder = { combat_armor = 18, @@ -847,15 +865,14 @@ newEntity{ base = "BASE_KNIFE", cost = 550, material_level = 5, combat = { - dam = 45, - apr = 11, - physcrit = 18, - dammod = {dex=0.55,str=0.35}, + dam = 50, + max_acc = 98, + critical_power = 2.5, + dammod = {dex=0.6,str=0.4}, }, wielder = { lite = 1, inc_damage={ - [DamageType.PHYSICAL] = 10, [DamageType.LIGHT] = 8, }, pin_immune = 0.5, @@ -877,9 +894,9 @@ newEntity{ base = "BASE_KNIFE", material_level = 3, combat = { dam = 25, - apr = 10, - physcrit = 8, - dammod = {dex=0.55,str=0.35}, + max_acc = 99, + critical_power = 2.1, + dammod = {dex=0.4,str=0.2}, no_stealth_break = true, melee_project={[DamageType.RANDOM_SILENCE] = 10}, }, @@ -899,9 +916,9 @@ newEntity{ base = "BASE_KNIFE", define_as = "ART_PAIR_MOON", material_level = 3, combat = { dam = 30, - apr = 30, - physcrit = 10, - dammod = {dex=0.45,str=0.45}, + max_acc = 96, + critical_power = 2, + dammod = {dex=0.3, str=0.3}, melee_project={[DamageType.DARKNESS] = 20}, }, wielder = { @@ -935,9 +952,9 @@ newEntity{ base = "BASE_KNIFE", define_as = "ART_PAIR_STAR", material_level = 3, combat = { dam = 25, - apr = 20, - physcrit = 20, - dammod = {dex=0.45,str=0.45}, + max_acc = 96, + critical_power = 2.1, + dammod = {dex=0.3, str=0.3}, melee_project={[DamageType.LIGHT] = 20}, }, wielder = { @@ -1001,10 +1018,10 @@ newEntity{ base = "BASE_GREATMAUL", cost = 650, material_level = 5, combat = { - dam = 82, - apr = 7, - physcrit = 4, - dammod = {str=1.2}, + dam = 160, + max_acc = 90, + critical_power = 2, + dammod = {str=1.25}, talent_on_hit = { [Talents.T_FLAMESHOCK] = {level=3, chance=10} }, melee_project={[DamageType.FIRE] = 30}, }, @@ -1027,10 +1044,10 @@ newEntity{ base = "BASE_GREATMAUL", cost = 250, material_level = 3, combat = { - dam = 48, - apr = 15, - physcrit = 3, - dammod = {str=1.2}, + dam = 70, + max_acc = 95, + critical_power = 1.5, + dammod = {str=0.75}, talent_on_hit = { [Talents.T_SUNDER_ARMOUR] = {level=3, chance=15} }, }, wielder = { @@ -1040,7 +1057,7 @@ newEntity{ base = "BASE_GREATMAUL", }, } -newEntity{ base = "BASE_MACE", +newEntity{ base = "BASE_MACE", define_as = "CROOKED_CLUB", power_source = {technique=true}, unique = true, name = "Crooked Club", color = colors.GREEN, image = "object/artifact/weapon_crooked_club.png", @@ -1053,9 +1070,9 @@ newEntity{ base = "BASE_MACE", material_level = 2, combat = { dam = 25, - apr = 4, - physcrit = 10, - dammod = {str=1}, + max_acc = 80, + critical_power = 1.8, + dammod = {str=0.4}, melee_project={[DamageType.RANDOM_CONFUSION] = 14}, }, wielder = {combat_atk=12,}, @@ -1073,9 +1090,9 @@ newEntity{ base = "BASE_MACE", cost = 350, material_level = 4, combat = { - dam = 40, - apr = 4, - physcrit = 9, + dam = 50, + max_acc = 90, + critical_power = 1.5, dammod = {str=1}, melee_project={[DamageType.RANDOM_SILENCE] = 10, [DamageType.NATURE] = 18}, }, @@ -1165,11 +1182,10 @@ newEntity{ base = "BASE_GLOVES", disarm_immune=0.4, knockback_immune=0.3, combat = { - dam = 18, - apr = 1, - physcrit = 7, - physspeed = -0.4, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, + dam = 20, + max_acc = 2, + critical_power = 0.7, + dammod = {dex=0.2, str=0.1, cun=0.2 }, }, }, } @@ -1189,16 +1205,13 @@ newEntity{ base = "BASE_GAUNTLETS", inc_damage = { [DamageType.PHYSICAL] = 10 }, combat_physcrit = 10, combat_spellcrit = 10, - combat_critical_power = 50, combat_armor = 6, combat = { dam = 35, - apr = 10, - physcrit = 10, - physspeed = -0.2, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, + max_acc = 15, + critical_power = .7, + dammod = {dex=0.2, str=0.1, cun=0.2 }, melee_project={[DamageType.ARCANE] = 20}, - damrange = 0.3, }, }, } @@ -1221,10 +1234,9 @@ newEntity{ base = "BASE_GLOVES", max_life = 60, combat = { dam = 16, - apr = 1, - physcrit = 4, - physspeed = -0.4, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, + max_acc = 10, + critical_power = 0.4, + dammod = {dex=0.1, str=0, cun=0.1 }, melee_project={ [DamageType.COLD] = 10, [DamageType.LIGHTNING] = 10, }, }, }, @@ -1249,17 +1261,14 @@ newEntity{ base = "BASE_GAUNTLETS", inc_damage = { [DamageType.LIGHTNING] = 10 }, resists_cap = { [DamageType.LIGHTNING] = 5 }, combat_spellcrit = 5, - combat_critical_power = 20, combat_armor = 3, combat = { - dam = 22, - apr = 10, - physcrit = 4, - physspeed = -0.2, - dammod = {dex=0.4, str=-0.6, cun=0.4 }, + dam = 40, + max_acc = 15, + critical_power = 1, + dammod = {dex=0.4, str=0.3, cun=0.4 }, melee_project={ [DamageType.LIGHTNING] = 20, }, talent_on_hit = { [Talents.T_LIGHTNING] = {level=3, chance=10} }, - damrange = 0.3, }, }, max_power = 16, power_regen = 1, @@ -1407,7 +1416,7 @@ newEntity{ base = "BASE_CLOTH_ARMOR", use_talent = { id = Talents.T_DAMAGE_SMEARING, level = 3, power = 100 }, } -newEntity{ base = "BASE_GEM", +newEntity{ base = "BASE_GEM", define_as = "GEM_TELOS", power_source = {arcane=true}, unique = true, unided_name = "scintillating white crystal", @@ -1448,9 +1457,12 @@ newEntity{ base = "BASE_GEM", who:sortInven(gem_inven) -- Change the staff + voice.modes = o.modes + voice.flavor_name = o.flavor_name voice.combat = o.combat - voice.combat.dam = voice.combat.dam * 1.4 - voice.combat.damtype = engine.DamageType.ARCANE + voice.combat.dam = math.floor(voice.combat.dam * 1.4) + voice.combat.sentient = "telos" + voice.wielder.inc_damage[voice.combat.damtype] = voice.combat.dam voice:identify(true) o:replaceWith(voice) who:sortInven() @@ -1486,8 +1498,8 @@ newEntity{ base = "BASE_STAFF", define_as = "VOICE_TELOS", max_mana = 100, inc_stats = { [Stats.STAT_MAG] = 6, [Stats.STAT_WIL] = 5, [Stats.STAT_CUN] = 4 }, lite = 1, - - inc_damage = { all=14 }, + inc_damage = {}, + learn_talent = {[Talents.T_COMMAND_STAFF] = 5}, }, } @@ -1527,15 +1539,14 @@ newEntity{ base = "BASE_BATTLEAXE", rarity = 300, material_level = 4, combat = { - dam = 68, - apr = 7, - physcrit = 10, - dammod = {str=1.3}, + dam = 120, + max_acc = 85, + critical_power = 2.1, + dammod = {str=1.1}, }, wielder = { inc_stats = { [Stats.STAT_CON] = 2, [Stats.STAT_DEX] = 2, }, combat_def = 6, combat_armor = 6, - inc_damage = { [DamageType.PHYSICAL]=10 }, stun_immune = 0.3, knockback_immune = 0.3, }, @@ -1564,10 +1575,10 @@ newEntity{ base = "BASE_BATTLEAXE", level_range = {20, 35}, material_level = 4, combat = { - dam = 52, - apr = 21, - physcrit = 2, - dammod = {str=1.2}, + dam = 75, + max_acc = 85, + critical_power = 3, + dammod = {str=1}, inc_damage_type = {dragon=25}, }, wielder = { @@ -1590,10 +1601,10 @@ newEntity{ base = "BASE_WARAXE", cost = 330, material_level = 4, combat = { - dam = 33, - apr = 4.5, - physcrit = 7, - dammod = {str=1}, + dam = 40, + max_acc = 90, + critical_power = 2.5, + dammod = {str=0.8}, melee_project={[DamageType.COLD] = 25}, }, wielder = { @@ -1611,9 +1622,9 @@ newEntity{ base = "BASE_WHIP", material_level = 3, combat = { dam = 28, - apr = 8, - physcrit = 5, - dammod = {dex=1}, + max_acc = 75, + critical_power = 2.5, + dammod = {dex=0.6}, melee_project={[DamageType.POISON] = 22}, }, wielder = { @@ -1940,10 +1951,10 @@ newEntity{ base = "BASE_GREATSWORD", moddable_tile = "special/golden_sword_right", moddable_tile_big = true, combat = { - dam = 40, - apr = 1, - physcrit = 7, - dammod = {str=1.2}, + dam = 70, + max_acc = 95, + critical_power = 2, + dammod = {str=1}, special_on_hit = {desc="9% chance to stun or confuse the target", fct=function(combat, who, target) if not rng.percent(9) then return end local eff = rng.table{"stun", "confusion"} @@ -1968,9 +1979,9 @@ newEntity{ base = "BASE_MACE", cost = 300, material_level = 5, combat = { - dam = 52, - apr = 5, - physcrit = 2.5, + dam = 82, + max_acc = 80, + critical_power = 2, dammod = {str=1}, special_on_hit = {desc="10% chance to shimer to a different hue and gain powers", fct=function(combat, who, target) if not rng.percent(10) then return end @@ -2036,17 +2047,15 @@ It is said the wielder will slowly grow mad. This, however, has never been prove rarity = 250, material_level = 5, combat = { - dam = 58, - apr = 16, - physcrit = 7, + dam = 70, + max_acc = 95, + critical_power = 2, dammod = {str=1}, - damrange = 1.4, damtype = DamageType.PHYSICALBLEED, }, wielder = { inc_stats = { [Stats.STAT_STR] = 4, [Stats.STAT_DEX] = 4, }, see_invisible = 5, - inc_damage = { [DamageType.PHYSICAL]=10 }, }, } @@ -2063,9 +2072,9 @@ newEntity{ base = "BASE_LONGSWORD", define_as = "ART_PAIR_TWSWORD", material_level = 3, combat = { dam = 28, - apr = 10, - physcrit = 8, - dammod = {str=0.8,mag=0.2}, + max_acc = 100, + critical_power = 1.3, + dammod = {str=0.5,mag=0.1}, melee_project={[DamageType.TEMPORAL] = 5}, }, wielder = { @@ -2101,9 +2110,9 @@ newEntity{ base = "BASE_KNIFE", define_as = "ART_PAIR_TWDAG", material_level = 3, combat = { dam = 25, - apr = 20, - physcrit = 20, - dammod = {dex=0.5,mag=0.5}, + max_acc = 100, + critical_power = 2, + dammod = {dex=0.3,mag=0.3}, melee_project={[DamageType.TEMPORAL] = 5}, }, wielder = { @@ -2137,9 +2146,10 @@ newEntity{ base = "BASE_LONGSWORD", cost = 650, material_level = 5, combat = { - dam = 45, - apr = 4, - physcrit = 10, + affects_spells = true, + dam = 65, + max_acc = 95, + critical_power = 1.8, dammod = {str=1}, talent_on_hit = { [Talents.T_MANA_CLASH] = {level=1, chance=25} }, }, @@ -2175,17 +2185,16 @@ newEntity{ base = "BASE_GAUNTLETS", }, fatigue = 10, combat_armor = 7, - inc_damage = { [DamageType.PHYSICAL]=5, [DamageType.ACID]=10, }, + inc_damage = { [DamageType.ACID]=10, }, resists = {[DamageType.ACID] = 20, [DamageType.PHYSICAL] = 10, }, resists_cap = {[DamageType.ACID] = 10, [DamageType.PHYSICAL] = 5, }, resists_pen = {[DamageType.ACID] = 15, [DamageType.PHYSICAL] = 15, }, combat = { - dam = 26, - apr = 15, - physcrit = 5, - dammod = {dex=0.3, str=-0.4, cun=0.3 }, + dam = 35, + max_acc = 10, + critical_power = 5, + dammod = {dex=0.2, str=0.1, cun=0.2 }, melee_project={[DamageType.ACID] = 10}, - damrange = 0.3, }, }, } diff --git a/game/modules/tome/data/gfx/effects/counterstrike.png b/game/modules/tome/data/gfx/effects/counterstrike.png new file mode 100644 index 0000000000000000000000000000000000000000..a2f835d4fe30267ae3b576bb56f44adb739e5e21 GIT binary patch literal 2275 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 literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/particles/ward.lua b/game/modules/tome/data/gfx/particles/ward.lua new file mode 100644 index 0000000000..570619f30f --- /dev/null +++ b/game/modules/tome/data/gfx/particles/ward.lua @@ -0,0 +1,53 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +base_size = 32 + +local color = color or {r=127, g=127, b=127} +local ad = rng.range(0, 360) +local a = math.rad(ad) +local dir = math.rad(ad + 90) +local r = 18 +local speed = rng.range(33, 99) +local dirv = math.pi * 2 / speed +local vel = math.pi * 2 * r / speed +local first = true + +return { generator = function() + local dr = rng.range(0, 2) + local da = math.rad(rng.range(0, 360)) + return { + life = core.particles.ETERNAL, + size = rng.range(3,8), sizev = 0, sizea = 0, + + x = r * math.cos(a) + dr * math.cos(da), xv = 0, xa = 0, + y = r * math.sin(a) + dr * math.cos(da), yv = 0, ya = 0, + dir = dir, dirv = dirv, dira = 0, + vel = vel, velv = 0, vela = 0, + + r = color.r/255, rv = 0, ra = 0, + g = color.g/255, gv = 0, ga = 0, + b = color.b/255, gv = 0, ga = 0, + a = rng.range(230, 225)/255, av = 0, aa = 0, + } +end, }, +function(self) + if first then self.ps:emit(10) first = false end +end, +10 diff --git a/game/modules/tome/data/gfx/talents/block.png b/game/modules/tome/data/gfx/talents/block.png new file mode 100644 index 0000000000000000000000000000000000000000..a94bc94e0d2557490f2cecfe26e19126a118b68a GIT binary patch literal 4274 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 U3ALL#VgLXD07*qoM6N<$g4*~`1ONa4 literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/talents/bloodflow.png b/game/modules/tome/data/gfx/talents/bloodflow.png new file mode 100644 index 0000000000000000000000000000000000000000..fbe8942ab1461dc2d5c05f1e4e16786e00494463 GIT binary patch literal 3295 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 literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/talents/command_staff.png b/game/modules/tome/data/gfx/talents/command_staff.png new file mode 100644 index 0000000000000000000000000000000000000000..30c6ed37cb0e5ebbead103f9b37eee91faadac33 GIT binary patch literal 3803 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 RoxT77002ovPDHLkV1nh9E>8de literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/talents/elemental_retribution.png b/game/modules/tome/data/gfx/talents/elemental_retribution.png new file mode 100644 index 0000000000000000000000000000000000000000..9ea122dc9b1bfc9737599600e710adc8ad23d9f2 GIT binary patch literal 4320 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 O0000<MNUMnLSTZ-4d9~y literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/talents/fearscape_fog.png b/game/modules/tome/data/gfx/talents/fearscape_fog.png new file mode 100644 index 0000000000000000000000000000000000000000..a4aa55f437f1d24e7c47adc00568aa2ac1282a3c GIT binary patch literal 3100 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 literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/talents/lifebind.png b/game/modules/tome/data/gfx/talents/lifebind.png new file mode 100644 index 0000000000000000000000000000000000000000..874c66ebf004f2d4002c23602702e1d18a22e90f GIT binary patch literal 2214 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 literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/talents/perception.png b/game/modules/tome/data/gfx/talents/perception.png new file mode 100644 index 0000000000000000000000000000000000000000..8385a28547b27855c5e9409697d4757989530f71 GIT binary patch literal 3049 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 literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/talents/reload.png b/game/modules/tome/data/gfx/talents/reload.png new file mode 100644 index 0000000000000000000000000000000000000000..e255d62a46ed2ac5bed74ef18b9a77778a3a63be GIT binary patch literal 4773 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 literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/talents/savagery.png b/game/modules/tome/data/gfx/talents/savagery.png new file mode 100644 index 0000000000000000000000000000000000000000..677101cd35a8fe505e355ffd5311313bec0b6d33 GIT binary patch literal 3767 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 literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/talents/soul_drain.png b/game/modules/tome/data/gfx/talents/soul_drain.png new file mode 100644 index 0000000000000000000000000000000000000000..1501e559646edf37bc9fd460f4778d8735c75f3a GIT binary patch literal 4903 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 Z{{t*dm%BHN;Vu9G002ovPDHLkV1mE4jqm^f literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/gfx/talents/ward.png b/game/modules/tome/data/gfx/talents/ward.png new file mode 100644 index 0000000000000000000000000000000000000000..5873554c26f252014d9406bc77514f9e12f55920 GIT binary patch literal 3552 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 a{{H}=aK~Cg3?q>M0000<MNUMnLSTXpWT?mh literal 0 HcmV?d00001 diff --git a/game/modules/tome/data/talents/celestial/light.lua b/game/modules/tome/data/talents/celestial/light.lua index 7e97189cc0..4b2a07a49a 100644 --- a/game/modules/tome/data/talents/celestial/light.lua +++ b/game/modules/tome/data/talents/celestial/light.lua @@ -25,7 +25,7 @@ newTalent{ random_ego = "defensive", cooldown = 10, positive = -10, - tactical = { HEAL = 2 }, + tactical = { HEAL = 2, }, getHeal = function(self, t) return self:combatTalentSpellDamage(t, 20, 440) end, is_heal = true, action = function(self, t) diff --git a/game/modules/tome/data/talents/chronomancy/energy.lua b/game/modules/tome/data/talents/chronomancy/energy.lua index ecacff1552..fd36177cb3 100644 --- a/game/modules/tome/data/talents/chronomancy/energy.lua +++ b/game/modules/tome/data/talents/chronomancy/energy.lua @@ -105,7 +105,7 @@ newTalent{ local target = game.level.map(tx, ty, Map.ACTOR) if not target then return end - if not self:checkHit(self:combatSpellpower(), target:combatSpellResist()) then + if not self:checkHit(self:combatSpellpower(), target:combatSpellResist(), 0, self:getMaxAccuracy("spell")) then game.logSeen(target, "%s resists!", target.name:capitalize()) return true end diff --git a/game/modules/tome/data/talents/chronomancy/matter.lua b/game/modules/tome/data/talents/chronomancy/matter.lua index 0ba31c6bd1..b0f895fd7e 100644 --- a/game/modules/tome/data/talents/chronomancy/matter.lua +++ b/game/modules/tome/data/talents/chronomancy/matter.lua @@ -175,7 +175,7 @@ newTalent{ -- Try to insta-kill if target then - if target:checkHit(self:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("instakill") and target.life > 0 and target.life < target.max_life * 0.2 then + if target:checkHit(self:combatSpellpower(), target:combatPhysicalResist(), 0, self:getMaxAccuracy("spell"), 15) and target:canBe("instakill") and target.life > 0 and target.life < target.max_life * 0.2 then -- KILL IT ! game.logSeen(target, "%s has been pulled apart at a molecular level!", target.name:capitalize()) target:die(self) diff --git a/game/modules/tome/data/talents/chronomancy/paradox.lua b/game/modules/tome/data/talents/chronomancy/paradox.lua index fe420b5acd..9fd8bd4ebe 100644 --- a/game/modules/tome/data/talents/chronomancy/paradox.lua +++ b/game/modules/tome/data/talents/chronomancy/paradox.lua @@ -86,7 +86,7 @@ newTalent{ if not target then return end -- does the spell hit? if not nothing happens - if not self:checkHit(self:combatSpellpower(), target:combatSpellResist()) then + if not self:checkHit(self:combatSpellpower(), target:combatSpellResist(), 0, self:getMaxAccuracy("spell")) then game.logSeen(target, "%s resists!", target.name:capitalize()) return true end diff --git a/game/modules/tome/data/talents/chronomancy/spacetime-folding.lua b/game/modules/tome/data/talents/chronomancy/spacetime-folding.lua index 7a9adb750a..1b811e8070 100644 --- a/game/modules/tome/data/talents/chronomancy/spacetime-folding.lua +++ b/game/modules/tome/data/talents/chronomancy/spacetime-folding.lua @@ -76,7 +76,7 @@ newTalent{ power = self:combatSpellpower() * (1 + self:getTalentLevel(self.T_SPACETIME_MASTERY)/10) end - if target:canBe("teleport") and self:checkHit(power, target:combatSpellResist() + (target:attr("continuum_destabilization") or 0)) then + if target:canBe("teleport") and self:checkHit(power, target:combatSpellResist() + (target:attr("continuum_destabilization") or 0), 0, self:getMaxAccuracy("spell")) then target:crossTierEffect(target.EFF_SPELLSHOCKED, self:combatSpellpower()) -- first remove the target so the destination tile is empty game.level.map:remove(target.x, target.y, Map.ACTOR) diff --git a/game/modules/tome/data/talents/chronomancy/spacetime-weaving.lua b/game/modules/tome/data/talents/chronomancy/spacetime-weaving.lua index c82a74d56b..af1fb26c58 100644 --- a/game/modules/tome/data/talents/chronomancy/spacetime-weaving.lua +++ b/game/modules/tome/data/talents/chronomancy/spacetime-weaving.lua @@ -102,7 +102,7 @@ newTalent{ self:project(tg, self.x, self.y, function(px, py) local target = game.level.map(px, py, Map.ACTOR) if not target or target == self then return end - if self:checkHit(power, target:combatSpellResist() + (target:attr("continuum_destabilization") or 0)) and target:canBe("teleport") then + if self:checkHit(power, target:combatSpellResist() + (target:attr("continuum_destabilization") or 0), 0, self:getMaxAccuracy("spell")) and target:canBe("teleport") then actors[#actors+1] = target else game.logSeen(target, "%s resists the banishment!", target.name:capitalize()) @@ -221,7 +221,7 @@ newTalent{ destabilization_power = self:combatSpellpower(0.3), summoned_by = self, -- "summoner" is immune to it's own traps triggered = function(self, x, y, who) - if who:checkHit(self.check_hit, who:combatSpellResist(), 0, 95, 15) and who:canBe("teleport") or who == self.summoned_by then + if who:checkHit(self.check_hit, who:combatSpellResist(), 0, self:getMaxAccuracy("spell"), 15) and who:canBe("teleport") or who == self.summoned_by then -- since we're using a precise teleport we'll look for a free grid first local tx, ty = util.findFreeGrid(self.dest.x, self.dest.y, 5, true, {[Map.ACTOR]=true}) if tx and ty then diff --git a/game/modules/tome/data/talents/chronomancy/timetravel.lua b/game/modules/tome/data/talents/chronomancy/timetravel.lua index c0aa022e62..9a68bb1fe1 100644 --- a/game/modules/tome/data/talents/chronomancy/timetravel.lua +++ b/game/modules/tome/data/talents/chronomancy/timetravel.lua @@ -25,13 +25,13 @@ newTalent{ message = "@Source@ rearranges history.", cooldown = 24, tactical = { PARADOX = 2 }, - getDuration = function(self, t) + getDuration = function(self, t) local duration = 1 + math.floor(self:getTalentLevel(t)/2) - + if self:knowTalent(self.T_PARADOX_MASTERY) then duration = 1 + math.floor((self:getTalentLevel(t)/2) + (self:getTalentLevel(self.T_PARADOX_MASTERY)/2)) end - + return duration end, getReduction = function(self, t) return self:combatTalentSpellDamage(t, 30, 300) end, @@ -74,9 +74,9 @@ newTalent{ local target = x and game.level.map(x, y, engine.Map.ACTOR) or nil if not target then return nil end - local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0)) + local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0), 0, self:getMaxAccuracy("spell")) if not hit then game.logSeen(target, "%s resists!", target.name:capitalize()) return true end - + target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)}) self:project(tg, x, y, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t))) game.level.map:particleEmitter(x, y, 1, "temporal_thrust") @@ -84,7 +84,7 @@ newTalent{ -- End it here if we've killed the target or the target is a player if target.dead or target.player then return true end - + -- set up instability local summoner = self -- Store the current terrain @@ -115,7 +115,7 @@ newTalent{ summoner_gain_exp = true, summoner = summoner, } - + -- Mixin the old terrain table.update(temporal_instability, terrain) -- Now update the display overlay @@ -129,12 +129,12 @@ newTalent{ else table.append(temporal_instability.add_displays, overlay) end - + game.logSeen(target, "%s has moved forward in time!", target.name:capitalize()) game.level:removeEntity(target) game.level:addEntity(temporal_instability) game.level.map(target.x, target.y, engine.Map.TERRAIN, temporal_instability) - + return true end, info = function(self, t) @@ -197,7 +197,7 @@ newTalent{ for tid, cd in pairs(self.talents_cd) do self.talents_cd[tid] = cd - t.getCooldownReduction(self, t) end - + local target = self local todel = {} for eff_id, p in pairs(target.tmp) do @@ -210,7 +210,7 @@ newTalent{ while #todel > 0 do target:removeEffect(table.remove(todel)) end - + return true end, info = function(self, t) diff --git a/game/modules/tome/data/talents/corruptions/blight.lua b/game/modules/tome/data/talents/corruptions/blight.lua index a70a041d94..a99c8bc6c6 100644 --- a/game/modules/tome/data/talents/corruptions/blight.lua +++ b/game/modules/tome/data/talents/corruptions/blight.lua @@ -91,7 +91,7 @@ newTalent{ if #effs == 0 then break end local eff = rng.tableRemove(effs) - if self:checkHit(self:combatSpellpower(), target:combatSpellResist(), 0, 95, 5) then + if self:checkHit(self:combatSpellpower(), target:combatSpellResist(), 0, self:getMaxAccuracy("spell"), 5) then target:crossTierEffect(target.EFF_SPELLSHOCKED, self:combatSpellpower()) if eff[1] == "effect" then target:removeEffect(eff[2]) diff --git a/game/modules/tome/data/talents/cunning/stealth.lua b/game/modules/tome/data/talents/cunning/stealth.lua index 90a728e76f..862945fdda 100644 --- a/game/modules/tome/data/talents/cunning/stealth.lua +++ b/game/modules/tome/data/talents/cunning/stealth.lua @@ -83,12 +83,12 @@ newTalent{ require = cuns_req2, mode = "passive", points = 5, - getMultiplier = function(self, t) return 1.5 + self:getTalentLevel(t) / 7 end, + getMultiplier = function(self, t) return self:getTalentLevel(t) / 7 end, info = function(self, t) local multiplier = t.getMultiplier(self, t) return ([[When striking from stealth, hits are automatically criticals if the target does not notice you. - Shadowstrikes do %.02f%% damage versus a normal hit.]]): - format(multiplier * 100) + Shadowstrike criticals have their multiplier increased by %.02f.]]): + format(multiplier) end, } diff --git a/game/modules/tome/data/talents/gifts/earthen-vines.lua b/game/modules/tome/data/talents/gifts/earthen-vines.lua index e4acaf4925..cefd04ab2e 100644 --- a/game/modules/tome/data/talents/gifts/earthen-vines.lua +++ b/game/modules/tome/data/talents/gifts/earthen-vines.lua @@ -45,7 +45,7 @@ newTalent{ -- Randomly take targets local tg = {type="hit", range=self:getTalentRange(t), talent=t} local a, id = rng.table(tgts) - local hit, chance = a:checkHit(self:combatTalentStatDamage(t, "wil", 5, 110), a:combatPhysicalResist(), 0, 95, 5) + local hit, chance = a:checkHit(self:combatTalentStatDamage(t, "wil", 5, 110), a:combatPhysicalResist(), 0, self:getMaxAccuracy("spell"), 5) if a:canBe("pin") and hit then local turns, dam = t.getValues(self, t) a:setEffect(a.EFF_STONE_VINE, turns, {dam=dam, src=self, free=rad*2, free_chance=100-chance}) diff --git a/game/modules/tome/data/talents/gifts/summon-distance.lua b/game/modules/tome/data/talents/gifts/summon-distance.lua index 8030af8c5e..b3db88cda7 100644 --- a/game/modules/tome/data/talents/gifts/summon-distance.lua +++ b/game/modules/tome/data/talents/gifts/summon-distance.lua @@ -463,7 +463,7 @@ newTalent{ infravision = 10, combat_armor = 15, combat_def = 0, - combat = { dam=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), atk=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), dammod={cun=1.1} }, + combat = { dam=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), atk=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), dammod={cun=resolvers.levelup(0.2, 5, 0.2, 1.1)} }, wild_gift_detonate = t.id, @@ -547,7 +547,7 @@ newTalent{ infravision = 10, combat_armor = 0, combat_def = 0, - combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,60), apr=25, dammod={str=1.1} }, + combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,60), apr=25, dammod={str=resolvers.levelup(0.2, 5, 0.2, 1.1)} }, on_melee_hit = {[DamageType.FIRE]=resolvers.mbonus(7, 2)}, resists = { [DamageType.FIRE] = 100, }, diff --git a/game/modules/tome/data/talents/gifts/summon-melee.lua b/game/modules/tome/data/talents/gifts/summon-melee.lua index 2bccf865da..5db790b091 100644 --- a/game/modules/tome/data/talents/gifts/summon-melee.lua +++ b/game/modules/tome/data/talents/gifts/summon-melee.lua @@ -75,7 +75,7 @@ newTalent{ infravision = 10, combat_armor = 2, combat_def = 4, - combat = { dam=self:getTalentLevel(t) * 10 + rng.avg(12,25), atk=10, apr=10, dammod={str=0.8} }, + combat = { dam=self:getTalentLevel(t) * 10 + rng.avg(12,25), atk=10, apr=10, dammod={str=resolvers.levelup(0.2, 5, 0.1, 0.8)} }, wild_gift_detonate = t.id, @@ -165,7 +165,7 @@ newTalent{ combat_armor = 1, combat_def = 1, never_move = 1, - combat = { dam=8, atk=15, apr=5, damtype=DamageType.ACID, dammod={str=0.7} }, + combat = { dam=8, atk=15, apr=5, damtype=DamageType.ACID, dammod={str=resolvers.levelup(0.2, 5, 0.1, 0.7)} }, wild_gift_detonate = t.id, @@ -360,7 +360,7 @@ newTalent{ level_range = {self.level, self.level}, exp_worth = 0, combat_armor = 25, combat_def = -20, - combat = { dam=25 + self:getWil(), atk=20, apr=5, dammod={str=0.9} }, + combat = { dam=25 + self:getWil(), atk=20, apr=5, dammod={str=resolvers.levelup(0.2, 5, 0.2, 0.9)} }, resolvers.talents{ [Talents.T_UNSTOPPABLE]=3, [Talents.T_STUN]=3, }, poison_immune=1, cut_immune=1, fear_immune=1, blind_immune=1, diff --git a/game/modules/tome/data/talents/gifts/summon-utility.lua b/game/modules/tome/data/talents/gifts/summon-utility.lua index 13bc856171..6ab854fe1d 100644 --- a/game/modules/tome/data/talents/gifts/summon-utility.lua +++ b/game/modules/tome/data/talents/gifts/summon-utility.lua @@ -249,7 +249,7 @@ newTalent{ infravision = 10, combat_armor = 0, combat_def = 0, - combat = { dam=resolvers.rngavg(20,25), atk=16, apr=9, damtype=DamageType.NATURE, dammod={dex=1.2} }, + combat = { dam=resolvers.rngavg(20,25), atk=16, apr=9, damtype=DamageType.NATURE, dammod={dex=resolvers.levelup(0.2, 5, 0.2, 1.2)} }, wild_gift_detonate = t.id, diff --git a/game/modules/tome/data/talents/misc/horrors.lua b/game/modules/tome/data/talents/misc/horrors.lua index 7593ce1331..49ba4f248a 100644 --- a/game/modules/tome/data/talents/misc/horrors.lua +++ b/game/modules/tome/data/talents/misc/horrors.lua @@ -457,7 +457,7 @@ newTalent{ autolevel = "summoner", ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=2, ai_move="move_snake" }, combat_armor = 1, combat_def = 1, - combat = { dam=resolvers.levelup(resolvers.mbonus(40, 15), 1, 1.2), atk=15, apr=15, dammod={wil=0.8}, damtype=DamageType.TEMPORAL }, + combat = { dam=resolvers.levelup(resolvers.mbonus(40, 15), 1, 1.2), atk=15, apr=15, dammod={wil=resolvers.levelup(0.2, 5, 0.2, 0.8)}, damtype=DamageType.TEMPORAL }, on_melee_hit = { [DamageType.TEMPORAL] = resolvers.mbonus(20, 10), }, infravision = 10, diff --git a/game/modules/tome/data/talents/misc/inscriptions.lua b/game/modules/tome/data/talents/misc/inscriptions.lua index 3ec8d32290..63ff771ffa 100644 --- a/game/modules/tome/data/talents/misc/inscriptions.lua +++ b/game/modules/tome/data/talents/misc/inscriptions.lua @@ -729,7 +729,7 @@ newInscription{ local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0)) if not hit then game.logSeen(target, "%s resists!", target.name:capitalize()) return true end - + target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)}) self:project(tg, x, y, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t))) game.level.map:particleEmitter(x, y, 1, "temporal_thrust") @@ -737,7 +737,7 @@ newInscription{ -- End it here if we've killed the target or the target is a player if target.dead or target.player then return true end - + -- set up instability local summoner = self -- Store the current terrain @@ -768,7 +768,7 @@ newInscription{ summoner_gain_exp = true, summoner = summoner, } - + -- Mixin the old terrain table.update(temporal_instability, terrain) -- Now update the display overlay @@ -782,7 +782,7 @@ newInscription{ else table.append(temporal_instability.add_displays, overlay) end - + game.logSeen(target, "%s has moved forward in time!", target.name:capitalize()) game.level:removeEntity(target) game.level:addEntity(temporal_instability) diff --git a/game/modules/tome/data/talents/misc/item.lua b/game/modules/tome/data/talents/misc/item.lua new file mode 100644 index 0000000000..713f48dae3 --- /dev/null +++ b/game/modules/tome/data/talents/misc/item.lua @@ -0,0 +1,491 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010, 2011 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +newTalent{ + name = "Command Staff", + type = {"misc/item", 1}, + cooldown = function(self, t) + --return math.max(30 - 5 * self:getTalentLevel(t), 5) + return 5 + end, + points = 5, + --hard_cap = 5, + no_npc_use = true, + --[=[ + en_fct = function(self, t) + if self:getTalentLevel(t) > 5 then + print("instant?") + return "instant" + else + print("not instant?") + return "1 turn" + end + end, +]=] + action = function(self, t) + local staff = self:hasStaffWeapon() + if not staff then + game.logPlayer(self, "You must be holding a staff.") + return + end + local state = {} + local Chat = require("engine.Chat") + local chat = Chat.new("command-staff", {name="Command Staff"}, self, {version=staff, state=state, co=coroutine.running()}) + local d = chat:invoke() + if not coroutine.yield() then return nil end + return true + end, + info = function(self, t) + --return ([[Alter the flow of energies through a staff. The effect is instantaneous at extremely high talent levels.]]) + return ([[Alter the flow of energies through a staff.]]) + end, +} + +newTalent{ + name = "Reload", + type = {"misc/item", 1}, + cooldown = 0, + points = 5, + hard_cap = 5, + tactical = { AMMO = 2 }, + on_pre_use = function(self, t, silent) if not self:hasAmmo() then if not silent then game.logPlayer(self, "You must have a quiver or pouch equipped.") end return false end return true end, + shots_per_turn = function(self, t) + local s = self:getTalentFromId(self.T_BOW_MASTERY) + local add = s.getReloadBoost(self, s) + return self:getTalentLevelRaw(t) + add + end, + action = function(self, t) + local q, err = self:hasAmmo() + if not q then + game.logPlayer(self, "%s", err) + return + end + if q.combat.shots_left == q.combat.capacity then + game.logPlayer(self, "Your %s is full.", q.name) + return + end + self:setEffect(self.EFF_RELOADING, q.combat.capacity, {ammo = q, shots_per_turn = t.shots_per_turn(self, t)}) + return true + end, + info = function(self, t) + local spt = t.shots_per_turn(self, t) + return ([[Reload your quiver or shot pouch at the rate of %d shot%s per turn.]]):format(spt, (spt > 1 and "s") or "") + end, +} + +newTalent{ + name = "Savagery", + type = {"misc/item", 1}, + points = 5, + hard_cap = 5, + mode = "passive", + getDuration = function(self, t) + return 2 * self:getTalentLevel(t) + 3 + end, + getPower = function(self, t) + return 0.5 + end, + do_savagery = function(self, t) + self:setEffect(self.EFF_SAVAGERY, t.getDuration(self, t), {power = t.getPower(self, t)}) + end, + info = function(self, t) + return ([[Whenever you land a critical strike, you gain a stacking bonus of %d to your critical power multiplier, up to a maximum bonus of 1.5. The buff lasts for %d turns.]]):format(t.getPower(self, t), t.getDuration(self, t)) + end, +} + +newTalent{ + name = "Ward", + type = {"misc/item", 1}, + cooldown = function(self, t) + return 45 - 5 * self:getTalentLevel(t) + end, + points = 5, + hard_cap = 5, + no_npc_use = true, + action = function(self, t) + local state = {} + local Chat = require("engine.Chat") + local chat = Chat.new("ward", {name="Ward"}, self, {version=self, state=state}) + local d = chat:invoke() + local co = coroutine.running() + --print("before d.unload, state.set_ward is ", state.set_ward) + d.unload = function() coroutine.resume(co, state.set_ward) end + --print("state.set_ward is ", state.set_ward) + if not coroutine.yield() then return nil end + return true + end, + info = function(self, t) + return ([[Bring a damage-type-specific ward into being. The ward will fully negate as many attacks of its element as it has charges.]]) + end, +} + + +newTalent{ + name = "Bloodflow", + type = {"misc/item", 1}, + cooldown = function(self, t) + return 45 - 5 * self:getTalentLevel(t) + end, + points = 5, + hard_cap = 5, + no_npc_use = true, + tactical = { BUFF = 2 }, + getTalentCount = function(self, t) return math.ceil(self:getTalentLevel(t) + 1) end, + getMaxLevel = function(self, t) return self:getTalentLevelRaw(t) end, + action = function(self, t) + local amount = self.life * 0.5 + if self.life <= amount + 1 then + game.logPlayer(self, "Doing this would kill you.") + return + end + local tids = {} + for tid, _ in pairs(self.talents_cd) do + local tt = self:getTalentFromId(tid) + if tt.type[2] <= t.getMaxLevel(self, t) then + tids[#tids+1] = tid + end + end + for i = 1, t.getTalentCount(self, t) do + if #tids == 0 then break end + local tid = rng.tableRemove(tids) + self.talents_cd[tid] = nil + end + self.changed = true + game:playSoundNear(self, "talents/spell_generic") + self:takeHit(amount, self) + return true + end, + info = function(self, t) + local talentcount = t.getTalentCount(self, t) + local maxlevel = t.getMaxLevel(self, t) + return ([[Sacrifice half of your current health to reset the cooldown of %d talents of tier %d or less.]]): + format(talentcount, maxlevel) + end, +} + +newTalent{ + name = "Elemental Retribution", + type = {"misc/item", 1}, + points = 5, + hard_cap = 5, + mode = "passive", + tactical = { BUFF = 1 }, + getDuration = function(self, t) + return 2 * self:getTalentLevel(t) + 3 + end, + getPower = function(self, t) + return self:getTalentLevel(t)*3 + end, + getElementsString = function(self, t) + if not self.elemental_retribution then return "(error 1)" end + local ret_list = {} + local count = 1 + for k, v in pairs(self.elemental_retribution) do + if v > 0 then + ret_list[count] = k + count = count + 1 + end + end + local n = #ret_list + --print("just defined n as: ", n) + if n < 1 then return "(error 2)" end + local e_string = "" + if n == 1 then + e_string = DamageType.dam_def[ret_list[1]].name + --print("1: e_string is ", e_string) + elseif n == 2 then + e_string = DamageType.dam_def[ret_list[1]].name.." or "..DamageType.dam_def[ret_list[2]].name + --print("2: e_string is ", e_string) + else + for i = 1, #ret_list-1 do + e_string = e_string..DamageType.dam_def[ret_list[i]].name..", " + --print("3+: e_string is ", e_string) + end + e_string = e_string.."or "..DamageType.dam_def[ret_list[n]].name + end + return e_string + end, + do_retribution = function(self, t) + self:setEffect(self.EFF_ELEMENTAL_RETRIBUTION, t.getDuration(self, t), {power = t.getPower(self, t), e_string = t.getElementsString(self, t), maximum = t.getPower(self, t)*3}) + end, + info = function(self, t) + return ([[Whenever you suffer %s damage, you gain a stacking bonus of %d to spellpower up to a maximum of %d. The buff lasts for %d turns.]]):format(t.getElementsString(self, t), t.getPower(self, t), t.getPower(self, t)*3, t.getDuration(self, t)) + end, +} + +newTalent{ + name = "Soul Drain", + type = {"misc/item", 1}, + points = 5, + hard_cap = 5, + cooldown = function(self, t) + return math.max(6, math.ceil(25 - self:getTalentLevelRaw(t)*3)) + end, + tactical = { DEFEND = 2, ATTACKAREA = 2, DISABLE = 1 }, + direct_hit = true, + range = 0, + radius = function(self, t) + return 2 + math.ceil(self:getTalentLevel(t)/2) + end, + target = function(self, t) + return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, talent=t} + end, + getLeech = function(self, t) + --return self:combatStatTalentIntervalDamage(t, "combatMindpower", 6, 30) + return 3 + end, + getDam = function(self, t) + return self:spellCrit(self:combatTalentSpellDamage(t, 28, 270)) + end, + action = function(self, t) + local leech = t.getLeech(self, t) + local dam = t.getDam(self, t) + local tg = self:getTalentTarget(t) + self:project(tg, self.x, self.y, function(tx, ty) + local act = game.level.map(tx, ty, engine.Map.ACTOR) + if act then + self:incMana(leech) + self:incVim(leech * 0.5) + self:incPositive(leech * 0.25) + self:incNegative(leech * 0.25) + self:incEquilibrium(-leech * 0.35) + self:incStamina(leech * 0.65) + self:incHate(leech * 0.05) + self:incPsi(leech * 0.2) + end + DamageType:get(DamageType.SOUL_DRAIN).projector(self, tx, ty, DamageType.SOUL_DRAIN, dam) + end) + -- Lightning ball gets a special treatment to make it look neat + local sradius = (tg.radius + 0.5) * (engine.Map.tile_w + engine.Map.tile_h) / 2 + local nb_forks = 16 + local angle_diff = 360 / nb_forks + for i = 0, nb_forks - 1 do + local a = math.rad(rng.range(0+i*angle_diff,angle_diff+i*angle_diff)) + local tx = self.x + math.floor(math.cos(a) * tg.radius) + local ty = self.y + math.floor(math.sin(a) * tg.radius) + game.level.map:particleEmitter(x, y, tg.radius, "lightning", {radius=tg.radius, grids=grids, tx=tx-self.x, ty=ty-self.y, nb_particles=25, life=8}) + end + + game:playSoundNear(self, "talents/lightning") + return true + end, + info = function(self, t) + local range = self:getTalentRadius(t) + local en = t.getLeech(self, t) + local dam = damDesc(self, DamageType.BLIGHT, t.getDam(self, t)) + return ([[You tear at the very soul of every target around you in a radius of %d. Deals %d blight damage. Reduces the mana, vim, positive enerty, negative energy, stamina, hate, and psi of each target by 50%%. Increases their equilibrium by 50%%. Provides a small boost to all of your resources.]]):format(range, dam) + end, +} + +newTalent{ + name = "Fearscape Fog", + type = {"misc/item", 1}, + points = 5, + cooldown = 20, + tactical = { + ATTACK = 10, + }, + range = 0, + radius = function(self, t) + return 2 + self:getTalentLevelRaw(t) + end, + direct_hit = true, + tactical = { DISABLE = 3 }, + --requires_target = true, + target = function(self, t) + return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), talent=t} + end, + action = function(self, t) + local tg = self:getTalentTarget(t) + --local x, y = self:getTarget(tg) + --if not x or not y then return nil end + self:project(tg, self.x, self.y, function(px, py) + local g = engine.Entity.new{name="darkness", show_tooltip=true, block_sight=true, always_remember=false, unlit=self:getTalentLevel(t) * 10} + game.level.map(px, py, Map.TERRAIN+1, g) + game.level.map.remembers(px, py, false) + game.level.map.lites(px, py, false) + end, nil, {type="dark"}) + game:playSoundNear(self, "talents/breath") + return true + end, + info = function(self, t) + return ([[Call forth the dread mists of the Fearscape, blocking all but the most powerful light in a radius of %d.]]):format(self:getTalentRadius(t)) + end, +} + +newTalent{ + name = "Perception", + type = {"misc/item", 1}, + points = 5, + tactical = { BUFF = 2 }, + cooldown = 30, + getSeeInvisible = function(self, t) return self:combatTalentSpellDamage(t, 10, 45) end, + getSeeStealth = function(self, t) return self:combatTalentSpellDamage(t, 10, 20) end, + getCriticalPower = function(self, t) return 0.3 + self:getTalentLevel(t) * 0.1 end, + action = function(self, t) + self:setEffect(self.EFF_PERCEPTION, 5, {si=t.getSeeInvisible(self, t), ss=t.getSeeStealth(self, t), crit=t.getCriticalPower(self, t)}) + game:playSoundNear(self, "talents/spell_generic") + return true + end, + info = function(self, t) + local seeinvisible = t.getSeeInvisible(self, t) + local seestealth = t.getSeeStealth(self, t) + local criticalpower = t.getCriticalPower(self, t) + return ([[You sharpen your senses to supernatural acuity. + See invisible: +%d + See through stealth: +%d + Critical power: +%.1f + The effects will improve with your Spellpower.]]): + format(seeinvisible, seestealth, criticalpower) + end, +} + +newTalent{ + name = "Lifebind", + type = {"misc/item", 1}, + points = 5, + cooldown = 50, + tactical = { ATTACK = 2 }, + range = function(self, t) + return self:getTalentLevel(t) + end, + direct_hit = true, + requires_target = true, + target = function(self, t) + return {type="hit", range=self:getTalentRange(t), talent=t} + end, + getDamage = function(self, t) return end, + action = function(self, t) + local tg = self:getTalentTarget(t) + local x, y, target = self:getTarget(tg) + if not x or not y then return nil end + game:playSoundNear(self, "talents/arcane") + + -- Try to insta-kill + if target then + if target:checkHit(self:combatSpellpower(), target:combatPhysicalResist(), 0, self:getMaxAccuracy("spell"), 15) and target:canBe("instakill") and target.life > 0 then + local t_percent = target.life / target.max_life + local s_percent = self.life / self.max_life + target.life = target.max_life * s_percent + self.life = self.max_life * t_percent + game.level.map:particleEmitter(x, y, 1, "entropythrust") + game.level.map:particleEmitter(self.x, self.y, 1, "entropythrust") + else + game.logSeen(target, "%s resists the lifebind!", target.name:capitalize()) + end + end + + return true + end, + info = function(self, t) + local damage = t.getDamage(self, t) + return ([[Attempts to swap your life force for that of the target. If the swap is successful, your health percentage will be set at the target's health percentage, and vice versa. Enemies that are immune to instakill effects will resist this. The range increases with talent level.]]) + end, +} + +newTalent{ + name = "Block", + type = {"misc/item", 1}, + cooldown = function(self, t) + return 8 - self:getTalentLevelRaw(t) + end, + points = 5, + hard_cap = 5, + on_pre_use = function(self, t, silent) if not self:hasShield() then if not silent then game.logPlayer(self, "You require a weapon and a shield to use this talent.") end return false end return true end, + getProperties = function(self, t) + local shield = self:hasShield() + --if not shield then return nil end + local p = { + sp = (shield and shield.special_combat and shield.special_combat.spellplated or false), + ref = (shield and shield.special_combat and shield.special_combat.reflective or false), + br = (shield and shield.special_combat and shield.special_combat.bloodruned or false), + } + return p + end, + getBlockValue = function(self, t) + local shield = self:hasShield() + if not shield then return 0 end + return (shield.special_combat and shield.special_combat.block) or 0 + end, + getBlockedTypes = function(self, t) + local shield = self:hasShield() + local bt = {DamageType.PHYSICAL} + if not shield then return bt, "error!" end + local count = 2 + if shield.wielder.resists then + for res, v in pairs(shield.wielder.resists) do + if v > 0 then + bt[count] = res + count = count + 1 + end + end + end + if shield.wielder.on_melee_hit then + for res, v in pairs(shield.wielder.on_melee_hit) do + if v > 0 then + local add = true + for i = 1, #bt do + if bt[i] == res then add = false end + end + if add then + bt[count] = res + count = count + 1 + end + end + end + end + local n = #bt + if n < 1 then return "(error 2)" end + local e_string = "" + if n == 1 then + e_string = DamageType.dam_def[bt[1]].name + elseif n == 2 then + e_string = DamageType.dam_def[bt[1]].name.." and "..DamageType.dam_def[bt[2]].name + else + for i = 1, #bt-1 do + e_string = e_string..DamageType.dam_def[bt[i]].name..", " + end + e_string = e_string.."and "..DamageType.dam_def[bt[n]].name + end + return bt, e_string + end, + action = function(self, t) + local properties = t.getProperties(self, t) + local bt, bt_string = t.getBlockedTypes(self, t) + self:setEffect(self.EFF_BLOCKING, 1, {power = t.getBlockValue(self, t), d_types=bt, properties=properties}) + return true + end, + info = function(self, t) + local properties = t.getProperties(self, t) + local sp_text = "" + local ref_text = "" + local br_text = "" + if properties.sp then + sp_text = (" Increases your spell save by %d for that turn."):format(t.getBlockValue(self, t)) + end + if properties.ref then + ref_text = " Reflects all blocked damage back to the source." + end + if properties.br then + br_text = " All blocked damage heals the wielder." + end + local bt, bt_string = t.getBlockedTypes(self, t) + return ([[Raise your shield into blocking position for one turn, reducing the damage of all %s attacks by %d. If you block all of an attack's damage, the attacker will be vulnerable to a deadly counterstrike for one turn.%s%s%s]]):format(bt_string, t.getBlockValue(self, t), sp_text, ref_text, br_text) + end, +} diff --git a/game/modules/tome/data/talents/misc/misc.lua b/game/modules/tome/data/talents/misc/misc.lua index e7ea5e0d6e..dfe1f32aea 100644 --- a/game/modules/tome/data/talents/misc/misc.lua +++ b/game/modules/tome/data/talents/misc/misc.lua @@ -23,6 +23,7 @@ newTalentType{ type="base/race", name = "race", hide = true, description = "The newTalentType{ type="inscriptions/infusions", name = "infusions", hide = true, description = "Infusions are not class abilities, you must find them or learn them from other people." } newTalentType{ is_spell=true, no_silence=true, type="inscriptions/runes", name = "runes", hide = true, description = "Runes are not class abilities, you must find them or learn them from other people." } newTalentType{ is_spell=true, no_silence=true, type="inscriptions/taints", name = "taints", hide = true, description = "Taints are not class abilities, you must find them or learn them from other people." } +newTalentType{ type="misc/item", name = "item", hide = true, description = "Talents granted only by special items." } -- Load other misc things load("/data/talents/misc/inscriptions.lua") @@ -30,6 +31,7 @@ load("/data/talents/misc/npcs.lua") load("/data/talents/misc/horrors.lua") load("/data/talents/misc/races.lua") load("/data/talents/misc/tutorial.lua") +load("/data/talents/misc/item.lua") -- Default melee attack newTalent{ @@ -312,3 +314,4 @@ newTalent{ format(physical_reduction, spell_reduction, mental_reduction) end, } + diff --git a/game/modules/tome/data/talents/misc/races.lua b/game/modules/tome/data/talents/misc/races.lua index b7c1fc0a58..6f7d60d509 100644 --- a/game/modules/tome/data/talents/misc/races.lua +++ b/game/modules/tome/data/talents/misc/races.lua @@ -368,7 +368,7 @@ newTalent{ autolevel = "none", ai = "summoned", ai_real = "tactical", ai_state = { talent_in=2, }, stats = {str=0, dex=0, con=0, cun=0, wil=0, mag=0}, - combat = { dam=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), atk=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), dammod={str=1.1} }, + combat = { dam=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), atk=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), dammod={str=resolvers.levelup(0.2, 5, 0.2, 1.1)} }, inc_stats = { str=25 + self:getWil() * self:getTalentLevel(t) / 5, dex=18, con=10 + self:getTalentLevel(t) * 2, }, level_range = {1, nil}, exp_worth = 0, diff --git a/game/modules/tome/data/talents/psionic/other.lua b/game/modules/tome/data/talents/psionic/other.lua index faadffdc9e..2def4b53d9 100644 --- a/game/modules/tome/data/talents/psionic/other.lua +++ b/game/modules/tome/data/talents/psionic/other.lua @@ -169,21 +169,22 @@ newTalent{ end if o.type == "weapon" then self.use_psi_combat = true - atk = self:combatAttack(o.combat) dam = self:combatDamage(o.combat) + critical_power = o.combat.critical_power + max_acc = o.combat.max_acc apr = self:combatAPR(o.combat) crit = self:combatCrit(o.combat) - speed = self:combatSpeed(o.combat) self.use_psi_combat = false end return ([[Allows you to wield a weapon telekinetically, directing it with your willpower and cunning rather than crude flesh. When activated, the telekinetically-wielded weapon will attack a random melee-range target each turn. The telekinetically-wielded weapon uses Willpower in place of Strength and Cunning in place of Dexterity to determine attack and damage. - Combat stats: - Accuracy: %d - Damage: %d - APR: %d - Crit: %0.2f - Speed: %0.2f]]): - format(atk, dam, apr, crit, speed) + Combat attributes: + + #LIGHT_GREEN#Damage:#WHITE# %d + #LIGHT_GREEN#Crit multiplier:#WHITE# %.1fx + #LIGHT_GREEN#Max accuracy:#WHITE# %d%% + #LIGHT_GREEN#APR:#WHITE# %d + #LIGHT_GREEN#Crit chance:#WHITE# %0.2f]]): + format(dam, critical_power, max_acc, apr, crit) end, } diff --git a/game/modules/tome/data/talents/spells/advanced-necrotic-minions.lua b/game/modules/tome/data/talents/spells/advanced-necrotic-minions.lua index 071434fd8e..bc71e032f9 100644 --- a/game/modules/tome/data/talents/spells/advanced-necrotic-minions.lua +++ b/game/modules/tome/data/talents/spells/advanced-necrotic-minions.lua @@ -22,7 +22,7 @@ local minions_list = { type = "undead", subtype = "giant", blood_color = colors.GREY, display = "K", - combat = { dam=resolvers.levelup(resolvers.mbonus(45, 20), 1, 1), atk=15, apr=10, dammod={str=0.8} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(45, 20), 1, 1), atk=15, apr=10, dammod={str=resolvers.levelup(0.2, 5, 0.2, 0.8)} }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, infravision = 10, life_rating = 12, @@ -56,7 +56,7 @@ local minions_list = { type = "undead", subtype = "giant", blood_color = colors.GREY, display = "K", - combat = { dam=resolvers.levelup(resolvers.mbonus(45, 20), 1, 1), atk=15, apr=10, dammod={str=0.8} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(45, 20), 1, 1), atk=15, apr=10, dammod={str=resolvers.levelup(0.2, 5, 0.2, 0.8)} }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, infravision = 10, life_rating = 12, @@ -90,7 +90,7 @@ local minions_list = { type = "undead", subtype = "giant", blood_color = colors.GREY, display = "K", - combat = { dam=resolvers.levelup(resolvers.mbonus(45, 20), 1, 1), atk=15, apr=10, dammod={str=0.8} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(45, 20), 1, 1), atk=15, apr=10, dammod={str=resolvers.levelup(0.2, 5, 0.2, 0.8)} }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, infravision = 10, life_rating = 12, @@ -126,7 +126,7 @@ local minions_list = { type = "undead", subtype = "giant", blood_color = colors.GREY, display = "K", - combat = { dam=resolvers.levelup(resolvers.mbonus(45, 20), 1, 1), atk=15, apr=10, dammod={str=0.8} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(45, 20), 1, 1), atk=15, apr=10, dammod={str=resolvers.levelup(0.2, 5, 0.2, 0.8)} }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, infravision = 10, life_rating = 12, diff --git a/game/modules/tome/data/talents/spells/conveyance.lua b/game/modules/tome/data/talents/spells/conveyance.lua index 0033308cf9..f62502d420 100644 --- a/game/modules/tome/data/talents/spells/conveyance.lua +++ b/game/modules/tome/data/talents/spells/conveyance.lua @@ -44,7 +44,7 @@ newTalent{ end end if target ~= self and target:canBe("teleport") then - local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0)) + local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0), 0, self:getMaxAccuracy("spell")) if not hit then game.logSeen(target, "The spell fizzles!") return true @@ -125,7 +125,7 @@ newTalent{ end if target ~= self and target:canBe("teleport") then - local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0)) + local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0), 0, self:getMaxAccuracy("spell")) if not hit then game.logSeen(target, "The spell fizzles!") return true diff --git a/game/modules/tome/data/talents/spells/golemancy.lua b/game/modules/tome/data/talents/spells/golemancy.lua index cede45bc1d..81e79d00ff 100644 --- a/game/modules/tome/data/talents/spells/golemancy.lua +++ b/game/modules/tome/data/talents/spells/golemancy.lua @@ -38,7 +38,7 @@ local function makeGolem() never_anger = true, save_hotkeys = true, - combat = { dam=10, atk=10, apr=0, dammod={str=1} }, + combat = { dam=10, atk=10, apr=0, dammod={str=resolvers.levelup(0.1, 5, 0.2, 1)} }, body = { INVEN = 1000, QS_MAINHAND = 1, QS_OFFHAND = 1, MAINHAND = 1, OFFHAND = 1, BODY=1, GEM=2 }, equipdoll = "alchemist_golem", diff --git a/game/modules/tome/data/talents/spells/necrotic-minions.lua b/game/modules/tome/data/talents/spells/necrotic-minions.lua index 1811bf67a4..ce9f1bef22 100644 --- a/game/modules/tome/data/talents/spells/necrotic-minions.lua +++ b/game/modules/tome/data/talents/spells/necrotic-minions.lua @@ -316,7 +316,7 @@ local minions_list = { T_ROTTING_DISEASE={base=1, every=10, max=5}, }, ai_state = { talent_in=4, }, - combat = { dam=resolvers.levelup(10, 1, 1), atk=resolvers.levelup(5, 1, 1), apr=3, dammod={str=0.6} }, + combat = { dam=resolvers.levelup(10, 1, 1), atk=resolvers.levelup(5, 1, 1), apr=3, dammod={str=resolvers.levelup(0.1, 5, 0.1, 0.6)} }, }, ghast = { type = "undead", subtype = "ghoul", @@ -344,7 +344,7 @@ local minions_list = { T_ROTTING_DISEASE={base=1, every=10, max=5}, }, ai_state = { talent_in=4, }, - combat = { dam=resolvers.levelup(10, 1, 1), atk=resolvers.levelup(5, 1, 1), apr=3, dammod={str=0.6} }, + combat = { dam=resolvers.levelup(10, 1, 1), atk=resolvers.levelup(5, 1, 1), apr=3, dammod={str=resolvers.levelup(0.1, 5, 0.1, 0.6)} }, }, ghoulking = { type = "undead", subtype = "ghoul", @@ -368,7 +368,7 @@ local minions_list = { combat_armor = 3, combat_def = 10, ai_state = { talent_in=2, ai_pause=20 }, rank = 3, - combat = { dam=resolvers.levelup(30, 1, 1.2), atk=resolvers.levelup(8, 1, 1), apr=4, dammod={str=0.6} }, + combat = { dam=resolvers.levelup(30, 1, 1.2), atk=resolvers.levelup(8, 1, 1), apr=4, dammod={str=resolvers.levelup(0.1, 5, 0.1, 0.6)} }, resolvers.talents{ T_STUN={base=3, every=9, max=7}, T_BITE_POISON={base=3, every=9, max=7}, @@ -382,7 +382,7 @@ local minions_list = { vampire = { type = "undead", subtype = "vampire", display = "V", - combat = { dam=resolvers.levelup(resolvers.mbonus(30, 10), 1, 0.8), atk=10, apr=9, damtype=DamageType.DRAINLIFE, dammod={str=1.9} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(30, 10), 1, 0.8), atk=10, apr=9, damtype=DamageType.DRAINLIFE, dammod={str=resolvers.levelup(0.3, 5, 0.2, 1.9)} }, level_range = {1, nil}, exp_worth = 0, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, autolevel = "warriormage", @@ -409,7 +409,7 @@ local minions_list = { m_vampire = { type = "undead", subtype = "vampire", display = "V", - combat = { dam=resolvers.levelup(resolvers.mbonus(30, 10), 1, 0.8), atk=10, apr=9, damtype=DamageType.DRAINLIFE, dammod={str=1.9} }, + combat = { dam=resolvers.levelup(resolvers.mbonus(30, 10), 1, 0.8), atk=10, apr=9, damtype=DamageType.DRAINLIFE, dammod={str=resolvers.levelup(0.3, 5, 0.2, 1.9)} }, level_range = {1, nil}, exp_worth = 0, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, autolevel = "warriormage", @@ -522,7 +522,7 @@ local minions_list = { combat_armor = 0, combat_def = resolvers.mbonus(10, 50), invisibility = resolvers.mbonus(5, 10), ai_state = { talent_in=4, }, - combat = { dam=resolvers.mbonus(45, 45), atk=resolvers.mbonus(25, 45), apr=100, dammod={str=0.5, mag=0.5} }, + combat = { dam=resolvers.mbonus(45, 45), atk=resolvers.mbonus(25, 45), apr=100, dammod={str=resolvers.levelup(0.1, 5, 0.1, 0.5), mag=resolvers.levelup(0.1, 5, 0.1, 0.5)} }, resolvers.talents{ T_BURNING_HEX={base=3, every=5, max=7}, T_BLUR_SIGHT={base=4, every=6, max=8}, @@ -532,7 +532,7 @@ local minions_list = { type = "undead", subtype = "lich", display = "L", rank = 3, size = 3, - combat = { dam=resolvers.rngavg(16,27), atk=16, apr=9, damtype=DamageType.DARKSTUN, dammod={mag=0.9} }, + combat = { dam=resolvers.rngavg(16,27), atk=16, apr=9, damtype=DamageType.DARKSTUN, dammod={mag=resolvers.levelup(0.2, 5, 0.2, 0.9)} }, body = { INVEN = 10, MAINHAND = 1, OFFHAND = 1, FINGER = 2, NECK = 1, LITE = 1, BODY = 1, HEAD = 1, CLOAK = 1, HANDS = 1, BELT = 1, FEET = 1}, equipment = resolvers.equip{ {type="armor", subtype="cloth", ego_chance=75, autoreq=true}, diff --git a/game/modules/tome/data/talents/spells/staff-combat.lua b/game/modules/tome/data/talents/spells/staff-combat.lua index 29e0b42e6d..5b64858ebd 100644 --- a/game/modules/tome/data/talents/spells/staff-combat.lua +++ b/game/modules/tome/data/talents/spells/staff-combat.lua @@ -72,6 +72,7 @@ newTalent{ elseif damtype == DamageType.NATURE then explosion = "slime" particle = "bolt_slime" trail = "slimetrail" elseif damtype == DamageType.BLIGHT then explosion = "slime" particle = "bolt_slime" trail = "slimetrail" elseif damtype == DamageType.PHYSICAL then explosion = "dark" particle = "stone_shards" trail = "earthtrail" + elseif damtype == DamageType.TEMPORAL then explosion = "manathrust" particle = "bolt_arcane" trail = "arcanetrail" else explosion = "manathrust" particle = "bolt_arcane" trail = "arcanetrail" damtype = DamageType.ARCANE end @@ -106,13 +107,13 @@ newTalent{ mode = "passive", require = spells_req2, points = 5, - getDamage = function(self, t) return self:getTalentLevel(t) * 5 end, - getPercentInc = function(self, t) return math.sqrt(self:getTalentLevel(t) / 10) / 2 end, + getDamage = function(self, t) return math.floor(t.getPercentInc(self, t) * self:combatSpellpower()) end, + getPercentInc = function(self, t) return self:getTalentLevel(t) / 10 end, info = function(self, t) local damage = t.getDamage(self, t) local inc = t.getPercentInc(self, t) - return ([[Increases Physical Power by %d. Also increases damage done with staves by %d%%.]]): - format(damage, 100 * inc) + return ([[Increases damage done with staves by %d%% of your spellpower (%d).]]): + format(100*inc, damage) end, } diff --git a/game/modules/tome/data/talents/techniques/2hweapon.lua b/game/modules/tome/data/talents/techniques/2hweapon.lua index 0d7468aa18..04a3075db0 100644 --- a/game/modules/tome/data/talents/techniques/2hweapon.lua +++ b/game/modules/tome/data/talents/techniques/2hweapon.lua @@ -185,7 +185,7 @@ newTalent{ -- Try to insta-kill if hit then - if target:checkHit(self:combatPhysicalpower(), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) and target:canBe("instakill") and target.life > 0 and target.life < target.max_life * 0.2 then + if target:checkHit(self:combatPhysicalpower(), target:combatPhysicalResist(), 0, self:getMaxAccuracy("physical", weapon.combat), 5 - self:getTalentLevel(t) / 2) and target:canBe("instakill") and target.life > 0 and target.life < target.max_life * 0.2 then -- KILL IT ! game.logSeen(target, "%s feels the pain of the death blow!", target.name:capitalize()) target:die(self) diff --git a/game/modules/tome/data/talents/techniques/archery.lua b/game/modules/tome/data/talents/techniques/archery.lua index 51d21fc41a..ce2b02c1f7 100644 --- a/game/modules/tome/data/talents/techniques/archery.lua +++ b/game/modules/tome/data/talents/techniques/archery.lua @@ -31,6 +31,9 @@ newTalent{ tactical = { ATTACK = { weapon = 1 } }, on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon() then if not silent then game.logPlayer(self, "You require a bow or sling for this talent.") end return false end return true end, no_unlearn_last = true, + on_learn = function(self, t) + self:learnTalent(self.T_RELOAD, true, 1, {no_unlearn=true}) + end, use_psi_archery = function(self, t) local inven = self:getInven("PSIONIC_FOCUS") if not inven then return false end diff --git a/game/modules/tome/data/talents/techniques/bow.lua b/game/modules/tome/data/talents/techniques/bow.lua index 0ff857f388..7467c0af1d 100644 --- a/game/modules/tome/data/talents/techniques/bow.lua +++ b/game/modules/tome/data/talents/techniques/bow.lua @@ -23,13 +23,15 @@ newTalent{ points = 10, require = { stat = { dex=function(level) return 12 + level * 3 end }, }, mode = "passive", - getDamage = function(self, t) return self:getTalentLevel(t) * 5 end, - getPercentInc = function(self, t) return math.sqrt(self:getTalentLevel(t) / 10) / 2 end, + getDamage = function(self, t) return math.floor(t.getPercentInc(self, t) * self:combatPhysicalpower()) end, + getPercentInc = function(self, t) return self:getTalentLevel(t) / 10 end, + getReloadBoost = function(self, t) return math.floor(self:getTalentLevel(t) / 5) end, info = function(self, t) - local damage = t.getDamage(self, t) local inc = t.getPercentInc(self, t) - return ([[Increases Physical Power by %d. Also increases damage done with bows by %d%%.]]): - format(damage, inc * 100) + local damage = t.getDamage(self, t) + local shots = t.getReloadBoost(self, t) + return ([[Increases damage done with bows by %d%% of your physical power (%d). Also increases the number of arrows you can reload per turn by %d.]]): + format(inc * 100, damage, shots) end, } diff --git a/game/modules/tome/data/talents/techniques/combat-training.lua b/game/modules/tome/data/talents/techniques/combat-training.lua index c16b5985b2..73d6f082e9 100644 --- a/game/modules/tome/data/talents/techniques/combat-training.lua +++ b/game/modules/tome/data/talents/techniques/combat-training.lua @@ -100,15 +100,15 @@ newTalent{ name = "Weapons Mastery", type = {"technique/combat-training", 1}, points = 10, - require = { stat = { str=function(level) return 12 + level * 3 end }, }, + require = { stat = { str=function(level) return math.ceil(12 + level * 4.5) end }, }, mode = "passive", - getDamage = function(self, t) return self:getTalentLevel(t) * 5 end, - getPercentInc = function(self, t) return math.sqrt(self:getTalentLevel(t) / 10) / 2 end, + getDamage = function(self, t) return math.floor(t.getPercentInc(self, t) * self:combatPhysicalpower()) end, + getPercentInc = function(self, t) return self:getTalentLevel(t) / 10 end, info = function(self, t) local damage = t.getDamage(self, t) local inc = t.getPercentInc(self, t) - return ([[Increases Physical Power by %d. Also increases damage done with swords, axes, maces by %d%%]]): - format(damage, 100*inc) + return ([[Increases damage done with swords, axes and maces by %d%% of your physical power (%d).]]): + format(100*inc, damage) end, } @@ -119,13 +119,13 @@ newTalent{ points = 10, require = { stat = { dex=function(level) return 10 + level * 3 end }, }, mode = "passive", - getDamage = function(self, t) return self:getTalentLevel(t) * 5 end, - getPercentInc = function(self, t) return math.sqrt(self:getTalentLevel(t) / 10) / 2 end, + getDamage = function(self, t) return math.floor(t.getPercentInc(self, t) * self:combatPhysicalpower()) end, + getPercentInc = function(self, t) return self:getTalentLevel(t) / 20 end, info = function(self, t) local damage = t.getDamage(self, t) local inc = t.getPercentInc(self, t) - return ([[Increases Physical Power by %d. Also increases damage done with knives by %d%%]]): - format(damage, 100*inc) + return ([[Increases damage done with knives by %d%% of your physical power (%d).]]): + format(100*inc, damage) end, } @@ -136,12 +136,12 @@ newTalent{ points = 10, require = { stat = { str=function(level) return 10 + level * 3 end, dex=function(level) return 10 + level * 3 end }, }, mode = "passive", - getDamage = function(self, t) return self:getTalentLevel(t) * 5 end, - getPercentInc = function(self, t) return math.sqrt(self:getTalentLevel(t) / 10) / 2 end, + getDamage = function(self, t) return math.floor(t.getPercentInc(self, t) * self:combatPhysicalpower()) end, + getPercentInc = function(self, t) return self:getTalentLevel(t) / 10 end, info = function(self, t) local damage = t.getDamage(self, t) local inc = t.getPercentInc(self, t) - return ([[Increases Physical Power by %d. Also increases damage done with exotic weapons by %d%%]]): - format(damage, 100*inc) + return ([[Increases damage done with exotic weapons by %d%% of your physical power (%d).]]): + format(100*inc, damage) end, } diff --git a/game/modules/tome/data/talents/techniques/finishing-moves.lua b/game/modules/tome/data/talents/techniques/finishing-moves.lua index 8fa504d7b2..81d60a8fba 100644 --- a/game/modules/tome/data/talents/techniques/finishing-moves.lua +++ b/game/modules/tome/data/talents/techniques/finishing-moves.lua @@ -218,7 +218,7 @@ newTalent{ -- Try to insta-kill if hit then - if target:checkHit(self:combatPhysicalpower(), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) and target:canBe("instakill") and target.life > 0 and target.life < target.max_life * 0.2 then + if target:checkHit(self:combatPhysicalpower(), target:combatPhysicalResist(), 0, self:getMaxAccuracy("physical", self.combat), 5 - self:getTalentLevel(t) / 2) and target:canBe("instakill") and target.life > 0 and target.life < target.max_life * 0.2 then -- KILL IT ! game.logSeen(target, "%s feels the pain of the death blow!", target.name:capitalize()) target:die(self) diff --git a/game/modules/tome/data/talents/techniques/sling.lua b/game/modules/tome/data/talents/techniques/sling.lua index 1063fe4c49..b1cf3b67da 100644 --- a/game/modules/tome/data/talents/techniques/sling.lua +++ b/game/modules/tome/data/talents/techniques/sling.lua @@ -23,13 +23,15 @@ newTalent{ points = 10, require = { stat = { dex=function(level) return 12 + level * 3 end }, }, mode = "passive", - getDamage = function(self, t) return self:getTalentLevel(t) * 5 end, - getPercentInc = function(self, t) return math.sqrt(self:getTalentLevel(t) / 10) / 2 end, + getDamage = function(self, t) return math.floor(t.getPercentInc(self, t) * self:combatPhysicalpower()) end, + getPercentInc = function(self, t) return self:getTalentLevel(t) / 10 end, + getReloadBoost = function(self, t) return math.floor(self:getTalentLevel(t) / 5) end, info = function(self, t) local damage = t.getDamage(self, t) local inc = t.getPercentInc(self, t) - return ([[Increases Physical Power by %d. Also increases damage done with slings by %d%%.]]): - format(damage, inc * 100) + local shots = t.getReloadBoost(self, t) + return ([[Increases damage done with slings by %d%% of your physical power (%d). Also increases the number of shots you can reload per turn by %d.]]): + format(inc * 100, damage, shots) end, } @@ -81,7 +83,8 @@ newTalent{ tactical = { ATTACK = { weapon = 2 }, DISABLE = { knockback = 2 }, ESCAPE = { knockback = 1 } }, on_pre_use = function(self, t, silent) if not self:hasArcheryWeapon("sling") then if not silent then game.logPlayer(self, "You require a sling for this talent.") end return false end return true end, archery_onhit = function(self, t, target, x, y) - if target:checkHit(self:combatAttack(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then + local w, a = self:hasArcheryWeapon("sling") + if target:checkHit(self:combatAttack(), target:combatPhysicalResist(), 0, self:getMaxAccuracy("physical", a.combat), 15) and target:canBe("knockback") then target:knockback(self.x, self.y, 4) target:crossTierEffect(target.EFF_OFFBALANCE, self:combatAttack()) game.logSeen(target, "%s is knocked back!", target.name:capitalize()) diff --git a/game/modules/tome/data/talents/techniques/unarmed-discipline.lua b/game/modules/tome/data/talents/techniques/unarmed-discipline.lua index 599d97354f..24e557f59d 100644 --- a/game/modules/tome/data/talents/techniques/unarmed-discipline.lua +++ b/game/modules/tome/data/talents/techniques/unarmed-discipline.lua @@ -82,7 +82,7 @@ newTalent{ getDamage = function(self, t) return self:combatTalentPhysicalDamage(t, 5, 50) * getUnarmedTrainingBonus(self) end, getDamageTwo = function(self, t) return self:combatTalentPhysicalDamage(t, 10, 75) * getUnarmedTrainingBonus(self) end, do_throw = function(self, target, t) - local hit = self:checkHit(self:combatAttack(), target:combatDefense(), 0, 95, 5 - self:getTalentLevel(t) / 2) + local hit = self:checkHit(self:combatAttack(), target:combatDefense(), 0, self:getMaxAccuracy("physical", self.combat), 5 - self:getTalentLevel(t) / 2) if hit then self:project(target, target.x, target.y, DamageType.PHYSICAL, self:physicalCrit(t.getDamageTwo(self, t), nil, target, self:combatAttack(), target:combatDefense())) -- if grappled stun diff --git a/game/modules/tome/data/talents/techniques/weaponshield.lua b/game/modules/tome/data/talents/techniques/weaponshield.lua index a84e1fe581..c676c5e350 100644 --- a/game/modules/tome/data/talents/techniques/weaponshield.lua +++ b/game/modules/tome/data/talents/techniques/weaponshield.lua @@ -72,8 +72,19 @@ newTalent{ require = techs_req2, mode = "passive", points = 5, + getDurInc = function(self, t) + return math.ceil(self:getTalentLevel(t)/4) + end, + getCritInc = function(self, t) + return self:combatTalentIntervalDamage(t, "dex", 10, 50) + end, info = function(self, t) - return ([[When you block/avoid a melee blow you have a %d%% chance to get a free, automatic melee attack against your foe. Your chances increase with dexterity.]]):format(self:getTalentLevel(t) * (5 + self:getDex(5, true))) + local inc = t.getDurInc(self, t) + return ([[Improves your ability to perform counterstrikes after blocks in the following ways: + Allows counterstrikes after incomplete blocks. + Increases the duration of the counterstrike debuff on attackers by %d turn%s. + Increases the number of counterstrikes you can perform on a target while they're vulnerable by %d. + Increases the crit chance of counterstrikes by %d%%. This increase scales with Dexterity.]]):format(inc, (inc > 1 and "s" or ""), inc, t.getCritInc(self, t)) end, } @@ -109,7 +120,7 @@ newTalent{ -- Try to stun ! if hit then - if target:checkHit(self:combatAttack(shield.special_combat), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) and target:canBe("knockback") then + if target:checkHit(self:combatAttack(shield.special_combat), target:combatPhysicalResist(), 0, self:getMaxAccuracy("physical", shield.special_combat), 5 - self:getTalentLevel(t) / 2) and target:canBe("knockback") then target:knockback(self.x, self.y, 4) else game.logSeen(target, "%s resists the knockback!", target.name:capitalize()) diff --git a/game/modules/tome/data/timed_effects/magical.lua b/game/modules/tome/data/timed_effects/magical.lua index 91385ab028..61fe7f805b 100644 --- a/game/modules/tome/data/timed_effects/magical.lua +++ b/game/modules/tome/data/timed_effects/magical.lua @@ -1601,3 +1601,85 @@ newEffect{ self:removeTemporaryValue("bloodcasting", eff.tmpid) end, } + + +newEffect{ + name = "WARD", image = "talents/ward.png", + desc = "Ward", + long_desc = function(self, eff) return ("Fully absorbs %d %s attack%s."):format(#eff.particles, DamageType.dam_def[eff.d_type].name, #eff.particles > 1 and "s" or "") end, + type = "magical", + subtype = { acrane=true }, + status = "beneficial", + parameters = { nb=3 }, + on_gain = function(self, eff) return ("#Target# warded against %s!"):format(DamageType.dam_def[eff.d_type].name), "+Ward" end, + on_lose = function(self, eff) return ("#Target#'s %s ward fades"):format(DamageType.dam_def[eff.d_type].name), "-Ward" end, + absorb = function(type, dam, eff, self, src) + if eff.d_type ~= type then return dam end + game.logPlayer(self, "Your %s ward absorbs the damage!", DamageType.dam_def[eff.d_type].name) + local pid = table.remove(eff.particles) + if pid then self:removeParticles(pid) end + if #eff.particles <= 0 then + --eff.dur = 0 + self:removeEffect(self.EFF_WARD) + end + return 0 + end, + activate = function(self, eff) + local nb = eff.nb + local ps = {} + for i = 1, nb do ps[#ps+1] = self:addParticles(Particles.new("ward", 1, {color=DamageType.dam_def[eff.d_type].color})) end + eff.particles = ps + end, + deactivate = function(self, eff) + for i, particle in ipairs(eff.particles) do self:removeParticles(particle) end + end, +} + +newEffect{ + name = "ELEMENTAL_RETRIBUTION", image = "talents/elemental_retribution.png", + desc = "Retribution", + long_desc = function(self, eff) return ("Seeking retribution for having suffered %s damage. Spellpower increased by %d."):format(eff.e_string, eff.power) end, + type = "magical", + subtype = { arcane=true }, + status = "beneficial", + parameters = { power=1 }, + on_gain = function(self, err) return nil, "+Retribution" end, + on_lose = function(self, err) return nil, "-Retribution" end, + on_merge = function(self, old_eff, new_eff) + -- stack the critical power boost up to a maximum + self:removeTemporaryValue("combat_spellpower", old_eff.tmpid) + old_eff.power = math.min(old_eff.power + new_eff.power, old_eff.maximum) + old_eff.tmpid = self:addTemporaryValue("combat_spellpower", old_eff.power) + old_eff.dur = new_eff.dur + return old_eff + end, + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("combat_spellpower", eff.power) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("combat_spellpower", eff.tmpid) + end, + +} + +newEffect{ + name = "PERCEPTION", image = "talents/perception.png", + desc = "Perception", + long_desc = function(self, eff) return ("Increased capacity for spotting invisible and stealthy foes, as well as taking advantage of enemy weak points. (%+d see invisible, %+d see through stealth, and %+.1f critical power)"):format(eff.si, eff.ss, eff.crit) end, + type = "magical", + subtype = { sense=true }, + status = "beneficial", + parameters = { power=10, crit=10, apr=10 }, + on_gain = function(self, err) return nil, "+Perception" end, + on_lose = function(self, err) return nil, "-Perception" end, + activate = function(self, eff) + eff.siid = self:addTemporaryValue("see_invisible", eff.si) + eff.ssid = self:addTemporaryValue("see_stealth", eff.ss) + eff.critid = self:addTemporaryValue("combat_critical_power", eff.crit) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("see_invisible", eff.siid) + self:removeTemporaryValue("see_stealth", eff.ssid) + self:removeTemporaryValue("combat_critical_power", eff.critid) + end, +} diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua index b588c8c486..895888e6b6 100644 --- a/game/modules/tome/data/timed_effects/mental.lua +++ b/game/modules/tome/data/timed_effects/mental.lua @@ -1148,14 +1148,14 @@ newEffect{ -- in range if not self:attr("never_move") and rng.percent(eff.chance) then local sourceX, sourceY = eff.source.x, eff.source.y - + local bestX, bestY local bestDistance = 0 local start = rng.range(0, 8) for i = start, start + 8 do local x = self.x + (i % 3) - 1 local y = self.y + math.floor((i % 9) / 3) - 1 - + if x ~= self.x or y ~= self.y then local distance = core.fov.distance(x, y, sourceX, sourceY) if distance > bestDistance @@ -1168,7 +1168,7 @@ newEffect{ end end end - + if bestX then self:move(bestX, bestY, false) game.logPlayer(self, "#F53CBE#You panic and flee from %s.", eff.source.name) @@ -1400,7 +1400,7 @@ newEffect{ on_timeout = function(self, eff) if eff.src.dead or not game.level:hasEntity(eff.src) then eff.dur = 0 return true end if rng.percent(eff.chance or 0) then - if self:checkHit(eff.src:combatSpellpower(), self:combatMentalResist(), 0, 95, 5) then + if self:checkHit(eff.src:combatSpellpower(), self:combatSpellResist(), 0, eff.src:getMaxAccuracy("spell"), 5) then local t = eff.src:getTalentFromId(eff.src.T_INNER_DEMONS) t.summon_inner_demons(eff.src, self, t) else @@ -1863,7 +1863,7 @@ newEffect{ addEffect = function(self, eff) if eff.physicalResistId then self:removeTemporaryValue("resists", eff.physicalResistId) end eff.physicalResistId = self:addTemporaryValue("resists", { [DamageType.PHYSICAL]=eff.physicalResistChange }) - + local maxId local maxValue = 0 for id, def in ipairs(self.stats_def) do @@ -1992,9 +1992,9 @@ newEffect{ if old_eff.incStatsId then self:removeTemporaryValue("inc_stats", old_eff.incStatsId) end old_eff.incStats = nil old_eff.incStatsId = nil - + self.tempeffect_def[self.EFF_MIMIC].activate(self, new_eff) - + return new_eff end } @@ -2123,6 +2123,33 @@ newEffect{ end, } +newEffect{ + name = "SAVAGERY", image = "talents/savagery.png", + desc = "Savage", + long_desc = function(self, eff) return ("Savagely seeking the lives of foes. Critical power increased by %.1f."):format(eff.power) end, + type = "physical", + subtype = { frenzy=true }, + status = "beneficial", + parameters = { power=1 }, + on_gain = function(self, err) return nil, "+Savagery" end, + on_lose = function(self, err) return nil, "-Savagery" end, + on_merge = function(self, old_eff, new_eff) + -- stack the critical power boost up to a maximum + self:removeTemporaryValue("combat_critical_power", old_eff.tmpid) + old_eff.power = math.min(old_eff.power + new_eff.power, 1.5) + old_eff.tmpid = self:addTemporaryValue("combat_critical_power", old_eff.power) + old_eff.dur = new_eff.dur + return old_eff + end, + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("combat_critical_power", eff.power) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("combat_critical_power", eff.tmpid) + end, + +} + newEffect{ name = "LOBOTOMIZED", image = "talents/psychic_lobotomy.png", desc = "Lobotomized", diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua index a38ffb5c15..72c9bb79ca 100644 --- a/game/modules/tome/data/timed_effects/other.lua +++ b/game/modules/tome/data/timed_effects/other.lua @@ -730,7 +730,7 @@ newEffect{ T_BITE_POISON={base=1, every=10, max=5}, T_ROTTING_DISEASE={base=1, every=10, max=5}, }, - combat = { dam=resolvers.levelup(10, 1, 1), atk=resolvers.levelup(5, 1, 1), apr=3, dammod={str=0.6} }, + combat = { dam=resolvers.levelup(10, 1, 1), atk=resolvers.levelup(5, 1, 1), apr=3, dammod={str=resolvers.levelup(0.2, 5, 0.1, 0.6)} }, }, doReprieveFromDeath = function(self, eff, target) local def = self.tempeffect_def[self.EFF_CURSE_OF_CORPSES] @@ -1131,7 +1131,7 @@ newEffect{ see_invisible = 80, max_life = resolvers.rngavg(50, 80), combat_armor = 1, combat_def = 10, - combat = { dam=resolvers.levelup(resolvers.rngavg(15,20), 1, 1.1), atk=resolvers.rngavg(5,15), apr=5, dammod={str=1} }, + combat = { dam=resolvers.levelup(resolvers.rngavg(15,20), 1, 1.1), atk=resolvers.rngavg(5,15), apr=5, dammod={str=resolvers.levelup(0.2, 5, 0.2, 1)} }, resolvers.talents{ }, }, @@ -1299,3 +1299,30 @@ newEffect{ return dam end, } + + +newEffect{ + name = "RELOADING", image = "talents/reload.png", + desc = "Reloading", + long_desc = function(self, eff) return ("Reloading.") end, + decrease = 0, + type = "other", + subtype = { miscellaneous=true }, + status = "beneficial", + parameters = {}, + activate = function(self, eff) + game.logPlayer(self, "#LIGHT_BLUE#You begin reloading.") + end, + deactivate = function(self, eff) + end, + on_timeout = function(self, eff) + for i = 1, eff.shots_per_turn do + eff.ammo.combat.shots_left = eff.ammo.combat.shots_left + 1 + if eff.ammo.combat.shots_left == eff.ammo.combat.capacity then + game.logPlayer(self, "Your %s is full.", eff.ammo.name) + self:breakReloading() + break + end + end + end, +} diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua index d46bbc3b10..b1829c1183 100644 --- a/game/modules/tome/data/timed_effects/physical.lua +++ b/game/modules/tome/data/timed_effects/physical.lua @@ -1566,6 +1566,73 @@ newEffect{ end, } +newEffect{ + name = "BLOCKING", image = "talents/block.png", + desc = "Blocking", + long_desc = function(self, eff) return ("Absorbs %d damage from the next blockable attack."):format(eff.power) end, + type = "physical", + subtype = { tactic=true }, + status = "beneficial", + parameters = { nb=1 }, + on_gain = function(self, eff) return nil, nil end, + on_lose = function(self, eff) return nil, nil end, + do_block = function(type, dam, eff, self, src) + local dur_inc = 0 + local crit_inc = 0 + local nb = 1 + if self:knowTalent(self.T_RIPOSTE) then + local t = self:getTalentFromId(self.T_RIPOSTE) + dur_inc = t.getDurInc(self, t) + crit_inc = t.getCritInc(self, t) + nb = nb + dur_inc + end + local b = false + for i = 1, #eff.d_types do + if type == eff.d_types[i] then b = true break end + end + if not b then return dam end + eff.dur = 0 + local amt = util.bound(dam - eff.power, 0, dam) + local blocked = dam - amt + if eff.properties.br then self:heal(blocked) end + if eff.properties.ref and src.life then DamageType.defaultProjector(src, src.x, src.y, type, blocked, tmp, true) end + if (self:knowTalent(self.T_RIPOSTE) or amt == 0) and src.life then src:setEffect(src.EFF_COUNTERSTRIKE, 1 + dur_inc, {power=eff.power, no_ct_effect=true, src=self, crit_inc=crit_inc, nb=nb}) end + return amt + end, + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("block", eff.power) + eff.def = self:addTemporaryValue("combat_def", -eff.power) + if eff.properties.sp then eff.spell = self:addTemporaryValue("combat_spellresist", eff.power) end + end, + deactivate = function(self, eff) + self:removeTemporaryValue("block", eff.tmpid) + self:removeTemporaryValue("combat_def", eff.def) + if eff.properties.sp then self:removeTemporaryValue("combat_spellresist", eff.spell) end + end, +} + +newEffect{ + name = "COUNTERSTRIKE", image = "effects/counterstrike.png", + desc = "Counterstrike", + long_desc = function(self, eff) return "Vulnerable to deadly counterstrikes. Next melee attack will inflict double damage." end, + type = "physical", + subtype = { tactic=true }, + status = "detrimental", + parameters = { nb=1 }, + on_gain = function(self, eff) return nil, "+Counter" end, + on_lose = function(self, eff) return nil, "-Counter" end, + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("counterstrike", 1) + eff.def = self:addTemporaryValue("combat_def", -eff.power) + eff.dur = eff.dur * (self.global_speed or 1) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("counterstrike", eff.tmpid) + self:removeTemporaryValue("combat_def", eff.def) + print("counterstrike gone!") + end, +} + newEffect{ name = "CURSED_WOUND", image = "talents/slash.png", desc = "Cursed Wound", @@ -1586,11 +1653,11 @@ newEffect{ -- add the remaining healing reduction spread out over the new duration old_eff.healFactorChange = math.max(-0.75, (old_eff.healFactorChange / old_eff.totalDuration) * old_eff.dur + new_eff.healFactorChange) old_eff.dur = math.max(old_eff.dur, new_eff.dur) - + self:removeTemporaryValue("healing_factor", old_eff.healFactorId) old_eff.healFactorId = self:addTemporaryValue("healing_factor", old_eff.healFactorChange) game.logSeen(self, "%s has re-opened a cursed wound!", self.name:capitalize()) - + return old_eff end, } @@ -1612,4 +1679,3 @@ newEffect{ self:removeTemporaryValue("inc_stealth", eff.stealthid) end, } - diff --git a/game/modules/tome/data/zones/arena/objects.lua b/game/modules/tome/data/zones/arena/objects.lua index 908003736a..14ef866eac 100644 --- a/game/modules/tome/data/zones/arena/objects.lua +++ b/game/modules/tome/data/zones/arena/objects.lua @@ -107,11 +107,12 @@ newEntity{ define_as = "ARENA_BOOTS_RUSH", name = "a pair of leather boots of ru newEntity{ define_as = "ARENA_BOW", name = "elm longbow of piercing arrows", base = "BASE_LONGBOW", + short_name = "elm", level_range = {1, 10}, power_source = {technique=true}, require = { stat = { dex=11 }, }, rarity = 30, - add_name = " #CHARGES#", + --add_name = " #CHARGES#", egoed = true, greater_ego = 1, identified = true, @@ -120,23 +121,21 @@ newEntity{ define_as = "ARENA_BOW", name = "elm longbow of piercing arrows", use_talent = { id = Talents.T_PIERCING_ARROW, level = 2, power = 10 }, max_power = 10, power_regen = 1, combat = { + dam = 5, + critical_power = 1.8, range = 8, physspeed = 0.8, - }, - basic_ammo = { - dam = 20, - apr = 5, - physcrit = 1, - dammod = {dex=0.7, str=0.5}, + dammod = {dex=0.2}, }, } newEntity{ define_as = "ARENA_SLING", name = "rough leather sling of flare", base = "BASE_SLING", + short_name = "rough", level_range = {1, 10}, power_source = {technique=true}, require = { stat = { dex=11 }, }, - add_name = " #CHARGES#", + --add_name = " #CHARGES#", rarity = 30, egoed = true, greater_ego = 1, @@ -146,13 +145,10 @@ newEntity{ define_as = "ARENA_SLING", name = "rough leather sling of flare", use_talent = { id = Talents.T_FLARE, level = 3, power = 25 }, max_power = 25, power_regen = 1, combat = { + dam = 5, + critical_power = 1.8, range = 8, physspeed = 0.8, - }, - basic_ammo = { - dam = 20, - apr = 1, - physcrit = 4, - dammod = {dex=0.7, cun=0.5}, + dammod = {dex=0.2}, }, } diff --git a/game/modules/tome/data/zones/deep-bellow/npcs.lua b/game/modules/tome/data/zones/deep-bellow/npcs.lua index e9a72f8b9e..bb6a87d108 100644 --- a/game/modules/tome/data/zones/deep-bellow/npcs.lua +++ b/game/modules/tome/data/zones/deep-bellow/npcs.lua @@ -92,7 +92,7 @@ It seems to come from the digestive system of the mouth.]], movement_speed = 3, size_category = 1, - combat = { dam=resolvers.mbonus(25, 15), damtype=DamageType.SLIME, dammod={str=1} }, + combat = { dam=resolvers.mbonus(25, 15), damtype=DamageType.SLIME, dammod={str=resolvers.levelup(0.1, 5, 0.2, 1)} }, autolevel = "warrior", ai = "dumb_talented_simple", ai_state = { talent_in=4, ai_move="move_astar" }, diff --git a/game/modules/tome/data/zones/high-peak/objects.lua b/game/modules/tome/data/zones/high-peak/objects.lua index 9dbf1a98e2..6292e3d7f5 100644 --- a/game/modules/tome/data/zones/high-peak/objects.lua +++ b/game/modules/tome/data/zones/high-peak/objects.lua @@ -21,12 +21,14 @@ load("/data/general/objects/objects-far-east.lua") load("/data/general/objects/lore/sunwall.lua") local Stats = require "engine.interface.ActorStats" +local Talents = require "engine.interface.ActorTalents" -- The staff of absorption, the reason the game exists! newEntity{ define_as = "STAFF_ABSORPTION_AWAKENED", base="BASE_STAFF", power_source = {unknown=true}, unique = true, godslayer=true, name = "Awakened Staff of Absorption", identified=true, force_lore_artifact=true, + flavor_name = "magestaff", display = "\\", color=colors.VIOLET, image = "object/artifact/staff_absorption.png", encumber = 7, desc = [[Carved with runes of power, this staff seems to have been made long ago. Yet it bears no signs of tarnishment. @@ -35,20 +37,42 @@ The Sorcerers seem to have awakened its power. #{italic}#"And lo they came to Amakthel himself, and thousands were killed in the assault on his throne, and three of the Godslayers were broken beneath his feet. But Falion with his dying breath pierced the great god on his knee with the icy sword Arkil, and seeing his opportunity Caldizar, leader of the Godslayers, advanced with the Staff of Absorption and struck a terrifying blow against Amakthel. So fell the greatest of the gods by the hands of his own children, and his face was forced into the dust."#{normal}#]], require = { stat = { mag=60 }, }, + modes = {"fire", "cold", "lightning", "arcane"}, combat = { - dam = 80, - apr = 60, - atk = 30, - dammod = {mag=1.3}, + is_greater = true, + of_breaching = true, + of_retribution = true, + dam = 60, + max_acc = 100, + critical_power = 2.5, + dammod = {mag=0.8}, damtype = DamageType.ARCANE, }, wielder = { combat_spellpower = 48, - combat_spellcrit = 15, max_mana = 100, max_positive = 50, max_negative = 50, inc_stats = { [Stats.STAT_MAG] = 10, [Stats.STAT_WIL] = 10 }, + inc_damage={ + [DamageType.FIRE] = 60, + [DamageType.LIGHTNING] = 60, + [DamageType.COLD] = 60, + [DamageType.ARCANE] = 60, + }, + resists_pen={ + [DamageType.FIRE] = 30, + [DamageType.LIGHTNING] = 30, + [DamageType.COLD] = 30, + [DamageType.ARCANE] = 30, + }, + elemental_retribution = { + [DamageType.FIRE] = 1, + [DamageType.LIGHTNING] = 1, + [DamageType.COLD] = 1, + [DamageType.ARCANE] = 1, + }, + learn_talent = {[Talents.T_COMMAND_STAFF] = 5, [Talents.T_ELEMENTAL_RETRIBUTION] = 5,}, speaks_shertul = 1, }, diff --git a/game/modules/tome/data/zones/norgos-lair/npcs.lua b/game/modules/tome/data/zones/norgos-lair/npcs.lua index 8e6ae846d5..4da6d3cf36 100644 --- a/game/modules/tome/data/zones/norgos-lair/npcs.lua +++ b/game/modules/tome/data/zones/norgos-lair/npcs.lua @@ -46,7 +46,7 @@ newEntity{ base="BASE_NPC_BEAR", define_as = "NORGOS", instakill_immune = 1, move_others=true, - combat = { dam=resolvers.levelup(17, 1, 0.8), atk=10, apr=9, dammod={str=1.2} }, + combat = { dam=resolvers.levelup(17, 1, 0.8), atk=10, apr=9, dammod={str=resolvers.levelup(0.3, 5, 0.2, 1.2)} }, resists = { [DamageType.COLD] = 20 }, diff --git a/game/modules/tome/data/zones/old-forest/npcs.lua b/game/modules/tome/data/zones/old-forest/npcs.lua index 7290ca07d7..fb712a3e59 100644 --- a/game/modules/tome/data/zones/old-forest/npcs.lua +++ b/game/modules/tome/data/zones/old-forest/npcs.lua @@ -51,7 +51,7 @@ newEntity{ define_as = "WRATHROOT", instakill_immune = 1, move_others=true, - combat = { dam=resolvers.levelup(27, 1, 0.8), atk=10, apr=0, dammod={str=1.2}, sound="actions/melee_thud" }, + combat = { dam=resolvers.levelup(27, 1, 0.8), atk=10, apr=0, dammod={str=resolvers.levelup(0.3, 5, 0.2, 1.2)}, sound="actions/melee_thud" }, resists = { [DamageType.FIRE] = -50 }, diff --git a/game/modules/tome/data/zones/paradox-plane/objects.lua b/game/modules/tome/data/zones/paradox-plane/objects.lua index c3eecb7dae..1856e65524 100644 --- a/game/modules/tome/data/zones/paradox-plane/objects.lua +++ b/game/modules/tome/data/zones/paradox-plane/objects.lua @@ -36,20 +36,17 @@ According to legend it was made from the first ash sapling to sprout after the S cost = 200, material_level = 5, combat = { + dam = 15, + critical_power = 1.8, range = 9, + dammod = {dex=0.3}, physspeed = 0.6, - }, - basic_ammo = { - dam = 30, - apr = 10, - physcrit = 2, - dammod = {dex=0.7, str=0.5}, + ranged_project={[DamageType.TEMPORAL] = 15}, }, wielder = { life_regen = 2.0, stamina_regen = 1.0, inc_damage={ [DamageType.TEMPORAL] = 10, }, inc_stats = { [Stats.STAT_DEX] = 5, [Stats.STAT_WIL] = 4, }, - ranged_project={[DamageType.TEMPORAL] = 15}, }, } diff --git a/game/modules/tome/data/zones/ritch-tunnels/npcs.lua b/game/modules/tome/data/zones/ritch-tunnels/npcs.lua index 78be453ab8..a8a9e2f067 100644 --- a/game/modules/tome/data/zones/ritch-tunnels/npcs.lua +++ b/game/modules/tome/data/zones/ritch-tunnels/npcs.lua @@ -32,7 +32,7 @@ newEntity{ Vicious predators, they inject corrupting diseases into their foes, and their sharp claws cut through most armours.]], killer_message = ", who incubated her eggs in the corpse,", - combat = { dam=resolvers.rngavg(10,32), atk=0, apr=4, damtype=DamageType.BLIGHT, dammod={dex=1.2} }, + combat = { dam=resolvers.rngavg(10,32), atk=0, apr=4, damtype=DamageType.BLIGHT, dammod={dex=resolvers.levelup(0.1, 5, 0.1, 1.2)} }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, @@ -110,7 +110,7 @@ newEntity{ base = "BASE_NPC_RITCH_REL", define_as = "HIVE_MOTHER", rank = 4, size_category = 4, - combat = { dam=30, atk=22, apr=7, dammod={str=1.1} }, + combat = { dam=30, atk=22, apr=7, dammod={str=resolvers.levelup(0.3, 5, 0.2, 1.1)} }, resists = { [DamageType.BLIGHT] = 40 }, diff --git a/game/modules/tome/data/zones/telmur/objects.lua b/game/modules/tome/data/zones/telmur/objects.lua index c95c07ee43..a8e30991bb 100644 --- a/game/modules/tome/data/zones/telmur/objects.lua +++ b/game/modules/tome/data/zones/telmur/objects.lua @@ -20,6 +20,7 @@ load("/data/general/objects/objects-maj-eyal.lua") local Stats = require "engine.interface.ActorStats" +local Talents = require "engine.interface.ActorTalents" newEntity{ base = "BASE_STAFF", power_source = {arcane=true}, @@ -32,13 +33,17 @@ newEntity{ base = "BASE_STAFF", require = { stat = { mag=35 }, }, encumberance = 2.5, cost = 500, + combat = { + dam = 10, + max_acc = 80, + critical_power = 1.1, + dammod = {mag=0.2}, + damtype = DamageType.PHYSICAL, + }, wielder = { inc_stats = { [Stats.STAT_MAG] = 4, }, max_mana = 50, combat_mentalresist = 8, - inc_damage={ - [DamageType.COLD] = 20, - [DamageType.ACID] = 20, - }, + learn_talent = {[Talents.T_SAVAGERY] = 5}, }, } diff --git a/game/modules/tome/data/zones/tutorial-combat-stats/npcs.lua b/game/modules/tome/data/zones/tutorial-combat-stats/npcs.lua index ca7c2850bc..67e3696bc1 100644 --- a/game/modules/tome/data/zones/tutorial-combat-stats/npcs.lua +++ b/game/modules/tome/data/zones/tutorial-combat-stats/npcs.lua @@ -135,7 +135,7 @@ newEntity{ base = "BASE_NPC_ORC", image="npc/humanoid_orc_orc_child.png", level_range = {1, nil}, exp_worth = 1, max_life = 100, - combat_atk = 6, + combat_atk = 7, combat_def = 86, never_move = 1, combat = false, @@ -146,7 +146,7 @@ newEntity{ base = "BASE_NPC_ORC", name = "Orc", color=colors.LIGHT_UMBER, image="npc/humanoid_orc_orc_child.png", level_range = {1, nil}, exp_worth = 1, - combat_atk = 6, + combat_atk = 7, max_life = 100, combat_def = 83, never_move = 1, diff --git a/game/modules/tome/dialogs/CharacterSheet.lua b/game/modules/tome/dialogs/CharacterSheet.lua index 6de75747d2..3c034358e3 100644 --- a/game/modules/tome/dialogs/CharacterSheet.lua +++ b/game/modules/tome/dialogs/CharacterSheet.lua @@ -51,7 +51,7 @@ function _M:init(actor) self.vs = Separator.new{dir="vertical", size=self.iw} self.c_tut = Textzone.new{width=self.iw * 0.6, auto_height=true, no_color_bleed=true, font = self.font, text=[[ -Values #00FF00#in bracets ( )#LAST# shows changes made from last character sheet checking. +Values #00FF00#in brackets ( )#LAST# shows changes made from last character sheet checking. Keyboard: #00FF00#'d'#LAST# to save character dump. #00FF00#TAB key#LAST# to switch between tabs. Mouse: Hover over stat for info ]]} @@ -188,6 +188,8 @@ function _M:drawDialog(kind, actor_to_compare) local w = 0 local text = "" + local dur_text = "" + local sp_text = "" if player.__te4_uuid and profile.auth and profile.auth.drupid then local path = "http://te4.org/characters/"..profile.auth.drupid.."/tome/"..player.__te4_uuid @@ -500,6 +502,32 @@ function _M:drawDialog(kind, actor_to_compare) print_stat(self.actor.STAT_CON, ("%-12s"):format(Stats.stats_def[self.actor.STAT_CON].name:capitalize()), self.TOOLTIP_CON) h = h + self.font_h + s:drawColorStringBlended(self.font, "#LIGHT_BLUE#Combat stats:", w, h, 255, 255, 255, true) h = h + self.font_h + + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatPhysicalpower() end, "%3d", "%+.0f") + dur_text = ("%d"):format(math.floor(player:combatPhysicalpower()/5)) + self:mouseTooltip(self.TOOLTIP_SPELL_POWER, s:drawColorStringBlended(self.font, ("Physical power: #00ff00#%s [+%s effect duration]"):format(text, dur_text), w, h, 255, 255, 255, true)) h = h + self.font_h + + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatSpellpower() end, "%3d", "%+.0f") + dur_text = ("%d"):format(math.floor(player:combatSpellpower()/5)) + self:mouseTooltip(self.TOOLTIP_SPELL_POWER, s:drawColorStringBlended(self.font, ("Spellpower : #00ff00#%s [+%s effect duration]"):format(text, dur_text), w, h, 255, 255, 255, true)) h = h + self.font_h + + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatMindpower() end, "%3d", "%+.0f") + dur_text = ("%d"):format(math.floor(player:combatMindpower()/5)) + self:mouseTooltip(self.TOOLTIP_SPELL_POWER, s:drawColorStringBlended(self.font, ("Mindpower : #00ff00#%s [+%s effect duration]"):format(text, dur_text), w, h, 255, 255, 255, true)) h = h + self.font_h + + text = compare_fields(player, actor_to_compare, function(actor, ...) return math.floor(actor:combatPhysicalResist(true)) end, "%3d", "%+.0f") + dur_text = ("%d"):format(math.floor(player:combatPhysicalResist(true)/5)) + self:mouseTooltip(self.TOOLTIP_PHYS_SAVE, s:drawColorStringBlended(self.font, ("Physical save : #00ff00#%s [-%s effect duration]"):format(text, dur_text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return math.floor(actor:combatSpellResist(true)) end, "%3d", "%+.0f") + dur_text = ("%d"):format(math.floor(player:combatSpellResist(true)/5)) + self:mouseTooltip(self.TOOLTIP_SPELL_SAVE, s:drawColorStringBlended(self.font, ("Spell save : #00ff00#%s [-%s effect duration]"):format(text, dur_text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return math.floor(actor:combatMentalResist(true)) end, "%3d", "%+.0f") + dur_text = ("%d"):format(math.floor(player:combatMentalResist(true)/5)) + self:mouseTooltip(self.TOOLTIP_MENTAL_SAVE, s:drawColorStringBlended(self.font, ("Mental save : #00ff00#%s [-%s effect duration]"):format(text, dur_text), w, h, 255, 255, 255, true)) h = h + self.font_h + + h = h + self.font_h + local nb_inscriptions = 0 for i = 1, player.max_inscriptions do if player.inscriptions[i] then nb_inscriptions = nb_inscriptions + 1 end end self:mouseTooltip(self.TOOLTIP_INSCRIPTIONS, s:drawColorStringBlended(self.font, ("#AQUAMARINE#Inscriptions (%d/%d)"):format(nb_inscriptions, player.max_inscriptions), w, h, 255, 255, 255, true)) h = h + self.font_h @@ -554,22 +582,26 @@ function _M:drawDialog(kind, actor_to_compare) for i, o in ipairs(player:getInven(player.INVEN_MAINHAND)) do local mean, dam = o.combat, o.combat - if o.archery and mean then - dam = (player:getInven("QUIVER")[1] and player:getInven("QUIVER")[1].combat) or o.basic_ammo - end if mean and dam then + local max_acc = o.combat.max_acc + if o.archery and player:hasAmmo(o.archery) then max_acc = player:hasAmmo(o.archery).combat.max_acc end + sp_text = (o.combat.affects_spells and " (affects spells)") or "" + local attack_speed_bonus = (1 / player:combatSpeed(o.combat))*100 - 100 s:drawColorStringBlended(self.font, WeaponTxt, w, h, 255, 255, 255, true) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return math.floor(actor:combatAttack(...)) end, "%3d", "%+.0f", 1, false, false, mean) - dur_text = ("%d"):format(math.floor(player:combatAttack(o.combat)/5)) - self:mouseTooltip(self.TOOLTIP_COMBAT_ATTACK, s:drawColorStringBlended(self.font, ("Accuracy : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatDamage(...) end, "%3d", "%+.0f", 1, false, false, dam) + + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:getCombinedDamage(o) end, "%d", "%+d", 1, false, false, dam) self:mouseTooltip(self.TOOLTIP_COMBAT_DAMAGE, s:drawColorStringBlended(self.font, ("Damage : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatAPR(...) end, "%3d", "%+.0f", 1, false, false, dam) - self:mouseTooltip(self.TOOLTIP_COMBAT_APR, s:drawColorStringBlended(self.font, ("APR : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatCrit(...) end, "%3d%%", "%+.0f%%", 1, false, false, dam) + text = compare_fields(player, actor_to_compare, function(actor, ...) return (o.combat.critical_power or 1.1) + (actor.combat_critical_power or 0)/100 end, "%.2fx", "%+.2f") + self:mouseTooltip(self.TOOLTIP_INC_CRIT_POWER , s:drawColorStringBlended(self.font, ("Crit mult. : #00ff00#%s%s"):format(text, sp_text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return (max_acc or 75) end, "%d%%", "%+d%%", 1, false, false, mean) + self:mouseTooltip(self.TOOLTIP_COMBAT_ATTACK, s:drawColorStringBlended(self.font, ("Max accuracy: #00ff00#%s%s"):format(text, sp_text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return attack_speed_bonus end, "%d%%", "%+d%%", 1, false, false, mean) + self:mouseTooltip(self.TOOLTIP_COMBAT_SPEED, s:drawColorStringBlended(self.font, ("Speed bonus : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatAPR(...) end, "%d", "%+d", 1, false, false, dam) + self:mouseTooltip(self.TOOLTIP_COMBAT_APR, s:drawColorStringBlended(self.font, ("Armor pen. : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatCrit(...) end, "%d%%", "%+d%%", 1, false, false, dam) self:mouseTooltip(self.TOOLTIP_COMBAT_CRIT, s:drawColorStringBlended(self.font, ("Crit. chance: #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatSpeed(...) end, "%.2f%%", "%+.2f%%", 100, false, false, mean) - self:mouseTooltip(self.TOOLTIP_COMBAT_SPEED, s:drawColorStringBlended(self.font, ("Speed : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h + end if mean and mean.range then self:mouseTooltip(self.TOOLTIP_COMBAT_RANGE, s:drawColorStringBlended(self.font, ("Range (Main Hand): #00ff00#%3d"):format(mean.range), w, h, 255, 255, 255, true)) h = h + self.font_h @@ -580,17 +612,23 @@ function _M:drawDialog(kind, actor_to_compare) s:drawColorStringBlended(self.font, "#LIGHT_BLUE#Unarmed:", w, h, 255, 255, 255, true) h = h + self.font_h local mean, dam = player.combat, player.combat if mean and dam then - text = compare_fields(player, actor_to_compare, function(actor, ...) return math.floor(actor:combatAttack(...)) end, "%3d", "%+.0f", 1, false, false, mean) - dur_text = ("%d"):format(math.floor(player:combatAttack(player.combat)/5)) - self:mouseTooltip(self.TOOLTIP_COMBAT_ATTACK, s:drawColorStringBlended(self.font, ("Accuracy : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatDamage(...) end, "%3d", "%+.0f", 1, false, false, dam) + sp_text = (player.combat.affects_spells and " (affects spells)") or "" + local attack_speed_bonus = (1 / player:combatSpeed(player.combat))*100 - 100 + local gloves = player:hasGloves() + local total_dam = player:combatDamage(player.combat) + (gloves and gloves:getMeleeProjectDam() or 0) + text = compare_fields(player, actor_to_compare, function(actor, ...) return total_dam end, "%d", "%+d", 1, false, false, dam) self:mouseTooltip(self.TOOLTIP_COMBAT_DAMAGE, s:drawColorStringBlended(self.font, ("Damage : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatAPR(...) end, "%3d", "%+.0f", 1, false, false, dam) - self:mouseTooltip(self.TOOLTIP_COMBAT_APR, s:drawColorStringBlended(self.font, ("APR : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatCrit(...) end, "%3d%%", "%+.0f%%", 1, false, false, dam) + text = compare_fields(player, actor_to_compare, function(actor, ...) return (actor.combat.critical_power or 1.1) + (actor.combat_critical_power or 0)/100 end, "%.2fx", "%+.2f") + self:mouseTooltip(self.TOOLTIP_INC_CRIT_POWER , s:drawColorStringBlended(self.font, ("Crit mult. : #00ff00#%s%s"):format(text, sp_text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor.combat.max_acc end, "%d%%", "%+d%%", 1, false, false, mean) + self:mouseTooltip(self.TOOLTIP_COMBAT_ATTACK, s:drawColorStringBlended(self.font, ("Max accuracy: #00ff00#%s%s"):format(text, sp_text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return attack_speed_bonus end, "%d%%", "%+d%%", 1, false, false, mean) + self:mouseTooltip(self.TOOLTIP_COMBAT_SPEED, s:drawColorStringBlended(self.font, ("Speed bonus : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatAPR(...) end, "%d", "%+d", 1, false, false, dam) + self:mouseTooltip(self.TOOLTIP_COMBAT_APR, s:drawColorStringBlended(self.font, ("Armor pen. : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatCrit(...) end, "%d%%", "%+d%%", 1, false, false, dam) self:mouseTooltip(self.TOOLTIP_COMBAT_CRIT, s:drawColorStringBlended(self.font, ("Crit. chance: #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatSpeed(...) end, "%.2f%%", "%+.2f%%", 100, false, false, mean) - self:mouseTooltip(self.TOOLTIP_COMBAT_SPEED, s:drawColorStringBlended(self.font, ("Speed : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h + end if mean and mean.range then self:mouseTooltip(self.TOOLTIP_COMBAT_RANGE, s:drawColorStringBlended(self.font, ("Range (Main Hand): #00ff00#%3d"):format(mean.range), w, h, 255, 255, 255, true)) h = h + self.font_h @@ -604,22 +642,25 @@ function _M:drawDialog(kind, actor_to_compare) local offmult = player:getOffHandMult() for i, o in ipairs(player:getInven(player.INVEN_OFFHAND)) do local mean, dam = o.combat, o.combat - if o.archery and mean then - dam = (player:getInven("QUIVER")[1] and player:getInven("QUIVER")[1].combat) or o.basic_ammo - end if mean and dam then + local max_acc = o.combat.max_acc + if o.archery and player:hasAmmo(o.archery) then max_acc = player:hasAmmo(o.archery).combat.max_acc end + sp_text = (o.combat.affects_spells and " (affects spells)") or "" + local attack_speed_bonus = (1 / player:combatSpeed(o.combat))*100 - 100 s:drawColorStringBlended(self.font, "#LIGHT_BLUE#Off Hand:", w, h, 255, 255, 255, true) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return math.floor(actor:combatAttack(...)) end, "%3d", "%+.0f", 1, false, false, mean) - dur_text = ("%d"):format(math.floor(player:combatAttack(o.combat)/5)) - self:mouseTooltip(self.TOOLTIP_COMBAT_ATTACK, s:drawColorStringBlended(self.font, ("Accuracy : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatDamage(...) end, "%3d", "%+.0f", offmult, false, false, dam) + + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:getCombinedDamage(o, offmult) end, "%d", "%+d", 1, false, false, dam) self:mouseTooltip(self.TOOLTIP_COMBAT_DAMAGE, s:drawColorStringBlended(self.font, ("Damage : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatAPR(...) end, "%3d", "%+.0f", 1, false, false, dam) - self:mouseTooltip(self.TOOLTIP_COMBAT_APR, s:drawColorStringBlended(self.font, ("APR : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatCrit(...) end, "%3d%%", "%+.0f%%", 1, false, false, dam) + text = compare_fields(player, actor_to_compare, function(actor, ...) return (o.combat.critical_power or 1.1) + (actor.combat_critical_power or 0)/100 end, "%.2fx", "%+.2f") + self:mouseTooltip(self.TOOLTIP_INC_CRIT_POWER , s:drawColorStringBlended(self.font, ("Crit mult. : #00ff00#%s%s"):format(text, sp_text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return (max_acc or 75) end, "%d%%", "%+d%%", 1, false, false, mean) + self:mouseTooltip(self.TOOLTIP_COMBAT_ATTACK, s:drawColorStringBlended(self.font, ("Max accuracy: #00ff00#%s%s"):format(text, sp_text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return attack_speed_bonus end, "%d%%", "%+d%%", 1, false, false, mean) + self:mouseTooltip(self.TOOLTIP_COMBAT_SPEED, s:drawColorStringBlended(self.font, ("Speed bonus : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatAPR(...) end, "%d", "%+d", 1, false, false, dam) + self:mouseTooltip(self.TOOLTIP_COMBAT_APR, s:drawColorStringBlended(self.font, ("Armor pen. : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h + text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatCrit(...) end, "%d%%", "%+d%%", 1, false, false, dam) self:mouseTooltip(self.TOOLTIP_COMBAT_CRIT, s:drawColorStringBlended(self.font, ("Crit. chance: #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return actor:combatSpeed(...) end, "%.2f%%", "%+.2f%%", 100, false, false, mean) - self:mouseTooltip(self.TOOLTIP_COMBAT_SPEED, s:drawColorStringBlended(self.font, ("Speed : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h end if mean and mean.range then self:mouseTooltip(self.TOOLTIP_COMBAT_RANGE, s:drawColorStringBlended(self.font, ("Range (Off Hand): #00ff00#%3d"):format(mean.range), w, h, 255, 255, 255, true)) h = h + self.font_h end end @@ -647,10 +688,8 @@ function _M:drawDialog(kind, actor_to_compare) h = 0 w = self.w * 0.5 - s:drawColorStringBlended(self.font, "#LIGHT_BLUE#Damage mods.:", w, h, 255, 255, 255, true) h = h + self.font_h - text = compare_fields(player, actor_to_compare, function(actor, ...) return 150 + (actor.combat_critical_power or 0) end, "%3d%%", "%+.0f%%") - self:mouseTooltip(self.TOOLTIP_INC_CRIT_POWER , s:drawColorStringBlended(self.font, ("Critical mult.: #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h - + s:drawColorStringBlended(self.font, "#LIGHT_BLUE#Damage mods:", w, h, 255, 255, 255, true) h = h + self.font_h + if player.inc_damage.all then text = compare_fields(player, actor_to_compare, function(actor, ...) return actor.inc_damage and actor.inc_damage.all or 0 end, "%3d%%", "%+.0f%%") self:mouseTooltip(self.TOOLTIP_INC_DAMAGE_ALL, s:drawColorStringBlended(self.font, ("All damage : #00ff00#%s"):format(text), w, h, 255, 255, 255, true)) h = h + self.font_h @@ -716,7 +755,7 @@ function _M:drawDialog(kind, actor_to_compare) h = 0 w = self.w * 0.75 - s:drawColorStringBlended(self.font, "#LIGHT_BLUE#Damage penetration.:", w, h, 255, 255, 255, true) h = h + self.font_h + s:drawColorStringBlended(self.font, "#LIGHT_BLUE#Damage penetration:", w, h, 255, 255, 255, true) h = h + self.font_h if player.resists_pen.all then text = compare_fields(player, actor_to_compare, function(actor, ...) return actor.resists_pen and actor.resists_pen.all or 0 end, "%3d%%", "%+.0f%%") @@ -931,30 +970,31 @@ function _M:dump() if player:getInven(player.INVEN_MAINHAND) then for i, o in ipairs(player:getInven(player.INVEN_MAINHAND)) do local mean, dam = o.combat, o.combat - if o.archery and mean then - dam = (player:getInven("QUIVER")[1] and player:getInven("QUIVER")[1].combat) or o.basic_ammo - end if mean and dam then - strings[1] = ("Accuracy(Main Hand): %3d"):format(player:combatAttack(mean)) - strings[2] = ("Damage (Main Hand): %3d"):format(player:combatDamage(dam)) - strings[3] = ("APR (Main Hand): %3d"):format(player:combatAPR(dam)) - strings[4] = ("Crit (Main Hand): %3d%%"):format(player:combatCrit(dam)) - strings[5] = ("Speed (Main Hand): %0.2f"):format(player:combatSpeed(mean)) + strings[1] = ("Damage (Main Hand): %d"):format(player:getCombinedDamage(o)) + strings[2] = ("crit mult (Main Hand): %.1fx"):format(o.combat.critical_power) + strings[3] = ("Max acc (Main Hand): %d"):format(o.combat.max_acc) + strings[4] = ("Sp. bonus (Main Hand): %d%%"):format((1 / player:combatSpeed(o.combat))*100 - 100) + strings[5] = ("APR (Main Hand): %d"):format(player:combatAPR(dam)) + strings[6] = ("Crit (Main Hand): %d%%"):format(player:combatCrit(dam)) end - if mean and mean.range then strings[6] = ("Range (Main Hand): %3d"):format(mean.range) end + if mean and mean.range then strings[7] = ("Range (Main Hand): %3d"):format(mean.range) end end end --Unarmed?? if player:isUnarmed() then + local gloves = player:hasGloves() + local total_dam = player:combatDamage(player.combat) + (gloves and gloves:getMeleeProjectDam() or 0) local mean, dam = player.combat, player.combat if mean and dam then - strings[1] = ("Accuracy(Unarmed): %3d"):format(player:combatAttack(mean)) - strings[2] = ("Damage (Unarmed): %3d"):format(player:combatDamage(dam)) - strings[3] = ("APR (Unarmed): %3d"):format(player:combatAPR(dam)) - strings[4] = ("Crit (Unarmed): %3d%%"):format(player:combatCrit(dam)) - strings[5] = ("Speed (Unarmed): %0.2f"):format(player:combatSpeed(mean)) - end - if mean and mean.range then strings[6] = ("Range (Unarmed): %3d"):format(mean.range) end + strings[1] = ("Damage (Main Hand): %d"):format(total_dam) + strings[2] = ("crit mult (Main Hand): %.1fx"):format(player.combat.critical_power) + strings[3] = ("Max acc (Main Hand): %d"):format(player.combat.max_acc) + strings[4] = ("Sp. bonus (Main Hand): %d%%"):format((1 / player:combatSpeed(player.combat))*100 - 100) + strings[5] = ("APR (Main Hand): %d"):format(player:combatAPR(dam)) + strings[6] = ("Crit (Main Hand): %d%%"):format(player:combatCrit(dam)) + end + if mean and mean.range then strings[7] = ("Range (Unarmed): %d"):format(mean.range) end end local enc, max = player:getEncumbrance(), player:getMaxEncumbrance() @@ -1016,18 +1056,16 @@ function _M:dump() local offmult = player:getOffHandMult() for i, o in ipairs(player:getInven(player.INVEN_OFFHAND)) do local mean, dam = o.combat, o.combat - if o.archery and mean then - dam = (player:getInven("QUIVER")[1] and player:getInven("QUIVER")[1].combat) or o.basic_ammo - end if mean and dam then nl() - nl(("Accuracy(Off Hand): %3d"):format(player:combatAttack(mean))) - nl(("Damage (Off Hand): %3d"):format(player:combatDamage(dam) * offmult)) - nl(("APR (Off Hand): %3d"):format(player:combatAPR(dam))) - nl(("Crit (Off Hand): %3d%%"):format(player:combatCrit(dam))) - nl(("Speed (Off Hand): %0.2f"):format(player:combatSpeed(mean))) + nl(("Damage (Main Hand): %d"):format(player:getCombinedDamage(o, offmult))) + nl(("crit mult (Main Hand): %.1fx"):format(o.combat.critical_power)) + nl(("Max acc (Main Hand): %d"):format(o.combat.max_acc)) + nl(("Sp. bonus (Main Hand): %d%%"):format((1 / player:combatSpeed(o.combat))*100 - 100)) + nl(("APR (Main Hand): %d"):format(player:combatAPR(dam))) + nl(("Crit (Main Hand): %d%%"):format(player:combatCrit(dam))) end - if mean and mean.range then strings[6] = ("Range (Off Hand): %3d"):format(mean.range) end + if mean and mean.range then strings[7] = ("Range (Off Hand): %d"):format(mean.range) end end end diff --git a/game/modules/tome/dialogs/LevelupDialog.lua b/game/modules/tome/dialogs/LevelupDialog.lua index 075a4d4277..bcad72a241 100644 --- a/game/modules/tome/dialogs/LevelupDialog.lua +++ b/game/modules/tome/dialogs/LevelupDialog.lua @@ -1186,9 +1186,6 @@ function _M:drawDialog(kind) for i, o in ipairs(self.actor:getInven(self.actor.INVEN_MAINHAND)) do local mean, dam = o.combat, o.combat - if o.archery and mean then - dam = (self.actor:getInven("QUIVER")[1] and self.actor:getInven("QUIVER")[1].combat) or o.basic_ammo - end if mean and dam then s:drawColorStringBlended(self.font, WeaponTxt, w, h, 255, 255, 255, true) h = h + self.font_h if self.actor.use_psi_combat then @@ -1196,7 +1193,7 @@ function _M:drawDialog(kind) else self:mouseTooltip(self.TOOLTIP_COMBAT_ATTACK, s:drawColorStringBlended(self.font, ("Accuracy : #00ff00#%.1f"):format(self.actor:combatAttack(mean) - self.actor_dup:combatAttack(mean)), w, h, 255, 255, 255, true)) h = h + self.font_h end - self:mouseTooltip(self.TOOLTIP_COMBAT_DAMAGE, s:drawColorStringBlended(self.font, ("Damage : #00ff00#%.1f"):format(self.actor:combatDamage(dam) - self.actor_dup:combatDamage(dam)), w, h, 255, 255, 255, true)) h = h + self.font_h + self:mouseTooltip(self.TOOLTIP_COMBAT_DAMAGE, s:drawColorStringBlended(self.font, ("Damage : #00ff00#%.1f"):format(self.actor:getCombinedDamage(o) - self.actor_dup:getCombinedDamage(o)), w, h, 255, 255, 255, true)) h = h + self.font_h self:mouseTooltip(self.TOOLTIP_COMBAT_APR, s:drawColorStringBlended(self.font, ("APR : #00ff00#%.1f"):format(self.actor:combatAPR(dam) - self.actor_dup:combatAPR(dam)), w, h, 255, 255, 255, true)) h = h + self.font_h self:mouseTooltip(self.TOOLTIP_COMBAT_CRIT, s:drawColorStringBlended(self.font, ("Crit. chance: #00ff00#%.1f%%"):format(self.actor:combatCrit(dam) - self.actor_dup:combatCrit(dam)), w, h, 255, 255, 255, true)) h = h + self.font_h self:mouseTooltip(self.TOOLTIP_COMBAT_SPEED, s:drawColorStringBlended(self.font, ("Speed : #00ff00#%.2f%%"):format((self.actor:combatSpeed(mean) - self.actor_dup:combatSpeed(mean))*100), w, h, 255, 255, 255, true)) h = h + self.font_h @@ -1224,9 +1221,6 @@ function _M:drawDialog(kind) local act_dup_offmult = self.actor_dup:getOffHandMult() for i, o in ipairs(self.actor:getInven(self.actor.INVEN_OFFHAND)) do local mean, dam = o.combat, o.combat - if o.archery and mean then - dam = (self.actor:getInven("QUIVER")[1] and self.actor:getInven("QUIVER")[1].combat) or o.basic_ammo - end if mean and dam then s:drawColorStringBlended(self.font, "#LIGHT_BLUE#Off Hand:", w, h, 255, 255, 255, true) h = h + self.font_h if self.actor.use_psi_combat then @@ -1234,7 +1228,7 @@ function _M:drawDialog(kind) else self:mouseTooltip(self.TOOLTIP_COMBAT_ATTACK, s:drawColorStringBlended(self.font, ("Accuracy : #00ff00#%.1f"):format(self.actor:combatAttack(mean) - self.actor_dup:combatAttack(mean)), w, h, 255, 255, 255, true)) h = h + self.font_h end - self:mouseTooltip(self.TOOLTIP_COMBAT_DAMAGE, s:drawColorStringBlended(self.font, ("Damage : #00ff00#%.1f"):format(self.actor:combatDamage(dam) * act_offmult - self.actor_dup:combatDamage(dam) * act_dup_offmult), w, h, 255, 255, 255, true)) h = h + self.font_h + self:mouseTooltip(self.TOOLTIP_COMBAT_DAMAGE, s:drawColorStringBlended(self.font, ("Damage : #00ff00#%.1f"):format(self.actor:getCombinedDamage(o) * act_offmult - self.actor_dup:getCombinedDamage(o) * act_dup_offmult), w, h, 255, 255, 255, true)) h = h + self.font_h self:mouseTooltip(self.TOOLTIP_COMBAT_APR , s:drawColorStringBlended(self.font, ("APR : #00ff00#%.1f"):format(self.actor:combatAPR(dam) - self.actor_dup:combatAPR(dam)), w, h, 255, 255, 255, true)) h = h + self.font_h self:mouseTooltip(self.TOOLTIP_COMBAT_CRIT , s:drawColorStringBlended(self.font, ("Crit. chance: #00ff00#%.1f%%"):format(self.actor:combatCrit(dam) - self.actor_dup:combatCrit(dam)), w, h, 255, 255, 255, true)) h = h + self.font_h self:mouseTooltip(self.TOOLTIP_COMBAT_SPEED , s:drawColorStringBlended(self.font, ("Speed : #00ff00#%.2f%%"):format((self.actor:combatSpeed(mean) - self.actor_dup:combatSpeed(mean))*100), w, h, 255, 255, 255, true)) h = h + self.font_h diff --git a/game/modules/tome/dialogs/SentientWeapon.lua b/game/modules/tome/dialogs/SentientWeapon.lua new file mode 100644 index 0000000000..4b76c1a5f8 --- /dev/null +++ b/game/modules/tome/dialogs/SentientWeapon.lua @@ -0,0 +1,205 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even th+e implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +require "engine.class" + +local Dialog = require "engine.ui.Dialog" +local ListColumns = require "engine.ui.ListColumns" +local Textzone = require "engine.ui.Textzone" +local TextzoneList = require "engine.ui.TextzoneList" +local Separator = require "engine.ui.Separator" + +--local LevelupTalentsDialog = require "mod.dialogs.LevelupTalentsDialog" + +module(..., package.seeall, class.inherit(Dialog)) + +local _points_text = "Points left: #00FF00#%d#WHITE#" + +function _M:init(actor, on_finish) + self.actor = actor.actor + + self.o = actor.o + print("Incoming factory settings:", self.o.factory_settings.dam, self.o.factory_settings.critical_power, self.o.factory_settings.max_acc) + print("Incoming factory setting mins:", self.o.factory_settings.mins.dam, self.o.factory_settings.mins.critical_power, self.o.factory_settings.mins.max_acc) + print("Incoming factory setting maxes:", self.o.factory_settings.maxes.dam, self.o.factory_settings.maxes.critical_power, self.o.factory_settings.maxes.max_acc) + self.actor_dup = actor.actor:clone() + self.unused_stats = self.o.unused_stats + --Dialog.init(self, self.o.name, 500, 300) + Dialog.init(self, self.o.name, 300, 200) + + self.sel = 1 + + self.c_tut = Textzone.new{width=math.floor(self.iw / 2 - 10), auto_height=true, no_color_bleed=true, text=[[ +Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#right key#FFFFFF# to increase stat; #00FF00#left key#FFFFFF# to decrease a stat. +Mouse: #00FF00#Left click#FFFFFF# to increase a stat; #00FF00#right click#FFFFFF# to decrease a stat. +]]} + self.c_desc = TextzoneList.new{width=math.floor(self.iw - 10), height=self.ih - self.c_tut.h - 20, no_color_bleed=true} + self.c_points = Textzone.new{width=math.floor(self.iw - 10), auto_height=true, no_color_bleed=true, text=_points_text:format(self.unused_stats)} + + self.c_list = ListColumns.new{width=math.floor(self.iw - 10), height=self.ih - 10, all_clicks=true, columns={ + {name="Stat", width=70, display_prop="name"}, + {name="Value", width=30, display_prop="val"}, + }, list={ + {name="Damage", val=self.o.combat.dam, stat_id = "dam", delta = self.o.material_level}, + {name="Critical power", val=self.o.combat.critical_power, stat_id = "critical_power", delta = 0.1}, + {name="Maximum hit chance", val=self.o.combat.max_acc, stat_id = "max_acc", delta = 5}, + --{name="Strength", val=self.actor:getStr(), stat_id=self.actor.STAT_STR}, + --{name="Dexterity", val=self.actor:getDex(), stat_id=self.actor.STAT_DEX}, + --{name="Magic", val=self.actor:getMag(), stat_id=self.actor.STAT_MAG}, + --{name="Willpower", val=self.actor:getWil(), stat_id=self.actor.STAT_WIL}, + --{name="Cunning", val=self.actor:getCun(), stat_id=self.actor.STAT_CUN}, + --{name="Constitution", val=self.actor:getCon(), stat_id=self.actor.STAT_CON}, + }, fct=function(item, _, v) + self:incStat(v == "left" and 1 or -1, item.stat_id) + --end, select=function(item, sel) self.sel = sel self.c_desc:switchItem(item, self.actor.stats_def[item.stat_id].description) end} + --end, select=function(item, sel) self.sel = sel game.logPlayer(game.player, "just selected %s", sel) end} + --end, select=function(item, sel) self.sel = sel game.logPlayer(game.player, "just selected %s", item.stat_id) end} + end, select=function(item, sel) self.sel = sel self.id = item.stat_id self.delta = item.delta end} + self:loadUI{ + {left=0, top=0, ui=self.c_points}, + --{left=5, top=self.c_points.h+5, ui=Separator.new{dir="vertical", size=math.floor(self.iw / 2) - 10}}, + {left=0, top=self.c_points.h+15, ui=self.c_list}, + + --{hcenter=0, top=5, ui=Separator.new{dir="horizontal", size=self.ih - 10}}, + + --{right=0, top=self.c_tut.h + 20, ui=self.c_desc}, + --{right=0, top=0, ui=self.c_tut}, + } + self:setFocus(self.c_list) + self:setupUI() + + self:update() + + self.key:addBinds{ + EXIT = function() + game:unregisterDialog(self) + self:finish() + end, + } +end + +function _M:finish() + --if self.actor.unused_stats == self.unused_stats then return end +--[=[ local reset = {} + for tid, act in pairs(self.actor.sustain_talents) do + if act then + local t = self.actor:getTalentFromId(tid) + if t.no_sustain_autoreset then + game.logPlayer(self.actor, "#LIGHT_BLUE#Warning: You have increased some of your statistics. Talent %s is actually sustained; if it is dependent on one of the stats you changed, you need to re-use it for the changes to take effect.", t.name) + else + reset[#reset+1] = tid + end + end + end + for i, tid in ipairs(reset) do + self.actor:forceUseTalent(tid, {ignore_energy=true, ignore_cd=true}) + self.actor:forceUseTalent(tid, {ignore_energy=true, ignore_cd=true}) + end + ]=] +end + +function _M:incStat(v, id) + print("inside incStat. self.sel is", self.sel) + print("inside incStat. id is", self.id) + local id = self.id + local delta = self.delta * v + if v == 1 then + if self.o.unused_stats <= 0 then + self:simplePopup("Not enough stat points", "You have no stat points left!") + return + end + if self.o.combat[id] >= self.o.factory_settings.maxes[id] then + self:simplePopup("Stat is at the maximum", "You can not increase this stat further!") + return + end + else + if self.o.combat[id] <= self.o.factory_settings.mins[id] then + self:simplePopup("Impossible", "You cannot take out more points!") + return + end + if self.o.combat[id] + delta <= 0 then + self:simplePopup("Impossible", "You cannot take out more points!") + return + end + end + + local sel = self.sel + self.o.combat[id] = self.o.combat[id] + delta + if id == "dam" then + for k, v in pairs(self.o.wielder["inc_damage"]) do + self.o.wielder["inc_damage"][k] = v + delta + end + if self.o.combat.of_breaching then + for k, v in pairs(self.o.wielder["resists_pen"]) do + self.o.wielder["resists_pen"][k] = v + (delta/2) + end + end + --update_secondary(self.o, delta/2, "resists_pen") + end + --self.actor:incStat(sel, v) + self.o.unused_stats = self.o.unused_stats - v + self.c_list.list[sel].val = self.o.combat[id] + self.c_list:generate() + self.c_list.sel = sel + self.c_list:onSelect() + self.c_points.text = _points_text:format(self.o.unused_stats) + self.c_points:generate() + self:update() +end + +--local function update_secondary(o, d, tab) +-- for k, v in pairs(o.wielder[tab]) do +-- o.wielder[tab][k] = v + d +-- end +--end + +function _M:update() + self.c_list.key:addBinds{ + ACCEPT = function() self.key:triggerVirtual("EXIT") end, + MOVE_LEFT = function() self:incStat(-1) end, + MOVE_RIGHT = function() self:incStat(1) end, + } +end + +function _M:drawDialog(s) + -- Description part + self:drawHBorder(s, self.iw / 2, 2, self.ih - 4) + local statshelp = ([[Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#right key#FFFFFF# to increase stat; #00FF00#left key#FFFFFF# to decrease a stat. +Mouse: #00FF00#Left click#FFFFFF# to increase a stat; #00FF00#right click#FFFFFF# to decrease a stat. +]]):splitLines(self.iw / 2 - 10, self.font) + local lines = self.actor.stats_def[self.sel].description:splitLines(self.iw / 2 - 10, self.font) + for i = 1, #statshelp do + s:drawColorStringBlended(self.font, statshelp[i], self.iw / 2 + 5, 2 + (i-1) * self.font:lineSkip()) + end + for i = 1, #lines do + s:drawColorStringBlended(self.font, lines[i], self.iw / 2 + 5, 2 + (i + #statshelp + 1) * self.font:lineSkip()) + end + + -- Stats + s:drawColorStringBlended(self.font, "Stats points left: #00FF00#"..self.actor.unused_stats, 2, 2) + self:drawWBorder(s, 2, 20, 200) + + self:drawSelectionList(s, 2, 25, self.font_h, { + "Strength", "Dexterity", "Magic", "Willpower", "Cunning", "Constitution" + }, self.sel) + self:drawSelectionList(s, 100, 25, self.font_h, { + self.actor:getStr(), self.actor:getDex(), self.actor:getMag(), self.actor:getWil(), self.actor:getCun(), self.actor:getCon(), + }, self.sel) + self.changed = false +end diff --git a/game/modules/tome/dialogs/UseTalents.lua b/game/modules/tome/dialogs/UseTalents.lua index d6fda8102a..6b127f8b4b 100644 --- a/game/modules/tome/dialogs/UseTalents.lua +++ b/game/modules/tome/dialogs/UseTalents.lua @@ -33,7 +33,7 @@ function _M:init(actor) Dialog.init(self, "Use Talents: "..actor.name, game.w * 0.8, game.h * 0.8) self.c_tut = Textzone.new{width=math.floor(self.iw / 2 - 10), height=1, auto_height=true, no_color_bleed=true, text=[[ -You can bind a talent to a hotkey by pressing the corresponding hotkey while selecting a talent or by right-clicking on the talent. +You can bind a non-passive talent to a hotkey by pressing the corresponding hotkey while selecting a talent or by right-clicking on the talent. Check out the keybinding screen in the game menu to bind hotkeys to a key (default is 1-0 plus control or shift). Right click or press '*' to configure. ]]} @@ -119,7 +119,8 @@ end function _M:use(item, button) if not item or not item.talent then return end - + local t = self.actor:getTalentFromId(item.talent) + if t.mode == "passive" then return end if button == "right" then local list = { {name="Unbind", what="unbind"}, @@ -127,7 +128,7 @@ function _M:use(item, button) {name="Bind to middle mouse click (on a target)", what="middle"}, } - local t = self.actor:getTalentFromId(item.talent) + --local t = self.actor:getTalentFromId(item.talent) if self.actor:isTalentAuto(t) then table.insert(list, 1, {name="Disable automatic use", what="auto-dis"}) else table.insert(list, 1, {name="Enable automatic use", what="auto-en"}) end @@ -248,6 +249,9 @@ function _M:generateList() elseif t.mode == "sustained" then if self.actor:isTalentActive(t.id) then nodes = sustained end status = self.actor:isTalentActive(t.id) and tstring{{"color", "YELLOW"}, "Sustaining"} or tstring{{"color", "LIGHT_GREEN"}, "Sustain"} + elseif t.mode == "passive" then + nodes = passives + status = tstring{{"color", "BLUE"}, "Passive"} end -- Pregenenerate icon with the Tiles instance that allows images @@ -262,6 +266,7 @@ function _M:generateList() desc=self.actor:getTalentFullDescription(t), color=function() return {0xFF, 0xFF, 0xFF} end, hotkey=function(item) + if t.mode == "passive" then return "" end for i = 1, 12 * self.actor.nb_hotkey_pages do if self.actor.hotkey[i] and self.actor.hotkey[i][1] == "talent" and self.actor.hotkey[i][2] == item.talent then return "H.Key "..i.."" end end diff --git a/game/modules/tome/resolvers.lua b/game/modules/tome/resolvers.lua index 5667020471..3e1be833e7 100644 --- a/game/modules/tome/resolvers.lua +++ b/game/modules/tome/resolvers.lua @@ -17,6 +17,8 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +local Talents = require "engine.interface.ActorTalents" + --- Resolves equipment creation for an actor function resolvers.equip(t) return {__resolver="equip", __resolve_last=true, t} @@ -243,25 +245,152 @@ function resolvers.calc.chatfeature(t, e) return nil end ---- Random bonus based on level (sets the mbonus max level, we use 60 instead of 50 to get some forced randomness at high level) + resolvers.mbonus_max_level = 90 ---- Random bonus based on level and material quality +--- Random bonus based on level and material quality. Contains standard inputs for rng.mbonus for each attribute found in egos. +-- The reason for centralizing ego bonuses here is ease of balancing. If we decide that, for example, combat_physcrit is too abundant on egos in general, we can change the value in the atts table below and alter all egos simultaneously. resolvers.current_level = 1 -function resolvers.mbonus_material(max, add, pricefct) - return {__resolver="mbonus_material", max, add, pricefct} +function resolvers.mbonus_material(att_name, mult, subtype_adjust, max, add, pricefct) + return {__resolver="mbonus_material", att_name, mult, subtype_adjust, max, add, pricefct} end function resolvers.calc.mbonus_material(t, e) + local att_name = t[1] or nil local ml = e.material_level or 1 - local v = math.ceil(rng.mbonus(t[1], resolvers.current_level, resolvers.mbonus_max_level) * ml / 5) + (t[2] or 0) - - if e.cost and t[3] then - local ap, nv = t[3](e, v) - e.cost = e.cost + ap - v = nv or v + local v = 0 + local atts = { + -- format is {max, add, factor1, factor2} + -- It's not necessary to have two factors, since they both get applied the same way. But they have two different purposes, and separating them makes things clearer. + + ---COMBAT STATS + combat_atk = {8, 2}, + combat_dam = {8, 2}, + combat_spellpower = {8, 2}, + combat_mindpower = {8, 2}, + combat_def = {8, 2}, + combat_def_ranged = {8, 2}, + combat_physresist = {13, 2}, + combat_spellresist = {13, 2}, + combat_mentalresist = {13, 2}, + save = {13, 2}, + ---OTHER + dam = {15, 5}, + critical_power = {8, 2, 1, 0.1}, + block = {95, 5}, + physspeed = {3, 1, 5, 0.01}, + learn_talent = {1, 1}, + learn_talent_5 = {4, 1}, + concussion = {5, 5, 10}, + combat_apr = {2, 1, 5}, + combat_physcrit = {4, 1}, + combat_spellcrit = {4, 1}, + combat_mindcrit = {4, 1}, + combat_armor = {2, 1, 5}, + combat_armor_hardiness = {2, 1, 5}, + fatigue = {3, 1, 5, -1}, + melee_project = {2, 1, 5}, + inc_stats = {3, 1}, + ranged_project = {5, 1, 5}, + on_melee_hit = {2, 1, 5}, + --resists = {1, 1, 25}, + resists = {1, 1, 10}, + rare_resists = {5, 5}, + resists_cap = {2, 1, 5}, + resists_pen = {2, 1, 5}, + inc_damage = {5, 5}, + damage_affinity = {3, 1, 10}, + esp_range = {9, 1}, + talents_types_mastery = {2, 2, 1, 0.1}, + talent_on_hit_level = {4, 1}, + talent_on_hit_chance = {3, 2, 10}, + combat_critical_power = {1, 1, 1, 0.1}, + disarm_bonus = {5, 1, 5}, + trap_detect_power = {5, 1, 5}, + inc_stealth = {2, 1, 5}, + max_encumber = {3, 2, 10}, + immunity = {1, 1, 10, 0.01}, + life_regen = {3, 1, 5, 0.1}, + stamina_regen = {4, 1, 1, 0.1}, + mana_regen = {4, 1, 1, 0.1}, + hate_regen = {3, 3, 1, 0.001}, + stamina_regen_on_hit = {5, 2, 5, 0.1}, + mana_regen_on_hit = {5, 2, 5, 0.1}, + equilibrium_regen_on_hit = {5, 2, 5, 0.1}, + mana_on_crit = {7, 1}, + die_at = {7, 3, 10, -1}, + max_life = {7, 3, 10}, + max_mana = {5, 2, 10}, + max_stamina = {3, 1, 10}, + max_hate = {5, 5, 1, 0.1}, + max_vim = {3, 1, 10}, + max_air = {3, 1, 10}, + lite = {1, 1}, + infravision = {2, 1}, + heightened_senses = {1, 1}, + see_invisible = {3, 1, 5}, + invisible = {9, 1}, + movement_speed = {1, 1, 1, .1}, + combat_physspeed = {3, 1, 5, 0.01}, + combat_spellspeed = {3, 1, 5, 0.01}, + healing_factor = {2, 1, 1, 0.1}, + life_leech_chance = {9, 1}, + life_leech_value = {2, 2, 5}, + resource_leech_chance = {4, 1, 10}, + resource_leech_value = {15, 5}, + inc_damage_type = {1, 1, 25}, + max_acc = {14, 1}, + capacity = {7, 3}, + ammo_regen = {3, 1}, + cross_tier_bonus = {5, 5}, + wards = {1, 1}, + +--[=[ --Unused, but here in case we want individual immunities to have different numbers. Right now, all egos using immunities just use the "immunity" key above + blind_immune = {1.5, 1, 25, 0.01}, + poison_immune = {1.5, 1, 25, 0.01}, + disease_immune = {1.5, 1, 25, 0.01}, + cut_immune = {1.5, 1, 25, 0.01}, + silence_immune = {1.5, 1, 25, 0.01}, + disarm_immune = {1.5, 1, 25, 0.01}, + confusion_immune = {1.5, 1, 25, 0.01}, + pin_immune = {1.5, 1, 25, 0.01}, + stun_immune = {1.5, 1, 25, 0.01}, + fear_immune = {1.5, 1, 25, 0.01}, + knockback_immune = {1.5, 1, 25, 0.01}, + instakill_immune = {1.5, 1, 25, 0.01}, + teleport_immune = {1.5, 1, 25, 0.01}, + ]=] + + + } + if not atts[att_name] then return 0 end + local parity_fix = 1 + if t[2] and t[2] < 0 then + parity_fix = -1 + end + local subtype_adjust = 1 + if t[3] then + if e.twohanded then subtype_adjust = 3 + elseif e.subtype == "dagger" then subtype_adjust = 1 + else subtype_adjust = 2 + end + end + local max = (atts[att_name][1] or 0) * (t[2] or 1) * parity_fix * subtype_adjust + local add = (atts[att_name][2] or 0) * (t[2] or 1) * parity_fix + if t[4] and t[5] then + v = math.ceil(rng.mbonus(t[4], resolvers.current_level, resolvers.mbonus_max_level) * ml / 5) + (t[5] or 0) + if e.cost and t[6] then + local ap, nv = t[6](e, v) + e.cost = e.cost + ap + v = nv or v + end + else + local min = add * (atts[att_name][3] or 1) * (atts[att_name][4] or 1) + v = math.ceil(rng.mbonus(max, resolvers.current_level, resolvers.mbonus_max_level) * ml / 5) + (add or 0) + v = v * (atts[att_name][3] or 1) * (atts[att_name][4] or 1) + if v < min then v = min end end - return v + return v * parity_fix end --- Random bonus based on level, more strict @@ -306,6 +435,74 @@ function resolvers.calc.mbonus(t, e) return v end +--- Random, normally-distributed positive bonus used for combat attributes on weapons + +function resolvers.cbonus(base, max, factor, stand) + return {__resolver="cbonus", base, max, factor, stand} +end +function resolvers.calc.cbonus(t, e) + local base = t[1] + local max = t[2] or 2 * base + local factor = t[3] or 1 + local stand = t[4] or (max - base) / 4 + local val = util.bound(math.floor(rng.normal(base, stand)), base, max) + + --update name with flavors that reflect the object's power: + if not e.flavor_names then e.flavor_names = {e.subtype, e.subtype, e.subtype, e.subtype} end + if not e.flavor_name and e.subtype ~= "staff" then + e.flavor_name = e.flavor_names[1] + e.name = e.name:gsub(e.subtype, e.flavor_name) + end + if val > base and e.subtype ~= "staff" then + e.pow = (e.pow or 1) + 1 + e.name = e.name:gsub(e.flavor_name or e.subtype, e.flavor_names[e.pow]) + e.flavor_name = e.flavor_names[e.pow] + end + --fill quivers to capacity + if e.combat and e.combat.capacity then e.combat.shots_left = e.combat.capacity end + return val * factor +end + +--Unused for now: +function resolvers.w_name() + return {__resolver="w_name"} +end +function resolvers.calc.w_name(t, e) + --update name with flavors that reflect the object's power: + if e.subtype ~= "staff" then + print("pow is", e.pow or 11) + if not e.flavor_names then e.flavor_names = {e.subtype, e.subtype, e.subtype, e.subtype} end + e.name = e.name:gsub(e.flavor_name or e.subtype, e.flavor_names[e.pow] or "error") + e.flavor_name = e.flavor_names[e.pow] + end +end + +--- give staves a flavor and appropriate damage type, as well as the command staff talent +function resolvers.staff_wielder(name) + return {__resolver="staff_wielder", name} +end +function resolvers.calc.staff_wielder(t, e) + local staff_type = rng.table{2, 2, 2, 2, 3, 3, 3, 4, 4, 4} + e.flavor_name = e["flavor_names"][staff_type] + if staff_type == 2 then + e.combat.damtype = rng.table{engine.DamageType.FIRE, engine.DamageType.COLD, engine.DamageType.LIGHTNING, engine.DamageType.ARCANE} + e.modes = {"fire", "cold", "lightning", "arcane"} + e.name = e.name:gsub(" staff", " magestaff") + elseif staff_type == 3 then + e.combat.damtype = rng.table{engine.DamageType.LIGHT, engine.DamageType.DARKNESS, engine.DamageType.TEMPORAL} + e.modes = {"light", "darkness", "temporal"} + e.name = e.name:gsub(" staff", " starstaff") + elseif staff_type == 4 then + e.combat.damtype = rng.table{engine.DamageType.NATURE, engine.DamageType.BLIGHT, engine.DamageType.ACID} + e.modes = {"nature", "blight", "acid"} + e.name = e.name:gsub(" staff", " earthstaff") + end + return { + inc_damage = {[e.combat.damtype] = e.combat.dam}, + learn_talent = {[Talents.T_COMMAND_STAFF] = e.material_level}, + } +end + --- Generic resolver, takes a function, executes at the end function resolvers.genericlast(fct) return {__resolver="genericlast", __resolve_last=true, fct} -- GitLab