Skip to content
Snippets Groups Projects
Commit 72f206f4 authored by dg's avatar dg
Browse files

stealth & such

git-svn-id: http://svn.net-core.org/repos/t-engine4@186 51575b47-30f0-44d4-a5cc-537603b46e54
parent 58afa088
No related branches found
No related tags found
No related merge requests found
Showing
with 116 additions and 10 deletions
......@@ -278,6 +278,12 @@ function _M:postUseTalent(ab, ret)
end
end
-- Cancel stealth!
if ab.id ~= self.T_STEALTH and self:isTalentActive(self.T_STEALTH) then
self:useTalent(self.T_STEALTH)
self.changed = true
end
return true
end
......@@ -300,6 +306,16 @@ function _M:canSee(actor)
-- Blindness means can't see anything
if self:attr("blind") then return false, 0 end
-- Check for stealth. Checks against the target cunning and level
if actor:attr("stealth") and actor ~= self then
local def = self.level / 2 + self:getCun(25)
local hit, chance = self:checkHit(def, actor:attr("stealth") + (actor:attr("inc_stealth") or 0), 0, 100)
print("Stealth", actor:attr("stealth") + (actor:attr("inc_stealth") or 0), "<:>", def, " ===> ", hit, chance)
if not hit then
return false, chance
end
end
-- Check for invisibility. This is a "simple" checkHit between invisible and see_invisible attrs
if actor:attr("invisible") then
-- Special case, 0 see invisible, can NEVER see invisible things
......
......@@ -163,7 +163,7 @@ function _M:display()
-- Display the map and compute FOV for the player if needed
if self.level.map.changed then
self.level.map:fov(self.player.x, self.player.y, 20)
self.level.map:fovLite(self.player.x, self.player.y, self.player.lite)
if self.player.lite > 0 then self.level.map:fovLite(self.player.x, self.player.y, self.player.lite) end
end
self.level.map:display()
......
......@@ -42,6 +42,13 @@ The ToME combat system has the following attributes:
function _M:attackTarget(target, damtype, mult, noenergy)
local speed = nil
-- Cancel stealth early if we are noticed
if self:isTalentActive(self.T_STEALTH) and target:canSee(self) then
self:useTalent(self.T_STEALTH)
self.changed = true
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
......@@ -76,6 +83,12 @@ function _M:attackTarget(target, damtype, mult, noenergy)
self:useEnergy(game.energy_to_act * speed)
self.did_energy = true
end
-- Cancel stealth!
if self:isTalentActive(self.T_STEALTH) then
self:useTalent(self.T_STEALTH)
self.changed = true
end
end
--- Computes a logarithmic chance to hit, opposing chance to hit to chance to miss
......@@ -111,8 +124,10 @@ function _M:attackTargetWith(target, weapon, damtype, mult)
local hitted = false
if self:checkHit(atk, def) then
local dam = dam - math.max(0, armor - apr)
local crit
dam = dam * mult
dam = self:physicalCrit(dam, weapon)
dam, crit = self:physicalCrit(dam, weapon)
game.logSeen(self, "%s performs a critical stike!", self.name:capitalize())
DamageType:get(damtype).projector(self, target.x, target.y, damtype, math.max(0, dam))
hitted = true
else
......@@ -213,20 +228,32 @@ end
--- Computes physical crit for a damage
function _M:physicalCrit(dam, weapon)
if self:isTalentActive(self.T_STEALTH) and self:knowTalent(self.T_SHADOWSTRIKE) then
return dam * (2 + self:getTalentLevel(self.T_SHADOWSTRIKE) / 5), true
end
local chance = self:combatCrit(weapon)
local crit = false
if rng.percent(chance) then
dam = dam * 2
crit = true
end
return dam
return dam, crit
end
--- Computes spell crit for a damage
function _M:spellCrit(dam)
if self:isTalentActive(self.T_STEALTH) and self:knowTalent(self.T_SHADOWSTRIKE) then
return dam * (2 + self:getTalentLevel(self.T_SHADOWSTRIKE) / 5), true
end
local chance = self:combatSpellCrit()
local crit = false
if rng.percent(chance) then
dam = dam * 2
crit = true
end
return dam
return dam, crit
end
--- Computes physical resistance
......
......@@ -73,11 +73,16 @@ newBirthDescriptor{
"Rogues are masters of tricks, they can steal from shops and monsters",
"and lure monsters into deadly traps.",
},
stats = { dex=3, con=1, cun=2, },
stats = { dex=3, wil=1, cun=3, },
talents_types = {
["physical/dualweapon"]=true,
["physical/combat-training"]=true,
["physical/weapon-training"]=true,
["cunning/stealth"]=true,
},
talents_types_mastery = {
["physical/dualweapon"]=0.2,
["cunning/stealth"]=0.3,
},
}
......
load("/data/talents/misc/misc.lua")
load("/data/talents/spells/spells.lua")
load("/data/talents/physical/physical.lua")
load("/data/talents/misc/misc.lua")
load("/data/talents/cunning/cunning.lua")
-- Cunning talents
newTalentType{ type="cunning/stealth", name = "stealth", description = "Allows the user to enter stealth." }
newTalentType{ type="cunning/traps", name = "traps", description = "The knowledge of traps." }
newTalentType{ type="cunning/dirty", name = "dirty fighting", description = "Teaches various talents to criple your foes." }
load("/data/talents/cunning/stealth.lua")
load("/data/talents/cunning/traps.lua")
load("/data/talents/cunning/dirty.lua")
newTalent{
name = "Stealth",
type = {"cunning/stealth", 1},
mode = "sustained",
points = 5,
cooldown = 10,
require = { stat = { cun=12 }, },
activate = function(self, t)
local armor = self:getInven("BODY")[1]
if armor and (armor.subtype == "heavy" or armor.subtype == "massive") then
game.logPlayer(self, "You cannot Stealth with such heavy armour!")
return nil
end
-- Check nearby actors
local grids = core.fov.circle_grids(self.x, self.y, math.floor(10 - self:getTalentLevel(t) * 1.3), true)
for x, yy in pairs(grids) do for y in pairs(yy) do
local actor = game.level.map(x, y, game.level.map.ACTOR)
if actor and actor ~= self and actor:reactionToward(self) < 0 then
game.logPlayer(self, "You cannot Stealth with nearby foes watching!")
return nil
end
end end
return {
stealth = self:addTemporaryValue("stealth", self:getCun(10) * self:getTalentLevel(t)),
lite = self:addTemporaryValue("lite", -100),
}
end,
deactivate = function(self, t, p)
self:removeTemporaryValue("stealth", p.stealth)
self:removeTemporaryValue("lite", p.lite)
return true
end,
info = function(self, t)
return ([[Enters stealth mode, making you harder to detect.
While in stealth mode, light radius is reduced to 0.
There needs to be no foes in sight in a radius of %d around you to enter stealth.]]):format(math.floor(10 - self:getTalentLevel(t) * 1.3))
end,
}
newTalent{
name = "Shadowstrike",
type = {"cunning/stealth", 1},
mode = "passive",
points = 5,
require = { stat = { cun=18 }, },
info = function(self, t)
return ([[When striking from stealth, hits are automatically criticals if the target does not notice you.
Shadowstrikes do %.02f%% more damage than a normal hit.]]):format(math.floor(2 + self:getTalentLevel(t) / 5))
end,
}
......@@ -2,13 +2,11 @@
newTalentType{ type="physical/2hweapon", name = "two handed weapons", description = "Allows the user to be more proficient with two handed weapons." }
newTalentType{ type="physical/dualweapon", name = "dual wielding", description = "Allows the user to be more proficient with dual wielding weapons." }
newTalentType{ type="physical/shield", name = "weapon and shields", description = "Allows the user to be more proficient with shields and one handed weapons." }
newTalentType{ type="physical/dirty", name = "dirty fighting", description = "Teaches various physical talents to criple your foes." }
newTalentType{ type="physical/weapon-training", name = "weapon-training", description = "Grants bonuses to the different weapon types." }
newTalentType{ type="physical/combat-training", name = "combat-training", description = "Teaches to use various armors and improves health." }
load("/data/talents/physical/2hweapon.lua")
load("/data/talents/physical/dualweapon.lua")
load("/data/talents/physical/weaponshield.lua")
load("/data/talents/physical/dirty.lua")
load("/data/talents/physical/weapon-training.lua")
load("/data/talents/physical/combat-training.lua")
......@@ -4,7 +4,7 @@ return {
level_scheme = "player",
max_level = 5,
width = 50, height = 50,
all_remembered = true,
-- all_remembered = true,
-- all_lited = true,
-- persistant = true,
generator = {
......@@ -27,7 +27,7 @@ return {
},
object = {
class = "engine.generator.object.Random",
nb_object = {200, 500},
nb_object = {2, 5},
ood = {chance=5, range={1, 10}},
},
},
......
File added
No preview for this file type
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment