fires the metaphorical hook and moves

<aside> 💡

For prevent hitting the player { ignore = self } need to be used in both case

resulting to castray for weapon, using onUpdate

and for example castRenderingRay for key, needing also onFrame handler.

</aside>

hitting terrain is possible removing or commenting

if result.hitObject == nil then active = 0 return end

also need larger hitting distance, say 300 units, to prevent going trought.

GLOBAL:

local core = require('openmw.core')
local util = require('openmw.util')

local function sjek_thehook(event)
    
    local newpos =  event.actor.position
    event.actor:teleport(event.actor.cell, util.transform.move(event.centervect * 40):apply(newpos) )

end

return {
    eventHandlers = { sjek_thehook = sjek_thehook }
}

PLAYER:

--local anim = require('openmw.animation')
--local ui = require('openmw.ui')
local camera = require("openmw.camera")
local nearby = require("openmw.nearby")
local util = require("openmw.util")
local core = require('openmw.core')
local self = require('openmw.self')
local I = require('openmw.interfaces')
local async = require('openmw.async')

local active = 0
local position
local centervect

local function onKeyPress(key)
    if key.symbol == 'c' and active == 0 then
      
      centervect = camera.viewportToWorldVector(util.vector2(0.5,0.5)):normalize()
      position = camera.getPosition()
      
      active = 1

    end
end

local function onFrame()
     if active == 1 then
     
     local result = nearby.castRenderingRay(position, position + centervect * 7000,{ ignore = self })
       if result.hitObject == nil then active = 0 return end
        
          core.sendGlobalEvent("sjek_thehook",{ target = result.hitpos , actor = self, centervect = centervect})
        
        if (result.hitPos - self.position):length() < 200 then
          print("hit", self.recordId, "and", result.hitObject.recordId)
          active = 0
        end
     end
end

return {  engineHandlers = { onKeyPress = onKeyPress, onFrame = onFrame } }

to modify using weapon

PLAYER:

--local anim = require('openmw.animation')
--local ui = require('openmw.ui')
local camera = require("openmw.camera")
local nearby = require("openmw.nearby")
local util = require("openmw.util")
local core = require('openmw.core')
local self = require('openmw.self')
local I = require('openmw.interfaces')
local async = require('openmw.async')
local types = require('openmw.types')

local active = 0
local position
local centervect

I.AnimationController.addTextKeyHandler('', function(groupname, key)
  if key == 'chop hit' and active == 0 then
    local weapon = "nerevarblade_01_flame"
    if types.Actor.getEquipment(self, types.Actor.EQUIPMENT_SLOT.CarriedRight).recordId == weapon then 
      centervect = camera.viewportToWorldVector(util.vector2(0.5,0.5)):normalize()
      position = camera.getPosition()
      
      active = 1
    end
  end
end)

local function onUpdate()
     if active == 1 then
     
     local cast = nearby.castRay(position, position + centervect * 7000, { ignore = self } )
       if cast.hitObject == nil then active = 0 return end
        
       core.sendGlobalEvent("sjek_thehook",{ target = cast.hitpos , actor = self, centervect = centervect})
        
        if (cast.hitPos - self.position):length() < 200 then
          print("hit", self.recordId, "and", cast.hitObject.recordId)
          active = 0
        end
     end
end

return {  engineHandlers = { onUpdate = onUpdate }