Forum

> > CS2D > Scripts > Pull a player to a wall
Forums overviewCS2D overview Scripts overviewLog in to reply

English Pull a player to a wall

6 replies
To the start Previous 1 Next To the start

old Pull a player to a wall

Mami Tomoe
User Off Offline

Quote
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:

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:

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

old Re: Pull a player to a wall

Mami Tomoe
User Off Offline

Quote
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:

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)

old Re: Pull a player to a wall

Edik
User Off Offline

Quote
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:

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

old Re: Pull a player to a wall

Mami Tomoe
User Off Offline

Quote
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?

old Re: Pull a player to a wall

Edik
User Off Offline

Quote
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
To the start Previous 1 Next To the start
Log in to reply Scripts overviewCS2D overviewForums overview