ID:138825
 
Code:
obj/fire
icon = 'fire.dmi'
density = 0
opacity = 0
luminosity = 1
Enter(mob/O)
O.health -= 4
step_away(O,src,1)
return ..()

New()
spawn(50)
opacity = 1
new src(locate(x+1,y+1,z))
new src(locate(x-1,y+1,z))
new src(locate(x+1,y-1,z))
new src(locate(x-1,y-1,z))
new src(locate(x,y+1,z))
new src(locate(x,y-1,z))
new src(locate(x+1,y,z))
new src(locate(x-1,y,z))


Problem description:
Supposedly, the fire will upon being spawned damage anything it touches and spawn more fire after 5 seconds. Problem is, it doesn't spawn any fire.
Instead, it gives me this error message:

runtime error: Cannot create objects of type /obj/fire.
proc name: New (/obj/fire/New)
usr: Timelimit (/mob/Mod/Admin)
src: the fire (/obj/fire)
call stack:
the fire (/obj/fire): New(the woodfloor (8,38,1) (/turf/woodfloor))


It also gives me this when I log in, and my Login() proc is completely irrelevant to fire.

A few things here:

A: Remember to call the default action at the end of <code>New()</code> or nothing will be created!

B: As you currently have it, this will spawn an infinate loop of fire spawning. I would suggest making a /fire/spawned type, and overwriting the <code>New()</code> proc to not spawn the fire again.

C: Try new src.type(etc)
In response to El Wookie (#1)
A: Thanks.

B: I actually do want it to spawn infinite fire, to make fire that keeps spreading, although I guess limiting it would be good, else eventually the whole world will be burnt to ashes.

C: It works, thanks!

I don't know if I said this earlier, but touching the fire doesn't damage me at all. Why is that?
In response to Timelimit (#2)
Timelimit wrote:
I don't know if I said this earlier, but touching the fire doesn't damage me at all. Why is that?

You never tried to enter the obj, but the turf that has it.
In response to Jemai1 (#3)
Jemai1 wrote:
Timelimit wrote:
I don't know if I said this earlier, but touching the fire doesn't damage me at all. Why is that?

You never tried to enter the obj, but the turf that has it.

I tried with Bump() instead of Enter() and making fire dense, still doesn't hurt me.
In response to Timelimit (#4)
It's not the obj that bumps your mob. It's your mob that bumps the obj. That's why.
In response to Jemai1 (#5)
Jemai1 wrote:
It's not the obj that bumps your mob. It's your mob that bumps the obj. That's why.

Ah, well here's what I tried after reading that:

// /mob stuff
Bump(O)
if(O.type == /turf/fire)
health-=4
if(health < 0)
Death(usr,30)


Which gives this error:

RPG_Game.dm:254:error: O.type: undefined var
RPG_Game.dm:254:error: /turf/fire: undefined type path


Also, another problem:

Sorry, the following is not valid: fire
usage: z-spawn parameter


This appeared when I tried spawning fire, after making a change that deletes the fire after it spawns more fire.

EDIT: Also, since I added this in the game goes more and more laggy constantly, even when I don't even do anything involving fire.
In response to Timelimit (#6)
RPG_Game.dm:254:error: O.type: undefined var

You didn't define O as a datum that holds a type var. Therefore, O.type is undefined.


RPG_Game.dm:254:error: /turf/fire: undefined type path

There's no such thing as /turf/fire on your code. You only have /obj/fire.


What you wanna do is something like this:
turf
Entered(atom/movable/Obj,atom/OldLoc)
if(ismob(Obj))
for(var/obj/O in src)
O.steppedonby(Obj) // Obj steps on O
return ..()

obj
proc
steppedonby(var/mob/M) // doesn't do anything by default

obj/fire

steppedonby(var/mob/M) // override
spawn
while(M && loc && loc == M.loc) // burn continuously while M exists and they are on the same location
M.damaged(4)
sleep(2)

fire // /obj/fire/fire, fire that spreads
New()
.=..()
for(var/turf/T in oview(src,1)) // spread fire around it
new /obj/fire (T) // fire that does not spread

mob
proc
damaged(var/d) // universal damaged proc
health -= d
if(health <= 0)
Death(src,30) // look up the src var in the reference/guide


In response to Jemai1 (#7)
I wouldn't recommend using a <code>while()</code> loop when there's this many of the fire objs. Rather the <code>Bump()</code> method.
In response to El Wookie (#8)
A while loop will only be called if some mob actually steps on a fire obj. Plus, the loop can be dropped by the OP if he wishes to do so since it's just an example.
In response to Jemai1 (#7)
I did something which SHOULD work (no errors at least), I still can't spawn fire though which is odd (the verb does let me spawn anything else though) and it still lags the game even when there's no fire on screen.

Here's the code which I'm using right now:

turf
Entered(mob/O)
if(/obj/fire in contents)
for()
O.health -= 4
if(!O in contents || !/obj/fire in contents)
break
sleep(10)
return ..




In response to Timelimit (#10)
turf
Entered(mob/O)
if( ismob(O) && (locate(/obj/fire) in src) )
spawn
while( O && O in src && (locate(/obj/fire) in src) )
O.health -= 4
//death check here
sleep(10)
return ..()


obj/fire
icon = 'fire.dmi'


Gtg to sleep. I have classes tomorrow.
In response to Jemai1 (#11)
I'm using that code and still, it just won't work. My health isn't going down.
In response to Timelimit (#12)
Enclose O in src with parentheses. Forgot to do that earlier.
while( O && (O in src) && (locate(/obj/fire) in src) )


Btw, there's a problem with the code that I showed you. There's a possibility that a mob enters, leaves and reenters the turf within 2 ticks. That would cause multiple and simultaneous burning damages. I'd recommend to change it to like this:
turf
var/tmp/burning = 0
Entered(atom/movable/O)
if( !burning && ismob(O) && (locate(/obj/fire) in src) )
burning = 1
spawn
while( locate(/obj/fire) in src )
for(var/mob/M in src)
M.health -= 4
if(M.health <= 0)
// respawn / delete / whatever
sleep(10)
burning = 0
return ..()


It may not be the best way to do it but it should work fine.
In response to Jemai1 (#13)
Ok, that works but I have another problem, I rewrote the code for spreading the fire so it won't spread through dense stuff. It looks like this:

fire
icon = 'fire.dmi'
density = 0
opacity = 0
luminosity = 1
New()
spawn(30)
var/turf/O
opacity = 1
for(O in orange(1,src))
if(!O.density)
new src.type(O)
del src


It spreads, but it doesn't delete itself.
In response to Timelimit (#14)
Hey, you. Yes, you. You are not listening.

Doing it like that will produce an infinite loop.
The New() proc will always be called when creating an instance of a datum, like when using new.
Meaning, whenever you make an instance of /obj/fire, it's New() proc will be called.

If you still didn't realize your mistake, your New() proc creates 8 /obj/fire instances around the original /obj/fire instance.
Those 8 /obj/fire instances' New() proc will also be called. They will create another 8 around them, each. That would be 64 more.
Those 64 will also create 8 each, and so on.

It is a never ending process. Thus, your del instruction never gets called.

In my previous example, I defined /obj/fire and /obj/fire/fire datums.
/obj/fire's New() proc was not overridden. It just creates the /obj/fire instance by default.
On the other hand, /obj/fire/fire's New() proc creates a instance of /obj/fire/fire then creates 8 /obj/fire instances around it.
Of course, those 8 /obj/fire instances' New() proc gets called but, as I have said earlier (written in italics), their New() proc don't do anything extra aside from the default behavior, which is just creating the instance. Therefore, it ends there.

In simple terms, if you create a /obj/fire/fire instance, you'll get additional 8 /obj/fire instances. Nothing more.