-- CONFIGURABLE PART
local kickTime = 1 -- en minutos, tiempo maximo que durara el juego
local delTime = 15 -- en segundos, tiempo que estara cada wall
local playerWeaps = {
-- color = {v= vertical wall id, h= horizontal wall id, sword = item id}
['green'] = {walls={v=3501, h=3498}, sword=7855},
['blue'] = {walls={v=6733, h=6731}, sword=7764}
}
local pilares = {9779} -- accepted items as pillars in the area
local area = {x1=1027, x2=1001, y1=1039, y2=1013, z=4} -- area limits
local playersInitPos = { -- where they must be to start
[1] = {x = 1032, y = 999, z = 4, stackpos = 253}, -- player 1
[2] = {x = 1034, y = 999, z = 4, stackpos = 253} -- player 2
}
local tpPos = { -- where they will be tp when start
[1] = {x = 1028, y = 1001, z = 4}, -- player 1
[2] = {x = 1038, y = 1013, z = 4} -- player 2
}
-- END OF CONFIGURABLE PART
local players = {}
local walls = {}
for _,w in pairs(playerWeaps) do
table.insert(walls,w.walls.v)
table.insert(walls,w.walls.h)
end
local path = {
[1] = {x=0,y=-1}, -- north
[2] = {x=1,y=0}, -- east
[3] = {x=0,y=1}, -- south
[4] = {x=-1,y=0} -- west
}
local function isNude(cid)
local nude = true
for i=1,10 do
if getPlayerSlotItem(cid, i).itemid ~= 0 then
nude = false
break
end
end
return nude
end
local function isWalkable(pos, creature, proj, pz)-- by Nord
if getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid == 0 then return false end
if getTopCreature(pos).uid > 0 and creature then return false end
if getTileInfo(pos).protection and pz then return false, true end
local n = not proj and 3 or 2
for i = 0, 255 do
pos.stackpos = i
local tile = getTileThingByPos(pos)
if tile.itemid ~= 0 and not isCreature(tile.uid) then
if hasProperty(tile.uid, n) or hasProperty(tile.uid, 7) then
return false
end
end
end
return true
end
local function isAdjacent(pos1, pos2)
return ((pos1.x-pos2.x)==0 and math.abs(pos1.y-pos2.y)==2 and "vertical") or ((pos1.y-pos2.y)==0 and math.abs(pos1.x-pos2.x)==2 and "horizontal") or false
end
local function eliminarWall(pos, itemid)
pos.stackpos = 1
local thing = getThingfromPos(pos)
while thing.uid ~= 0 do
if thing.itemid == itemid then
doRemoveItem(thing.uid)
end
pos.stackpos = pos.stackpos + 1
thing = getThingfromPos(pos)
end
end
local function endGame(winner)
local msg = winner and "You win!" or "Draw!"
for _,pl in pairs(players) do
if isInRange(getCreaturePosition(pl),{x=area.x1,y=area.y1,z=area.z},{x=area.x2,y=area.y2,z=area.z}) then
doPlayerSendTextMessage(pl, MESSAGE_INFO_DESCR, msg)
doSendMagicEffect(getCreaturePosition(pl),10)
doTeleportThing(pl, getTownTemplePosition(getPlayerTown(pl)), TRUE)
doSendMagicEffect(getCreaturePosition(pl),10)
end
end
end
local function checkTrapeds()
for _,pl in pairs(players) do
local pos = getCreaturePosition(pl)
local name = getCreatureName(pl)
local traps = 0
for _,p in pairs(path) do
for i=1,2 do
local checkPos = {x=pos.x+p.x,y=pos.y+p.y,z=pos.z,stackpos = i}
local thing = getThingfromPos(checkPos)
if isInArray(walls,thing.itemid) then
if getItemAttribute(thing.uid, "owner") ~= getCreatureName(pl) then
traps=traps+1
end
end
end
end
if traps == 4 then
doPlayerSendTextMessage(pl, MESSAGE_INFO_DESCR, "You have been traped! You lose!")
doSendMagicEffect(getCreaturePosition(pl),10)
doTeleportThing(pl, getTownTemplePosition(getPlayerTown(pl)), TRUE)
doSendMagicEffect(getCreaturePosition(pl),10)
addEvent(endGame,2*1000,true)
break
end
end
end
local function createWall(weapon, itemid, pos1, pos2)
local dest = {x=pos1.x - ((pos1.x - pos2.x)/2),y=pos1.y - ((pos1.y - pos2.y)/2),z=pos1.z, stackpos = 1}
local thing = getThingfromPos(dest)
local exist = false
while thing.uid ~= 0 do
if thing.itemid == itemid then
exist = true
break
end
dest.stackpos = dest.stackpos + 1
thing = getThingfromPos(dest)
end
if not exist then
dest.stackpos = 253
thing = getThingfromPos(dest)
if thing.itemid > 0 then
for dir,p in pairs(path) do
local pathpos = {x=getCreaturePosition(thing.uid).x+p.x,y=getCreaturePosition(thing.uid).y+p.y,z=getCreaturePosition(thing.uid).z}
if isWalkable(pathpos) and isInRange(pathpos,{x=area.x1,y=area.y1,z=area.z},{x=area.x2,y=area.y2,z=area.z}) then
doMoveCreature(thing.uid, dir-1)
break
end
end
end
local wall = doCreateItem(itemid,1,dest)
addEvent(eliminarWall, delTime*1000, dest, itemid)
doItemSetAttribute(wall, "owner", getItemAttribute(weapon, "owner"))
end
checkTrapeds()
end
function onUse(cid, item, fromPosition, itemEx, toPosition)
-- switch part
if item.itemid == 1945 then
if table.lenght(playerWeaps) ~= table.lenght(playersInitPos) or table.lenght(playersInitPos) ~= table.lenght(tpPos) then
return doPlayerSendCancel(cid,"Call an admin, there's an error in the conf. of the script.") and doSendMagicEffect(getCreaturePosition(cid),CONST_ME_POFF)
and print("Error: galileoPuzzle.lua. 'playerWeaps("..table.lenght(playerWeaps)..")', 'playersInitPos("..table.lenght(playersInitPos)..")' and 'tpPos("..table.lenght(tpPos)..")' arrays must have same number of items.")
end
-- CHECK IF SOME1 INSIDE
for arenax = area.x1, area.x2 do
for arenay = area.y1, area.y2 do
arenapos = {x=arenax, y=arenay, z=area.z, stackpos=253}
arenacreature = getThingfromPos(arenapos)
if arenacreature.itemid > 0 then
return doPlayerSendCancel(cid,"Espera a que la sala esté vacia.") and doSendMagicEffect(getCreaturePosition(cid),CONST_ME_POFF)
end
end
end
players = {}
for _, plpos in pairs (playersInitPos) do
local pl = getThingfromPos(plpos)
if pl.itemid < 1 then
return doPlayerSendCancel(cid,"You need "..#playersInitPos.." players to play this puzzle game.") and doSendMagicEffect(getCreaturePosition(cid),CONST_ME_POFF)
end
if not isNude(pl.uid) then
return doPlayerSendCancel(cid,"All "..#playersInitPos.." players must be nude.") and doSendMagicEffect(getCreaturePosition(cid),CONST_ME_POFF)
end
table.insert(players,pl.uid)
end
local i = 0
for col,it in pairs(playerWeaps) do
i = i+1
local weap = doCreateItemEx(it.sword)
doItemSetAttribute(weap, "colour", col)
doItemSetAttribute(weap, "owner", getCreatureName(players[i]))
doItemSetAttribute(weap, "aid", item.actionid)
doPlayerAddItemEx(players[i], weap)
doTeleportThing(players[i], tpPos[i])
end
-- startTimer()
return true
elseif item.itemid == 1946 then
return doTransformItem(item.uid, 1945)
end
-- end of switch part
if isInArray(pilares,itemEx.itemid) then
local savedPos = getItemAttribute(item.uid, "savedPos")
if savedPos == nil then -- primera vez que se usa, guardamos pos y ya
local pos = ""..toPosition.x..","..toPosition.y..","..toPosition.z..","
doItemSetAttribute(item.uid, "savedPos", pos)
doSendMagicEffect(toPosition,3)
else -- creamos muro (si se puede), y guardamos pos
local pos = {}
for p in savedPos:gmatch("(.-),(.-)") do
table.insert(pos,p)
end
local adjWall = isAdjacent(toPosition,{x=pos[1],y=pos[2],z=pos[3]})
if adjWall then
if adjWall == "horizontal" then
createWall(item.uid, playerWeaps[getItemAttribute(item.uid, "colour")].walls.h,toPosition,{x=pos[1],y=pos[2],z=pos[3]})
elseif adjWall == "vertical" then
createWall(item.uid, playerWeaps[getItemAttribute(item.uid, "colour")].walls.v,toPosition,{x=pos[1],y=pos[2],z=pos[3]})
else
print("Error: This message should not appear! Wall obtained: "..adjWall)
end
end
local pos = ""..toPosition.x..","..toPosition.y..","..toPosition.z..","
doItemSetAttribute(item.uid, "savedPos", pos)
doSendMagicEffect(toPosition,3)
end
elseif isInArray(walls,itemEx.itemid) then -- aun se podria mejorar, en vez de usar itemEx chekar los stackpos
if playerWeaps[getItemAttribute(item.uid, "colour")].walls.v == itemEx.itemid or playerWeaps[getItemAttribute(item.uid, "colour")].walls.h == itemEx.itemid then
doRemoveItem(itemEx.uid)
doSendMagicEffect(toPosition,CONST_ME_POFF)
end
else
return doSendMagicEffect(getCreaturePosition(cid),CONST_ME_POFF)
end
return true
end