ID:2961165
 
(See the best response by Ter13.)
Code:
obj/Item
var
MouseDrop(over_object,src_location,over_location,src_control,over_control,params)
if(src_control=="backpack"&&over_control == "default.map1")
src.Drop()


I'm trying to create an item drop system and equip it by dragging it from the backpack, I'm not having success, could anyone help me?

Best response
Your code snippet's invalid. MouseDrop() is not a var.

But also, you really want to implement this the other way around:

atom/proc
ItemDropped(obj/item/item,atom/src_location,atom/item_location,src_control,item_control,params)

obj/item
MouseDrop(atom/over_object,atom/src_location,atom/over_location,src_control,over_control,params)
over_object?.ItemDropped(src,over_location,src_location,over_control,src_control,params)


Now you've got a function that allows you to respond to when an item is dropped on something.

Let's add dropping behavior when you drag it over an atom on the map.

atom
proc
ItemDropped(obj/item/item,atom/src_location,atom/item_location,src_control,item_control,params)
if(!item_location && src_control=="default.map1" && isturf(src_location))
item.Dropped(usr, src_location)

obj/item
proc
Dropped(mob/user, turf/location)
src.Move(location)


You can also override this function for any UI objects that need to receive items from a drag and drop.
In response to Ter13
Ter13 wrote:
Your code snippet's invalid. MouseDrop() is not a var.

But also, you really want to implement this the other way around:

> atom/proc
> ItemDropped(obj/item/item,atom/src_location,atom/item_location,src_control,item_control,params)
>
> obj/item
> MouseDrop(atom/over_object,atom/src_location,atom/over_location,src_control,over_control,params)
> over_object?.ItemDropped(src,over_location,src_location,over_control,src_control,params)
>

Now you've got a function that allows you to respond to when an item is dropped on something.

Let's add dropping behavior when you drag it over an atom on the map.

> atom
> proc
> ItemDropped(obj/item/item,atom/src_location,atom/item_location,src_control,item_control,params)
> if(!item_location && src_control=="default.map1" && isturf(src_location))
> item.Dropped(usr, src_location)
>
> obj/item
> proc
> Dropped(mob/user, turf/location)
> src.Move(location)
>

You can also override this function for any UI objects that need to receive items from a drag and drop.

obj/item
MouseDrag(src_object,over_object,src_location,over_location,src_control,over_control,params)
mouse_drag_pointer = icon(icon, icon_state)
MouseDrop(over_object,src_location,over_location,src_control,over_control,params)
if(src_control=="backpack.mapbackpack"&&over_control == "default.map1") //
if(usr.dir == NORTH)
src.loc = locate(usr.x,usr.y+1,usr.z)
if(usr.dir == SOUTH)
src.loc = locate(usr.x,usr.y-1,usr.z)
if(usr.dir == EAST)
src.loc = locate(usr.x+1,usr.y,usr.z)
if(usr.dir == WEST)
src.loc = locate(usr.x-1,usr.y,usr.z)


My code is working like this, but the item does not leave the backpack when dropped on the map, any suggestions?
Did you ever remove the object from the screen?
In response to Ter13
Ter13 wrote:
Did you ever remove the object from the screen?

The object only falls on the map but does not leave the backpack, it is not removed from it
In response to Haxter123
Haxter123 wrote:
Ter13 wrote:
Did you ever remove the object from the screen?

The object only falls on the map but does not leave the backpack, it is not removed from it

The backpack is in the screen, right? The items are in the screen right? You need to remove them from the screen.

You added these objects to the screen/backpack somehow. You need to do the inverse: Remove them from the screen/backpack.


A few additional pointers:

You're doing a lot of work here:

if(usr.dir == NORTH)
src.loc = locate(usr.x,usr.y+1,usr.z)
if(usr.dir == SOUTH)
src.loc = locate(usr.x,usr.y-1,usr.z)
if(usr.dir == EAST)
src.loc = locate(usr.x+1,usr.y,usr.z)
if(usr.dir == WEST)
src.loc = locate(usr.x-1,usr.y,usr.z)


You could use some of BYOND's built-ins to do less work:

var/turf/t = get_step(usr.loc,usr.dir)
if(t)
src.loc = t


If you're worried about this logic not being the same, because your logic doesn't handle diagonals:

var/dir = usr.dir
if(dir&dir-1) //only true for diagonals (only when dir is 8-state)
dir &= (EAST | WEST) //bias the direction toward east/west when diagonal
var/turf/t = get_step(usr.loc,dir)
if(t)
src.loc = t
In response to Ter13
Ter13 wrote:
Haxter123 wrote:
Ter13 wrote:
Did you ever remove the object from the screen?

The object only falls on the map but does not leave the backpack, it is not removed from it

The backpack is in the screen, right? The items are in the screen right? You need to remove them from the screen.

You added these objects to the screen/backpack somehow. You need to do the inverse: Remove them from the screen/backpack.

mob/proc/AddItems(obj/items/I)
for(var/Grid/G in src.client.screen)
if(G.used) continue
I.screen_loc = G.screen_loc ; src.client.screen+=I
G.used =1 ; return


As I'm new to this, and I'm using a code developed by someone else, I believe this is the code to add the item to the backpack, am I correct?
Correct. You'd want to remove it from the screen.

Also, as an aside, if you ever see the pattern:

for(something in client.screen)


You are following degenerate design axioms. You should never have to loop over the client's screen to find something. There are very few situations where this pattern is ever valid.

Generally, you should be storing the objects that you are looking for in a list that only contains like items. This massively reduces the amount of stuff you are asking the engine to filter through to find what you are looking for.

Scope out BYONDiscord; You'll get more responsive help and better pointers over there. The forums are kinda dead.

Login to reply.