ID:1488155
 
(See the best response by Ter13.)
Code:
Zones   
var/MonsterSpot1
var/MonsterSpot2
var/MonsterSpot3
var/MonsterSpot4
var/MonsterSpot5
var/SpellandTrapZone1
var/SpellandTrapZone2
var/SpellandTrapZone3
var/SpellandTrapZone4
var/SpellandTrapZone5
proc
SetUpField(mob/M)
M = usr
if(M.Dueling != TRUE) return
switch(M.dir)
if(NORTH)
src.MonsterSpot1 = locate(M.x, M.y + 2, M.z)
src.MonsterSpot2 = locate(M.x+1,M.y+2,M.z)
src.MonsterSpot3 = locate(M.x-1,M.y + 2,M.z)
src.MonsterSpot4 = locate(M.x-2,M.y + 2,M.z)
src.MonsterSpot5 = locate(M.x + 2,M.y + 2,M.z)
if(SOUTH)
src.MonsterSpot1 = locate(M.x ,M.y-2, M.z)
src.MonsterSpot2 = locate(M.x +1, M.y-2,M.z)
src.MonsterSpot3 = locate(M.x-1, M.y-2,M.z)
src.MonsterSpot4 = locate(M.x-2,M.y-2,M.z)
src.MonsterSpot5 = locate(M.x +2,M.y-2,M.z)
if(WEST)
src.MonsterSpot1 = locate(-2, 0, 0)
src.MonsterSpot2 = locate(-2, 1, 0)
src.MonsterSpot3 = locate(-2, -1, 0)
src.MonsterSpot4 = locate(-2, -2, 0)
src.MonsterSpot5 = locate(-2, 2, 0)
if(WEST)
src.MonsterSpot1 = locate(2, 0, 0)
src.MonsterSpot2 = locate(2, 1, 0)
src.MonsterSpot3 = locate(2, -1, 0)
src.MonsterSpot4 = locate(2, -2, 0)
src.MonsterSpot5 = locate(2, 2, 0)
__________________________________________________
//somewhere in code
var/Zones/zones = new
if(usr.Monsters_Played == 0)
src.loc = locate(usr.zones.MonsterSpot1)


Problem description:
Hi, I found a bug with my original summoning verb for cards, so I remade it. I decided to make it so that when you start the duel, 10 zones appear in front of you(based on dir and how many tiles apart from player.) For some reason though, every time I go to summon, it does not appear on the zone I pointed it towards. I was wondering if someone could help me on why the cards are not appearing on the zones. (Also, this is my first time using Datums)
Are you testing with NORTH or SOUTH dir?
Yes, I am
You didn't understand his question he said are you testing it with the North or the South direction.
I am testing it with both North and South.
There's a lot more to this code that we'd need to analyze to know what's going on I'd imagine.

Add some debugging information in there so that things aren't left to assumption.

Is SetUpField() being called for certain?

Is mob/M what you think it is?


Also, show us more of the code in the second group where it says "somewhere in the code".
Can you face NORTHEAST, SOUTHEAST, SOUTHWEST, or NORTHWEST or do you have your directionals set up to not allow these directions?
obj
var/CardPosition = ""
var/mob/Owner
Cards
var
list/Options = list("Summon", "Set")
DblClick(usr.Hand, MainWindow.info1) //double click card in hand to the choose options
if(!src.Owner)
src.Owner=usr
if(usr.Dueling == 0)
return
if(usr.currentphase == "Battle Phase")
return
else if(src.Owner==usr&&usr.Dueling == 1)
var/cardoptions = input(usr, "Select Option", "Select")as null | anything in src.Options
if(src in usr.Monsters_on_Field)
return
if(cardoptions == "Summon") //option
if(usr.Monsters_Played == 5) return
if(usr.Normal_Summoned == TRUE)
usr << "You cannot normal summon this turn"
return
if(usr.isturn == FALSE)
usr << "You cannot normal summon during your opponent's turn!"
return
if(src.Card != "Monster")
return
if(src.Level <= 4)
usr.Normal_Summoned = TRUE
src.Owner = usr
src.CardPosition = "Attack"
src.dir = usr.dir
usr.Hand.Remove(src)
if(usr.Monsters_Played == 0) //here is where the datum proc is called
src.loc = locate(usr.zones.MonsterSpot1) //Card location equals MonsterSpot1 location
usr.Monsters_on_Field += src //adds it to player's field list to keep track of everything
usr.Monsters_Played ++
animate(src, alpha = 255, time = 10)
Zones
var/MonsterSpot1
var/MonsterSpot2
var/MonsterSpot3
var/MonsterSpot4
var/MonsterSpot5
var/SpellandTrapZone1
var/SpellandTrapZone2
var/SpellandTrapZone3
var/SpellandTrapZone4
var/SpellandTrapZone5
proc
SetUpField(mob/M)
M = usr //M is equal to usr, who is the player. Src is /Zones.
if(M.Dueling != TRUE) return //if the opponent isn't dueling, it returns.
switch(M.dir) //switches the players dir
if(NORTH)
src.MonsterSpot1 = locate(M.x, M.y + 2, M.z)
src.MonsterSpot2 = locate(M.x+1,M.y+2,M.z)
src.MonsterSpot3 = locate(M.x-1,M.y + 2,M.z)
src.MonsterSpot4 = locate(M.x-2,M.y + 2,M.z)
src.MonsterSpot5 = locate(M.x + 2,M.y + 2,M.z)
if(SOUTH)
src.MonsterSpot1 = locate(M.x ,M.y-2, M.z)
src.MonsterSpot2 = locate(M.x +1, M.y-2,M.z)
src.MonsterSpot3 = locate(M.x-1, M.y-2,M.z)
src.MonsterSpot4 = locate(M.x-2,M.y-2,M.z)
src.MonsterSpot5 = locate(M.x +2,M.y-2,M.z)
if(WEST)
src.MonsterSpot1 = locate(-2, 0, 0)
src.MonsterSpot2 = locate(-2, 1, 0)
src.MonsterSpot3 = locate(-2, -1, 0)
src.MonsterSpot4 = locate(-2, -2, 0)
src.MonsterSpot5 = locate(-2, 2, 0)
if(WEST)
src.MonsterSpot1 = locate(2, 0, 0)
src.MonsterSpot2 = locate(2, 1, 0)
src.MonsterSpot3 = locate(2, -1, 0)
src.MonsterSpot4 = locate(2, -2, 0)
src.MonsterSpot5 = locate(2, 2, 0)


Here's more of the code. The proc is certainly being called in another proc, but I didn't think it was that important since it's just calling the proc. (The proc it's calling is SetUpField() which, as you guessed, sets up the field between two players) Also, I have it so the other cardinal directions are NOT set up. This is intentional.
               if(WEST)
src.MonsterSpot1 = locate(-2, 0, 0)
src.MonsterSpot2 = locate(-2, 1, 0)
src.MonsterSpot3 = locate(-2, -1, 0)
src.MonsterSpot4 = locate(-2, -2, 0)
src.MonsterSpot5 = locate(-2, 2, 0)
if(WEST)
src.MonsterSpot1 = locate(2, 0, 0)
src.MonsterSpot2 = locate(2, 1, 0)
src.MonsterSpot3 = locate(2, -1, 0)
src.MonsterSpot4 = locate(2, -2, 0)
src.MonsterSpot5 = locate(2, 2, 0)


You might want one of these to be EAST.
Also the Z level for these locations are 0, that's void.
So, both players initiate a call to SetUpField()? Just for sanity's sake, put in some diagnostics information in the SetUpField() procedure like so...

    proc
SetUpField(mob/M)
M = usr //M is equal to usr, who is the player. Src is /Zones.
world << "M = [M]"
if(M.Dueling != TRUE)
world << "M is not dueling."
return //if the opponent isn't dueling, it returns.
world << "M.dir = [M.dir]"
switch(M.dir) //switches the players dir
if(NORTH)
src.MonsterSpot1 = locate(M.x, M.y + 2, M.z)
src.MonsterSpot2 = locate(M.x+1,M.y+2,M.z)
src.MonsterSpot3 = locate(M.x-1,M.y + 2,M.z)
src.MonsterSpot4 = locate(M.x-2,M.y + 2,M.z)
src.MonsterSpot5 = locate(M.x + 2,M.y + 2,M.z)
if(SOUTH)
src.MonsterSpot1 = locate(M.x ,M.y-2, M.z)
src.MonsterSpot2 = locate(M.x +1, M.y-2,M.z)
src.MonsterSpot3 = locate(M.x-1, M.y-2,M.z)
src.MonsterSpot4 = locate(M.x-2,M.y-2,M.z)
src.MonsterSpot5 = locate(M.x +2,M.y-2,M.z)
I feel like it'd be easier to just use a reference point and iteratively assign the turfs to variables.

Zone/DZ = new ()
/* You seem to be keeping x or y constant, so let's jam that
into a variable*/

var/dist_dif = 2
/* Unless it's terribly important that these monster spots
be in this order (it probably isn't), I'd use a list.*/

var/list/MosnterSpots = list()
var/steady = "Y"
switch(M.dir)
if(NORTH)
break // Don't need to change anything for NORTH
if(WEST) // Just an additional example
steady = "X"
break
for(var/i = -2 , i <= 2, i++)
if(steady == "Y")
MonsterSpots += locate(M.x + i, M.y + dist_diff, M.z))


I dunno, maybe I overthink things.

EDIT: I'd probably add a dist_dir variable so I know whether to add dist_diff or subtract it.
Not a bad way to accomplish things, but I believe his problem is occurring elsewhere and would probably persist using your method as well.
Ok, so I figured out the problem and had to get rid of the datum :/ (which sucks because I really wanted to use it). Anywho, now my problem resides in the monsters placement. Basically, if there is something in MonsterSpot1, the card should be in MonsterSpot2. If there's a card in MonsterSpot2 and 3, the card location should be placed in MonsterSpot1(that is, if MonsterSpot1 isn't taken). What's my problem? I can't figure out the best way to do this while also saving me some time. Let me post my code I have and I'll show you where this MonsterSpot placement thing should be.

obj
var/CardPosition = ""
var/mob/Owner
Cards
var
list/Options = list("Summon", "Set")
DblClick(usr.Hand, MainWindow.info1)
if(!src.Owner)
src.Owner=usr
if(usr.Dueling == 0)
return
if(usr.currentphase == "Battle Phase")
return
else if(src.Owner==usr&&usr.Dueling == 1)
var/cardoptions = input(usr, "Select Option", "Select")as null | anything in src.Options
if(src in usr.Monsters_on_Field)
return
if(cardoptions == "Summon")
if(usr.Monsters_Played == 5) return
if(usr.Normal_Summoned == TRUE)
usr << "You cannot normal summon this turn"
return
if(usr.isturn == FALSE)
usr << "You cannot normal summon during your opponent's turn!"
return
if(src.Card != "Monster")
return
if(src.Level <= 4)
usr.Normal_Summoned = TRUE
src.Owner = usr
src.CardPosition = "Attack"
src.dir = usr.dir
usr.Hand.Remove(src)
//code here to where monster placement begins
usr.Monsters_on_Field += src
usr.Monsters_Played ++
animate(src, alpha = 255, time = 10)
mob
var/MonsterSpot1
var/MonsterSpot2
var/MonsterSpot3
var/MonsterSpot4
var/MonsterSpot5
var/SpellandTrapZone1
var/SpellandTrapZone2
var/SpellandTrapZone3
var/SpellandTrapZone4
var/SpellandTrapZone5
proc
SetUpField() //M is equal to usr, who is the player. Src is /Zones.
if(src.Dueling != TRUE) return //if the opponent isn't dueling, it returns.
switch(src.dir) //switches the players dir
if(NORTH)
MonsterSpot1 = locate(src.x, src.y + 2, src.z)
MonsterSpot2 = locate(src.x+1,src.y+2,src.z)
MonsterSpot3 = locate(src.x-1,src.y + 2,src.z)
MonsterSpot4 = locate(src.x-2,src.y + 2,src.z)
MonsterSpot5 = locate(src.x + 2,src.y + 2,src.z)
if(SOUTH)
MonsterSpot1 = locate(src.x ,src.y-2, src.z)
MonsterSpot2 = locate(src.x +1, src.y-2,src.z)
MonsterSpot3 = locate(src.x-1, src.y-2,src.z)
MonsterSpot4 = locate(src.x-2,src.y-2,src.z)
MonsterSpot5 = locate(src.x +2,src.y-2,src.z)
if(WEST)
MonsterSpot1 = locate(-2, 0, 0)
MonsterSpot2 = locate(-2, 1, 0)
MonsterSpot3 = locate(-2, -1, 0)
MonsterSpot4 = locate(-2, -2, 0)
MonsterSpot5 = locate(-2, 2, 0)
if(EAST)
MonsterSpot1 = locate(2, 0, 0)
MonsterSpot2 = locate(2, 1, 0)
MonsterSpot3 = locate(2, -1, 0)
MonsterSpot4 = locate(2, -2, 0)
MonsterSpot5 = locate(2, 2, 0)
Best response
Doing a lot of unnecessary work there. A list based approach would be infinitely better to work with.

mob
var/tmp
field/field
proc
buildField()
field = new/field(dir,x,y,z)
field
var
dir
list/monsterspaces
list/spellspaces
New(dir,x,y,z)
src.dir = dir
var/dx = 0
var/dy = 0
switch(dir)
if(NORTH)
dy = 1
if(SOUTH)
dy = -1
if(EAST)
dx = 1
if(WEST)
dx = -1
else
return null
//get spaces based on deltaX/Y
monsterspaces = list(locate(x + 2*dx,y + 2*dy,z),locate(x + dy + 2*dx,y + dx + 2*dy,z),locate(x - dy + 2*dx,y - dx + 2*dy,z),locate(x + 2*dy + 2*dx,y + 2*dx + 2*dy,z),locate(x - 2*dy + 2*dx,y - 2*dx + 2*dy,z))
spellspaces = list(locate(x + dx,y + dy,z),locate(x + dy + dx,y + dx + dy,z),locate(x - dy + dx,y - dx + dy,z),locate(x + 2*dy + dx,y + 2*dx + dy,z),locate(x - 2*dy + dx,y - 2*dx + dy,z))
return src


obj
visual_card
var/tmp
mob/owner
card/card
field_card
New(owner,card,turf/t)
src.loc = t
src.owner = owner
src.card = card
return src
DblClick()
usr.FieldSelection(src,owner)
hand_card
DblClick()
usr.HandSelection(src,owner)


Now, let's say we want to place the card on the field?

We are going to do something like this: (Where src is equal to mob.)

var/list/l
if(card.field_placement==MONSTER_CARD)
l = src.field.monsterspaces
else if(card.field_placement==SPELL_CARD)
l = src.field.spellspaces

for(var/turf/t in l)
if(!(locate(/obj/visual_card/field_card) in t)
return new/obj/visual_card/field_card(src,card,t)
return null


The above will look through the areas that we set up in the field datum for the mob, then if it finds an open space, it will create the card on the field and return it. If we don't find a space, it does nothing, and returns null.

Since the monster/spell spaces are in order, going outward from the center, the cards will be created at the center, and tend to go outward from there.

This saves you a lot of those messy if-statements you were using, and shortens up your code quite a bit.
Oh, and to answer your original problem:

The reason the object is not showing up, is because of this line:

src.loc = locate(usr.zones.MonsterSpot1)


usr.zones.MonsterSpot1 is a turf.

locate(turf) is going to return null.

You want to use this instead:

src.loc = usr.zones.MonsterSpot1


Other than that, check out my above post for better approaches to how you are handling things.