ID:1137758
 
Sometimes it pays to have enemies block the player but it's not always good to let other people block the player. To stop players from bumping into each other you just need to add this code.

I'm not saying this is perfect code, if there's improvements I can make then let me know.

mob
var
isUser = 1

density = 1

Cross(atom/theAtom)

if(istype(theAtom, /mob) && is_user(theAtom) && isUser)
return 1


Enter(atom/theAtom)

if(istype(theAtom, /mob) && is_user(theAtom) && isUser)
return 1

proc
is_user(mob/theMob)
if(theMob.isUser == 1) return 1
else return 0

mob/Enemies // Any mob types you don't want to be thought of as a user.
isUser = 0
density = 1


To test if you added it correctly make your enemy types isUser equal 1 and you should be able to walk through them. Remember to undo that and return it to 0 though =)
You don't need a variable "isUser" to do it. Just, for example make the client mob be mob/Player and remove those isUser checks. Then do on istype(theAtom, /mob/Player)

mob/Player/var
density = 1

mob/Player/Cross(atom/theAtom)
if(istype(theAtom, /mob/Player))
return 1

mob/Player/Enter(atom/theAtom)
if(istype(theAtom, /mob/Player))
return 1


And then make enemies mob/Enemy.
In response to Blastcore
Hey, good idea but just wondering how you change client.mob. I'm having difficulties.
To set default mob as mob/Player you can do:

world/mob = /mob/Player


Then all the stuff for client's mob would be like:

mob/Player/Login()

mob/Player/Logout()


etc.
In response to Blastcore
Cool, that works great. I tested. It's just a little complicated I think for most people just cause it changes how some of their code is going to work. I'd rather just leave the tutorial as is but if people want to use your idea that's cool. Everything they need is written here.
If you define player/Enter() that way, you won't be able to pick up items using item.Move(player). I don't think you want players to be inside of other players anyway, so it's entirely unnecessary.

Anyway, if you're doing an if() check on some proc or operation that returns the same value you want to return, you might as well return the condition.
//  Return true if p is a player,
// OR return what Cross normally would.
mob/player
Cross(mob/player/p)
return istype(p) || ..()

// Written longhand, it looks like this:
mob/player
Cross(mob/player/p)
// Let other players cross players regardless of density!
if(istype(p, /mob/player))
return 1

// Let non-dense objects cross players!
return ..()

return istype(p) || ..()

That is very sexy. Hot, even...
Using the group list has the intended effect.

Anything belonging to the same group will swap places/move through one another when they bump.

Adding online players to a list, then copying that list into each player's group could also be an option.
In the reference it says that behavior will only work if both mobs move in full tiles. Was this changed?

Besides, that seems like an inefficient way to do it. Group lists are independent for each mob. That means any time a player logs in or out, all player's lists must be updated.
Three lines of code is inefficient?
Login()
onlineplayers+=src
src.group=onlineplayers.Copy()


Logout()
onlineplayers-=src
src.group.Cut()//just to make sure no mobs are saved with logout.


//And to update automatically. with a few modifications

mob/player
Stat()
updateplayerlist()//called automatically to update the list.
..()
var
update_delay=50//every 5 ticks, 10 seconds, 30 seconds, once a minute, whenever.
update_wait=0
proc
updateplayerlist()
if(update_wait<world.time)
update_wait=world.time+update_delay
src.group.Cut()//empty list.
src.group=onlineplayers.Copy()//copy list.
I'm not talking about the time it takes to write the code, I mean that you are constantly updating as many lists as you have players in the game. I understand that the most popular byond games have no more than 50 players on a server...even so, why copy 50 lists every time someone logs in or out (or every 10 seconds for that matter), when all you need is a simple check when they bump into each other?

Furthermore, the group Bump() behavior doesn't even work with pixel movement.

It's possible you would want to maintain a list of players online for other reasons too, but in that case it would be better just to maintain a single global list. Then when a collision happens you could test to see if both mobs belong to the player list. Still, I don't see the advantage in that.
In response to Red Hall Dev
Red Hall Dev wrote:
Cool, that works great. I tested. It's just a little complicated I think for most people just cause it changes how some of their code is going to work.

As an alternative you could test to see if the bumping mob has a key. Then you would not need different mob types, and you are using a built in variable
In response to Magicsofa
Magicsofa wrote:
I'm not talking about the time it takes to write the code, I mean that you are constantly updating as many lists as you have players in the game. I understand that the most popular byond games have no more than 50 players on a server...even so, why copy 50 lists every time someone logs in or out (or every 10 seconds for that matter), when all you need is a simple check when they bump into each other?

Furthermore, the group Bump() behavior doesn't even work with pixel movement.

It's possible you would want to maintain a list of players online for other reasons too, but in that case it would be better just to maintain a single global list. Then when a collision happens you could test to see if both mobs belong to the player list. Still, I don't see the advantage in that.

Point taken. ^_^
In response to Dariuc
Yeah, updating a lot of lists every few ticks through the Stat() of potentially many players seems less efficient than returning a value whenever the situation (a mob moves into another mob) arises.

Also, list.Copy(other_list) is incorrect. The proper syntax is list = other_list.Copy().
Also, mob.group is a tmp var. It will not be saved.
In response to Kaiochao
Kaiochao wrote:
Yeah, updating a lot of lists every few ticks through the Stat() of potentially many players seems less efficient than returning a value whenever the situation (a mob moves into another mob) arises.

Also, list.Copy(other_list) is incorrect. The proper syntax is list = other_list.Copy().
Also, mob.group is a tmp var. It will not be saved.

Good to know,t/y