# Forum  CS2D Scripts Pull a player to a wall

# Pull a player to a wall

6 replies
Goto Page  1  Goo
User
Offline 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
User
Offline Share time limited free games here Goo
User
Offline 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)
Edik
User
Offline 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 = {}
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

function falways()
for id, _ in pairs(p_move) do
if p_move[id].action then
action(id)
end
end
end
Goo
User
Offline 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?
Edik
User
Offline 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 = {}
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

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
Goo
User
Offline Thanks! That works great!   1  ﻿