ID:2107809
 
(See the best response by Kaiochao.)
Code:
Add_Player_SummonList(mob/M in world)
set category="Owner"
set name="Add to Summon List"
SummonList+=M
usr<<"You added [M] to the Summon List!"
Remove_Player_SummonList(mob/M in world)
set category="Owner"
set name="Remove from Summon List"
SummonList-=M
usr<<"You removed [M] from the Summon List!"
Summon_SummonList()
set category="Owner"
set name="Summoner"
for(var/mob/M in SummonList)
world<<output("<B><font color=red>Kuchiyose no Jutsu! [M.name]!")
new/obj/immortality(M.loc)
M.freeze=1
sleep(10)
new/obj/immortalityfire(M.loc)
sleep(1)
M.alpha=0
sleep(1)
new/obj/immortality(locate(x,y-2,z))
sleep(10)
new/obj/immortalityfire(locate(x,y-2,z))
sleep(1)
M.alpha=initial(alpha)
sleep(1)
M.loc=(locate(x,y-2,z))
M.freeze=0
M.loc=(locate(x,y-2,z))
new/obj/immortality(M.loc)
M.freeze=1
sleep(10)
new/obj/immortalityfire(M.loc)
sleep(1)
M.alpha=0
sleep(1)
new/obj/immortality(locate(x-2,y,z))
sleep(10)
new/obj/immortalityfire(locate(x-2,y,z))
sleep(1)
M.alpha=initial(alpha)
sleep(1)
M.loc=(locate(x-2,y,z))
M.freeze=0
M.loc=(locate(x-2,y,z))


Problem description:

I am trying to add mobs to a list, and then summon them with a nifty visual, but...

Currently it will summon the mob once at the first location, then summon it at the next, and the moves on to other mobs in the list.

I can't figure a way to essentially summon the first mob at the first location, while simultaneously the other mob at the second, and so on so forth for the four directions around my player.

I have tried several ways, but I ain't that good with lists, and I am stuck.

Can anyone explain a little bit, about what I am doing wrong here?

Or lead me to a source so I can learn what I am doing wrong?

Best response
Everything in the body of your for() loop is repeated "for each" of the mobs in the list, so of course it's going to do the same everything for everything.

You need something to be different for each of the mobs in the list. Here's one way you could do that:
// list of your 4 summon locations
var summon_locations[] = list(
locate(x, y-2, z), // first location
locate(x-2, y, z), // second location,
// etc.
)

// i goes from 1 to the length of SummonList (should be no more than 4)
for(var/i in 1 to SummonList.len)
var mob/M = SummonList[i] // M is the i'th mob in SummonList
M.loc = summon_locations[i] // M.loc is the i'th location in summon_locations
// flashy effects spawn at M.loc etc.
I don't know why but X,Y,Z part of the code gives me an error that they're undefined...

I have never had this problem before, do you reckon I still need to define the X,y,Z vars for this to work?

Or might there be something else I am doing wrong?

 var summon_locations[] = list(
locate(x-2, y, z),
locate(x, y-2, z),
)

Add_Player_SummonList(mob/M in world)
set category="Owner"
set name="Add to Summon List"
SummonList+=M
usr<<"You added [M] to the Summon List!"
Remove_Player_SummonList(mob/M in world)
set category="Owner"
set name="Remove from Summon List"
SummonList-=M
usr<<"You removed [M] from the Summon List!"
Summon_SummonList()
set category="Owner"
set name="Summoner"
for(var/i in 1 to SummonList.len)
var mob/M = SummonList[i] // M is the i'th mob in SummonList
M.loc = summon_locations[i] // M.loc is the i'th location in summon_locations
world<<output("<B><font color=red>Kuchiyose no Jutsu! [M.name]!")
new/obj/immortality(M.loc)
M.freeze=1
sleep(10)
new/obj/immortalityfire(M.loc)
sleep(1)
M.alpha=0
sleep(1)
new/obj/immortality(loc = summon_locations[i])
sleep(10)
new/obj/immortalityfire(loc = summon_locations[i])
sleep(1)
M.alpha=initial(alpha)
sleep(1)


That's what I currently have, I can't get past the var issues, cause I didn't think I'd need to define x,y,z vars :/

Correct me if I am wrong.
mob/var/list/SummonList = list()
mob/var/list/summon_locations[] = list(
locate(x-2, y, z),
locate(x, y-2, z),
)


Tried this but it gives me:

Coding\1.9.Admin Commands.dm:2:error: =: expected a constant expression
In response to Reaperjnr2
Reaperjnr2 wrote:
I don't know why but X,Y,Z part of the code gives me an error that they're undefined...

Because they are undefined. I believe he put "x,y,z" as a matter of example. Fill in the summon_locations list with your desired coordinates.

That kind of confuses me, since I am trying to make it so, the people in the List, will get teleported near me.

In all directions, like so:

 
var/list/SummonList = list()
var/list/summon_locations[] = list(
locate(x-2, y, z), // first location
locate(x, y-2, z), //second
locate(x+2, y, z),
locate(x, y+2, z)
)
//Trying to summon them with this...
Summon_SummonList()
set category="Owner"
set name="Summoner"
for(var/i in 1 to SummonList.len)
var mob/M = SummonList[i] // M is the i'th mob in SummonList
M.loc = summon_locations[i] // M.loc is the i'th location in summon_locations
world<<output("<B><font color=red>Kuchiyose no Jutsu! [M.name]!")
new/obj/immortality(M.loc)
M.freeze=1
sleep(10)
new/obj/immortalityfire(M.loc)
sleep(1)
M.alpha=0
sleep(1)
new/obj/immortality(loc = summon_locations[i])
sleep(10)
new/obj/immortalityfire(loc = summon_locations[i])
sleep(1)
M.alpha=initial(alpha)
sleep(1)
)


Currently trying using the usr.x, usr,y, and usr,z, but that also does not work...
In response to Reaperjnr2
Reaperjnr2 wrote:
That kind of confuses me, since I am trying to make it so, the people in the List, will get teleported near me.

Since I recognize that this is for a Naruto game, I'd personally do it a little differently: I'd have the summon locations be a random tile around my location with an if-statement check to make sure the tile is valid (empty, non-dense, and not already chosen). Doing it that way would be simpler because it's automated through code rather than having to define a static list full of locs.

Example:

Summon_SummonList()
set category="Owner"
set name="Summoner"
var/list/possibleTiles = list() //This will hold all of the possible tiles you can summon to around the player
for(var/turf/T in oview(world.view,usr)) //Populate the list
possibleTiles += T
for(var/i in 1 to SummonList.len)
var/mob/M = SummonList[i] // M is the i'th mob in SummonList
var/turf/chosenTile = pick(summonLocs) //Choose a random turf from the list we populated above
if(chosenTile && chosenTile.Enter(M)) //Make sure it's a valid turf
M.loc = T
possibleTiles -= chosenTile //This prevents summoning to the same tile twice
//**do your other stuff here**


Off-topic but be careful with using sleeps in your for loops. With the way you have it set up, those sleeps will cause problems if the player logs out while the proc is executing the code or something else occurs while it's executing such as the player being killed or something.
That code you gave me needed a new var, so I did it like this:

var/list/SummonList = list()
var/list/summonLocs = list()


and:

Summon_SummonList()
set category="Owner"
set name="Summoner"
var/list/possibleTiles = list() //This will hold all of the possible tiles you can summon to around the player
for(var/turf/T in oview(world.view,usr)) //Populate the list
possibleTiles += T
for(var/i in 1 to SummonList.len)
var/mob/M = SummonList[i] // M is the i'th mob in SummonList
var/turf/chosenTile = pick(summonLocs) //Choose a random turf from the list we populated above
if(chosenTile && chosenTile.Enter(M)) //Make sure it's a valid turf
possibleTiles -= chosenTile //This prevents summoning to the same tile twice
M.freeze=1
new/obj/immortality(M.loc)
sleep(10)
new/obj/immortalityfire(M.loc)
sleep(1)
M.alpha=0
sleep(1)
new/obj/immortality(M.loc)
sleep(10)
new/obj/immortalityfire(M.loc)
sleep(1)
M.alpha=initial(alpha)
M.loc = T
sleep(1)


It gives me:

T undefined var, do I need to make a new var for that just like I did with the list?

I am a newb coder, but trying to figure things out as much as possible on my own.

Those sleep() are used to make the visual look neat, since the mob gets spawned and then the visuals get spawned, instead of visuals first, then the mob.
I made a var with the list:

var/T


didn't work so I tried:

Var/T=0


Didn't work either.

The compilation error didn't occur, but when you click on the verb, it just doesn't do anything :/
In response to Reaperjnr2
Reaperjnr2 wrote:
That code you gave me needed a new var, so I did it like this:

That was my mistake; I changed the name of the variable from summonLocs to possibleTiles because I felt that it was a more explicit name and forgot to change it in the pick(). Just change var/turf/chosenTile = pick(summonLocs) to var/turf/chosenTile = pick(possibleTiles) and remove the summonLocs variable altogether. Hope my mistake didn't confuse you too much.

In response to Reaperjnr2
Reaperjnr2 wrote:
M.loc = T
sleep(1)

It gives me:

T undefined var, do I need to make a new var for that just like I did with the list?

should be M.loc = chosenTile that's why you're getting that error
Goddamn those fixes were so obvious, it hurt my soul that I couldn't find those.

No, in contrary, now I have another way of coding I didn't know before, which did EXACTLY what I wanted, and BETTER.

I cannot thank you ALL enough!
In response to Reaperjnr2
Reaperjnr2 wrote:
Goddamn those fixes were so obvious, it hurt my soul that I couldn't find those.

No, in contrary, now I have another way of coding I didn't know before, which did EXACTLY what I wanted, and BETTER.

I cannot thank you ALL enough!

Here's a simple way you can handle animations without bogging your code up with sleeps. I commented everything so you can understand what's going on:

obj/effect
icon = 'effects.dmi' //Change this to whatever icon you have your effects in
icon_state = "" //Make a blank icon_state so that the effect is only visible during the animation
layer = EFFECTS_LAYER //doesn't have to be
mouse_opacity = 0 //Since this is purely visual, you don't want the mouse to be able to interact with it
New()
spawn(10) del(src) //Assuming you don't have explosions or anything
//with animations longer than 10 frames, this will auto-delete the effect after 10 ticks.
//Even if the animation is only 4 frames (for example), you're fine because we made it only
//visible for the duration of the animation thanks to flick!
..()

proc/showEffect(effectToShow=null, turf/location) //effectToShow is the icon_state of the animation
if(!effectToShow || !location) return
var/obj/effect/E = new(location)
flick(effectToShow,E)


Here's an example of how you could use this in the verb we just fixed:

if(chosenTile && chosenTile.Enter(M)) //Make sure it's a valid turf
M.loc = chosenTile
possibleTiles -= chosenTile //This prevents summoning to the same tile twice
showEffect("smoke cloud", M.loc)

Problem with that is, that it indeed makes the effect show up, but it shows up at the wrong spot.

It instantly transports everyone at the same time, but it shows the summoning effect on a different tile...

 Summon_SummonList()
set category="Owner"
set name="Summoner"
var/list/possibleTiles = list() //This will hold all of the possible tiles you can summon to around the player
for(var/turf/T in oview(world.view,usr)) //Populate the list
possibleTiles += T
for(var/i in 1 to SummonList.len)
var/mob/M = SummonList[i] // M is the i'th mob in SummonList
var/turf/chosenTile = pick(possibleTiles) //Choose a random turf from the list we populated above
if(chosenTile && chosenTile.Enter(M)) //Make sure it's a valid turf
M.freeze=1
M.loc = chosenTile
showEffect("summon", M.loc)
possibleTiles -= chosenTile //This prevents summoning to the same tile twice


Have it set up the right way, it just doesn't spawn them under the summoned.
Oh and I always use the text people send me, after the snippets, since that helps me memorize the functioning of each code better :)
In response to Reaperjnr2
Reaperjnr2 wrote:
Problem with that is, that it indeed makes the effect show up, but it shows up at the wrong spot.

It instantly transports everyone at the same time, but it shows the summoning effect on a different tile...

Have it set up the right way, it just doesn't spawn them under the summoned.

Problem is that I don't know the visual effect you're trying to achieve. Can you take a screenshot of where the effects show and then explain where you want them to show instead?

The showEffect proc allows you to pass in any location so it should be an easy fix once we know where you're trying to make the animations appear

I screenshotted it, and I want the effect to appear under the person I am "summoning"

http://i.imgur.com/DA2oRFU.png
In response to Reaperjnr2
Reaperjnr2 wrote:
I screenshotted it, and I want the effect to appear under the person I am "summoning"

http://i.imgur.com/DA2oRFU.png

For starters, if your effect is larger than world.icon_size, adjustments need to be made to its visual offset. I made the quick showEffect proc under the assumption that your effects were the same size as your mobs. As this is not the case, we'll just need to alter the proc a bit. If we want to keep things simple, we can just add a couple additional arguments to tell the proc the layer and dimensions of the effect it will be showing, and then handle the offset based on that argument:

proc/showEffect(effectToShow=null, turf/location, size=world.icon_size, effLayer=EFFECTS_LAYER) //effectToShow is the icon_state of the animation
if(!effectToShow || !location) return
var/obj/effect/E = new(location)
E.layer = effLayer
var/offset = 0
switch(size)
if(64) offset = 16
if(96) offset = 32
E.pixel_x -= offset
E.pixel_y -= offset
flick(effectToShow,E)


Note: there's a better way to handle the offset with less lines of code that doesn't require switch, but my brain refuses to math right now.

Our updated showEffect proc in use for your specific problem (assuming those summon seals are 96x96 and your mobs are 32x32):

showEffect("summon",M.loc,96,M.layer-1)

... The summon list goes in the verb, too. I copied the locations straight from your code. x, y, z belong to src.
In response to Kaiochao
Kaiochao wrote:
... The summon list goes in the verb, too. I copied the locations straight from your code. x, y, z belong to src.


I am a little bit confused as to what you mean, care to elaborate?

Page: 1 2