diff --git a/game/engine/Chat.lua b/game/engine/Chat.lua index 39ef86f10b6499d173aae940dd68997cbcf9273d..4d3455deca11a135aff0a0fe6555824e78e304a7 100644 --- a/game/engine/Chat.lua +++ b/game/engine/Chat.lua @@ -28,7 +28,8 @@ function _M:init(name, npc, player) self.npc = npc self.player = player - local f = loadfile("/data/chats/"..name..".lua") + local f, err = loadfile("/data/chats/"..name..".lua") + if not f and err then error(err) end setfenv(f, setmetatable({ newChat = function(c) self:addChat(c) end, }, {__index=_G})) diff --git a/game/engine/interface/ActorTemporaryEffects.lua b/game/engine/interface/ActorTemporaryEffects.lua index 2e6084a754b8f64af1b64f7eba04d594b9d6d75f..2f7fa5ae3928787020733458e4df4e88bcdd0530 100644 --- a/game/engine/interface/ActorTemporaryEffects.lua +++ b/game/engine/interface/ActorTemporaryEffects.lua @@ -65,7 +65,6 @@ end function _M:timedEffects() local todel = {} for eff, p in pairs(self.tmp) do - p.dur = p.dur - 1 if p.dur <= 0 then todel[#todel+1] = eff else @@ -75,6 +74,7 @@ function _M:timedEffects() end end end + p.dur = p.dur - 1 end while #todel > 0 do diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index a6cb0b193126f622cb2426870261a573d3fda9d5..fa6dc0b8b4aae958a3797d0e5940b0214696a987 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -83,9 +83,9 @@ function _M:init(t, no_default) t.rank = t.rank or 2 t.life_rating = t.life_rating or 10 - t.mana_rating = t.mana_rating or 10 - t.stamina_rating = t.stamina_rating or 4 - t.positive_negative_rating = t.positive_negative_rating or 4 + t.mana_rating = t.mana_rating or 4 + t.stamina_rating = t.stamina_rating or 3 + t.positive_negative_rating = t.positive_negative_rating or 3 t.esp = t.esp or {range=10} @@ -1070,16 +1070,18 @@ function _M:addedToLevel(level, x, y) if self.make_escort then for _, filter in ipairs(self.make_escort) do for i = 1, filter.number do - -- Find space - local x, y = util.findFreeGrid(self.x, self.y, 10, true, {[Map.ACTOR]=true}) - if not x then break end - - -- Find an actor with that filter - local m = game.zone:makeEntity(game.level, "actor", filter) - if m and m:canMove(x, y) then - if filter.no_subescort then m.make_escort = nil end + if not filter.chance or rng.percent(filter.chance) then + -- Find space + local x, y = util.findFreeGrid(self.x, self.y, 10, true, {[Map.ACTOR]=true}) + if not x then break end + + -- Find an actor with that filter + local m = game.zone:makeEntity(game.level, "actor", filter) + if m and m:canMove(x, y) then + if filter.no_subescort then m.make_escort = nil end game.zone:addEntity(game.level, m, "actor", x, y) - elseif m then m:removed() end + elseif m then m:removed() end + end end end self.make_escort = nil diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 20ea9b694ee6822223b5e0d1b4081048116940f0..5fbc605e9844845e5401c76b836af8204c6bafb8 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -396,14 +396,6 @@ function _M:display() self.target.target.x, self.target.target.y = tmx, tmy end self.old_tmx, self.old_tmy = tmx, tmy ---[[ too slow - if self.test_path and self.key.status[self.key._LSHIFT] then - for i, c in ipairs(self.test_path) do - local lx, ly = c.x, c.y - self.test_sprite:toScreen(self.level.map.display_x + (lx - game.level.map.mx) * self.level.map.tile_w, self.level.map.display_y + (ly - game.level.map.my) * self.level.map.tile_h) - end - end -]] if self.minimap_mode == 2 then self.level.map:minimapDisplay(self.w - 200, 20, util.bound(self.player.x - 25, 0, self.level.map.w - 50), util.bound(self.player.y - 25, 0, self.level.map.h - 50), 50, 50, 0.6) diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua index 6510766d40cb0221fdfbd4863a09cec3a1da5e33..f0ae2465802f23afd616ff672e65a4e567edae28 100644 --- a/game/modules/tome/class/Object.lua +++ b/game/modules/tome/class/Object.lua @@ -99,11 +99,11 @@ 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)).." dam, "..(c.apr or 0).." apr" + return c.dam.."-"..(c.dam*(c.damrange or 1.1)).." power, "..(c.apr or 0).." apr" elseif attr == "ARMOR" then return (self.wielder and self.wielder.combat_def or 0).." def, "..(self.wielder and self.wielder.combat_armor or 0).." armor" elseif attr == "ATTACK" then - return (self.wielder and self.wielder.combat_atk or 0).." attack, "..(self.wielder and self.wielder.combat_apr or 0).." apr"..(self.wielder and self.wielder.combat_dam or 0).." dam" + return (self.wielder and self.wielder.combat_atk or 0).." attack, "..(self.wielder and self.wielder.combat_apr or 0).." apr"..(self.wielder and self.wielder.combat_dam or 0).." power" elseif attr == "MONEY" then return ("worth %0.2f"):format(self.money_value / 10) end @@ -179,13 +179,13 @@ function _M:getDesc() for stat, i in pairs(self.combat.dammod or {}) do dm[#dm+1] = ("+%d%% %s"):format(i * 100, Stats.stats_def[stat].name) end - desc[#desc+1] = ("%d Damage [Range %0.2f] (%s), %d Attack, %d Armor Penetration, Crit %d%%"):format(self.combat.dam or 0, self.combat.damrange or 1.1, table.concat(dm, ','), self.combat.atk or 0, self.combat.apr or 0, self.combat.physcrit or 0) + desc[#desc+1] = ("%d Power [Range %0.2f] (%s), %d Attack, %d Armor Penetration, Crit %d%%"):format(self.combat.dam or 0, self.combat.damrange or 1.1, table.concat(dm, ','), self.combat.atk or 0, self.combat.apr or 0, self.combat.physcrit or 0) if self.combat.range then desc[#desc+1] = "Firing range: "..self.combat.range end desc[#desc+1] = "" end local w = self.wielder or {} - if w.combat_atk or w.combat_dam or w.combat_apr then desc[#desc+1] = ("Attack %d, Armor Penetration %d, Physical Crit %d%%, Physical damage %d"):format(w.combat_atk or 0, w.combat_apr or 0, w.combat_physcrit or 0, w.combat_dam or 0) end + if w.combat_atk or w.combat_dam or w.combat_apr then desc[#desc+1] = ("Attack %d, Armor Penetration %d, Physical Crit %d%%, Physical power %d"):format(w.combat_atk or 0, w.combat_apr or 0, w.combat_physcrit or 0, w.combat_dam or 0) end if w.combat_armor or w.combat_def then desc[#desc+1] = ("Armor %d, Defense %d"):format(w.combat_armor or 0, w.combat_def or 0) end if w.fatigue then desc[#desc+1] = ("Fatigue %d%%"):format(w.fatigue) end diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index f69de834e4aa5aab1205a82e31358a18645d8765..cad19d70eb86f017c48232b90ad48124635559d0 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -453,20 +453,23 @@ function _M:combatDamage(weapon) local sub_con_to_str = false if weapon.talented and weapon.talented == "knife" and self:knowTalent(Talents.T_LETHALITY) then sub_con_to_str = true end - local add = 0 + local totstat = 0 if weapon.dammod then for stat, mod in pairs(weapon.dammod) do if sub_con_to_str and stat == "str" then stat = "cun" end - add = add + (self:getStat(stat) - 10) * 0.7 * mod + totstat = totstat + self:getStat(stat) * mod end end + local add = 0 if self:knowTalent(Talents.T_ARCANE_DESTRUCTION) then add = add + self:combatSpellpower() * self:getTalentLevel(Talents.T_ARCANE_DESTRUCTION) / 9 end - local talented_mod = self:combatCheckTraining(weapon) - return self.combat_dam + (weapon.dam or 1) * (1 + talented_mod / 4) + add + local talented_mod = math.sqrt(self:combatCheckTraining(weapon) / 10) + 1 + local power = self.combat_dam + (weapon.dam or 1) + add + power = (math.sqrt(power / 10) - 1) * 0.8 + 1 + return totstat / 1.5 * power * talented_mod end --- Gets spellpower @@ -479,7 +482,15 @@ function _M:combatSpellpower(mod) if self:knowTalent(self.T_SHADOW_CUNNING) then add = (15 + self:getTalentLevel(self.T_SHADOW_CUNNING) * 3) * self:getCun() / 100 end - return (self.combat_spellpower + add + self:getMag() * 0.7) * mod + return (self.combat_spellpower + add + self:getMag()) * mod +end + +--- Gets damage based on talent +function _M:combatTalentSpellDamage(t, base, max) + -- Compute at "max" + local mod = max / ((base + 100) * ((math.sqrt(5) - 1) * 0.8 + 1)) + -- Compute real + return (base + self:combatSpellpower()) * ((math.sqrt(self:getTalentLevel(t)) - 1) * 0.8 + 1) * mod end --- Gets spellcrit diff --git a/game/modules/tome/data/birth/classes/mage.lua b/game/modules/tome/data/birth/classes/mage.lua index 1e327534b989c1bbfb707b644bda26dff35b2950..8fdc58c4dd937664a1923884eaea0323f3d0aad3 100644 --- a/game/modules/tome/data/birth/classes/mage.lua +++ b/game/modules/tome/data/birth/classes/mage.lua @@ -38,7 +38,7 @@ newBirthDescriptor{ -- All mages are of angolwen faction faction = "angolwen", mana_regen = 0.5, - mana_rating = 10, + mana_rating = 5, resolvers.generic(function(e) e.hotkey[10] = {"inventory", "potion of lesser mana"} end), diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 2e616733cd158ec67322547e52512415ba27566b..50e7d5111953941c5baffb27b9830f0fbdcbdb76 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -214,7 +214,8 @@ newDamageType{ local target = game.level.map(x, y, Map.ACTOR) if target then -- Set on fire! - target:setEffect(target.EFF_BURNING, 3, {src=src, power=dam / 6}) + dam = dam / 2 + target:setEffect(target.EFF_BURNING, 3, {src=src, power=dam / 3}) end end, } diff --git a/game/modules/tome/data/talents/spells/air.lua b/game/modules/tome/data/talents/spells/air.lua index 496e2a266c7861f2240f35d29cdcd56347b927ab..8f1d55839c11f0384c608ae424fd75fe8ed5fa2b 100644 --- a/game/modules/tome/data/talents/spells/air.lua +++ b/game/modules/tome/data/talents/spells/air.lua @@ -33,7 +33,7 @@ newTalent{ local tg = {type="beam", range=self:getTalentRange(t), talent=t} local x, y = self:getTarget(tg) if not x or not y then return nil end - local dam = self:spellCrit(20 + self:combatSpellpower(0.8) * self:getTalentLevel(t)) + local dam = self:spellCrit(self:combatTalentSpellDamage(t, 20, 290)) self:project(tg, x, y, DamageType.LIGHTNING, rng.avg(dam / 5, dam, 3)) local _ _, x, y = self:canProject(tg, x, y) game.level.map:particleEmitter(self.x, self.y, math.max(math.abs(x-self.x), math.abs(y-self.y)), "lightning", {tx=x-self.x, ty=y-self.y}) @@ -42,7 +42,7 @@ newTalent{ end, info = function(self, t) return ([[Conjures up mana into a powerful beam of lightning doing %0.2f to %0.2f damage - The damage will increase with the Magic stat]]):format((20 + self:combatSpellpower(0.8) * self:getTalentLevel(t)) / 5, 20 + self:combatSpellpower(0.8) * self:getTalentLevel(t)) + The damage will increase with the Magic stat]]):format(self:combatTalentSpellDamage(t, 20, 290) / 5, self:combatTalentSpellDamage(t, 20, 290)) end, } @@ -102,7 +102,7 @@ newTalent{ for i, actor in ipairs(targets) do local tgr = {type="beam", range=self:getTalentRange(t), friendlyfire=false, talent=t, x=sx, y=sy} print("[Chain lightning] jumping from", sx, sy, "to", actor.x, actor.y) - self:project(tgr, actor.x, actor.y, DamageType.LIGHTNING, rng.avg(1, self:spellCrit(20 + self:combatSpellpower(0.8) * self:getTalentLevel(t)), 5)) + self:project(tgr, actor.x, actor.y, DamageType.LIGHTNING, rng.avg(1, self:spellCrit(self:combatTalentSpellDamage(t, 10, 200)), 5)) game.level.map:particleEmitter(sx, sy, math.max(math.abs(actor.x-sx), math.abs(actor.y-sy)), "lightning", {tx=actor.x-sx, ty=actor.y-sy}) sx, sy = actor.x, actor.y end @@ -116,7 +116,7 @@ newTalent{ It can hit up to %d targets and will never hit the same one twice, neither will it hit the caster. The damage will increase with the Magic stat]]): format( - 20 + self:combatSpellpower(0.8) * self:getTalentLevel(t), + self:combatTalentSpellDamage(t, 10, 200), 3 + self:getTalentLevelRaw(t) ) end, @@ -194,7 +194,7 @@ newTalent{ local a, id = rng.table(tgts) table.remove(tgts, id) - self:project(tg, a.x, a.y, DamageType.LIGHTNING, rng.avg(1, self:spellCrit(20 + self:combatSpellpower(0.2) * self:getTalentLevel(t)), 3)) + self:project(tg, a.x, a.y, DamageType.LIGHTNING, rng.avg(1, self:spellCrit(self:combatTalentSpellDamage(t, 15, 80)), 3)) game.level.map:particleEmitter(self.x, self.y, math.max(math.abs(a.x-self.x), math.abs(a.y-self.y)), "lightning", {tx=a.x-self.x, ty=a.y-self.y}) game:playSoundNear(self, "talents/lightning") end @@ -215,6 +215,6 @@ newTalent{ return ([[Conjures a furious, raging lightning storm with a radius of 5 that follows you as long as this spell is active. Each turn a random lightning bolt will hit up to %d of your foes for 1 to %0.2f damage. This powerful spell will continuously drain mana while active. - The damage will increase with the Magic stat]]):format(self:getTalentLevel(t), 20 + self:combatSpellpower(0.2) * self:getTalentLevel(t)) + The damage will increase with the Magic stat]]):format(self:getTalentLevel(t), self:combatTalentSpellDamage(t, 15, 80)) end, } diff --git a/game/modules/tome/data/talents/spells/fire.lua b/game/modules/tome/data/talents/spells/fire.lua index 143cab10f1d90ce51d4f38c2091fd4003e833388..f620c37a06351b389bea4b50dad194f028cc7b58 100644 --- a/game/modules/tome/data/talents/spells/fire.lua +++ b/game/modules/tome/data/talents/spells/fire.lua @@ -33,13 +33,13 @@ newTalent{ local tg = {type="bolt", range=self:getTalentRange(t), talent=t} local x, y = self:getTarget(tg) if not x or not y then return nil end - self:project(tg, x, y, DamageType.FIREBURN, self:spellCrit(25 + self:combatSpellpower(0.8) * self:getTalentLevel(t)), {type="flame"}) + self:project(tg, x, y, DamageType.FIREBURN, self:spellCrit(self:combatTalentSpellDamage(t, 25, 290)), {type="flame"}) game:playSoundNear(self, "talents/fire") return true end, info = function(self, t) return ([[Conjures up a bolt of fire, setting the target ablaze and doing %0.2f fire damage over 3 turns. - The damage will increase with the Magic stat]]):format(25 + self:combatSpellpower(0.8) * self:getTalentLevel(t)) + The damage will increase with the Magic stat]]):format(self:combatTalentSpellDamage(t, 25, 290)) end, } @@ -58,13 +58,13 @@ newTalent{ local tg = {type="cone", range=0, radius=3 + self:getTalentLevelRaw(t), friendlyfire=false, talent=t} local x, y = self:getTarget(tg) if not x or not y then return nil end - self:project(tg, x, y, DamageType.FLAMESHOCK, {dur=self:getTalentLevelRaw(t) + 2, dam=self:spellCrit(10 + self:combatSpellpower(0.6) * self:getTalentLevel(t))}, {type="flame"}) + self:project(tg, x, y, DamageType.FLAMESHOCK, {dur=self:getTalentLevelRaw(t) + 2, dam=self:spellCrit(self:combatTalentSpellDamage(t, 10, 120))}, {type="flame"}) game:playSoundNear(self, "talents/fire") return true end, info = function(self, t) return ([[Conjures up a cone of flame. Any target caught in the area will take %0.2f fire damage and be stunned over %d turns. - The damage will increase with the Magic stat]]):format(10 + self:combatSpellpower(0.6) * self:getTalentLevel(t), self:getTalentLevelRaw(t) + 2) + The damage will increase with the Magic stat]]):format(self:combatTalentSpellDamage(t, 10, 120), self:getTalentLevelRaw(t) + 2) end, } @@ -83,7 +83,7 @@ newTalent{ local tg = {type="ball", range=self:getTalentRange(t), radius=1 + self:getTalentLevelRaw(t), friendlyfire=self:spellFriendlyFire(), talent=t} local x, y = self:getTarget(tg) if not x or not y then return nil end - local grids = self:project(tg, x, y, DamageType.FIRE, self:spellCrit(28 + self:combatSpellpower(0.6) * self:getTalentLevel(t))) + local grids = self:project(tg, x, y, DamageType.FIREBURN, self:spellCrit(self:combatTalentSpellDamage(t, 28, 200))) local _ _, x, y = self:canProject(tg, x, y) game.level.map:particleEmitter(x, y, tg.radius, "fireflash", {radius=tg.radius, grids=grids, tx=x, ty=y}) @@ -93,7 +93,7 @@ newTalent{ end, info = function(self, t) return ([[Conjures up a flash of fire doing %0.2f fire damage in a radius of %d. - The damage will increase with the Magic stat]]):format(28 + self:combatSpellpower(0.6) * self:getTalentLevel(t), 1 + self:getTalentLevelRaw(t)) + The damage will increase with the Magic stat]]):format(self:combatTalentSpellDamage(t, 28, 200), 1 + self:getTalentLevelRaw(t)) end, } @@ -111,7 +111,7 @@ newTalent{ action = function(self, t) local duration = 5 + self:getTalentLevel(t) local radius = 5 - local dam = 15 + self:combatSpellpower(0.15) * self:getTalentLevel(t) + local dam = self:combatTalentSpellDamage(t, 15, 80) local tg = {type="ball", range=self:getTalentRange(t), radius=radius} local x, y = self:getTarget(tg) if not x or not y then return nil end @@ -133,6 +133,6 @@ newTalent{ end, info = function(self, t) return ([[Raging flames burn foes and allies alike doing %0.2f fire damage in a radius of 5 each turn for %d turns. - The damage and duration will increase with the Magic stat]]):format(15 + self:combatSpellpower(0.15) * self:getTalentLevel(t), 5 + self:getTalentLevel(t)) + The damage and duration will increase with the Magic stat]]):format(self:combatTalentSpellDamage(t, 15, 80), 5 + self:getTalentLevel(t)) end, } diff --git a/game/modules/tome/data/zones/rak-shor-pride/npcs.lua b/game/modules/tome/data/zones/rak-shor-pride/npcs.lua index 47c71401c0777694beda084dc075299d8d54017c..130423f51087547a534247189c22d8ca78f90a5b 100644 --- a/game/modules/tome/data/zones/rak-shor-pride/npcs.lua +++ b/game/modules/tome/data/zones/rak-shor-pride/npcs.lua @@ -17,22 +17,27 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org -load("/data/general/npcs/orc.lua") +load("/data/general/npcs/ghoul.lua", function(e) if e.rarity then e.rarity = e.rarity * 3 end end) +load("/data/general/npcs/skeleton.lua", function(e) if e.rarity then e.rarity = e.rarity * 3 end end) +load("/data/general/npcs/orc.lua", function(e) if e.rarity then e.rarity = e.rarity * 3 end end) +load("/data/general/npcs/orc-rak-shor.lua") local Talents = require("engine.interface.ActorTalents") -newEntity{ define_as = "RAK_SHOR", +newEntity{ base="BASE_NPC_ORC_RAK_SHOR", define_as = "RAK_SHOR", name = "Rak'shor, Grand Necromancer of the Pride", color=colors.VIOLET, unique = true, desc = [[An old orc, wearing black robes. He commands his undead armies to destroy you.]], level_range = {35, 50}, exp_worth = 2, rank = 4, - max_life = 150, life_rating = 14, fixed_rating = true, + max_life = 150, life_rating = 16, fixed_rating = true, infravision = 20, stats = { str=15, dex=10, cun=12, mag=16, con=14 }, + combat_armor = 10, combat_def = 10, + open_door = true, - autolevel = "warriormage", + autolevel = "caster", ai = "dumb_talented_simple", ai_state = { talent_in=2, ai_move="move_astar", }, body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, @@ -42,6 +47,16 @@ newEntity{ define_as = "RAK_SHOR", {type="weapon", subtype="staff", ego_change=100, autoreq=true}, {type="armor", subtype="cloth", ego_change=100, autoreq=true}, }, + + summon = { + {type="undead", subtype="skeleton", number=3, hasxp=false}, + {type="humanoid", subtype="ghoul", number=3, hasxp=false}, + }, + make_escort = { + {type="undead", subtype="ghoul", no_subescort=true, number=resolvers.mbonus(4, 4)}, + {type="undead", subtype="skeleton", no_subescort=true, number=resolvers.mbonus(4, 4)}, + }, + resolvers.talents{ -- [Talents.T_]=2, }, diff --git a/game/modules/tome/load.lua b/game/modules/tome/load.lua index 11ffc1c61c7b738e24e5f85671b66008e3d8c78e..ea048084b277b3be9d6aef6ac6fab5b39cffd766 100644 --- a/game/modules/tome/load.lua +++ b/game/modules/tome/load.lua @@ -87,12 +87,12 @@ ActorResource:defineResource("Positive", "positive", ActorTalents.T_POSITIVE_POO ActorResource:defineResource("Negative", "negative", ActorTalents.T_NEGATIVE_POOL, "negative_regen", "Negative energy represents your reserve of negative power. It slowly decreases.") -- Actor stats -ActorStats:defineStat("Strength", "str", 10, 1, 80, "Strength defines your character's ability to apply physical force. It increases your melee damage, damage done with heavy weapons, your chance to resist physical effects, and carrying capacity.") -ActorStats:defineStat("Dexterity", "dex", 10, 1, 80, "Dexterity defines your character's ability to be agile and alert. It increases your chance to hit, your ability to avoid attacks, and your damage with light weapons.") -ActorStats:defineStat("Magic", "mag", 10, 1, 80, "Magic defines your character's ability to manipulate the magic of the world. It increases your spell power, and the effect of spells and other magic items.") -ActorStats:defineStat("Willpower", "wil", 10, 1, 80, "Willpower defines your character's ability to concentrate. It increases your mana and stamina capacity, and your chance to resist mental attacks.") -ActorStats:defineStat("Cunning", "cun", 10, 1, 80, "Cunning defines your character's ability to learn, think, and react. It allows you to learn many wordly abilities, increases your mental resistance, armor penetration, and critical chance.") -ActorStats:defineStat("Constitution", "con", 10, 1, 80, "Constitution defines your character's ability to withstand and resist damage. It increases your maximum life and physical resistance.") +ActorStats:defineStat("Strength", "str", 10, 1, 100, "Strength defines your character's ability to apply physical force. It increases your melee damage, damage done with heavy weapons, your chance to resist physical effects, and carrying capacity.") +ActorStats:defineStat("Dexterity", "dex", 10, 1, 100, "Dexterity defines your character's ability to be agile and alert. It increases your chance to hit, your ability to avoid attacks, and your damage with light weapons.") +ActorStats:defineStat("Magic", "mag", 10, 1, 100, "Magic defines your character's ability to manipulate the magic of the world. It increases your spell power, and the effect of spells and other magic items.") +ActorStats:defineStat("Willpower", "wil", 10, 1, 100, "Willpower defines your character's ability to concentrate. It increases your mana and stamina capacity, and your chance to resist mental attacks.") +ActorStats:defineStat("Cunning", "cun", 10, 1, 100, "Cunning defines your character's ability to learn, think, and react. It allows you to learn many wordly abilities, increases your mental resistance, armor penetration, and critical chance.") +ActorStats:defineStat("Constitution", "con", 10, 1, 100, "Constitution defines your character's ability to withstand and resist damage. It increases your maximum life and physical resistance.") -- Luck is hidden and starts at half max value (50) which is considered the standard ActorStats:defineStat("Luck", "lck", 50, 1, 100, "Luck defines your character's chance when dealing with unknown events. It increases your critical strike chance, your chance of random encounters, ...")