ID:160995
 
I know how to make multi-tiled mobs but i can only do it with overlays so only one piece of the mob is dense how can i make it so the whole mob is dense.
You could make several mobs that are dense and Move() with the player.
Or, you could make the objects you're using as an overlay dense.
Shadow Darke has a big atom library you can use. I think he also made a dream makers article a while back on it, too.
In response to XeroXen
Overlays become stored in an internal format, so adding a dense object doesn't retain it's density, since it's just an image.
In response to Naokohiro
Naokohiro wrote:
You could make several mobs that are dense and Move() with the player.

sounds good but how would i keep the parts in the right place (some of the mobs have up to 7 parts)
In response to Riku411811
Here's what I came up with:
Basically, it's making some objects that are moved to follow the player every time the player moves, and they are dense so other mobs or objs will bump into them.
<dm>
mob/var //Make some mob vars
multi=0//boolean mob var determining if multi-tiles are on
list/multi_objs=list()//list created to store the mob's multi-tiled objs

obj/multi //a new obj called "multi"
var/list/xandy=list(0,0)//A list to store the x and y offsets
density=1//Make them dense

mob/New()//called when the mob is created
//add multi-tiled objs to list
multi=1//turn the mob's multi var on
src.icon_state="0,0"//set it's icon state (optional)
//creating objs to add:
var/obj/multi/O=new/obj/multi //create a new multi obj
O.icon='icon.dmi'//set it's icon to something
O.icon_state="0,1"//set it's icon_state (optional)
O.xandy=list(0,1)//Set it's x and y offset
//The numbers you use here determine the offset next to the player
//For example, if you wanted it to be directly south of the player,
//You'd use list(0,-1)
multi_objs+=O//Add the multi obj to the mob's list
//You then repeat the creating objs to add step to add all of them
//I recommend making a list of some sort that has all the data to take
//from.
src.MultisMove()//Then this loads them onto the player

mob/proc/MultisMove()//Making a new proc
for(var/obj/multi/O in src.multi_objs)//This gets all of the multis in the player's list
O.Move(locate(src.x+O.xandy[1],src.y+O.xandy[2],src.z))//this moves them to the correct offset

mob/Move()//called when the player moves
if(src.multi)//only do all this if the player has multi-tiles
for(var/obj/multi/O in src.multi_objs) O.density=0//temporarily set density of multi-tiles to zero
//I'm setting the density temporarily to zero, so they don't bump into eachother,
//and so the player doesn't bump into them
.=..()//call the parent proc and set the default return value to it
if(.)//if the player is able to move
src.MultisMove()//Load all of the tiles around the player
for(var/obj/multi/O in src.multi_objs) O.density=1//Turn their density back on
else
return ..()//Do default action when no multi-tiles
In response to Naokohiro
It works but i'm not sure how to stop them from moving diagonally. i can stop players but not npcs.
In response to Riku411811
mob/Move(loc)
var/dir = get_dir(src, loc)
return !(dir & (dir - 1)) && ..()
In response to Naokohiro
two things
1)thank you Popisfizzy
2)umm how do i delete all the stored icon parts when the monster is destroyed?
In response to Naokohiro
There are multiple misconceptions and mistakes (not meaning actual errors) there. You should probably experiment and test your code first after coming up with it.
In response to Riku411811
You would need to delete all of the objects in the list, probably on mob/Del().
mob/Del()
if(src.multi) for(var/obj/multi/O in src.multi_objs) del O
In response to Naokohiro
thanks for helping me
In response to Popisfizzy
Popisfizzy wrote:
> mob/Move(loc)
> var/dir = get_dir(src, loc)
> return (dir & (dir - 1)) && ..()
>

Wouldn't this work better in this case?:
mob/Move(L,D)
if(D&(D-1)) return 0
In response to Naokohiro
The dir argument isn't always set. In retrospect, this would be a slightly better way to do it:
mob/Move(loc, dir)
dir = dir || get_dir(src, loc)
return !(dir & (dir - 1)) && ..()

There was also a slight error on the last line, which I've fixed.
In response to Popisfizzy
Popisfizzy wrote:
In retrospect, this would be a slightly better way to do it:

Not quite. In fact, your initial implementation was better because even when the dir argument is supplied, in actuality, it isn't necessarily the direction of movement (as it can be specified manually in a call to alter dir). Additionally, you should probably not take into account the direction related functionality in the case of a movement long-range; if someone is to be teleported a long distance, it probably should not be blocked if it happens to be in an X direction.