ID:2421255
 
Error:

runtime error: bad icon operation
proc name: Insert (/icon/proc/Insert)
usr: IceFire2050 (/mob)
src: /icon (/icon)
usr.loc: (41,129,1) (/turf/FLOOR/ROAD)
call stack:
/icon (/icon): Insert(/icon (/icon), "", 2, 1, null, null)
IceFire2050 (/mob): Number Overlay Test()

Code:
    Number_Icon_Test()
set category = "Testing"

var/obj/number_overlay/number = new

var/obj/number_overlay/grow_a1 = new
var/obj/number_overlay/grow_a2 = new
var/obj/number_overlay/grow_a3 = new

var/obj/number_overlay/grow_b1 = new
var/obj/number_overlay/grow_b2 = new
var/obj/number_overlay/grow_b3 = new

var/obj/number_overlay/grow_c1 = new
var/obj/number_overlay/grow_c2 = new
var/obj/number_overlay/grow_c3 = new


var/obj/number_overlay/number_c = new
var/obj/number_overlay/c_glow = new

//Icons to work on
var/icon/i_b = new
var/icon/i_o = new
var/icon/i_i = new

var/icon/i_b2 = new
var/icon/i_o2 = new
var/icon/i_i2 = new

var/icon/i_b3 = new
var/icon/i_o3 = new
var/icon/i_i3 = new

var/icon/i_b4 = new
var/icon/i_o4 = new
var/icon/i_i4 = new

//Chaos
var/icon/i_c1 = new
var/icon/i_c2 = new
var/icon/i_c3 = new
var/icon/i_c4 = new
var/icon/i_c5 = new

var/icon/i_bx = icon('number_overlay.dmi')
var/icon/i_ox = icon('number_overlay_o.dmi')
var/icon/i_ix = icon('number_overlay_i.dmi')
var/icon/i_chaos = icon('number_overlay_chaos.dmi')

var/R1 = 255
var/G1 = 255
var/B1 = 255

var/R2 = 255
var/G2 = 0
var/B2 = 0

var/istate = ""
var/istate2 = ""
var/istate3 = ""
var/istate4 = ""

var/text_input = input("Enter a Number name","Number Select") as text

var/number_string = ""

var/number_rank = ""

var/num_end = 0

if(findtext(text_input,":"))
num_end = findtext(text_input,":")

number_string = copytext(text_input,8,num_end)


if(findtext(number_string,"iC"))
number_rank = "iC"
number_string = dd_replacetextUD(number_string,"iC","")

if(findtext(number_string,"C"))
number_rank = "C"
number_string = dd_replacetextUD(number_string,"C","")
if(findtext(number_string,"S"))
number_rank = "S"
number_string = dd_replacetextUD(number_string,"S","")
if(findtext(number_string,"F"))
number_rank = "F"
number_string = dd_replacetextUD(number_string,"F","")

if(number_string)
istate = copytext(number_string,1,2)
number_string = copytext(number_string,2,length(number_string)+1)
if(number_string)
istate2 = copytext(number_string,1,2)
number_string = copytext(number_string,2,length(number_string)+1)
if(number_string)
istate3 = copytext(number_string,1,2)
number_string = copytext(number_string,2,length(number_string)+1)
if(number_string)
istate4 = copytext(number_string,1,2)
number_string = copytext(number_string,2,length(number_string)+1)

if(!istate2)
istate2 = istate
istate = "0"

for(var/state in i_bx.IconStates())

if(state == "[istate]")
i_b.Insert(icon(i_bx, state), state == "[istate]" ? "" : state,SOUTH,1)

if(state == "[istate2]")
i_b2.Insert(icon(i_bx, state), state == "[istate2]" ? "" : state,SOUTH,1)

if(istate3)
if(state == "[istate3]")
i_b3.Insert(icon(i_bx, state), state == "[istate3]" ? "" : state,SOUTH,1)

if(istate4)
if(state == "[istate4]")
i_b4.Insert(icon(i_bx, state), state == "[istate4]" ? "" : state,SOUTH,1)


Problem description:

This is only a portion of the code but I'm getting the errors at the insert lines at that point.

It's eventually going to be fed strings of text by another proc, but for testing right now, it asks for an input.

The strings are always going to be in the format of...

"Number 17: Leviathan Dragon"
"Number 39: Utopia"
"Number C96: Dark Storm"
"Number S0: Utopic ZEXAL"

The code takes the string input...
-Removes all text from the string past the colon
-Removes the "Number " from the beginning leaving us with just a string of numbers or possibly 1 letter and a number.
-If the first character is a letter, it gets trimmed out and stored in a seperate var for later use.
-Turns each digit of the number in to its own individual string, up to a possible 4 digits.
-If the Number is single digit, its moved to the second var and a "0" is put in the first var. (Turns 5 in to 05)

Then it looks in the 3 icons provided 'number_overlay.dmi','number_overlay_i.dmi', and 'number_overlay_o.dmi' (stored as i_bx, i_ox, and i_ix) at their states...
-If the state matches one of the digits of the number previously extracted...
-It takes just the state in that file that matches the number and inserts that state in to a new icon based on its digit position (i_b, i_b2, i_b3, and i_b4) and renames it to a blank icon state.

This code WAS working earlier, but i've been working on it all day and after some recent modifications it seems to have stopped working. I cant figure out why, I must have changed something here without remembering it, but I cant find the problem. I use similar code like this for something else in the game and it works fine there.

For clarification... the 3 icons listed are icons with states named "0" , "1", "2", "3", etc etc up to "9".

I get errors on the insert lines. Not sure why, can anyone else help me with a 2nd set of eyes?
After playing around with it a bit more this morning, I only seem to be getting the error on the 1st insert line, not the other 3 but I cant figure out why.
Insert() has to be used on a blank icon, not just an empty icon object, you'd want to create a blank .dmi file and use that inside of icon/new() instead of nothing.

At least it was the last time I used it, the issue may be different at this point because I haven't used icon.Insert() in a very long time, but I do remember always having to use a blank icon to start with.
Try clearing your BYOND cache. It's been known to cause icon procs to fail.
    Number_Overlay_Test_X()
set category = "Testing"

//Overlay Object
var/obj/number_overlay/number = new

var/obj/number_overlay/grow_a1 = new
var/obj/number_overlay/grow_a2 = new
var/obj/number_overlay/grow_a3 = new

var/obj/number_overlay/grow_b1 = new
var/obj/number_overlay/grow_b2 = new
var/obj/number_overlay/grow_b3 = new

var/obj/number_overlay/grow_c1 = new
var/obj/number_overlay/grow_c2 = new
var/obj/number_overlay/grow_c3 = new


var/obj/number_overlay/number_c = new
var/obj/number_overlay/c_glow = new

//Icons to work on
var/icon/i_b = new
var/icon/i_o = new
var/icon/i_i = new

var/icon/i_b2 = new
var/icon/i_o2 = new
var/icon/i_i2 = new

var/icon/i_b3 = new
var/icon/i_o3 = new
var/icon/i_i3 = new

var/icon/i_b4 = new
var/icon/i_o4 = new
var/icon/i_i4 = new

//Chaos
var/icon/i_c1 = new
var/icon/i_c2 = new
var/icon/i_c3 = new
var/icon/i_c4 = new
var/icon/i_c5 = new

var/icon/i_bx = icon('number_overlay.dmi')
var/icon/i_ox = icon('number_overlay_o.dmi')
var/icon/i_ix = icon('number_overlay_i.dmi')
var/icon/i_chaos = icon('number_overlay_chaos.dmi')

var/R1 = 255
var/G1 = 255
var/B1 = 255

var/R2 = 255
var/G2 = 0
var/B2 = 0

var/istate = ""
var/istate2 = ""
var/istate3 = ""
var/istate4 = ""

var/text_input = input("Enter a Number name","Number Select") as text

world << "DEBUG: Input was... '[text_input]'"

var/number_string = ""

var/number_rank = ""

var/num_end = 0

if(findtext(text_input,":"))
num_end = findtext(text_input,":")

number_string = copytext(text_input,8,num_end)

world << "DEBUG: Number is... [number_string]"

if(findtext(number_string,"iC"))
number_rank = "iC"
number_string = dd_replacetextUD(number_string,"iC","")

if(findtext(number_string,"C"))
number_rank = "C"
number_string = dd_replacetextUD(number_string,"C","")
if(findtext(number_string,"S"))
number_rank = "S"
number_string = dd_replacetextUD(number_string,"S","")
if(findtext(number_string,"F"))
number_rank = "F"
number_string = dd_replacetextUD(number_string,"F","")

if(number_string)
istate = copytext(number_string,1,2)
number_string = copytext(number_string,2,length(number_string)+1)
if(number_string)
istate2 = copytext(number_string,1,2)
number_string = copytext(number_string,2,length(number_string)+1)
if(number_string)
istate3 = copytext(number_string,1,2)
number_string = copytext(number_string,2,length(number_string)+1)
if(number_string)
istate4 = copytext(number_string,1,2)
number_string = copytext(number_string,2,length(number_string)+1)

if(!istate2)
istate2 = istate
istate = "0"

world << "DEUBG: Number is ... -[istate]/[istate2]/[istate3]/[istate4]-"

for(var/state in i_bx.IconStates())

if(state == "[istate]")
world.log << "||||||||||CHECK 1 - '[state]' matches '[istate]'|||||||||||||"
i_b.Insert(icon(i_bx, state), state == state ? "" : state,SOUTH,1)
world.log << "||||||||||CHECK 1 - i_b insert complete|||||||||||||"


if(state == "[istate2]")
world.log << "||||||||||CHECK 1 - '[state]' matches '[istate2]'|||||||||||||"
i_b2.Insert(icon(i_bx, state), state == state ? "" : state,SOUTH,1)
world.log << "||||||||||CHECK 1 - i_b2 insert complete|||||||||||||"

if(istate3)
if(state == "[istate3]")
world.log << "||||||||||CHECK 1 - '[state]' matches '[istate3]'|||||||||||||"
i_b3.Insert(icon(i_bx, state), state == state ? "" : state,SOUTH,1)
world.log << "||||||||||CHECK 1 - i_b3 insert complete|||||||||||||"

if(istate4)
if(state == "[istate4]")
world.log << "||||||||||CHECK 1 - '[state]' matches '[istate4]'|||||||||||||"
i_b4.Insert(icon(i_bx, state), state == state ? "" : state,SOUTH,1)
world.log << "||||||||||CHECK 1 - i_b4 insert complete|||||||||||||"

var/obj/number_overlay/numberx1 = new
var/obj/number_overlay/numberx2 = new
var/obj/number_overlay/numberx3 = new
var/obj/number_overlay/numberx4 = new

numberx1.icon = i_b
numberx2.icon = i_b2
numberx3.icon = i_b3
numberx4.icon = i_b4
numberx1.Move(locate(usr.x,usr.y+1,usr.z))
numberx2.Move(locate(usr.x+1,usr.y+1,usr.z))
numberx3.Move(locate(usr.x+2,usr.y+1,usr.z))
numberx4.Move(locate(usr.x+3,usr.y+1,usr.z))

for(var/state in i_ox.IconStates())
if(state == "[istate]")
i_o.Insert(icon(i_ox, state), state == state ? "" : state,,1)
if(state == "[istate2]")
i_o2.Insert(icon(i_ox, state), state == state ? "" : state,,1)
if(istate3)
if(state == "[istate3]")
i_o3.Insert(icon(i_ox, state), state == state ? "" : state,,1)
if(istate4)
if(state == "[istate4]")
i_o4.Insert(icon(i_ox, state), state == state ? "" : state,,1)

var/obj/number_overlay/numberxo1 = new
var/obj/number_overlay/numberxo2 = new
var/obj/number_overlay/numberxo3 = new
var/obj/number_overlay/numberxo4 = new

numberxo1.icon = i_o
numberxo2.icon = i_o2
numberxo3.icon = i_o3
numberxo4.icon = i_o4
numberxo1.Move(locate(usr.x,usr.y+2,usr.z))
numberxo2.Move(locate(usr.x+1,usr.y+2,usr.z))
numberxo3.Move(locate(usr.x+2,usr.y+2,usr.z))
numberxo4.Move(locate(usr.x+3,usr.y+2,usr.z))
for(var/state in i_ix.IconStates())
if(state == "[istate]")
i_i.Insert(icon(i_ix, state), state == state ? "" : state,,1)
if(state == "[istate2]")
i_i2.Insert(icon(i_ix, state), state == state ? "" : state,,1)
if(istate3)
if(state == "[istate3]")
i_i3.Insert(icon(i_ix, state), state == state ? "" : state,,1)
if(istate4)
if(state == "[istate4]")
i_i4.Insert(icon(i_ix, state), state == state ? "" : state,,1)

var/obj/number_overlay/numberxi1 = new
var/obj/number_overlay/numberxi2 = new
var/obj/number_overlay/numberxi3 = new
var/obj/number_overlay/numberxi4 = new

numberxi1.icon = i_i
numberxi2.icon = i_i2
numberxi3.icon = i_i3
numberxi4.icon = i_i4
numberxi1.Move(locate(usr.x,usr.y+3,usr.z))
numberxi2.Move(locate(usr.x+1,usr.y+3,usr.z))
numberxi3.Move(locate(usr.x+2,usr.y+3,usr.z))
numberxi4.Move(locate(usr.x+3,usr.y+3,usr.z))

var/num_switch = "[istate][istate2][istate3][istate4]"

return


Did a bit more testing, added some new lines to get a better idea of how its screwing up, and its definitely the 1st insert line for some reason.

If I enter the string "Number 17: Test"

world << "DEUBG: Number is ... -[istate]/[istate2]/[istate3]/[istate4]-"

spits out

DEUBG: Number is ... -1/7//-"

which it should.

        var/obj/number_overlay/numberx1 = new
var/obj/number_overlay/numberx2 = new
var/obj/number_overlay/numberx3 = new
var/obj/number_overlay/numberx4 = new

numberx1.icon = i_b
numberx2.icon = i_b2
numberx3.icon = i_b3
numberx4.icon = i_b4
numberx1.Move(locate(usr.x,usr.y+1,usr.z))
numberx2.Move(locate(usr.x+1,usr.y+1,usr.z))
numberx3.Move(locate(usr.x+2,usr.y+1,usr.z))
numberx4.Move(locate(usr.x+3,usr.y+1,usr.z))


This code creates 4 objects and positions them where I wanted to see the icons properly, but the first one has no icon.


            if(state == "[istate]")
world.log << "||||||||||CHECK 1 - '[state]' matches '[istate]'|||||||||||||"
i_b.Insert(icon(i_bx, state), state == state ? "" : state,SOUTH,1)
world.log << "||||||||||CHECK 1 - i_b insert complete|||||||||||||"

That is throwing the error for some reason. The logs there seem to run fine.

There doesn't seem to be any reason why that line will throw an error but...

            if(state == "[istate2]")
world.log << "||||||||||CHECK 1 - '[state]' matches '[istate2]'|||||||||||||"
i_b2.Insert(icon(i_bx, state), state == state ? "" : state,SOUTH,1)
world.log << "||||||||||CHECK 1 - i_b2 insert complete|||||||||||||"


That line wont. The only thing different is the icon var. 1st one using 'istate' and the 2nd using 'istate2'

The icon files aren't missing any states, i've tested it and it doesn't matter which number i feed through the state, its always giving an error on that first insert

https://i.imgur.com/zFGIoXK.png
That's the end result on the screen from that. Obviously I should have a set of 1's above me and a set of matching 7's next to it, but the objects with the 1 dont have anything in their icon files.
In response to Kaiochao
Nadrew wrote:
Insert() has to be used on a blank icon, not just an empty icon object, you'd want to create a blank .dmi file and use that inside of icon/new() instead of nothing.

At least it was the last time I used it, the issue may be different at this point because I haven't used icon.Insert() in a very long time, but I do remember always having to use a blank icon to start with.

I have 2 other procs that it works just fine with. 1 in a custom icon creator system and another in a seperate concept proc like this one. They both work fine inserting in to a blank icon object.

In addition, in the example above, only the 1st insert of the 4 is giving an error, the other 3 are working just fine.

Kaiochao wrote:
Try clearing your BYOND cache. It's been known to cause icon procs to fail.

And I've tried clearing my cache, I've tried doing a clean compile, I've tried modifying the icon file slightly to change the header information on the file. None of that has helped.
So I tracked down the apparent cause of the problem... I just dont know how to fix it or even why it's causing a problem in the first place.

Somehow these lines...

        //Chaos
var/icon/i_c1 = new
var/icon/i_c2 = new
var/icon/i_c3 = new
var/icon/i_c4 = new
var/icon/i_c5 = new


Are screwing up this code...

        for(var/state in i_bx.IconStates())


if(state == "[istate]")
world.log << "||||||||||CHECK 1 - '[state]' matches '[istate]'|||||||||||||"
i_b.Insert(icon(i_bx, state), state == state ? "" : state,SOUTH,1)
world.log << "||||||||||CHECK 1 - i_b insert complete|||||||||||||"

if(state == "[istate2]")
world.log << "||||||||||CHECK 1 - '[state]' matches '[istate2]'|||||||||||||"
i_b2.Insert(icon(i_bx, state), state == state ? "" : state,SOUTH,1)
world.log << "||||||||||CHECK 1 - i_b2 insert complete|||||||||||||"

if(istate3)
if(state == "[istate3]")
world.log << "||||||||||CHECK 1 - '[state]' matches '[istate3]'|||||||||||||"
i_b3.Insert(icon(i_bx, state), state == state ? "" : state,SOUTH,1)
world.log << "||||||||||CHECK 1 - i_b3 insert complete|||||||||||||"

if(istate4)
if(state == "[istate4]")
world.log << "||||||||||CHECK 1 - '[state]' matches '[istate4]'|||||||||||||"
i_b4.Insert(icon(i_bx, state), state == state ? "" : state,SOUTH,1)
world.log << "||||||||||CHECK 1 - i_b4 insert complete|||||||||||||"

var/obj/number_overlay/numberx1 = new
var/obj/number_overlay/numberx2 = new
var/obj/number_overlay/numberx3 = new
var/obj/number_overlay/numberx4 = new

numberx1.icon = i_b
numberx2.icon = i_b2
numberx3.icon = i_b3
numberx4.icon = i_b4
numberx1.Move(locate(usr.x,usr.y+1,usr.z))
numberx2.Move(locate(usr.x+1,usr.y+1,usr.z))
numberx3.Move(locate(usr.x+2,usr.y+1,usr.z))
numberx4.Move(locate(usr.x+3,usr.y+1,usr.z))

for(var/state in i_ox.IconStates())
if(state == "[istate]")
i_o.Insert(icon(i_ox, state), state == state ? "" : state,,1)
if(state == "[istate2]")
i_o2.Insert(icon(i_ox, state), state == state ? "" : state,,1)
if(istate3)
if(state == "[istate3]")
i_o3.Insert(icon(i_ox, state), state == state ? "" : state,,1)
if(istate4)
if(state == "[istate4]")
i_o4.Insert(icon(i_ox, state), state == state ? "" : state,,1)

var/obj/number_overlay/numberxo1 = new
var/obj/number_overlay/numberxo2 = new
var/obj/number_overlay/numberxo3 = new
var/obj/number_overlay/numberxo4 = new

numberxo1.icon = i_o
numberxo2.icon = i_o2
numberxo3.icon = i_o3
numberxo4.icon = i_o4
numberxo1.Move(locate(usr.x,usr.y+2,usr.z))
numberxo2.Move(locate(usr.x+1,usr.y+2,usr.z))
numberxo3.Move(locate(usr.x+2,usr.y+2,usr.z))
numberxo4.Move(locate(usr.x+3,usr.y+2,usr.z))
for(var/state in i_ix.IconStates())
if(state == "[istate]")
i_i.Insert(icon(i_ix, state), state == state ? "" : state,,1)
if(state == "[istate2]")
i_i2.Insert(icon(i_ix, state), state == state ? "" : state,,1)
if(istate3)
if(state == "[istate3]")
i_i3.Insert(icon(i_ix, state), state == state ? "" : state,,1)
if(istate4)
if(state == "[istate4]")
i_i4.Insert(icon(i_ix, state), state == state ? "" : state,,1)

var/obj/number_overlay/numberxi1 = new
var/obj/number_overlay/numberxi2 = new
var/obj/number_overlay/numberxi3 = new
var/obj/number_overlay/numberxi4 = new

numberxi1.icon = i_i
numberxi2.icon = i_i2
numberxi3.icon = i_i3
numberxi4.icon = i_i4
numberxi1.Move(locate(usr.x,usr.y+3,usr.z))
numberxi2.Move(locate(usr.x+1,usr.y+3,usr.z))
numberxi3.Move(locate(usr.x+2,usr.y+3,usr.z))
numberxi4.Move(locate(usr.x+3,usr.y+3,usr.z))


For the example below im using the string "Number 1000: Test" to test all 4 inserts and all 4 digit placements.

I stripped the insert stuff down to bare bones at first and it worked again in the smaller segment. So I went back and removed smaller segments of the code 1 by 1 until i found the apparent problem. When I removed those i_c1 - i_c5 vars from the code, it worked again.

https://i.imgur.com/5oWTKdm.png

I put them back in and just removed 1 of them and somehow I got 1 of the inserts to work, when I removed 2 of them, all of the segments worked.

https://i.imgur.com/fP0I9Ky.png

So to clarify...

        var/icon/i_c1 = new
var/icon/i_c2 = new
var/icon/i_c3 = new
var/icon/i_c4 = new
var/icon/i_c5 = new

Fails the first insert of the icon state from i_bx in to i_b, the insert from i_ox in to i_o, and the insert from i_ix in to i_i. But doesnt fail the inserts in to i_b2/i_b3/i_b4 or i_o2/i_o3/i_o4 or i_i2/i_i3/i_i4

//      var/icon/i_c1 = new
// var/icon/i_c2 = new
// var/icon/i_c3 = new
// var/icon/i_c4 = new
// var/icon/i_c5 = new

allows all 12 inserts to work no problem

        var/icon/i_c1 = new
var/icon/i_c2 = new
var/icon/i_c3 = new
var/icon/i_c4 = new
// var/icon/i_c5 = new

Prevents the inserts from i_bx in to i_b and from i_ox in to i_o but allows i_ix in to i_i as well as all the others that normally work.

        var/icon/i_c1 = new
var/icon/i_c2 = new
var/icon/i_c3 = new
// var/icon/i_c4 = new
// var/icon/i_c5 = new

Allows all inserts to work just fine.

I am honestly loss at what's happening at this point. Does anyone have any idea why this is happening?
well... after swapping out my uses of my i_ix, i_ox, and i_bx vars to just icon('____.dmi'), the code seems to be working again.

I dont really understand what the actual issue is here though, if I'm hitting some type of built-in memory issue with icon vars where I can only have so many in the proc before it screws up or something?

Now I need to try and get the actual proc i snipped this code out of working with these changes I guess.
Okay, the big question here: Why are you using icon math operations for a number overlay? Even if you chose not to use maptext, there are far better approaches available for most of these cases.
Im using the code to build icons for use in other parts of the game.

There are 3 layers that are different colors, a number, an outer glow, and an inner glow.

The various layers are being combined in various ways and have different effects/animations applied to them.

This felt like the easier approach to doing that then to icon 130~ ish base icons + animations by hand.

https://i.imgur.com/P1mUoAm.png

I am sure there is a better way to do this, but I'm still relatively new to coding and kind of learning by making procs like this.

I was the head admin on my game when the owner just gave up on the project, he gave me the source but I only had basic coding knowledge, so I've been learning by picking apart the code and making procs like this. I try to use the developer reference when possible, but it's not always helpful.

But my options were either let the game die or learn as I go, I decided to learn as I go instead of shutting things down.
You would definitely do well to look into using maptext for that, especially as there are filters now in 512 that will give you the look you want for minimal fuss. You can use a drop-shadow filter for an inner glow and another for an outer glow, very easily. This is also way less resource-intensive and will result in a better player experience.

Not necessarily a right-now thing, but it'd be a fun project to tackle that would probably give you a good idea of how to improve the game in other areas.