diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index cf1f29b9ccc2b5fc1322c2e9e7509df1482a9f9d..52f1cdab38e9da500713883a2deae7ad85b90f5a 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -1168,6 +1168,7 @@ function _M:canBe(what) if what == "confusion" and rng.percent(100 * (self:attr("confusion_immune") or 0)) then return false end if what == "blind" and rng.percent(100 * (self:attr("blind_immune") or 0)) then return false end if what == "silence" and rng.percent(100 * (self:attr("silence_immune") or 0)) then return false end + if what == "disarm" and rng.percent(100 * (self:attr("disarm_immune") or 0)) then return false end if what == "stun" and rng.percent(100 * (self:attr("stun_immune") or 0)) then return false end if what == "fear" and rng.percent(100 * (self:attr("fear_immune") or 0)) then return false end if what == "knockback" and rng.percent(100 * (self:attr("knockback_immune") or 0)) then return false end @@ -1195,6 +1196,9 @@ function _M:updateEffectDuration(dur, what) elseif what == "pin" then local p = self:combatPhysicalResist(), rankmod * (util.bound(self:combatPhysicalResist() * 3, 40, 115) / 100) dur = dur - math.ceil(dur * (p) / 100) + elseif what == "disarm" then + local p = self:combatPhysicalResist(), rankmod * (util.bound(self:combatPhysicalResist() * 3, 40, 115) / 100) + dur = dur - math.ceil(dur * (p) / 100) elseif what == "frozen" then local p = self:combatSpellResist(), rankmod * (util.bound(self:combatSpellResist() * 3, 40, 115) / 100) dur = dur - math.ceil(dur * (p) / 100) diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index d337f057a698eeb46a7db9c739bebbd5ba7a9200..5015cf16f579ce34906d28ecf4634e908a583d8e 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -469,7 +469,7 @@ function _M:setupCommands() self.player.esp.all = 1 self.player.esp.range = 50 self.player.inc_damage.all = 100000 - self:changeLevel(2, "caverns-osse") + self:changeLevel(2, "vor-pride") -- self:changeLevel(1, "wilderness-arda-fareast") -- game.memory_levels["wilderness-arda-fareast-1"] = game.level -- self.player:grantQuest("orc-pride") diff --git a/game/modules/tome/class/interface/Archery.lua b/game/modules/tome/class/interface/Archery.lua index 34eee44ad5fc3ff06fbc297112823b404eff2d35..c326e7afa5a258cd7899dccfac22bf0e7f1012e9 100644 --- a/game/modules/tome/class/interface/Archery.lua +++ b/game/modules/tome/class/interface/Archery.lua @@ -164,6 +164,10 @@ function _M:archeryShoot(targets, talent, tg, params) game.logPlayer(self, "You must wield a bow or a sling (%s)!", ammo) return nil end + if self:attr("disarmed") then + game.logPlayer(self, "You are disarmed!") + return nil + end print("[SHOOT WITH]", weapon.name, ammo.name) local realweapon = weapon @@ -186,6 +190,10 @@ end --- Check if the actor has a bow or sling and corresponding ammo function _M:hasArcheryWeapon() + if self:attr("disarmed") then + return nil, "disarmed" + end + if not self:getInven("MAINHAND") then return nil, "no shooter" end if not self:getInven("QUIVER") then return nil, "no ammo" end local weapon = self:getInven("MAINHAND")[1] diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 999d7c6603dd5a30db9afdbb30d2d2710d2c2979..bdd92ab1a59b08d90d9c24e6dd582565f96a760f 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -81,34 +81,36 @@ function _M:attackTarget(target, damtype, mult, noenergy) game.logPlayer(self, "%s notices you at the last moment!", target.name:capitalize()) end - -- All weaponsin main hands - if self:getInven(self.INVEN_MAINHAND) then - for i, o in ipairs(self:getInven(self.INVEN_MAINHAND)) do - if o.combat then - print("[ATTACK] attacking with", o.name) - local s, h = self:attackTargetWith(target, o.combat, damtype, mult) - speed = math.max(speed or 0, s) - hit = hit or h - if hit and not sound then sound = o.combat.sound - elseif not hit and not sound_miss then sound_miss = o.combat.sound_miss end + if not self:attr("disarmed") then + -- All weapons in main hands + if self:getInven(self.INVEN_MAINHAND) then + for i, o in ipairs(self:getInven(self.INVEN_MAINHAND)) do + if o.combat then + print("[ATTACK] attacking with", o.name) + local s, h = self:attackTargetWith(target, o.combat, damtype, mult) + speed = math.max(speed or 0, s) + hit = hit or h + if hit and not sound then sound = o.combat.sound + elseif not hit and not sound_miss then sound_miss = o.combat.sound_miss end + end end end - end - -- All wpeaons in off hands - -- Offhand atatcks are with a damage penality, taht can be reduced by talents - if self:getInven(self.INVEN_OFFHAND) then - local offmult = (mult or 1) / 2 - if self:knowTalent(Talents.T_DUAL_WEAPON_TRAINING) then - offmult = (mult or 1) / (2 - (self:getTalentLevel(Talents.T_DUAL_WEAPON_TRAINING) / 6)) - end - for i, o in ipairs(self:getInven(self.INVEN_OFFHAND)) do - if o.combat then - print("[ATTACK] attacking with", o.name) - local s, h = self:attackTargetWith(target, o.combat, damtype, offmult) - speed = math.max(speed or 0, s) - hit = hit or h - if hit and not sound then sound = o.combat.sound - elseif not hit and not sound_miss then sound_miss = o.combat.sound_miss end + -- All wpeaons in off hands + -- Offhand atatcks are with a damage penality, taht can be reduced by talents + if self:getInven(self.INVEN_OFFHAND) then + local offmult = (mult or 1) / 2 + if self:knowTalent(Talents.T_DUAL_WEAPON_TRAINING) then + offmult = (mult or 1) / (2 - (self:getTalentLevel(Talents.T_DUAL_WEAPON_TRAINING) / 6)) + end + for i, o in ipairs(self:getInven(self.INVEN_OFFHAND)) do + if o.combat then + print("[ATTACK] attacking with", o.name) + local s, h = self:attackTargetWith(target, o.combat, damtype, offmult) + speed = math.max(speed or 0, s) + hit = hit or h + if hit and not sound then sound = o.combat.sound + elseif not hit and not sound_miss then sound_miss = o.combat.sound_miss end + end end end end @@ -555,6 +557,10 @@ end --- Check if the actor has a staff weapon function _M:hasStaffWeapon() + if self:attr("disarmed") then + return nil, "disarmed" + end + if not self:getInven("MAINHAND") then return end local weapon = self:getInven("MAINHAND")[1] if not weapon or weapon.subtype ~= "staff" then @@ -565,6 +571,10 @@ end --- Check if the actor has a two handed weapon function _M:hasTwoHandedWeapon() + if self:attr("disarmed") then + return nil, "disarmed" + end + if not self:getInven("MAINHAND") then return end local weapon = self:getInven("MAINHAND")[1] if not weapon or not weapon.twohanded then @@ -575,6 +585,10 @@ end --- Check if the actor has a shield function _M:hasShield() + if self:attr("disarmed") then + return nil, "disarmed" + end + if not self:getInven("MAINHAND") or not self:getInven("OFFHAND") then return end local shield = self:getInven("OFFHAND")[1] if not shield or not shield.special_combat then @@ -585,6 +599,10 @@ end --- Check if the actor dual wields function _M:hasDualWeapon() + if self:attr("disarmed") then + return nil, "disarmed" + end + if not self:getInven("MAINHAND") or not self:getInven("OFFHAND") then return end local weapon = self:getInven("MAINHAND")[1] local offweapon = self:getInven("OFFHAND")[1] diff --git a/game/modules/tome/data/general/npcs/all.lua b/game/modules/tome/data/general/npcs/all.lua index 6c6dea9dfcf66d5fa956a24b52b158c63255ab52..3a7027574193df3457c1882137b110f7fff0e8cf 100644 --- a/game/modules/tome/data/general/npcs/all.lua +++ b/game/modules/tome/data/general/npcs/all.lua @@ -38,7 +38,7 @@ loadIfNot("/data/general/npcs/minotaur.lua") loadIfNot("/data/general/npcs/molds.lua") loadIfNot("/data/general/npcs/multihued-drake.lua") --loadIfNot("/data/general/npcs/mummy.lua") ---loadIfNot("/data/general/npcs/naga.lua") +loadIfNot("/data/general/npcs/naga.lua") loadIfNot("/data/general/npcs/ooze.lua") loadIfNot("/data/general/npcs/orc-grushnak.lua") loadIfNot("/data/general/npcs/orc.lua") diff --git a/game/modules/tome/data/general/npcs/bear.lua b/game/modules/tome/data/general/npcs/bear.lua index d9605bad338fd5223e0a6517b96f57c8c5dfcea2..de1035a10d0b4c87823fac236fc6907abe7c7431 100644 --- a/game/modules/tome/data/general/npcs/bear.lua +++ b/game/modules/tome/data/general/npcs/bear.lua @@ -84,7 +84,7 @@ newEntity{ base = "BASE_NPC_BEAR", max_life = resolvers.rngavg(100,120), combat_armor = 9, combat_def = 4, combat = { dam=resolvers.rngavg(13,17), atk=10, apr=3, physspeed=2 }, - resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=2, [Talents.T_KNOCKBACK]=1,}, + resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=2, [Talents.T_KNOCKBACK]=1, [Talents.T_DISARM]=3,}, } newEntity{ base = "BASE_NPC_BEAR", @@ -95,7 +95,7 @@ newEntity{ base = "BASE_NPC_BEAR", max_life = resolvers.rngavg(110,120), combat_armor = 10, combat_def = 5, combat = { dam=resolvers.rngavg(15,20), atk=10, apr=3, physspeed=2 }, - resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=3, [Talents.T_KNOCKBACK]=2,}, + resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=3, [Talents.T_KNOCKBACK]=2, [Talents.T_DISARM]=3,}, } newEntity{ base = "BASE_NPC_BEAR", @@ -106,6 +106,6 @@ newEntity{ base = "BASE_NPC_BEAR", max_life = resolvers.rngavg(110,120), combat_armor = 10, combat_def = 7, combat = { dam=resolvers.rngavg(15,20), atk=12, apr=3, physspeed=2 }, - resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=3, [Talents.T_KNOCKBACK]=2,}, + resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=3, [Talents.T_KNOCKBACK]=2, [Talents.T_DISARM]=3,}, resists = { [DamageType.COLD] = 100, }, } diff --git a/game/modules/tome/data/general/npcs/multihued-drake.lua b/game/modules/tome/data/general/npcs/multihued-drake.lua index 6b151a3b67446b288c89bb7a1775ec3678e66af6..ec87c5907e22d56c0ce14179dd4f2009d69cfc30 100644 --- a/game/modules/tome/data/general/npcs/multihued-drake.lua +++ b/game/modules/tome/data/general/npcs/multihued-drake.lua @@ -109,6 +109,8 @@ newEntity{ base = "BASE_NPC_MULTIHUED_DRAKE", resolvers.talents{ [Talents.T_SUMMON]=1, + [Talents.T_SILENCE]=3, + [Talents.T_DISARM]=3, [Talents.T_ICE_CLAW]=8, [Talents.T_WING_BUFFET]=5, [Talents.T_DEVOURING_FLAME]=8, diff --git a/game/modules/tome/data/general/npcs/orc-grushnak.lua b/game/modules/tome/data/general/npcs/orc-grushnak.lua index 789158c542f1e9156f80b2c56fecd79cb1b65bf8..534c2bb9d7c413f8023c724ed48198e9457c6a5e 100644 --- a/game/modules/tome/data/general/npcs/orc-grushnak.lua +++ b/game/modules/tome/data/general/npcs/orc-grushnak.lua @@ -66,6 +66,7 @@ newEntity{ base = "BASE_NPC_ORC_GRUSHNAK", [Talents.T_RUSH]=3, [Talents.T_SHIELD_PUMMEL]=3, [Talents.T_OVERPOWER]=3, + [Talents.T_DISARM]=3, }, } diff --git a/game/modules/tome/data/general/npcs/skeleton.lua b/game/modules/tome/data/general/npcs/skeleton.lua index 686018b3ce295b6a5c9e99c05d91af2bca2fd0d1..e45a07252a8163b2d7ff4bea84b81163b6739053 100644 --- a/game/modules/tome/data/general/npcs/skeleton.lua +++ b/game/modules/tome/data/general/npcs/skeleton.lua @@ -123,6 +123,7 @@ newEntity{ base = "BASE_NPC_SKELETON", [Talents.T_SHIELD_PUMMEL]=1, [Talents.T_RIPOSTE]=3, [Talents.T_OVERPOWER]=1, + [Talents.T_DISARM]=3, }, resolvers.equip{ {type="weapon", subtype="longsword", autoreq=true}, {type="armor", subtype="shield", autoreq=true}, {type="armor", subtype="heavy", autoreq=true} }, ai_state = { talent_in=1, }, diff --git a/game/modules/tome/data/general/npcs/thieve.lua b/game/modules/tome/data/general/npcs/thieve.lua index 12b75ee254a6e8c0c5bc2793bc52c6a7301a6b39..8c3dc00472781b84e95d0d9976009c90b0ac3dba 100644 --- a/game/modules/tome/data/general/npcs/thieve.lua +++ b/game/modules/tome/data/general/npcs/thieve.lua @@ -79,7 +79,7 @@ newEntity{ base = "BASE_NPC_THIEF", level_range = {3, nil}, exp_worth = 1, rarity = 1, combat_armor = 3, combat_def = 5, - resolvers.talents{ [Talents.T_STEALTH]=2, }, + resolvers.talents{ [Talents.T_STEALTH]=2, [Talents.T_DISARM]=2, }, max_life = resolvers.rngavg(70,90), } @@ -121,7 +121,7 @@ newEntity{ base = "BASE_NPC_THIEF", define_as = "THIEF_ASSASSIN", level_range = {12, nil}, exp_worth = 1, rarity = 3, combat_armor = 3, combat_def = 10, - resolvers.talents{ [Talents.T_STEALTH]=3, [Talents.T_PRECISION]=3, [Talents.T_DUAL_WEAPON_TRAINING]=2, [Talents.T_DUAL_WEAPON_DEFENSE]=2, [Talents.T_DUAL_STRIKE]=1, [Talents.T_SWEEP]=1, [Talents.T_SHADOWSTRIKE]=2, [Talents.T_LETHALITY]=5, }, + resolvers.talents{ [Talents.T_STEALTH]=3, [Talents.T_PRECISION]=3, [Talents.T_DUAL_WEAPON_TRAINING]=2, [Talents.T_DUAL_WEAPON_DEFENSE]=2, [Talents.T_DUAL_STRIKE]=1, [Talents.T_SWEEP]=1, [Talents.T_SHADOWSTRIKE]=2, [Talents.T_LETHALITY]=5, [Talents.T_DISARM]=3, }, max_life = resolvers.rngavg(70,90), resolvers.sustains_at_birth(), diff --git a/game/modules/tome/data/general/npcs/troll.lua b/game/modules/tome/data/general/npcs/troll.lua index 9fb60fe58ee834ac02cdb4fe4e0b03e82a14bcb4..73f9d92cb996e37bfc9ce83e7c549ceef52b1653 100644 --- a/game/modules/tome/data/general/npcs/troll.lua +++ b/game/modules/tome/data/general/npcs/troll.lua @@ -86,7 +86,7 @@ newEntity{ base = "BASE_NPC_TROLL", rarity = 3, max_life = resolvers.rngavg(120,140), combat_armor = 12, combat_def = 4, - resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=3, [Talents.T_KNOCKBACK]=3, [Talents.T_RUSH]=3, }, + resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=3, [Talents.T_KNOCKBACK]=3, [Talents.T_RUSH]=3, [Talents.T_DISARM]=3, }, } newEntity{ base = "BASE_NPC_TROLL", diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua index 84f44964b01d46ac8a96cd4252f57646fe716af5..cdc7fe1d99118b60bc7e2999864e765885294a63 100644 --- a/game/modules/tome/data/talents/misc/npcs.lua +++ b/game/modules/tome/data/talents/misc/npcs.lua @@ -175,6 +175,34 @@ newTalent{ end, } +newTalent{ + name = "Disarm", + type = {"technique/other", 1}, + points = 5, + cooldown = 6, + stamina = 8, + require = { stat = { str=12 }, }, + action = function(self, t) + local tg = {type="hit", range=self:getTalentRange(t)} + local x, y, target = self:getTarget(tg) + if not x or not y or not target then return nil end + if math.floor(core.fov.distance(self.x, self.y, x, y)) > 1 then return nil end + local hit = self:attackTarget(target, nil, self:combatTalentWeaponDamage(t, 0.5, 1), true) + + -- No check to see if the attack hit + if target:checkHit(self:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) and target:canBe("disarm") then + target:setEffect(target.EFF_DISARMED, 2 + self:getTalentLevel(t), {}) + else + game.logSeen(target, "%s resists the blow!", target.name:capitalize()) + end + + return true + end, + info = function(self, t) + return ([[Hits the target doing %d%% damage and try to disarm the target.]]):format(100 * self:combatTalentWeaponDamage(t, 0.5, 1)) + end, +} + newTalent{ name = "Constrict", type = {"technique/other", 1}, diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua index 5f0c3cae92d535aadf44d61a34af72208949094f..21aef45e33bc47972dc5bca4ec02c260c57f7a37 100644 --- a/game/modules/tome/data/timed_effects.lua +++ b/game/modules/tome/data/timed_effects.lua @@ -265,6 +265,23 @@ newEffect{ end, } +newEffect{ + name = "DISARMED", + desc = "Disarmed", + type = "physical", + status = "detrimental", + parameters = {}, + on_gain = function(self, err) return "#Target# is disarmed!", "+Disarmed" end, + on_lose = function(self, err) return "#Target# rearms.", "-Disarmed" end, + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("disarmed", 1) + eff.dur = self:updateEffectDuration(eff.dur, "disarmed") + end, + deactivate = function(self, eff) + self:removeTemporaryValue("disarmed", eff.tmpid) + end, +} + newEffect{ name = "CONSTRICTED", desc = "Constricted", diff --git a/game/modules/tome/data/zones/trollshaws/npcs.lua b/game/modules/tome/data/zones/trollshaws/npcs.lua index 380f5b26a79f652df00e685831197902755c84fb..b465e04eef52651224fc9990268d2a0e40966005 100644 --- a/game/modules/tome/data/zones/trollshaws/npcs.lua +++ b/game/modules/tome/data/zones/trollshaws/npcs.lua @@ -53,7 +53,9 @@ newEntity{ define_as = "TROLL_BILL", drops = resolvers.drops{chance=100, nb=3, {ego_chance=100} }, resolvers.talents{ - [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=2, [Talents.T_KNOCKBACK]=1, + [Talents.T_STUN]=2, + [Talents.T_KNOCKBACK]=1, + [Talents.T_DISARM]=3, }, autolevel = "warrior",