English Pull a player to a wall

6 replies
Goto Page
To the start Previous 1 Next To the start
17.06.19 09:56:31 pm
Up
Goo
User
Offline Off
Hello!
It's not often where I ask for entire functions but this time I just couldn't find a good way to make something work.

I need a function that will teleport a player (overtime, but quickly) towards his mouse cursor, for the sake of this experiment it would be nice if the speed can easily be modified.

But it will only pull him up to a wall and not into the wall.
So it can't be used to go over/inside walls, just to get to them.

Similar to... Spiderman?

It should also have a limited range that can be easily modified, if the player is too far from a wall (using the limit), it will not move him at all.

This is how far I got, I couldn't really make it work very well:

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
local limit = 0
          
          while true do
               limit = limit + 1
               
               local rot = player(p, 'rot')
               
               if rot < -90 then rot = rot + 360 end
               
               local angle = _math.rad( _math.abs( rot + 90 ) ) - _math.pi
               local x = future_x(p) + _math.cos(angle) * 10
               local y = future_y(p) + _math.sin(angle) * 10
               
               local tx, ty = _math.floor(x / 32), _math.floor(y / 32)
               
               local property = tile(tx, ty, 'property')
               
               if property >= 1 and property <= 4 or tile(tx, ty, 'frame') == 0 or limit >= 20 then
                    break
               end
               
               hc.players[p].test.f_x = x
               hc.players[p].test.f_y = y
               
               timer(limit * 15, 'parse', 'setpos ' .. p .. ' ' .. x .. ' ' .. y)
          end


Using the following functions:

Code:
1
2
3
4
5
6
7
local future_x = function(p)
     return hc.players[p].test.f_x or player(p, 'x')
end

local future_y = function(p)
     return hc.players[p].test.f_y or player(p, 'y')
end
17.06.19 10:15:54 pm
Up
Bowlinghead
User
Offline Off
Here you are:
file cs2d Skriptbasierte Bewegungen (4)

Kinda. Do your mouse cursor change while running this function?
Share time limited free games here
17.06.19 11:56:03 pm
Up
Goo
User
Offline Off
It seems to do what I want but the collision with walls doesn't seem to work very well, players can end up stuck in a wall or use it to get past a wall.

Also it seems to sometimes teleport you to a random place and then teleport you back to where you belong, like flickering.

Could those be fixed?

This is how I did it:

Code:
1
2
3
4
5
6
7
8
9
local rot = player(p, 'rot')

if rot < -90 then rot = rot + 360 end
          
local angle = _math.rad( _math.abs( rot + 90 ) ) - _math.pi
local x = _math.cos(angle) * 10
local y = _math.sin(angle) * 10

move(p, 0, 0, 40, 1, x, y, 1)
18.06.19 03:09:50 pm
Up
Edik
User
Offline Off
The posted script "move.lua" uses timer which is doing the following functions even if you already have reached a wall. And as he counts, he also adds the distance in relation to the counting. Thats why it couldnt work properly. Also the script uses global variables for each player. This could lead to problems, if many people want to use it at the same time.

So here, I made something for you:

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
p_move = {}
addbind("mouse3")
addhook("key","fKey")
function fKey(id,key,state)
     if key == "mouse3" then
          if state == 1 then
               local range = 40
               local speed = 10
               move(id, range, speed)
          end
     end
end

function move(id, range, speed)
     local start_x = player(id,"x")
     local start_y = player(id,"y")
     
     local rot = player(id, 'rot')
     if rot < -90 then rot = rot + 360 end
     local angle = math.rad( math.abs( rot + 90 ) ) - math.pi
     local distance_x = math.cos(angle) * speed
     local distance_y = math.sin(angle) * speed
     
     p_move[id] = {action=true, start_x=start_x, start_y=start_y, range=range, distance_x=distance_x, distance_y=distance_y, counter=0}
end

function action(id)
     if p_move[id].action then
          if p_move[id].counter > p_move[id].range then p_move[id].action = false end
          p_move[id].counter = p_move[id].counter + 1
          -- vars shorten for better understanding
          local start_x = p_move[id].start_x
          local start_y = p_move[id].start_y
          local counter = p_move[id].counter
          local distance_x = p_move[id].distance_x
          local distance_y = p_move[id].distance_y
          
          local new_x = start_x + (counter*distance_x)
          local new_y = start_y + (counter*distance_y)
          local tile_x = math.floor(new_x/32)
          local tile_y = math.floor(new_y/32)
          
          if tile(tile_x,tile_y,"walkable") then
               parse("setpos "..id.." "..new_x.." "..new_y)
          else
               new_x = math.floor((start_x + ((counter-1)*distance_x))/32)*32+16
               new_y = math.floor((start_y + ((counter-1)*distance_y))/32)*32+16
               parse("setpos "..id.." "..new_x.." "..new_y)
               p_move[id].action = false
          end
     end
end

addhook("always","falways")
function falways()
     for id, _ in pairs(p_move) do
          if p_move[id].action then
               action(id)
          end
     end
end
18.06.19 03:33:43 pm
Up
Goo
User
Offline Off
Thanks after modifying that code a little bit it is 90% of what I needed.

The only other thing I needed was for it to only move you towards a wall if there is a wall, basically if there's no wall ahead of you (range) you will stay in place.

Is that easily possible?
18.06.19 05:35:29 pm
Up
Edik
User
Offline Off
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
p_move = {}
addbind("mouse3")
addhook("key","fKey")
function fKey(id,key,state)
     if key == "mouse3" then
          if state == 1 then
               local range = 230
               local speed = 10
               move(id, range, speed) -- range in pixel
          end
     end
end

function move(id, range, speed)
     local start_x = player(id,"x")
     local start_y = player(id,"y")
     
     local rot = player(id, 'rot')
     if rot < -90 then rot = rot + 360 end
     local angle = math.rad( math.abs( rot + 90 ) ) - math.pi
     local distance_x = math.cos(angle) * speed
     local distance_y = math.sin(angle) * speed
     
     local repeats = range/speed
     
     local distance_tiles = math.floor(range/32)
     local x1 = math.floor(start_x)
     local y1 = math.floor(start_y)
     local x2 = math.floor((start_x+repeats*distance_x))
     local y2 = math.floor((start_y+repeats*distance_y))
     
    for i=1, range do
        if tile(math.floor((x1 + i * math.cos(math.atan2(y2 - y1, x2 - x1))) / 32),math.floor((y1 + i * math.sin(math.atan2(y2 - y1, x2 - x1))) / 32), "walkable") == false then
            p_move[id] = {action=true, start_x=start_x, start_y=start_y, range=range, distance_x=distance_x, distance_y=distance_y, counter=0, repeats=repeats}
               return
        end
    end
end

function action(id)
     if p_move[id].counter > p_move[id].repeats then p_move[id].action = false end
     if p_move[id].action then
          p_move[id].counter = p_move[id].counter + 1
          -- vars shorten for better understanding
          local start_x = p_move[id].start_x
          local start_y = p_move[id].start_y
          local counter = p_move[id].counter
          local distance_x = p_move[id].distance_x
          local distance_y = p_move[id].distance_y
          
          local new_x = start_x + (counter*distance_x)
          local new_y = start_y + (counter*distance_y)
          local tile_x = math.floor(new_x/32)
          local tile_y = math.floor(new_y/32)
          
          if tile(tile_x,tile_y,"walkable") then
               parse("setpos "..id.." "..new_x.." "..new_y)
          else
               new_x = math.floor((start_x + ((counter-1)*distance_x))/32)*32+16
               new_y = math.floor((start_y + ((counter-1)*distance_y))/32)*32+16
               parse("setpos "..id.." "..new_x.." "..new_y)
               p_move[id].action = false
          end
     end
end

addhook("always","falways")
function falways()
     for id, _ in pairs(p_move) do
          if p_move[id].action then
               action(id)
          end
     end
end


I changed range from loops to range in pixels
18.06.19 07:48:55 pm
Up
Goo
User
Offline Off
Thanks! That works great!
To the start Previous 1 Next To the start