Skip to content
Snippets Groups Projects
Commit 5be5b1e1 authored by dg's avatar dg
Browse files

Prevent temporary terrains from overriding one an other or "loosing" the default terrain

git-svn-id: http://svn.net-core.org/repos/t-engine4@5453 51575b47-30f0-44d4-a5cc-537603b46e54
parent 3f1ba077
No related branches found
No related tags found
No related merge requests found
Showing
with 120 additions and 159 deletions
......@@ -38,7 +38,12 @@ I cannot stay. I still have much to do. But take this-- it should help you.
local g = game.zone:makeEntityByName(game.level, "terrain", "RIFT")
g.change_level = 3
g.change_zone = "daikara"
game.zone:addEntity(game.level, g, "terrain", player.x, player.y)
local oe = game.level.map(player.x, player.y, engine.Map.TERRAIN)
if oe:attr("temporary") and oe.old_feat then
oe.old_feat = g
else
game.zone:addEntity(game.level, g, "terrain", player.x, player.y)
end
end},
}
}
......
......@@ -85,8 +85,13 @@ start_ambush = function(self, who)
game.logPlayer(self, "#VIOLET#You wake up after a few hours, surprised to be alive, but the staff is gone!")
game.logPlayer(self, "#VIOLET#Go at once to Last Hope to report those events!")
game.level.map(self.x, self.y, game.level.map.TERRAIN, game.zone.grid_list.GRASS_UP_WILDERNESS)
local oe = game.level.map(self.x, self.y, engine.Map.TERRAIN)
if oe:attr("temporary") and oe.old_feat then
oe.old_feat = game.level.map(self.x, self.y, game.level.map.TERRAIN, game.zone.grid_list.GRASS_UP_WILDERNESS)
else
game.level.map(self.x, self.y, game.level.map.TERRAIN, game.zone.grid_list.GRASS_UP_WILDERNESS)
end
self:setQuestStatus("staff-absorption", engine.Quest.COMPLETED, "ambush-finish")
end
......@@ -102,7 +107,12 @@ killed_ukruk = function(self, who)
game.logPlayer(self, "#VIOLET#You are surprised to still be alive.")
game.logPlayer(self, "#VIOLET#Go at once to Last Hope to report those events!")
game.level.map(who.x, who.y, game.level.map.TERRAIN, game.zone.grid_list.GRASS_UP_WILDERNESS)
local oe = game.level.map(who.x, who.y, engine.Map.TERRAIN)
if oe:attr("temporary") and oe.old_feat then
oe.old_feat = game.level.map(who.x, who.y, game.level.map.TERRAIN, game.zone.grid_list.GRASS_UP_WILDERNESS)
else
game.level.map(who.x, who.y, game.level.map.TERRAIN, game.zone.grid_list.GRASS_UP_WILDERNESS)
end
who:setQuestStatus("staff-absorption", engine.Quest.COMPLETED, "survived-ukruk")
end
......@@ -102,27 +102,18 @@ newTalent{
self:unlearnTalent(self.T_JUMPGATE_TELEPORT)
end,
activate = function(self, t)
local terrain = game.level.map(game.player.x, game.player.y, engine.Map.TERRAIN)
local jumpgate = mod.class.Object.new(terrain)
-- Force the tile to be remembered
-- jumpgate.always_remember = true
jumpgate.old_feat = terrain
local jumpgate_overlay = engine.Entity.new{
image = "terrain/wormhole.png",
local oe = game.level.map(self.x, self.y, engine.Map.TERRAIN)
if not oe or oe:attr("temporary") then return false end
local e = mod.class.Object.new{
old_feat = oe, type = oe.type, subtype = oe.subtype,
name = "jumpgate", image = oe.image, add_mos = {{image = "terrain/wormhole.png"}},
display = '&', color=colors.PURPLE,
display_on_seen = true,
display_on_remember = true,
temporary = 1, -- This prevents overlapping of terrain changing effects; as this talent is a sustain it does nothing else
}
if not jumpgate.add_displays then
jumpgate.add_displays = {jumpgate_overlay}
else
table.append(jumpgate.add_displays, jumpgate_overlay)
end
game.level.map(game.player.x, game.player.y, engine.Map.TERRAIN, jumpgate)
game.level.map(game.player.x, game.player.y, engine.Map.TERRAIN, e)
local ret = {
jumpgate = jumpgate,
jumpgate_x = game.player.x,
jumpgate_y = game.player.y,
jumpgate = e, jumpgate_x = game.player.x, jumpgate_y = game.player.y,
jumpgate_level = game.zone.short_name .. "-" .. game.level.level,
particle = self:addParticles(Particles.new("time_shield", 1))
}
......@@ -138,6 +129,7 @@ newTalent{
local jumpgate_teleport = self:getTalentFromId(self.T_JUMPGATE_TELEPORT)
local range = jumpgate_teleport.getRange(self, jumpgate_teleport)
return ([[Create a shadow jumpgate at your location. As long as you sustain this spell you can use 'Jumpgate: Teleport' to instantly travel to the jumpgate as long as you are within %d tiles of it.
Note that stairs underneath the jumpgate will be unusable while the spell is sustained and you may need to cancel it in order to leave certain locations.
At talent level 4 you learn to create and sustain a second jumpgate.]]):format(range)
end,
}
......@@ -291,27 +283,18 @@ newTalent{
end
end,
activate = function(self, t)
local terrain = game.level.map(game.player.x, game.player.y, engine.Map.TERRAIN)
local jumpgate2 = mod.class.Object.new(terrain)
-- Force the tile to be remembered
-- jumpgate2.always_remember = true
jumpgate2.old_feat = terrain
local jumpgate2_overlay = engine.Entity.new{
local oe = game.level.map(self.x, self.y, engine.Map.TERRAIN)
if not oe or oe:attr("temporary") then return false end
local e = mod.class.Object.new{
old_feat = oe, type = oe.type, subtype = oe.subtype,
name = "jumpgate", image = oe.image, add_mos = {{image = "terrain/wormhole.png"}},
display = '&', color=colors.PURPLE,
image = "terrain/wormhole.png",
display_on_seen = true,
display_on_remember = true,
temporary = 1, -- This prevents overlapping of terrain changing effects; as this talent is a sustain it does nothing else
}
if not jumpgate2.add_displays then
jumpgate2.add_displays = {jumpgate2_overlay}
else
table.append(jumpgate2.add_displays, jumpgate2_overlay)
end
game.level.map(game.player.x, game.player.y, engine.Map.TERRAIN, jumpgate2)
game.level.map(game.player.x, game.player.y, engine.Map.TERRAIN, e)
local ret = {
jumpgate2 = jumpgate2,
jumpgate2_x = game.player.x,
jumpgate2_y = game.player.y,
jumpgate2 = e, jumpgate2_x = game.player.x, jumpgate2_y = game.player.y,
jumpgate2_level = game.zone.short_name .. "-" .. game.level.level,
particle = self:addParticles(Particles.new("time_shield", 1))
}
......
......@@ -220,7 +220,7 @@ newTalent{
triggered = function(self, x, y, who)
if who == self.summoned_by or who:checkHit(self.check_hit, who:combatSpellResist(), 0, 95, 15) and who:canBe("teleport") then
-- since we're using a precise teleport we'll look for a free grid first
local tx, ty = util.findFreeGrid(self.dest.x, self.dest.y, 5, true, {[Map.ACTOR]=true})
local tx, ty = util.findFreeGrid(self.dest.x, self.dest.y, 5, true, {[engine.Map.ACTOR]=true})
if tx and ty then
if not who:teleportRandom(tx, ty, 0) then
game.logSeen(who, "%s tries to enter the wormhole but a violent force pushes it back.", who.name:capitalize())
......
......@@ -62,39 +62,33 @@ newTalent{
direct_hit = true,
reflectable = true,
requires_target = true,
target = function(self, t)
return {type="hit", range=self:getTalentRange(t), talent=t}
end,
getDamage = function(self, t) return self:combatTalentSpellDamage(t, 25, 250) * getParadoxModifier(self, pm) end,
getDuration = function(self, t) return 2 + math.ceil(self:getTalentLevel(t) / 2 * getParadoxModifier(self, pm)) end,
action = function(self, t)
local tg = {type="hit", range=self:getTalentRange(t), talent=t}
local x, y, _ = self:getTarget(tg)
local tg = self:getTalentTarget(t)
local x, y = self:getTarget(tg)
if not x or not y then return nil end
x, y = checkBackfire(self, x, y)
_, x, y = self:canProject(tg, x, y)
local target = x and game.level.map(x, y, engine.Map.ACTOR) or nil
if not target then return nil end
local _ _, x, y = self:canProject(tg, x, y)
local target = game.level.map(x, y, Map.ACTOR)
if not target then return end
local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0))
if not hit then game.logSeen(target, "%s resists!", target.name:capitalize()) return true end
target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)})
self:project(tg, x, y, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t)))
game.level.map:particleEmitter(x, y, 1, "temporal_thrust")
game:playSoundNear(self, "talents/arcane")
-- End it here if we've killed the target or the target is a player
if target.dead or target.player then return true end
-- set up instability
local summoner = self
-- Store the current terrain
local terrain = game.level.map(target.x, target.y, engine.Map.TERRAIN)
-- Store target attributes as needed
local a = {}
a.life = target.life
-- Instability
local temporal_instability = mod.class.Object.new{
old_feat = game.level.map(target.x, target.y, engine.Map.TERRAIN),
name = "temporal instability", type="temporal", subtype="anomaly",
target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)})
-- Replace the target with a temporal instability for a few turns
local oe = game.level.map(target.x, target.y, engine.Map.TERRAIN)
if not oe or oe:attr("temporary") then return true end
local e = mod.class.Object.new{
old_feat = oe, type = oe.type, subtype = oe.subtype,
name = "temporal instability", image = oe.image, add_mos = {{image="object/temporal_instability.png"}},
display = '&', color=colors.LIGHT_BLUE,
temporary = t.getDuration(self, t),
canAct = false,
......@@ -107,33 +101,19 @@ newTalent{
game.level.map(self.target.x, self.target.y, engine.Map.TERRAIN, self.old_feat)
game.level:removeEntity(self)
local mx, my = util.findFreeGrid(self.target.x, self.target.y, 20, true, {[engine.Map.ACTOR]=true})
self.target._rst_full = true
game.zone:addEntity(game.level, self.target, "actor", mx, my)
self.target.life = a.life
end
end,
summoner_gain_exp = true,
summoner = summoner,
}
-- Mixin the old terrain
table.update(temporal_instability, terrain)
-- Now update the display overlay
local overlay = engine.Entity.new{
display = '&', color=colors.LIGHT_BLUE, image="object/temporal_instability.png",
display_on_seen = true,
display_on_remember = true,
summoner_gain_exp = true, summoner = self,
}
if not temporal_instability.add_displays then
temporal_instability.add_displays = {overlay}
else
table.append(temporal_instability.add_displays, overlay)
end
game.logSeen(target, "%s has moved forward in time!", target.name:capitalize())
game.level:removeEntity(target)
game.level:addEntity(temporal_instability)
game.level.map(target.x, target.y, engine.Map.TERRAIN, temporal_instability)
game.level:addEntity(e)
game.level.map(x, y, Map.TERRAIN, e)
game.nicer_tiles:updateAround(game.level, x, y)
game.level.map:updateMap(x, y)
return true
end,
info = function(self, t)
......
......@@ -103,9 +103,11 @@ newTalent{
local _ _, _, _, x, y = self:canProject(tg, x, y)
if game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") then return nil end
local addwall = function(x, y)
self:project(tg, x, y, function(px, py, tg, self)
local oe = game.level.map(px, py, Map.TERRAIN)
if not oe or oe:attr("temporary") or game.level.map:checkAllEntities(px, py, "block_move") then return end
local e = Object.new{
old_feat = game.level.map(x, y, Map.TRAP),
old_feat = oe,
name = "ice wall", image = "npc/iceblock.png",
type = "wall", subtype = "ice",
display = '#', color=colors.LIGHT_BLUE, back_color=colors.BLUE,
......@@ -114,31 +116,26 @@ newTalent{
block_move = true,
block_sight = false,
temporary = 4 + self:getTalentLevel(t),
x = x, y = y,
x =px, y = py,
canAct = false,
act = function(self)
self:useEnergy()
self.temporary = self.temporary - 1
if self.temporary <= 0 then
if self.old_feat then game.level.map(self.x, self.y, engine.Map.TRAP, self.old_feat)
else game.level.map:remove(self.x, self.y, engine.Map.TRAP) end
game.level.map(self.x, self.y, engine.Map.TERRAIN, self.old_feat)
game.level:removeEntity(self)
game.level.map:updateMap(self.x, self.y)
end
end,
knownBy = function() return true end,
canTrigger = function() return false end,
canDisarm = function() return false end,
setKnown = function() end,
summoner_gain_exp = true,
summoner = self,
}
game.level:addEntity(e)
game.level.map(x, y, Map.TRAP, e)
end
self:project(tg, x, y, addwall)
game.level.map:redisplay()
game.level.map(px, py, Map.TERRAIN, e)
-- game.nicer_tiles:updateAround(game.level, px, py)
-- game.level.map:updateMap(px, py)
end)
return true
end,
info = function(self, t)
......
......@@ -734,7 +734,7 @@ newInscription{
end,
}
-- This is mostly a copy of Time Skip .. uuuglly
-- This is mostly a copy of Time Skip :P
newInscription{
name = "Rune of the Rift",
type = {"inscriptions/runes", 1},
......@@ -745,40 +745,38 @@ newInscription{
reflectable = true,
requires_target = true,
range = 4,
target = function(self, t)
return {type="hit", range=self:getTalentRange(t), talent=t}
end,
getDamage = function(self, t) return 150 + self:getWil() * 4 end,
getDuration = function(self, t) return 4 end,
action = function(self, t)
local tg = {type="hit", range=self:getTalentRange(t), talent=t}
local x, y, _ = self:getTarget(tg)
local tg = self:getTalentTarget(t)
local x, y = self:getTarget(tg)
if not x or not y then return nil end
_, x, y = self:canProject(tg, x, y)
local target = x and game.level.map(x, y, engine.Map.ACTOR) or nil
if not target then return nil end
local _ _, x, y = self:canProject(tg, x, y)
local target = game.level.map(x, y, Map.ACTOR)
if not target then return end
local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0))
if not hit then game.logSeen(target, "%s resists!", target.name:capitalize()) return true end
target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)})
self:project(tg, x, y, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t)))
game.level.map:particleEmitter(x, y, 1, "temporal_thrust")
game:playSoundNear(self, "talents/arcane")
-- End it here if we've killed the target or the target is a player
self:incParadox(-60)
if target.dead or target.player then return true end
target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)})
-- set up instability
local summoner = self
-- Store the current terrain
local terrain = game.level.map(target.x, target.y, engine.Map.TERRAIN)
-- Instability
local temporal_instability = mod.class.Object.new{
old_feat = game.level.map(target.x, target.y, engine.Map.TERRAIN),
name = "temporal instability", type="temporal", subtype="anomaly",
-- Replace the target with a temporal instability for a few turns
local oe = game.level.map(target.x, target.y, engine.Map.TERRAIN)
if not oe or oe:attr("temporary") then return true end
local e = mod.class.Object.new{
old_feat = oe, type = oe.type, subtype = oe.subtype,
name = "temporal instability", image = oe.image, add_mos = {{image="object/temporal_instability.png"}},
display = '&', color=colors.LIGHT_BLUE,
temporary = t.getDuration(self, t),
canAct = false,
target = target,
back_life = target.life,
act = function(self)
self:useEnergy()
self.temporary = self.temporary - 1
......@@ -787,35 +785,19 @@ newInscription{
game.level.map(self.target.x, self.target.y, engine.Map.TERRAIN, self.old_feat)
game.level:removeEntity(self)
local mx, my = util.findFreeGrid(self.target.x, self.target.y, 20, true, {[engine.Map.ACTOR]=true})
self.target._rst_full = true
game.zone:addEntity(game.level, self.target, "actor", mx, my)
self.target.life = self.back_life
end
end,
summoner_gain_exp = true,
summoner = summoner,
summoner_gain_exp = true, summoner = self,
}
-- Mixin the old terrain
table.update(temporal_instability, terrain)
-- Now update the display overlay
local overlay = engine.Entity.new{
display = '&', color=colors.LIGHT_BLUE, image="object/temporal_instability.png",
display_on_seen = true,
display_on_remember = true,
}
if not temporal_instability.add_displays then
temporal_instability.add_displays = {overlay}
else
table.append(temporal_instability.add_displays, overlay)
end
game.logSeen(target, "%s has moved forward in time!", target.name:capitalize())
game.level:removeEntity(target)
game.level:addEntity(temporal_instability)
game.level.map(target.x, target.y, engine.Map.TERRAIN, temporal_instability)
self:incParadox(-60)
game.level:addEntity(e)
game.level.map(x, y, Map.TERRAIN, e)
game.nicer_tiles:updateAround(game.level, x, y)
game.level.map:updateMap(x, y)
return true
end,
info = function(self, t)
......
......@@ -1285,7 +1285,7 @@ newTalent{
if game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") then return nil end
local oe = game.level.map(x, y, Map.TERRAIN)
if not oe or oe.is_volcano then return end
if not oe or oe:attr("temporary") then return end
local e = Object.new{
old_feat = oe,
......@@ -1294,7 +1294,6 @@ newTalent{
display = '&', color=colors.LIGHT_RED, back_color=colors.RED,
always_remember = true,
temporary = 4 + self:getTalentLevel(t),
is_volcano = true,
x = x, y = y,
canAct = false,
nb_projs = math.floor(self:getTalentLevel(self.T_VOLCANO)),
......@@ -1729,7 +1728,9 @@ newTalent{
game:playSoundNear(game.player, "talents/fireflash")
for i = x-1, x+1 do for j = y-1, y+1 do
if (core.fov.distance(x, y, i, j) < 1 or rng.percent(40)) and (game.level.map:checkEntity(i, j, engine.Map.TERRAIN, "dig") or game.level.map:checkEntity(i, j, engine.Map.TERRAIN, "grow")) then
local oe = game.level.map(x + i, y + j, Map.TERRAIN)
if oe and not oe:attr("temporary") and
(core.fov.distance(x, y, i, j) < 1 or rng.percent(40)) and (game.level.map:checkEntity(i, j, engine.Map.TERRAIN, "dig") or game.level.map:checkEntity(i, j, engine.Map.TERRAIN, "grow")) then
local g = terrains.LAVA_FLOOR:clone()
g:resolve() g:resolve(nil, true)
g.temporary = 8
......
......@@ -157,10 +157,8 @@ newTalent{
local x, y = self:getTarget(tg)
if not x or not y then return nil end
local _ _, x, y = self:canProject(tg, x, y)
if game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") then return nil end
local oe = game.level.map(x, y, Map.TERRAIN)
if not oe or oe.is_maelstrom then return end
if not oe or oe:attr("temporary") or oe.is_maelstrom or game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") then return nil end
local e = Object.new{
old_feat = oe,
......
......@@ -126,7 +126,7 @@ newTalent{
-- Now build our Barrier
self:project(tg, x, y, function(px, py, tg, self)
local oe = game.level.map(px, py, Map.TERRAIN)
if rng.percent(50) or not oe or oe.is_forgebarrier or game.level.map:checkAllEntities(px, py, "block_move") then return end
if rng.percent(50) or not oe or oe:attr("temporary") or game.level.map:checkAllEntities(px, py, "block_move") then return end
local e = Object.new{
old_feat = oe,
......@@ -140,7 +140,6 @@ newTalent{
block_move = true,
block_sight = true,
temporary = t.getDuration(self, t),
is_forgebarrier = true,
x = px, y = py,
canAct = false,
dam = forge_damage,
......
......@@ -133,13 +133,14 @@ newTalent{
end
for i = -1, 1 do for j = -1, 1 do if game.level.map:isBound(x + i, y + j) then
if not game.level.map:checkAllEntities(x + i, y + j, "block_move") then
local oe = game.level.map(x + i, y + j, Map.TERRAIN)
if oe and not oe:attr("temporary") and not game.level.map:checkAllEntities(x + i, y + j, "block_move") then
-- Ok some explanation, we make a new *OBJECT* because objects can have energy and act
-- it stores the current terrain in "old_feat" and restores it when it expires
-- We CAN set an object as a terrain because they are all entities
local e = Object.new{
old_feat = game.level.map(x + i, y + j, Map.TERRAIN),
old_feat = oe,
name = "summoned wall", image = "terrain/granite_wall1.png",
display = '#', color_r=255, color_g=255, color_b=255, back_color=colors.GREY,
always_remember = true,
......
......@@ -67,7 +67,12 @@ return {
portal_next = function(npc)
local g = game.zone:makeEntityByName(game.level, "terrain", "RIFT")
game.zone:addEntity(game.level, g, "terrain", npc.x, npc.y)
local oe = game.level.map(npc.x, npc.y, engine.Map.TERRAIN)
if oe:attr("temporary") and oe.old_feat then
oe.old_feat = g
else
game.zone:addEntity(game.level, g, "terrain", npc.x, npc.y)
end
end,
background = function(level, x, y, nb_keyframes)
......
......@@ -150,13 +150,13 @@ return {
end,
portal_next = function(npc)
-- Remove any special terrain already there, for example Volcano
local old = game.level.map(npc.x, npc.y, engine.Map.TERRAIN)
if game.level:hasEntity(old) then
game.level:removeEntity(old)
end
local g = game.zone:makeEntityByName(game.level, "terrain", "RIFT")
game.zone:addEntity(game.level, g, "terrain", npc.x, npc.y)
local oe = game.level.map(npc.x, npc.y, engine.Map.TERRAIN)
if oe:attr("temporary") and oe.old_feat then
oe.old_feat = g
else
game.zone:addEntity(game.level, g, "terrain", npc.x, npc.y)
end
end,
background = function(level, x, y, nb_keyframes)
......
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