So, like the title suggests, I'm working on a spell that teleports the party a short distance in the direction they're facing. It shouldn't function exactly like a teleport, because I want them to be stopped by walls/doors, but I don't want it to be stopped by monsters. The idea is to give some more spells to a kind of "support mage", so moving through monsters is pretty important to the concept.
The problem is, Map:isBlocked() and Map:isObstacle() both return true for tiles with a monster on it (I really don't know what the difference is between these functions). checkLineofFire() (which is necessary to detect doors) also catches on monsters (as you would expect), but checkLineOfSight() DOESN'T catch on a bunch of things, including trees.
I've tried coding my own checkLineOfFire(), but I really don't know how that's done, because I can't figure out how to access component lists and I'm not even sure how I would check what kind of components an entity held even if I could access them dynamically.
So, to reiterate, the spell should check some number of tiles in front of the party based on the direction they're facing. If it finds any kind of obstacle besides a monster, it should stop and try to teleport the party to the tile farthest before the obstacle, otherwise it moves them to the farthest checked tile. Some checks to stop the party from teleporting on top of a monster should also be done (no free tele-frags).
Does anyone have any ideas how, really, any of this could be done? It really seems like a custom checkLineOfFire() is the key, but maybe I'm missing something far simpler?
Help with teleport spell?
-
- Posts: 168
- Joined: Thu Oct 30, 2014 1:56 am
Re: Help with teleport spell?
I just started working on my own teleport spell. My plan is to use a projectile that teleports the party to the impact site. If you want it to teleport through monsters, you could set the projectile to ignore monsters.
Re: Help with teleport spell?
IIRC in Grimrock 1 this was accomplished by creating a spawner and trying to spawn a monster from it. If it succeeded, that meant the square was clear, so you'd delete the resulting monster and teleport the party there. If it failed, that meant there was something in the way.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
-
- Posts: 168
- Joined: Thu Oct 30, 2014 1:56 am
Re: Help with teleport spell?
Here is what I have so far.
Script Entity in dungeon named "script_teleport"
spells.lua
Everything works except for one case I've found so far. If your projectile hits a monster, it correctly teleports you in front of it, but if the monster is moving towards you, you will end up teleporting behind it due to the logic of the script. What happens is when you hit a monster moving towards you, the hit registers on the tile it is leaving and that tile is not flagged as an obstacle anymore, so you end up being teleported behind it. What I need to do is put some kind of check like:
if entity.monster:isMoving() then
--fizzle spell
end
However, the entity can be anything and the game doesn't like you to call components that don't exist. So if you shoot the spell at a door, the game will crash.
Otherwise, casting the spell sends a little ball of light that teleports you to the tile it lands on. There are checks to make sure you don't end up inside a blocked tile. The script tries to move you one space back from where the teleport lands if it is blocked(which always happens when you hit a monster). If for somereason that space becomes blocked too, then the spell fizzles. The point blank spell always fizzles.
EDITED updated with improved script
Script Entity in dungeon named "script_teleport"
Code: Select all
function partyteleport(self, what, entity)
local x = self.go.x
local y = self.go.y
local facing = party.facing
local elevation = self.go.elevation
local level = self.go.level
local movingmonster = false
local pfacing = self.go.facing
local partyblock = false
if entity ~= nil then
if entity:getComponent("monster") then
if entity.monster:isMoving() then
movingmonster = true
end
end
end
if party.x == x and party.y == y and party.elevation == elevation and party.level == level then
playSound("spell_fizzle")
else
if party.map:isObstacle(x, y, elevation) or party.map:isBlocked(x, y, elevation) then
if pfacing == 0 then
y = y + 1
elseif pfacing == 1 then
x = x - 1
elseif pfacing == 2 then
y = y - 1
elseif pfacing == 3 then
x = x + 1
end
if party.map:isObstacle(x, y, elevation) or party.map:isBlocked(x, y, elevation) then
playSound("spell_fizzle")
elseif party.x == x and party.y == y and party.elevation == elevation and party.level == level then
playSound("spell_fizzle")
else
party:setPosition(x, y, facing, elevation, level)
spawn("teleportation_effect",level,x,y,facing,elevation)
end
else
if movingmonster == true then
if pfacing == 0 then
y = y + 1
elseif pfacing == 1 then
x = x - 1
elseif pfacing == 2 then
y = y - 1
elseif pfacing == 3 then
x = x + 1
end
if party.x == x and party.y == y and party.elevation == elevation and party.level == level then
partyblock = true
end
if party.map:isObstacle(x, y, elevation) or party.map:isBlocked(x, y, elevation) and partyblock == false then
if pfacing == 0 then
y = y + 1
elseif pfacing == 1 then
x = x - 1
elseif pfacing == 2 then
y = y - 1
elseif pfacing == 3 then
x = x + 1
end
if party.x == x and party.y == y and party.elevation == elevation and party.level == level then
playSound("spell_fizzle")
else
if partyblock == true then
if pfacing == 0 then
y = y - 2
elseif pfacing == 1 then
x = x + 2
elseif pfacing == 2 then
y = y + 2
elseif pfacing == 3 then
x = x - 2
end
party:setPosition(x, y, facing, elevation, level)
spawn("teleportation_effect",level,x,y,facing,elevation)
else
party:setPosition(x, y, facing, elevation, level)
spawn("teleportation_effect",level,x,y,facing,elevation)
end
end
else
if pfacing == 0 then
y = y - 1
elseif pfacing == 1 then
x = x + 1
elseif pfacing == 2 then
y = y + 1
elseif pfacing == 3 then
x = x - 1
end
party:setPosition(x, y, facing, elevation, level)
spawn("teleportation_effect",level,x,y,facing,elevation)
end
else
party:setPosition(x, y, facing, elevation, level)
spawn("teleportation_effect",level,x,y,facing,elevation)
end
end
end
end
Code: Select all
defineSpell{
name = "teleport_spell",
uiName = "Teleport",
skill = "air_magic",
requirements = {"air_magic", 3, "concentration", 3},
gesture = 1478963,
manaCost = 50,
icon = 14,
spellIcon = 13,
description = "Teleport the party a short distance",
onCast = function(champion, x, y, direction, elevation, skillLevel)
local s = spawn("open_door",party.level,party.x,party.y,party.facing,party.elevation)
s.projectile:setIgnoreEntity(party)
s.projectile:setVelocity(15)
s.projectile:addConnector("onProjectileHit", "script_teleport", "partyteleport")
end,
}
if entity.monster:isMoving() then
--fizzle spell
end
However, the entity can be anything and the game doesn't like you to call components that don't exist. So if you shoot the spell at a door, the game will crash.
Otherwise, casting the spell sends a little ball of light that teleports you to the tile it lands on. There are checks to make sure you don't end up inside a blocked tile. The script tries to move you one space back from where the teleport lands if it is blocked(which always happens when you hit a monster). If for somereason that space becomes blocked too, then the spell fizzles. The point blank spell always fizzles.
EDITED updated with improved script
Last edited by GoldenShadowGS on Sun Nov 30, 2014 6:56 am, edited 2 times in total.
-
- Posts: 168
- Joined: Thu Oct 30, 2014 1:56 am
Re: Help with teleport spell?
Also, does anyone know how I can avoid needing to split the script into two sections. I don't know else to write the part with the onProjectileHit connector.
-
- Posts: 168
- Joined: Thu Oct 30, 2014 1:56 am
Re: Help with teleport spell?
I finally got it working as I initially intended. No teleporting behind enemies walking towards you, you can teleport right next to enemies walking away from you.
Updated above post with new script.
Updated above post with new script.