ID:145656
 
Code:
mob/Ice_Wizard/spells
verb
Ice_Idol()
set category = "Spells"
if(istype(usr.loc.loc,/area/no_spell)) {usr << "<b>No casting spells in a no-spell area!"; return;} //In your spellcasting VERB
if(usr.Mana<=25)
usr << "<font color=blue><font size=2>*Not Enough Mana!"
return
if(usr.Mana>=25)
usr.Mana-=25
view() << "<font color=red><font size=2>*[usr] drops to the ground,rises up slowly and summons an ice idol that will last 30 sec!!"
new /obj/wall/iceidol (src.loc)

obj/wall/iceidol/New()
..()
spawn(300) del src

obj/wall/iceidol
icon = 'Spells.dmi'
icon_state = "ice idol"
layer=4
for(var/mob/M in range(4,src))
if(M.element=="Ice Wizard")
M << "<font color=red><font size=2>*You feel the presence of an Ice Idol and you gain power!"
M.Health+=40
M.Mana+=40
return
else
M << "<font color=red><font size=2>*You see an Ice Idol but cannot harness its power."


Problem description:
I am trying to make a spell were you can create an idol on the ground that gives off bonuses for ice wizards only if they are near it. This code is kind of like how I want it to be, when the Ice Idol is present add some stuff, then it disappears after 30 secs and the bonuses retract.

Well you can't simply put for() under an obj definition and expect it to work. for() belongs in a verb or proc.

In this case, though, a constant polling loop is no good. Think of all the cycles this thing is going to drain while it's doing nothing, and meanwhile it'll spam anyone in range with messages.

What I'd suggest instead is to create a new type, /obj/proximity, and put the ice idol under that. When a player enters a turf, it checks for any /obj/proximity objects in the area and then checks their range to see if you're in it. If you weren't before, it notifies the object of the change of status and the object will run a proc to display a message or so, and keep operating as long as you're in range. The same notification may occur if the object moves.
obj/proximity
var/myrange=4
var/rsq
var/list/mobs

New()
..()
rsq = myrange * (myrange+1) // use for circular distance check

proc/EnterRange(mob/M)
if(!M || !isatom(M) || (M in mobs)) return
if(M.z!=z || (M.x-x)*(M.x-x) + (M.y-y)*(M.y-y) > rsq) return
if(!mobs) mobs=new
mobs+=M
Effect(M)

proc/ExitRange(mob/M)
if(!M || !isatom(M) || !(M in mobs)) return
if(M.z==z && (M.x-x)*(M.x-x) + (M.y-y)*(M.y-y) <= rsq) return
mobs-=M
if(!mobs.len) mobs=null

proc/Effect()
// leave blank; could be used for looping

Move()
. = ..()
if(.)
var/mob/M
for(M in range(myrange, src)-mobs)
EnterRange(M)
for(M in mobs)
ExitRange(M)

turf
Entered(atom/movable/A)
if(ismob(A))
for(var/obj/proximity/P in range(12, src))
P.EnterRange(A)

Exited(atom/movable/A)
if(ismob(A))
for(var/obj/proximity/P in range(12, src))
P.ExitRange(A)

Lummox JR
In response to Lummox JR
Lummox, please, you can't think Drakiel is going to understand any of that? :|
In response to Mysame
Mysame wrote:
Lummox, please, you can't think Drakiel is going to understand any of that? :|

The beauty of it is, he doesn't have to. That code is pretty much plug 'n' play. All he has to do is make sure he redefines his idol as /obj/proximity/iceidol, and puts the relevant code in the Effect() proc, like so:
obj/proximity/iceidol
icon = 'Spells.dmi'
icon_state = "ice idol"
layer=4
myrange=4

Effect(mob/M)
if(M.element=="Ice Wizard")
M << "<span class=spell>You feel the presence of an Ice Idol and you gain power!</span>"
else
M << "<span class=spell>You see an Ice Idol but cannot harness its power.</span>"
return
while(1)
sleep(10)
if(!(M in mobs)) return
M.Health = min(M.Health + 1, M.MaxHealth)
M.Mana = min(M.Mana + 1, M.MaxMana)

Now this system is probably limited in that there's really no way yet to cancel the ongoing Effect() proc, and that sets up a potential for abuse by stepping out and then back in quickly. I'd recommend adding another var to prevent that.
  var/list/affecting

Effect(mob/M)
if(M.element=="Ice Wizard")
M << "<span class=spell>You feel the presence of an Ice Idol and you gain power!</span>"
else
M << "<span class=spell>You see an Ice Idol but cannot harness its power.</span>"
return
if(!affecting) affecting=new
affecting[M]=world.time+10
while(1)
sleep(10)
if(!(M in mobs))
affecting-=M
if(!affecting) affecting=null
return
// avoid double-tapping
if(world.time<affecting[M]) return
affecting[M]=world.time+10
M.Health = min(M.Health + 1, M.MaxHealth)
M.Mana = min(M.Mana + 1, M.MaxMana)

Lummox JR
In response to Lummox JR
error:isatom:undefined proc

I put everything together, except for the verb itself on how to put it down...unless the first way I had it was kind of right...
Anywho, I need help on where I put the effects
M.Health = min(M.Health + 1, M.MaxHealth)
M.Mana = min(M.Mana + 1, M.MaxMana)

Im not sure if i replace the 1 with watever I want or not.