ID:2422162
 
(See the best response by Kaiochao.)
Code:
mob
Move(turf/NewLoc,Dir,Step_x,Step_y)
if(istype(NewLoc, /turf/Test))
world<<"Walking on blue box "
world<<step_x
world<<step_y
return ..()


Problem description:
Hello, I try to calculate "bounds" for turfs (You know, i have 32x32 icon - cliff edge i want allow player come to 50% of turf size (16 px),
Im try to check im on the tile, and if i'm i want to calculate my step_x and step_y to get "virtual edges"

Can anyone explain me how work Move() proc and why when i cross the tile my "NewLoc" is still old tile?
My bound box is equal to default (32)




@Edit:

Ok i have one solution, i can deal with bound_x adn bound_y. But i stil don't understand why i it won't work by default…

@Edit2:
No i can't becouse i forget about collisons….
Use objs.
In response to Kaiochao
Kaiochao wrote:
Use objs.

Yep i thought same but you know, objs need more counting from BYOND engine, turfs are faster. On corners i need 2 objs one vertical and one horizontal... and if i'll have +/- 10000 (?) Objs just for cliffs edges, my project slow down.
Don't forget about any others map decorations, like barrels, etc.

Ter13 wrote:
http://www.byond.com/forum/?post=1999512
In response to Marekssj3
Best response
Ter's flowchart says that you should use objs.

Does it move? No
Tile or Pixel movement? Pixel
Is its bounding area the same size as a tile? No
Is its bounding area equally divisible by tile size on both axes? No
obj

I agree that 10k objs in the world just for non-moving dense cliffs does sound pretty bad. That doesn't mean you can't use objs at all, though. I think you can use objs to handle the collision detection without having all potential edge objs exist at all times.

For example, you could add a flag to the turfs that require partial density that describes which sides should be dense. These turfs could then generate the dense corner objs when necessary, whether you have a way to detect a player approaching them or you have a chunk-based initializer or whatever. And you can destroy them when they're not in use, if you have a way to determine that (like chunk-based).

As a quick proof of concept, I tried overriding Enter for the turf, generating the corner objs before calling ..(), but creating obstacles inside Enter before ..() doesn't seem to actually prevent overlapping the newly-created obstacles. Might have to ask Lummox if that should be happening.
#include<kaiochao/shapes/shapes.dme>

world
fps = 60
maxx = 25
maxy = 25
turf = /turf/random
mob = /mob/player

turf/random
New()
..()
if(prob(5))
new/turf/wall(src)
else if(prob(15))
new/turf/partial_dense(src)
else
new/turf/checker(src)

turf/checker
icon_state = "rect"

New()
..()
if((x + y) % 2)
color = "silver"
else
color = "gray"

turf/wall
icon_state = "rect"
color = "black"
density = TRUE

turf/partial_dense
icon_state = "rect"
color = "green"

var
corners = 0

New()
..()
// Randomize which corners are made
for(var/n = 0 to 3)
if(prob(50))
corners |= 1 << n

// Generate corners on entry,
// theoretically before the obstacle check
Enter(atom/movable/m)
if(corners)
BuildCorners()
return ..()

proc
BuildCorners()
var obj/quarter_tile/q
if(corners & 1) // Bottomleft
q = new(src)
if(corners & 2) // Bottomright
q = new(src)
q.step_x = 16
if(corners & 4) // Topleft
q = new(src)
q.step_y = 16
if(corners & 8) // Topright
q = new(src)
q.step_x = 16
q.step_y = 16
corners = 0

obj/quarter_tile
icon_state = "rect"
color = "red"
transform = matrix(1/2, 0, -8, 0, 1/2, -8)
bounds = "16,16"
density = TRUE

mob/player
icon_state = "rect"
color = "blue"
step_size = 2
Ter's flowchart should also include an option for using a different engine.

This is one of those cases.
In response to Kaiochao
You make my day, i have idea how to resolve it.
How can i check (by calling Exit()/Exited() proc) is any other mob(player) standing on the turf? (same loc)

1. I have my corner - no dense turf.
2. Player enter the tile and call Enter() proc.
3. Tile spawn corner obj (same as you make it)
4. When player exit tile this corner will be removed.

5. But i have to remember it's online game and
if someone was stay on tile before, my corner will not spawn 2nd time, and when I 1st exit tile and someone is still standing my corner shuldn't be removed.
This will not work. Objects created during a movement will not affect the current movement.
In response to Ter13
In that case, chunk-based (or generally region based) init and de-init would probably be the best way to go. Plus, these edge objs can be made completely invisible so that they don't exist to clients or affect client-side performance at all.
In response to Kaiochao
Ok guys i made it and it's satisfied me, it's little tricky becouse edges isn't match, but for me its all right.
Now please let me know is my code technicly is correct? Also should i know, how work "corners |= 1 << n". I know its something with binary… but I'm a like "programer".

I have to fix nameing, etc... i know that.


#include<kaiochao/shapes/shapes.dme>


turf/wall
icon_state = "rect"
color = "black"
density = TRUE

turf/partial_dense
icon_state = "rect"
color = "green"

var
corners = 0
list/blocks=list()

Enter(atom/movable/m)
if(corners)
BuildCorners(m)
return ..()
Exit(atom/movable/m)
for(var/obj/quarter_tile/q in src.blocks) if(q.owner==m) q.loc=null
return ..()

proc
BuildCorners(atom/movable/m)
var obj/quarter_tile/q
if(corners & 1) // Top
q = new(src, m)
q.step_x = 2
q.step_y = 16
q.transform = matrix(1, 0, -2, 0, 1/2, -8)
if(corners & 2) // Bottom
q = new(src, m)
q.step_x = 2
q.step_y = 2
if(corners & 4) // Right
q = new(src, m)
q.bounds = "14,28"
q.transform = matrix(1/2, 0, -8, 0, 1, -2)
q.step_x = 16
q.step_y = 2
if(corners & 8) // Left
q = new(src, m)
q.bounds = "14,28"
q.transform = matrix(1/2, 0, -10, 0, 1, -2)
q.step_x = 2
q.step_y = 2
src.blocks+=q


obj/quarter_tile
var/tmp/mob/owner
icon_state = "rect"
color = "red"
transform = matrix(1, 0, -2, 0, 1/2, -10)
bounds = "28,14"
density = TRUE
New(var/Loc, var/mob/Owner)
src.loc=Loc
if(istype(Owner, /mob/player)) src.owner = Owner

mob/player
icon='mob.dmi'
icon_state="16x16"
step_size = 2
bounds = "16,16"
corners |= 1 << n

That's the << shift operator. It shifts the 1 bit n times to the left (in binary representation).

n 1<<n
0 1 (1)
1 10 (2)
2 100 (4)
3 1000 (8)

It looks to me like your solution wouldn't work with step_size higher than 2 due to the usual issue.