Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
-- Skirmisher, a class for Tales of Maj'Eyal 1.1.5
--
-- 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/>.
local sling_equipped = function(self, silent)
if not self:hasArcheryWeapon("sling") then
if not silent then
game.logPlayer(self, "You must wield a sling!")
end
return false
end
return true
end
-- Currently just a copy of Sling Mastery.
newTalent {
short_name = "SKIRMISHER_SLING_SUPREMACY",
name = "Sling Supremacy",
image = "talents/sling_mastery.png",
type = {"technique/skirmisher-slings", 1},
points = 5,
require = { stat = { dex=function(level) return 12 + level * 6 end }, },
mode = "passive",
getDamage = function(self, t) return self:getTalentLevel(t) * 10 end,
getPercentInc = function(self, t) return math.sqrt(self:getTalentLevel(t) / 5) / 2 end,
ammo_mastery_reload = function(self, t)
end,
passives = function(self, t, p)
self:talentTemporaryValue(p, 'ammo_mastery_reload', t.ammo_mastery_reload(self, t))
end,
info = function(self, t)
local damage = t.getDamage(self, t)
local inc = t.getPercentInc(self, t)
local reloads = t.ammo_mastery_reload(self, t)
return ([[Increases Physical Power by %d and increases weapon damage by %d%% when using slings.
Also, increases your reload rate by %d.]]):format(damage, inc * 100, reloads)
end,
}
newTalent {
short_name = "SKIRMISHER_SWIFT_SHOT",
name = "Swift Shot",
type = {"technique/skirmisher-slings", 2},
require = techs_dex_req2,
points = 5,
no_energy = "fake",
random_ego = "attack",
tactical = {ATTACK = {weapon = 2}},
range = archery_range,
cooldown = 5,
on_pre_use = function(self, t, silent) return sling_equipped(self, silent) end,
getDamage = function(self, t)
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
end,
callbackOnMove = function(self, t, moved, force, ox, oy)
local cooldown = self.talents_cd[t.id] or 0
if cooldown > 0 then
self.talents_cd[t.id] = math.max(cooldown - 1, 0)
end
end,
action = function(self, t)
local old_speed = self.combat_physspeed
self.combat_physspeed = old_speed * 2
local targets = self:archeryAcquireTargets(nil, {one_shot=true})
if not targets then
self.combat_physspeed = old_speed
return
end
self:archeryShoot(targets, t, nil, {mult=t.getDamage(self, t)})
-- Cooldown Hurricane Shot by 1.
local hurricane_cd = self.talents_cd["T_SKIRMISHER_HURRICANE_SHOT"]
if hurricane_cd then
self.talents_cd["T_SKIRMISHER_HURRICANE_SHOT"] = math.max(0, hurricane_cd - 1)
end
self.combat_physspeed = old_speed
return true
end,
info = function(self, t)
return ([[Fire off a quick sling bullet for %d%% damage, at double your normal attack speed. Moving lowers the cooldown by 1.]])
:format(t.getDamage(self, t) * 100)
end,
}
newTalent {
short_name = "SKIRMISHER_HURRICANE_SHOT",
name = "Hurricane Shot",
type = {"technique/skirmisher-slings", 3},
require = techs_dex_req3,
points = 5,
no_energy = "fake",
random_ego = "attack",
tactical = {ATTACKALL = {weapon = 3}},
range = 0,
radius = archery_range,
cooldown = 7,
target = function(self, t)
return {
type = "cone",
range = self:getTalentRange(t),
radius = self:getTalentRadius(t),
selffire = false,
talent = t,
--cone_angle = 50, -- degrees
}
end,
on_pre_use = function(self, t, silent) return sling_equipped(self, silent) end,
damage_multiplier = function(self, t)
end,
-- Maximum number of shots fired.
limit_shots = function(self, t)
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
end,
action = function(self, t)
-- Get list of possible targets, possibly doubled.
local double = self:getTalentLevel(t) >= 3
local tg = self:getTalentTarget(t)
local x, y = self:getTarget(tg)
if not x or not y then return end
local targets = {}
local add_target = function(x, y)
local target = game.level.map(x, y, game.level.map.ACTOR)
if target and self:reactionToward(target) < 0 and self:canSee(target) then
targets[#targets + 1] = target
if double then targets[#targets + 1] = target end
end
end
self:project(tg, x, y, add_target)
if #targets == 0 then return end
table.shuffle(targets)
-- Fire each shot individually.
local old_target_forced = game.target.forced
local limit_shots = t.limit_shots(self, t)
local shot_params_base = {mult = t.damage_multiplier(self, t), phasing = true}
local fired = nil -- If we've fired at least one shot.
for i = 1, math.min(limit_shots, #targets) do
local target = targets[i]
game.target.forced = {target.x, target.y, target}
local targets = self:archeryAcquireTargets({type = "hit", speed = 200}, {one_shot=true, no_energy = fired})
if targets then
local params = table.clone(shot_params_base)
local target = targets.dual and targets.main[1] or targets[1]
params.phase_target = game.level.map(target.x, target.y, game.level.map.ACTOR)
self:archeryShoot(targets, t, {type = "hit", speed = 200}, params)
fired = true
else
-- If no target that means we're out of ammo.
break
end
end
game.target.forced = old_target_forced
return fired
end,
info = function(self, t)
return ([[Take aim and unload up to %d shots for %d%% weapon damage each against random enemies inside a cone. Each enemy can only be hit once (twice for talent level 3 and higher). Using Swift Shot lowers the cooldown by 1.]])
:format(t.limit_shots(self, t),
t.damage_multiplier(self, t) * 100)
end,
}
-- The cost on this is extreme because its a completely ridiculous talent
-- We don't have any other talents like this, really, that are incredibly hard to use for much of anything until late. Should be interesting.
newTalent {
short_name = "SKIRMISHER_BOMBARDMENT",
name = "Bombardment",
type = {"technique/skirmisher-slings", 4},
require = techs_dex_req4,
points = 5,
mode = "sustained",
no_energy = true,
tactical = { BUFF = 2 },
on_pre_use = function(self, t, silent) return sling_equipped(self, silent) end,
cooldown = function(self, t)
end,
shot_stamina = function(self, t)
return 25 * (1 + self:combatFatigue() * 0.01)
end,
damage_multiplier = function(self, t)
end,
activate = function(self, t) return {} end,
deactivate = function(self, t, p) return true end,
info = function(self, t)
return ([[While activated, your basic Shot talent now fires %d sling bullets, each dealing %d%% Ranged damage, at a cost of %d Stamina per attack.]])
:format(t.bullet_count(self, t), t.damage_multiplier(self, t) * 100, t.shot_stamina(self, t))
end,
}