[Item] Functioning scope
Posted: Mon May 18, 2015 7:56 pm
Hi. While playing a little bit with custom cameras, I created a functioning "scope". In order to have it, do as follows:
a) in item.lua add:
b) in a script_entity named "gui_script", put:
c) put in your dungeon a "new_scope" object; it works by right-clicking on it (i.e., using it). Be careful that it does not check whether you are inside a dungeon or outside, or if the place you are zooming to is "admissible" (the resolution of these problems is left as an exercise to the reader...).
Alois
a) in item.lua add:
Code: Select all
defineObject{
name = "party",
baseObject = "party",
components = {
{
class = "Party",
name = "party",
onDrawGui = function(self,g)
return gui_script.script.onDrawGui(self,g)
end,
},
{
class = "Script",
name = "data",
source = [[
data = {}
function set(self,name,value)
self.data[name] = value
end
function get(self,name)
return self.data[name]
end
]]
}
},
}
defineObject{
name = "scope_camera",
baseObject = "base_item",
components = {
{
class = "Camera",
name = "camera",
enabled = false,
},
},
}
defineObject{
name = "new_scope",
baseObject = "base_item",
components = {
{
class = "Model",
name = "model",
model = "assets/models/items/scope.fbx",
},
{
class = "Item",
name = "item",
weight = 0.7,
uiName = "Scope",
gfxIndex = 336,
description = "A delicate instrument that greatly enhances clarity of sight.\n'q' and 'e' to look left/right\n'w' and 's' to raise/lower\n 'a' and 'd' to zoom in/out.",
},
{
class = "UsableItem",
name = "usableitem",
onUseItem = function(self,champion)
return gui_script.script.onUseItem(self,champion)
end
},
{
class = "Script",
name = "data",
source = [[
data = {active = false}
function set(self,name,value)
self.data[name] = value
end
function get(self,name)
return self.data[name]
end
]]
},
},
}
defineObject{
name = "scope_timer",
baseObject = "timer",
components = {
{
class = "Timer",
name = "timer",
TimerInterval = 1,
DisableSelf = false,
onActivate = function(self)
local count = self.go.data:get("count") + 1
if (count < self.go.data:get("countmax")) then -- increase counter
playSound("click_up")
self.go.data:set("count",count)
else
playSound("click_down")
GameMode.setCamera(nil) -- revert to standard camera
findEntity(party.data:get("camera")):destroy() -- destroy the custom camera
party.data:set("camera",nil) -- tell "data" that there is no camera
GameMode.setGameFlag("DisableMovement",false) -- party can move
GameMode.setGameFlag("DisableMouseLook",false) -- party can mouse-look
self.go:destroy() -- destroy the timer
end
end,
},
{
class = "Script",
name = "data",
source = [[
data = {count = 0, countmax = 15} -- 15 seconds = duration of the scope look
function set(self,name,value)
self.data[name] = value
end
function get(self,name)
return self.data[name]
end
]]
},
}
}
Code: Select all
function onDrawGui(self,g)
if (self.go.data:get("camera")) then
local cam = findEntity(self.go.data:get("camera"))
if g.keyDown("e") then -- turn right
local angles = self.go.data:get("angles")
if (angles > -45) then
cam:setWorldRotationAngles(0,angles-5,0)
self.go.data:set("angles",angles-5)
end
end
if g.keyDown("q") then -- turn left
local angles = self.go.data:get("angles")
if (angles < 45) then
cam:setWorldRotationAngles(0,angles+5,0)
self.go.data:set("angles",angles+5)
end
end
if g.keyDown("w") then -- raise the camera
local offset = cam:getWorldPosition()
local poffset = party:getWorldPosition()
if (math.abs(offset.y - poffset.y) < 6) then
cam:setWorldPosition(vec(offset.x,offset.y+0.5,offset.z))
end
end
if g.keyDown("s") then -- lower the camera
local offset = cam:getWorldPosition()
local poffset = party:getWorldPosition()
if (math.abs(offset.y - poffset.y) > 0.55) then
cam:setWorldPosition(vec(offset.x,offset.y-0.5,offset.z))
end
end
if g.keyDown("d") then -- zoom in
local fov = cam.camera:getFov()
if (fov > 10) then
cam.camera:setFov(fov - 5)
end
end
if g.keyDown("a") then -- zoom out
local fov = cam.camera:getFov()
if (fov < 130) then
cam.camera:setFov(fov + 5)
end
end
end
return true
end
function onUseItem(self,champion)
if (findEntity("timer_" .. self.go.id)) then
-- a timer is already active: scope already in use!
return false
else
-- spawn the timer and the camera
local timer = spawn("scope_timer",party.level,party.x,party.y,party.facing,party.elevation,"timer_" .. self.go.id)
local cam = spawn("scope_camera",party.level,party.x,party.y,party.facing,party.elevation)
-- set the position and the offset of the camera
local dx,dy = getForward(party.facing)
cam:setPosition(party.x+5*dx,party.y+5*dy,party.facing,party.elevation,party.level)
local offset = cam:getWorldPosition()
cam:setWorldPosition(vec(offset.x,offset.y+1.5,offset.z))
-- set camera field of view
cam.camera:setFov(100)
-- disable movement and mouse look
GameMode.setGameFlag("DisableMovement",true)
GameMode.setGameFlag("DisableMouseLook",true)
-- start the custom camera
GameMode.setCamera(cam.camera)
-- tell the party which camera is active
party.data:set("camera",cam.id)
-- and reset its angles
party.data:set("angles",0)
-- "false" to prevent the scope to be "consumed"
return false
end
endAlois