Commit b9cb66bd6f15b125e85b8c7c2af264ad2ba96515

Authored by dg
1 parent d7961dd3

skeleton & ghoul player races


git-svn-id: http://svn.net-core.org/repos/t-engine4@554 51575b47-30f0-44d4-a5cc-537603b46e54
... ... @@ -110,10 +110,15 @@ function _M:trigger(x, y, who)
110 110 str = str:gsub("@Target@", tname:capitalize())
111 111 game.logSeen(who, "%s", str)
112 112 end
113   - if self:triggered(x, y, who) then
  113 + local known, del = self:triggered(x, y, who)
  114 + if known then
114 115 self:setKnown(who, true)
115 116 game.level.map:updateMap(x, y)
116 117 end
  118 + if del then
  119 + game.level.map:remove(x, y, Map.TRAP)
  120 + if self.removed then self:removed(x, y, who) end
  121 + end
117 122 end
118 123
119 124 --- When moving on a trap, trigger it
... ...
... ... @@ -357,6 +357,23 @@ function _M:onTakeHit(value, src)
357 357 end
358 358 end
359 359
  360 + if self:attr("damage_shield") then
  361 + -- Absorb damage into the shield
  362 + if value <= self.damage_shield_absorb then
  363 + self.damage_shield_absorb = self.damage_shield_absorb - value
  364 + value = 0
  365 + else
  366 + self.damage_shield_absorb = 0
  367 + value = value - self.damage_shield_absorb
  368 + end
  369 +
  370 + -- If we are at the end of the capacity, release the time shield damage
  371 + if self.damage_shield_absorb <= 0 then
  372 + game.logPlayer(self, "Your shield crumbles under the damage!")
  373 + self:removeEffect(self.EFF_DAMAGE_SHIELD)
  374 + end
  375 + end
  376 +
360 377 if self:attr("displacement_shield") then
361 378 -- Absorb damage into the displacement shield
362 379 if value <= self.displacement_shield and rng.percent(self.displacement_shield_chance) then
... ...
... ... @@ -33,8 +33,14 @@ newBirthDescriptor{
33 33 {
34 34 __ALL__ = "never",
35 35 Ghoul = function() return config.settings.tome.allow_build.undead_ghoul and "allow" or "never" end,
  36 + Skeleton = function() return config.settings.tome.allow_build.undead_skeleton and "allow" or "never" end,
  37 + Vampire = function() return config.settings.tome.allow_build.undead_vampire and "allow" or "never" end,
  38 + Wight = function() return config.settings.tome.allow_build.undead_wight and "allow" or "never" end,
36 39 },
37 40 },
  41 + copy = {
  42 + undead = 1,
  43 + }
38 44 }
39 45
40 46 newBirthDescriptor
... ... @@ -48,6 +54,7 @@ newBirthDescriptor
48 54 "- bleeding immunity",
49 55 "- stun resistance",
50 56 "- fear immunity",
  57 + "- special ghoul talents: ghoulish leap, gnaw and retch",
51 58 "The rotting body of ghouls also forces them to act a bit slower than most creatures.",
52 59 },
53 60 descriptor_choices =
... ... @@ -60,7 +67,7 @@ newBirthDescriptor
60 67 },
61 68 stats = { str=3, con=5, wil=-2, mag=0, dex=1, cun=2 },
62 69 talents_types = {
63   - ["undead/ghoul"]={true, 0.3},
  70 + ["undead/ghoul"]={true, 0.1},
64 71 },
65 72 talents = {
66 73 [ActorTalents.T_GHOUL]=1,
... ... @@ -80,3 +87,47 @@ newBirthDescriptor
80 87 },
81 88 experience = 2,
82 89 }
  90 +
  91 +newBirthDescriptor
  92 +{
  93 + type = "subrace",
  94 + name = "Skeleton",
  95 + desc = {
  96 + "Skeletons are animated bones, undead creatures, both strong and dextrous.",
  97 + "They have access to special skeleton talents and a wide range of undead abilities:",
  98 + "- poison immunity",
  99 + "- bleeding immunity",
  100 + "- fear immunity",
  101 + "- no need to breath",
  102 + "- special skeleton talents: ",
  103 + "The rotting body of ghouls also forces them to act a bit slower than most creatures.",
  104 + },
  105 + descriptor_choices =
  106 + {
  107 + sex =
  108 + {
  109 + __ALL__ = "never",
  110 + Male = "allow",
  111 + },
  112 + },
  113 + stats = { str=3, con=0, wil=0, mag=0, dex=4, cun=0 },
  114 + talents_types = {
  115 + ["undead/skeleton"]={true, 0.1},
  116 + },
  117 + talents = {
  118 + [ActorTalents.T_SKELETON]=1,
  119 + },
  120 + copy = {
  121 + type = "undead", subtype="skeleton",
  122 + default_wilderness = {"wilderness/main", 39, 17},
  123 + starting_zone = "tower-amon-sul",
  124 + starting_quest = "start-dunadan",
  125 + starting_intro = "dwarf",
  126 + life_rating=12,
  127 + poison_immune = 1,
  128 + cut_immune = 1,
  129 + fear_immune = 1,
  130 + no_breath = 1,
  131 + },
  132 + experience = 2,
  133 +}
... ...
... ... @@ -278,6 +278,20 @@ newDamageType{
278 278 end,
279 279 }
280 280
  281 +-- Bleeding damage
  282 +newDamageType{
  283 + name = "bleed", type = "BLEED",
  284 + projector = function(src, x, y, type, dam)
  285 + DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam / 6)
  286 + dam = dam - dam / 6
  287 + local target = game.level.map(x, y, Map.ACTOR)
  288 + if target and target:canBe("cut") then
  289 + -- Set on fire!
  290 + target:setEffect(target.EFF_CUT, 5, {src=src, power=dam / 5})
  291 + end
  292 + end,
  293 +}
  294 +
281 295 -- Slime damage
282 296 newDamageType{
283 297 name = "slime", type = "SLIME",
... ... @@ -404,3 +418,16 @@ newDamageType{
404 418 end
405 419 end,
406 420 }
  421 +
  422 +-- Retch: heal undead; damage living
  423 +newDamageType{
  424 + name = "retch", type = "RETCH",
  425 + projector = function(src, x, y, type, dam)
  426 + local target = game.level.map(x, y, Map.ACTOR)
  427 + if target and target.undead then
  428 + target:heal(dam)
  429 + elseif target then
  430 + DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam)
  431 + end
  432 + end,
  433 +}
... ...
... ... @@ -24,11 +24,15 @@ newTalent{
24 24 require = undeads_req1,
25 25 points = 5,
26 26 on_learn = function(self, t)
  27 + self:incStat(self.STAT_STR, 2)
  28 + self:incStat(self.STAT_CON, 2)
27 29 end,
28 30 on_unlearn = function(self, t)
  31 + self:incStat(self.STAT_STR, -2)
  32 + self:incStat(self.STAT_CON, -2)
29 33 end,
30 34 info = function(self, t)
31   - return ([[Improves your ghoulish body.]]):format()
  35 + return ([[Improves your ghoulish body, increasing strength and constitution by %d.]]):format(2 * self:getTalentLevelRaw(t))
32 36 end,
33 37 }
34 38
... ... @@ -110,13 +114,31 @@ newTalent{
110 114 type = {"undead/ghoul",4},
111 115 require = undeads_req4,
112 116 points = 5,
  117 + cooldown = 25,
113 118 tactical = {
114 119 DEFEND = 10,
  120 + ATTACK = 10,
115 121 },
  122 + range=1,
116 123 action = function(self, t)
  124 + local duration = self:getTalentLevel(t) / 2 + 4
  125 + local radius = 3
  126 + local dam = (2 + self:getCon(8)) * self:getTalentLevel(t)
  127 + local tg = {type="ball", range=self:getTalentRange(t), radius=radius}
  128 + -- Add a lasting map effect
  129 + game.level.map:addEffect(self,
  130 + self.x, self.y, duration,
  131 + DamageType.RETCH, dam,
  132 + radius,
  133 + 5, nil,
  134 + engine.Entity.new{alpha=100, display='', color_br=30, color_bg=180, color_bb=60},
  135 + nil, self:spellFriendlyFire()
  136 + )
  137 + game:playSoundNear(self, "talents/cloud")
117 138 return true
118 139 end,
119 140 info = function(self, t)
120   - return ([[Vomit on the ground aruond you, healing any undeads in the area and damaging others.]])
  141 + return ([[Vomit on the ground aruond you, healing any undeads in the area and damaging others.
  142 + Lasts %d turns and deals %d blight damage.]]):format(self:getTalentLevel(t) / 2 + 4, (2 + self:getCon(8)) * self:getTalentLevel(t))
121 143 end,
122 144 }
... ...
  1 +-- ToME - Tales of Middle-Earth
  2 +-- Copyright (C) 2009, 2010 Nicolas Casalini
  3 +--
  4 +-- This program is free software: you can redistribute it and/or modify
  5 +-- it under the terms of the GNU General Public License as published by
  6 +-- the Free Software Foundation, either version 3 of the License, or
  7 +-- (at your option) any later version.
  8 +--
  9 +-- This program is distributed in the hope that it will be useful,
  10 +-- but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 +-- GNU General Public License for more details.
  13 +--
  14 +-- You should have received a copy of the GNU General Public License
  15 +-- along with this program. If not, see <http://www.gnu.org/licenses/>.
  16 +--
  17 +-- Nicolas Casalini "DarkGod"
  18 +-- darkgod@te4.org
  19 +
  20 +newTalent{
  21 + name = "Skeleton",
  22 + type = {"undead/skeleton", 1},
  23 + mode = "passive",
  24 + require = undeads_req1,
  25 + points = 5,
  26 + on_learn = function(self, t)
  27 + self:incStat(self.STAT_STR, 2)
  28 + self:incStat(self.STAT_DEX, 2)
  29 + end,
  30 + on_unlearn = function(self, t)
  31 + self:incStat(self.STAT_STR, -2)
  32 + self:incStat(self.STAT_DEX, -2)
  33 + end,
  34 + info = function(self, t)
  35 + return ([[Improves your skeletal condition, increasing strength and dexterity by %d.]]):format(2 * self:getTalentLevelRaw(t))
  36 + end,
  37 +}
  38 +
  39 +newTalent{
  40 + name = "Sharp Bones",
  41 + type = {"undead/skeleton", 2},
  42 + require = undeads_req2,
  43 + points = 5,
  44 + cooldown = 15,
  45 + tactical = {
  46 + ATTACK = 10,
  47 + },
  48 + range = 1,
  49 + action = function(self, t)
  50 + local x, y = self.x, self.y
  51 + if game.level.map(x, y, game.level.map.TRAP) then
  52 + game.logPlayer(self, "There is already a trap here!")
  53 + return
  54 + end
  55 +
  56 + local dam = (10 + self:getStr(20)) * self:getTalentLevel(t)
  57 +
  58 + local e = require("mod.class.Trap").new{
  59 + type = "physical", subtype="sharp", id_by_type=true, unided_name = "trap", identified=true,
  60 + name = "sharp bones",
  61 + display = '^', color=colors.ANTIQUE_WHITE,
  62 + triggered = function(self, x, y, who)
  63 + self:project({type="hit",x=x,y=y}, x, y, engine.DamageType.BLEED, dam)
  64 + return true, true
  65 + end,
  66 + summoner_gain_exp = true,
  67 + summoner = self,
  68 + }
  69 + game.zone:addEntity(game.level, e, "trap", x, y)
  70 +
  71 + game:playSoundNear(self, "talents/earth")
  72 + return true
  73 + end,
  74 + info = function(self, t)
  75 + return ([[Lay down some sharpened bones to make a simple trap that will cause anyone stepping on it to bleed for %d damage.]]):
  76 + format((10 + self:getStr(20)) * self:getTalentLevel(t))
  77 + end,
  78 +}
  79 +
  80 +newTalent{
  81 + name = "Bone Armour",
  82 + type = {"undead/skeleton", 3},
  83 + require = undeads_req3,
  84 + points = 5,
  85 + cooldown = 30,
  86 + tactical = {
  87 + DEFEND = 20,
  88 + },
  89 + range = 1,
  90 + action = function(self, t)
  91 + self:setEffect(self.EFF_DAMAGE_SHIELD, 10, {power=(8 + self:getDex(20)) * self:getTalentLevel(t)})
  92 + return true
  93 + end,
  94 + info = function(self, t)
  95 + return ([[Creates a shield of bones absorbing %d damage. Lasts for 10 turns.]]):
  96 + format((5 + self:getDex(20)) * self:getTalentLevel(t))
  97 + end,
  98 +}
  99 +
  100 +newTalent{ short_name = "SKELETON_REASSEMBLE",
  101 + name = "Re-assemble",
  102 + type = {"undead/skeleton",4},
  103 + require = undeads_req4,
  104 + points = 5,
  105 + cooldown = 45,
  106 + tactical = {
  107 + DEFEND = 10,
  108 + },
  109 + range=1,
  110 + action = function(self, t)
  111 + self:heal(self:getTalentLevel(t) * self.level / 2, self)
  112 + game:playSoundNear(self, "talents/heal")
  113 + return true
  114 + end,
  115 + info = function(self, t)
  116 + return ([[Re-position some of your bones, healing yourself for %d.
  117 + At level 5 you will gain the ability to completly re-assemble your body should it be destroyed (can only be used once)]]):
  118 + format(self:getTalentLevel(t) * self.level / 2)
  119 + end,
  120 +}
... ...
... ... @@ -41,3 +41,4 @@ undeads_req5 = {
41 41 }
42 42
43 43 load("/data/talents/undeads/ghoul.lua")
  44 +load("/data/talents/undeads/skeleton.lua")
... ...
... ... @@ -395,6 +395,24 @@ newEffect{
395 395 end,
396 396 }
397 397
  398 +newEffect{
  399 + name = "DAMAGE_SHIELD",
  400 + desc = "Damage Shield",
  401 + type = "magical",
  402 + status = "beneficial",
  403 + parameters = { power=100 },
  404 + on_gain = function(self, err) return "A shield forms around #target#.", "+Shield" end,
  405 + on_lose = function(self, err) return "The shield around #target# crumbles.", "-Shield" end,
  406 + activate = function(self, eff)
  407 + eff.tmpid = self:addTemporaryValue("damage_shield", eff.power)
  408 + --- Warning there can be only one time shield active at once for an actor
  409 + self.damage_shield_absorb = eff.power
  410 + end,
  411 + deactivate = function(self, eff)
  412 + self:removeTemporaryValue("damage_shield", eff.tmpid)
  413 + self.damage_shield_absorb = nil
  414 + end,
  415 +}
398 416
399 417 newEffect{
400 418 name = "TIME_SHIELD",
... ...
... ... @@ -134,6 +134,13 @@ function _M:use()
134 134 self:cleanActor()
135 135 self:restoreRessources()
136 136 self:resurrectBasic()
  137 + elseif act == "skeleton" then
  138 + self.actor:attr("re-assembled", 1)
  139 + game.logPlayer(self.actor, "#YELLOW#Your bones magically come back together. You are once more able to dish pain to your foes!")
  140 +
  141 + self:cleanActor()
  142 + self:restoreRessources()
  143 + self:resurrectBasic()
137 144 end
138 145 end
139 146
... ... @@ -142,6 +149,7 @@ function _M:generateList()
142 149
143 150 if config.settings.tome.cheat then list[#list+1] = {name="Resurrect by cheating", action="cheat"} end
144 151 if self.actor:attr("blood_life") and not self.actor:attr("undead") then list[#list+1] = {name="Resurrect with the Blood of Life", action="blood_life"} end
  152 + if self.actor:getTalentLevelRaw(self.actor.T_SKELETON_REASSEMBLE) >= 5 and not self.actor:attr("re-assembled") then list[#list+1] = {name="Re-assemble your bones ad resurrect (Skeleton ability)", action="skeleton"} end
145 153
146 154 list[#list+1] = {name="Character dump", action="dump"}
147 155 list[#list+1] = {name="Exit to main menu", action="exit"}
... ...
No preview for this file type