1. The rescue script. Create a script entity in your dungeon and name it "rescue_script" include the following code in it:
SpoilerShow
cells = {0,0,0,0,0}
prisonerLocations = {{5,10}, {11,14}, {11,18}, {13,24}, {3,24}} --these are custom to your own dungeon
prisonerFacings = {0,0,2,0,1}
cellDoorLocations = {{4, 11},{13,16},{13,19},{12, 21},{4, 21}} --these are custom to your own dungeon
function clearCell()
local i = 1
while i < 6 do
if prisonerLocations[1] == party.x and prisonerLocations[2] == party.y then
cells = 0
--print("cell cleared.")
end
i = i + 1
end
end
function sendToPrison()
local myNum = math.random(1, 5)
while cells[myNum] == 1 do
myNum = math.random(1, 5)
end
--print("sendToPrison(): area: "..myNum.."")
cells[myNum] = 1
--shootProjectile(projectile, level, x, y, direction, speed, gravity, velocityUp, offsetX, offsetY, offsetZ, attackPower, ignoreEntity, fragile)
shootProjectile("rescue_icon", 6, prisonerLocations[myNum][1], prisonerLocations[myNum][2], prisonerFacings[myNum], 0, 0, 0, 0, 0, 0, 0, party, true)
local doors = entitiesAt(6, cellDoorLocations[myNum][1], cellDoorLocations[myNum][2])
for i in doors do
if i.name == "prison_door_portcullis" then
i:close()
end
end
end
function notifyRescuePartyMember(sender)
--print("party member rescued")
playSound("level_up")
clearCell()
local i = 1
while i <= 4 do
local champion = party:getChampion(i)
if champion:getEnabled() == false then
champion:setEnabled(true)
champion:setStat("health", champion:getStatMax("health") / 2)
--champion:setStat("health", 0)
hudPrint(""..champion:getName().." has joined the party.")
doRandomRescueChatter(champion)
return
end
i = i + 1
end
end
function notifyChampionCaptured(sender, ordinal)
local utils = findEntity("utils")
--print("notifyChampionCaptured: "..ordinal.."")
local champion = getChampionFromOrdinal(ordinal)
if champion then
hudPrint(""..champion:getName().." has been captured.")
champion:setEnabled(false)
sendToPrison()
end
end
function doRandomRescueChatter(champion)
local c = party:getChampion(math.random(1,4))
while c:getEnabled() == false or c == champion or c:isAlive() == false do
c = party:getChampion(math.random(1,4))
end
local myNum = math.random(1,4)
if myNum == 1 then
hudPrint(""..champion:getName()..": Thank you, my friends!\n"..c:getName()..": Welcome back!")
elseif myNum == 2 then
hudPrint(""..c:getName()..": Are you alright?\n"..champion:getName()..": I'm better now that you are here!")
elseif myNum == 3 then
hudPrint(""..champion:getName()..": I hope I didn't miss anything. Let us continue...")
elseif myNum == 4 then
hudPrint(""..champion:getName()..": You came back for me!\n"..c:getName()..": You would do the same for us, "..champion:getName()..". Now let's move out!")
end
end
function getChampionFromOrdinal(ord)
local i = 1
while i <= 4 do
local champion = party:getChampion(i)
if champion:getOrdinal() == ord then
return champion
end
i = i + 1
end
end
prisonerLocations = {{5,10}, {11,14}, {11,18}, {13,24}, {3,24}} --these are custom to your own dungeon
prisonerFacings = {0,0,2,0,1}
cellDoorLocations = {{4, 11},{13,16},{13,19},{12, 21},{4, 21}} --these are custom to your own dungeon
function clearCell()
local i = 1
while i < 6 do
if prisonerLocations[1] == party.x and prisonerLocations[2] == party.y then
cells = 0
--print("cell cleared.")
end
i = i + 1
end
end
function sendToPrison()
local myNum = math.random(1, 5)
while cells[myNum] == 1 do
myNum = math.random(1, 5)
end
--print("sendToPrison(): area: "..myNum.."")
cells[myNum] = 1
--shootProjectile(projectile, level, x, y, direction, speed, gravity, velocityUp, offsetX, offsetY, offsetZ, attackPower, ignoreEntity, fragile)
shootProjectile("rescue_icon", 6, prisonerLocations[myNum][1], prisonerLocations[myNum][2], prisonerFacings[myNum], 0, 0, 0, 0, 0, 0, 0, party, true)
local doors = entitiesAt(6, cellDoorLocations[myNum][1], cellDoorLocations[myNum][2])
for i in doors do
if i.name == "prison_door_portcullis" then
i:close()
end
end
end
function notifyRescuePartyMember(sender)
--print("party member rescued")
playSound("level_up")
clearCell()
local i = 1
while i <= 4 do
local champion = party:getChampion(i)
if champion:getEnabled() == false then
champion:setEnabled(true)
champion:setStat("health", champion:getStatMax("health") / 2)
--champion:setStat("health", 0)
hudPrint(""..champion:getName().." has joined the party.")
doRandomRescueChatter(champion)
return
end
i = i + 1
end
end
function notifyChampionCaptured(sender, ordinal)
local utils = findEntity("utils")
--print("notifyChampionCaptured: "..ordinal.."")
local champion = getChampionFromOrdinal(ordinal)
if champion then
hudPrint(""..champion:getName().." has been captured.")
champion:setEnabled(false)
sendToPrison()
end
end
function doRandomRescueChatter(champion)
local c = party:getChampion(math.random(1,4))
while c:getEnabled() == false or c == champion or c:isAlive() == false do
c = party:getChampion(math.random(1,4))
end
local myNum = math.random(1,4)
if myNum == 1 then
hudPrint(""..champion:getName()..": Thank you, my friends!\n"..c:getName()..": Welcome back!")
elseif myNum == 2 then
hudPrint(""..c:getName()..": Are you alright?\n"..champion:getName()..": I'm better now that you are here!")
elseif myNum == 3 then
hudPrint(""..champion:getName()..": I hope I didn't miss anything. Let us continue...")
elseif myNum == 4 then
hudPrint(""..champion:getName()..": You came back for me!\n"..c:getName()..": You would do the same for us, "..champion:getName()..". Now let's move out!")
end
end
function getChampionFromOrdinal(ord)
local i = 1
while i <= 4 do
local champion = party:getChampion(i)
if champion:getOrdinal() == ord then
return champion
end
i = i + 1
end
end
2. A Custom party, with a couple hooks in it. This could be called MyCustomParty.lua. Make sure you include this in your init.lua script as well.
SpoilerShow
cloneObject{
name = "party",
baseObject = "party",
onProjectileHit = function(champion, projectile, amount)
if projectile.name == "rescue_icon" then
local rescue_script = findEntity("rescue_script")
if rescue_script then
rescue_script:notifyRescuePartyMember()
end
return false
end
return true
end,
onDie = function (champion)
local rescue_script = findEntity("rescue_script")
if rescue_script then
local o = champion:getOrdinal()
rescue_script:notifyChampionCaptured(o)
end
return true
end,
}
name = "party",
baseObject = "party",
onProjectileHit = function(champion, projectile, amount)
if projectile.name == "rescue_icon" then
local rescue_script = findEntity("rescue_script")
if rescue_script then
rescue_script:notifyRescuePartyMember()
end
return false
end
return true
end,
onDie = function (champion)
local rescue_script = findEntity("rescue_script")
if rescue_script then
local o = champion:getOrdinal()
rescue_script:notifyChampionCaptured(o)
end
return true
end,
}
3. A custom object representing the captured party member. This is a 3D mesh, but it can be a spinning icon with a question mark on it if you like.
Make sure you define this "rescue_icon" on your items.lua file:
SpoilerShow
defineObject{
name = "rescue_icon",
class = "Item",
uiName = "Rescue Icon",
--gfxAtlas = "my_icons_icons.tga",
--gfxIndex = 3,
castShadow = true,
model = "mod_assets/models/rescue_icon.fbx",
weight = 0.1,
projectileRotationSpeed = 0,
}
name = "rescue_icon",
class = "Item",
uiName = "Rescue Icon",
--gfxAtlas = "my_icons_icons.tga",
--gfxIndex = 3,
castShadow = true,
model = "mod_assets/models/rescue_icon.fbx",
weight = 0.1,
projectileRotationSpeed = 0,
}
Here is a link to a video of the script in action, as well as some commentary on the code:
http://youtu.be/PFQevJZvgTU
As always, comments and questions are welcome and encouraged. Enjoy!