local _name = "" epressed = 0 local state = "" local throw_speed = 700 local hold_height = 10 local hold_dist = 50 local max_throw_dist = 5 --maximum time (in seconds) the hook will travel if it doesnt hit anything local max_charge_time = 1 --seconds til max throw length reached local show_timer = 1 local ghtimer = 0 local perc = 0 local angle_Y = 0 local n_max_time = 0 function grapplinghook_init_name(e,name) _name = name state = "wait pick up" max_charge_time = max_charge_time*1000 max_throw_dist = max_throw_dist*1000 end function grapplinghook_main(e) if state == "wait pick up" then if PlayerLooking(e,150,20) > 0 then PromptLocal(e,"Collect the ".._name.."? (E)") if g_KeyPressE == 1 and epressed == 0 then epressed = 1 state = "picking" end end elseif state == "picking" then if g_KeyPressE == 0 then StartTimer(e) state = "holding" end elseif state == "holding" then CollisionOff(e) SetRotation(e,g_PlayerAngX,g_PlayerAngY,g_PlayerAngZ) SetPosition(e,g_PlayerPosX,g_PlayerPosY+hold_height,g_PlayerPosZ) angle_Y = math.rad(g_PlayerAngY) local pos_X = g_PlayerPosX + (math.sin(angle_Y) * hold_dist) local pos_Z = g_PlayerPosZ + (math.cos(angle_Y) * hold_dist) SetPosition(e,pos_X,g_PlayerPosY+hold_height,pos_Z) CollisionOn(e) if g_KeyPressE == 1 then ghtimer = GetTimer(e) if show_timer == 1 then Panel(40,80,64,86) if ghtimer > max_charge_time then ghtimer = max_charge_time end perc = ((ghtimer / max_charge_time)*10)*2 for a = 1,perc do Panel(40+a,81,41+a,82) end perc = ghtimer / max_charge_time n_max_time = max_throw_dist * perc perc = perc * 100 perc = round(perc,0) TextCenterOnX(50,76,3,perc.." % ") end else if perc > 0 then perc = 0 state = "firing" end ghtimer = 0 StartTimer(e) end elseif state == "firing" then CollisionOff(e) MoveForward(e,throw_speed) CollisionOn(e) local x1 = GetEntityPositionX(e) local y1 = GetEntityPositionY(e) local z1 = GetEntityPositionZ(e) local y2 = y1 local x2 = x1 + (math.sin(angle_Y) * 45) local z2 = z1 + (math.cos(angle_Y) * 45) local obstructionhit = IntersectAll(x1,y1,z1,x2,y2,z2,g_Entity[e]['obj']) if obstructionhit == nil then obstructionhit = 0 end if obstructionhit ~= 0 then --Prompt ("obstructed") state = "hit" else thit = RayTerrain(x1,y1,z1,x2,y2+10,z2) if thit ~= 1 then else state = "hit" --prompt ("obstructed") end end if state ~= "hit" then if GetTimer(e) > n_max_time then state = "return" end end elseif state == "hit" then StartTimer(e) angle_Y = g_PlayerAngY local x1 = g_PlayerPosX local y1 = g_PlayerPosY+10 local z1 = g_PlayerPosZ local y2 = y1 local x2 = x1 + (math.sin(angle_Y) * 80) local z2 = z1 + (math.cos(angle_Y) * 80) local obstructionhit = IntersectAll(x1,y1,z1,x2,y2,z2,0) if obstructionhit == nil then obstructionhit = 0 end if obstructionhit ~= 0 then angle_Y = RotatePlayerToEntity(e) angle_Y = math.rad(angle_Y) local pos_X = g_PlayerPosX + (math.sin(angle_Y) * -(throw_speed/10)) local pos_Z = g_PlayerPosZ + (math.cos(angle_Y) * -(throw_speed/10)) SetFreezePosition(pos_X,g_PlayerPosY,pos_Z) SetFreezeAngle(0,g_PlayerAngY,0) TransportToFreezePosition() state = "return" return end if GetPlayerDistance(e) < 200 then state = "holding" return end angle_Y = RotatePlayerToEntity(e) angle_Y = math.rad(angle_Y) local pos_X = g_PlayerPosX + (math.sin(angle_Y) * (throw_speed/10)) local pos_Z = g_PlayerPosZ + (math.cos(angle_Y) * (throw_speed/10)) SetFreezePosition(pos_X,g_PlayerPosY,pos_Z) SetFreezeAngle(0,g_PlayerAngY,0) TransportToFreezePosition() elseif state == "return" then StartTimer(e) if GetPlayerDistance(e) > 150 then CollisionOff(e) RotateToPlayer(e) MoveForward(e,throw_speed) CollisionOn(e) else state = "holding" end end end function grapplinghook_preexit(e) end function grapplinghook_exit(e) end function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end function RotatePlayerToEntity(e) if g_Entity[e] ~= nil then local x = g_Entity[e]['x'] - g_PlayerPosX local z = g_Entity[e]['z'] - g_PlayerPosZ local angle = math.atan2(x,z) angle = angle * (180.0 / math.pi) if angle < 0 then angle = 360 + angle elseif angle > 360 then angle = angle - 360 end SetFreezeAngle(g_PlayerAngX,angle,g_PlayerAngZ) SetFreezePosition(g_PlayerPosX,g_PlayerPosY,g_PlayerPosZ) TransportToFreezePosition() return angle end end function PlayerLooking(e,dis,v) if g_Entity[e] ~= nil then if dis == nil then dis = 3000 end if v == nil then v = 0.5 end if GetPlayerDistance(e) <= dis then local destx = g_Entity[e]['x'] - g_PlayerPosX local destz = g_Entity[e]['z'] - g_PlayerPosZ local angle = math.atan2(destx,destz) angle = angle * (180.0 / math.pi) if angle <= 0 then angle = 360 + angle elseif angle > 360 then angle = angle - 360 end while g_PlayerAngY < 0 or g_PlayerAngY > 360 do if g_PlayerAngY <= 0 then g_PlayerAngY = 360 + g_PlayerAngY elseif g_PlayerAngY > 360 then g_PlayerAngY = g_PlayerAngY - 360 end end local L = angle - v local R = angle + v if L <= 0 then L = 360 + L elseif L > 360 then L = L - 360 end if R <= 0 then R = 360 + R elseif R > 360 then R = R - 360 end if (L < R and math.abs(g_PlayerAngY) > L and math.abs(g_PlayerAngY) < R) then return 1 elseif (L > R and (math.abs(g_PlayerAngY) > L or math.abs(g_PlayerAngY) < R)) then return 1 else return 0 end else return 0 end end end