ID:281611
 


Nope.
Well, that was a ridiculously long explanation to get a few lines of "correct" code.
-That if(istype(a)) doesn't seem like what you'd want. Allowing non-mobs (generally non-player-mobs) to enter doorways is usually undesirable.
-You never really explained how to set the tag variable.
-Implementing doorways as /turfs can be somewhat flunky, since all turfs in a single tile merge into a single entity. Now that the Cross type procs have been implemented, you can effectively use /objs for doorways.
-Building doorway code into Enter() is acceptable. Entered() could allow for potential blocking of doorways, which isn't necessary desirable. Enter() vs Entered() in your code would provide essentially identical results.
-Your code would also result in an instant movement as soon as they "touched" the doorway, which is generally a poor looking effect. If you're going to use Entered(), you may as well implement a graphically functional delay.
In response to Falacy (#1)
Falacy wrote:
Well, that was a ridiculously long explanation to get a few lines of "correct" code.
-That if(istype(a)) doesn't seem like what you'd want. Allowing non-mobs (generally non-player-mobs) to enter doorways is usually undesirable.

Then you use the magic of overwriting the method and calling the parent proc. I start with the most free case, which can then be restricted. It is not possible to be restricted and then go to a freer case. Thus, my generalized solution is the best here. If you wish to change it, it is as simple as follows.

turf/newturf
Entered(mypath/foo)
if(istype(foo))
..()


If I were to choose the more restrictive choice, then the only option is to rewrite all of the code. This is unnecessary.

-You never really explained how to set the tag variable.

This is a valid mistake, which I will edit in.

-Implementing doorways as /turfs can be somewhat flunky, since all turfs in a single tile merge into a single entity. Now that the Cross type procs have been implemented, you can effectively use /objs for doorways.

The caveat with this method is that BYOND's default movement interface never results in the Enter() proc being called for any type of /atom/movable. Consequently, this would require a change to the Move() proc in /atom/movable, which is a much more involved modification.

-Building doorway code into Enter() is acceptable. Entered() could allow for potential blocking of doorways, which isn't necessary desirable. Enter() vs Entered() in your code would provide essentially identical results.

Building this sort of code into Enter() is functional, yes. But it should not be considered acceptable, as it breaks the interface. Using the terminology of other languages, if BYOND were strictly-typed, the Enter() method should be bool, and the Entered() method should be void. Entered() should be an event handler, and Enter() should be whether that event can even occur.

While I was overstating it in the tutorial, the affect of Enter() on the world should be minimal, at best. The most I could see it doing is alerting someone than an attempt to Enter() was made. Even in this case, I believe this would be bettered handled by something like a NoEntered() or EnteredFail() event (one of the things I believe the basic interface is lacking), rather than it actual occurring within Enter().

-Your code would also result in an instant movement as soon as they "touched" the doorway, which is generally a poor looking effect. If you're going to use Entered(), you may as well implement a graphically functional delay.

Once again, I do not know whether the user would want to implement this, or how they would prefer to implement it. I am not going to make a fumbled attempt at implementing something I can not predict, but I can implement it in a way that it can be usefully overridden. As above, all the programmer has to do is wait until they prefer, and then call ..() in the Entered() proc they overwrite, and the effect would be preserved. Thus, making an attempt at implementing it is both useless and outside the scope of the tutorial.

[Edit]

On top of all that, this is a tutorial, not a library. I am demonstrating and guiding a user through the process to implement these things, not implementing it myself. It is up to the user to decide what exactly they need, and how to implement it.
In response to Popisfizzy (#2)
Popisfizzy wrote:
The caveat with this method is that BYOND's default movement interface never results in the Enter() proc being called for any type of /atom/movable. Consequently, this would require a change to the Move() proc in /atom/movable, which is a much more involved modification.

The Cross type procs work on movable atoms in essentially the same same way that Enter type procs would on a turf. I have found them to be useful, and somewhat ridiculous that they weren't added before pixel movement. You can use them to easily implement things like pushing objects, allowing players to walk through each other, triggering events, etc.
In response to Falacy (#3)
Falacy wrote:
The Cross type procs work on movable atoms in essentially the same same way that Enter type procs would on a turf.

Interesting. I rarely use DM anymore, and thus was not aware of this addition. Perhaps in the future I'll make a demonstration or tutorial involving it, but it's currently beyond the scope of this tutorial. In any case, I'll make a note in the last section about it.
so for the code
 turf
// This is the tag of the location we're moving to.
var/moveto_tag

Entered(atom/movable/a)
if(istype(a))

// This stores the turf we're moving to. Note that tag
// isn't only on turfs, but all /atom types. Therefore,
// it's entirely possible that this is not a turf.
// I do not typecheck here, though, because it is
// up to the map designer to put a tag on the right
// object, and they could have a reason for moving
// the player to a non-turf.
var/turf/t = locate(moveto_tag)
if(t)
a.loc = t
lets say i wanted to make it so that if you entered a icon state i made called
entrancel
icon = 'person.dmi'
icon_state = "castle-entrancel"
what do i change in the code to make it so you are teleported on the same spot on the second layer in the map
In response to Disasterousclown (#5)
It is extremely clear you are in over your head. You need to start here or here, and forget where you're at now. You don't have near enough basic knowledge to attempt any of this relatively-basic stuff.
The problem with using turfs is that you're binding the warp behavior to the turf type. If you want to change the map to make the ground be dirt instead of grass, you need to update the warp turf. I wouldn't consider being a warp a property of the turf, I'd rather use areas (or invisible objects) for this type of thing. This way you can place them on any turf to turn that turf into a warp.

area
warp
Entered(mob/m)

// the destination is the turf in this area
// that the mob isn't standing on.
var/turf/destination
for(var/turf/t in src)
if(t != m.loc)
destination = t
break

m.loc = destination

warp_01
warp_02
warp_03

You can give the warp areas an icon (that is set to null in their constructor) so you can easily see them on the map. I find it a lot easier than managing tags.
Creating that extra destination var and then moving the mob after the loop is ugly. You could set m.loc=t in the loop. Also, you should throw an ismob(m) type check in there (and maybe return ..()), since you know noobs are gonna copy/paste this code and hope it works =P
Actually, to fix it up, I'd do it like this.
In response to Falacy (#8)
Falacy wrote:
Creating that extra destination var and then moving the mob after the loop is ugly. You could set m.loc=t in the loop. Also, you should throw an ismob(m) type check in there (and maybe return ..()), since you know noobs are gonna copy/paste this code and hope it works =P

He could also do it like this:
var area/a = target_type ? (locate(target_type) in world) : src
m.loc = locate(/turf) in (a.contents - m.loc)

But that's just hard to read. Readability is important.
In response to Kaiochao (#10)
Kaiochao wrote:
Readability is important.

That was my point, I'm not sure why you're trying to post nonsense with no context.

His library is pointlessly overcomplicated, barely readable, and still has no type checking.
In response to Falacy (#11)
Falacy wrote:
Kaiochao wrote:
Readability is important.

That was my point, I'm not sure why you're trying to post broken nonsense with no context.

His library is pointlessly overcomplicated, barely readable, and still has no type checking.

1. The context of my code is his library (specifically, in destination()), and it works.
2. Type-checking isn't very important if only movable atoms can enter areas.
3. If anything, the overcomplicating parts of his library make it even more readable.
It's much easier to understand that "destination" means destination, rather than "t".
In response to Kaiochao (#12)
Kaiochao wrote:
1. The context of my code is his library (specifically, in destination()), and it works.
Inserted into a specific point of his library, perhaps. However, they don't have that context in your post, where they are just 2 random lines.

2. Type-checking isn't very important if only movable atoms can enter areas.
Entered() is a proc like any other, people could call it with whatever parameters they wanted.

3. If anything, the overcomplicating parts of his library make it even more readable.
It took him over 50 lines to accomplish what should be a perfectly readable example in less than 5.

"destination" is easier to understand to be a destination than "t", of course.
"t" being a poor variable name doesn't make a destination proc any more necessary or readable. "target" isn't a good variable name either, since it doesn't properly describe what is being referenced, and is later named "target_type" in the destination proc.
In response to Falacy (#11)
Falacy wrote:
His library is pointlessly overcomplicated, barely readable,

Those things don't always matter. What's most important is the interface that the library provides - how easy it is for developers to make use of the library to suit their needs. Sometimes the internals of the library have to be complicated to accommodate all the ways people might want to use it. If you only cared about making a single warp that moves you to another location, you'd do this:

turf/Enter(mob/m)
m.loc = locate(4, 30, 1)

It's certainly readable and isn't overcomplicated =)

and still has no type checking.

The library makes no assumptions about what objects can or cannot use warps. That's not something the library would do, but it's something you can easily implement using the library:

warp
// player-only warps:
player_only
warp(mob/player/p)
if(istype(p))
..()
In response to Forum_account (#14)
Forum_account wrote:
It's certainly readable and isn't overcomplicated =)
It also isn't functionally reusable. When you have 20 different doorways using that method, it becomes a lot less readable, due to the amount of repetitive spam code you would need.

The library makes no assumptions about what objects can or cannot use warps. That's not something the library would do
The issue isn't about the library limiting functionality, but preventing errors.

There is also a problem with both of these examples; if you want to have a doorway that is more than a single tile.
In response to Falacy (#13)
Falacy wrote:
Entered() is a proc like any other, people could call it with whatever parameters they wanted.

If it's going to account for stupidity, how do you plan on stopping them from overriding the proc?
I think type checking would be bad, I would prefer them to get an error message letting them know they screwed up.

Falacy wrote:
It took him over 50 lines to accomplish what should be a perfectly readable example in less than 5.

I happen to like his example, but I would prefer it if he buffered the destination so it didn't have to look for it every time.
In response to Falacy (#13)
Falacy wrote:
It took him over 50 lines to accomplish what should be a perfectly readable example in less than 5.

The demos are what counts. If the library was only 5 lines it couldn't be as flexible and the demos would be more complex. The goal is to keep the demos (or whatever project uses the library) as simple as possible.

Also, lines of code isn't a good measure of complexity (consider Kaiochao's 2-line example above). You're also counting whitespace and comments towards that total, it's really only 25 lines of code.
In response to Forum_account (#17)
Forum_account wrote:
The demos are what counts. If the library was only 5 lines it couldn't be as flexible and the demos would be more complex. The goal is to keep the demos (or whatever project uses the library) as simple as possible.
None of it matters, really. The noobs who would need to use a library for something would never bother to actually read through it anyway.

Also, lines of code isn't a good measure of complexity (consider Kaiochao's 2-line example above).
His code isn't a good example of complexity because it is out of context (would take several more lines to even compile that code), and is an intentional example of pointlessly unreadable code designed to save space without improving functionality or efficiency.

You're also counting whitespace and comments towards that total, it's really only 25 lines of code.
The awkwardly placed whitespace, and unnecessary comments certainly contribute to the poor readability.
In response to Falacy (#15)
Falacy wrote:
There is also a problem with both of these examples; if you want to have a doorway that is more than a single tile.

For a two-tile wide door, create two warps.

One catch would be having a door that's shown as being two tiles wide on the outside but one tile wide on the inside. I considered making a version of the library that uses the Region library, which would make it easier to handle things like that (it'd also avoid other problems).

I would like to add other default types of warps to the library. The current one, a simple back-and-forth between two tiles, is sufficient for a lot of things. There are some things that are quite a bit out of reach. Suppose you wanted to link edges of two z levels together so it behaved like they were adjacent. You wouldn't want to create 100 warp types to place along the edge of a 100x100 map. I'm looking to find ways for the library to easily support these kinds of warps in a generic way.
Page: 1 2