ID:1773934
 
Keywords: blend, icon
(See the best response by Kaiochao.)
Code:
mob
proc
AddText(var/text,mob/M)
var/leftspot=round((length(text)/2)*-3.65)
for(var/i=1,i<=length(text),i++)
var/obj/Text
Text.icon_state="[copytext(text,i,i+1)]"
var/icon/N = new(Text.icon,Text.icon_state)
N.layer=10000
var/r=0
var/g=0
var/b=0
switch(M.Village)
if("Leaf")
r=0
g=238
b=0
if("Rock")
r=133
g=94
b=66
if("Cloud")
r=255
g=215
b=0
if("Mist")
r=198
g=226
b=255
if("Sand")
r=235
g=199
b=158
if("Rain")
r=0
g=150
b=150
if("Grass")
r=0
g=225
b=0
if("Dark")
r=0
g=0
b=0
if("Sun")
r=253
g=208
b=104
if("Moon")
r=159
g=217
b=229
if("Thunder")
r=208
g=255
b=77
if("Waterfall")
r=77
g=214
b=255
if("Sound")
r=213
g=246
b=255
if("Star")
r=156
g=0
b=178
if("Snow")
r=255
g=255
b=255
else
r=0
g=0
b=0
N.Blend(rgb(r,g,b))
N.pixel_x=leftspot
src.overlays+=N
leftspot+=8
obj
Text
icon='Arial7pt.dmi'
icon_state=""
layer=MOB_LAYER+99999999999
pixel_y=-32


Problem description:

Ok..so basically. I'm trying to make something that displays text under mobs. I made it work, but I decided to make it seperate colors for certain Villages, so I did "switch(M.Village) if("Leaf") etc...", but after all that I didn't know how to like.. Blend the new color into the text, anyone know how I can make this work?

By the way,
I'm new at this don't laugh if my post sucks D:
If I do that, it's something like this in game:
runtime error: type mismatch: Text (/obj/Text) += "#00ee00"
proc name: AddText (/mob/proc/AddText)
source file: TextStuff.dm,83
usr: Yusuke11 (/mob)
src: Yusuke11 (/mob)
call stack:
Yusuke11 (/mob): AddText("Yusuke11", Yusuke11 (/mob))
Yusuke11 (/mob): Name()
I don't think I did anything wrong.
Yo problem fixed,ty for helping.
I just decided to make the
var/obj/Text back into var/obj/N=new/obj/Text
and at the end put, N.color=rgb(r,g,b)
Best response
Or, you know,
var village_colors[] = list(
Leaf = rgb(0, 238, 0),
Rock = rgb(133, 94, 66),
// etc.
)
I'm not sure how you're using associative lists.

There's really only one way to use them, which is what I have there.
If you didn't know anything about programming and you were asked to describe this text coloring system, you might say something like "each village has a certain color."

In other words (still not technically programming lingo): "each village is associated with a certain color."

In DM, we can represent a set of associations as an associative list, where one thing (e.g. village) gets you another thing (e.g. color).
:o those help a learned and I learned a lot ty, I'm actually a beginner at this stuff xD
Reformist wrote:
Considering rgb() is an icon proc, you should just be able to do N += rgb(r,g,b).

rgb() is not an icon proc. It returns a text string in the format of "#RRGGBB" or "#RRGGBBAA"
Or I can just do:
mob
var
Village="Cloud"
VillageColors=list(Leaf = rgb(0, 238, 0),Cloud = rgb(255,255,0))//etc
proc
AddText(var/text,mob/M)
var/leftspot=round((length(text)/2)*-3.65)
for(var/i=1,i<=length(text),i++)
var/obj/N = new/obj/Text
N.icon_state="[copytext(text,i,i+1)]"
N.pixel_x=leftspot
N.color = VillageColors[src.Village]
src.overlays+=N
leftspot+=8
obj
Text
icon='Arial7pt.dmi'
icon_state=""
layer=10000
pixel_y=-32

:P
In response to Yusuke11
You could also try to use the built-in maptext feature, which is a lot more efficient, doesn't need a bunch of objects as overlays, doesn't need an icon file full of characters, and can be colored and formatted using HTML.
mob
var obj/village_text

proc
AddText(Text)
if(village_text)
overlays -= village_text
else
village_text = new
village_text.pixel_y = -32
village_text.layer = 1e5
village_text.maptext = "<font face=arial size=7 color=[VillageColors[Village]]>[Text]"
overlays += village_text
You could also try to use the built-in maptext feature, which is a lot more efficient, doesn't need a bunch of objects as overlays, doesn't need an icon file full of characters, and can be colored and formatted using HTML.

Or if he really wants to use a DMI-based font (for whatever reason you would do that these days), he could get way better performance out of it by only initializing two objects.

mob
var
Village="Cloud"
VillageColors=list(Leaf = rgb(0, 238, 0),Cloud = rgb(255,255,0))//etc
proc
AddText(var/text,mob/M)
var/len = length(text)
var/obj/Text/O = new()
O.color = VillageColors[src.Village]
O.pixel_x = round((len/2)*-3.65)
var/obj/N = new()
N.layer = FLOAT_LAYER
for(var/i=1;i<=len;i++)
N.icon_state = "[text2ascii(text,i)]"
N.pixel_x += 8
O.overlays += N
src.overlays += O


text2ascii is a lot faster than copytext(). It's also a lot safer to use because BYOND's strings don't support quite a few characters properly.

You only need to initialize two objects. One to contain the overlays and one to act as the temporary overlay. I also changed your loop to use length caching, which is a lot faster than what you were doing before. Don't check the length of a string that isn't going to change every iteration. BYOND's string functions are slow and it's best to avoid as many of them as possible.

Also, you don't need to put "[copytext()]" in quotes and brackets like that. It's completely pointless as copytext returns text already. You don't need to make a string out of a string. You've already got a string. Use it.

You might want to hang on to O in a variable somewhere, because you can't remove the overlay without it.
Another question, say there's already text and I want to change it, how would I do that? (If this is a bad question, mb lol)
Example:
So I have my name under the text, then I change my name from "Yusuke11" to "Yusuke", and I do AddText(usr.name,usr)
Is there a way to make it so that the proc automatically deletes all the obj/Text in your name already when initiated?
In response to Yusuke11
Going off of 8BitParagon's example, you'd keep O around (perhaps store it in a variable such as mob/var/name_overlay) and then remove it from the player's overlays list first.
LordAndrew is spot on. You can't remove anything from the overlay's list without a reference to an appearance. So any time you change an appearance-related variable (kind of hard to list them all here), the appearance of an object changes. When/if the appearance of an object changes you can't remove the overlay that was added to the player's overlays by subtracting the object from it.

This is why I used a two objects: So you could store O in a variable, remove it from the overlay's list, then clear its overlay's list.

Here's roughly how you'd do it:

mob
var
obj/Text/name_label
Village="Cloud"
VillageColors=list(Leaf = rgb(0, 238, 0),Cloud = rgb(255,255,0))//etc
proc
setNameLabel(var/text)
var/len = length(text)
if(!name_label)
name_label = new()
else
//you must remove the label first, then remove its overlays. If you do this in any other order, it will fail.
overlays -= name_label
name_label.overlays.Cut(1,0)
name_label.color = VillageColors[src.Village]
name_label.pixel_x = round((len/2)*-3.65)
var/obj/N = new()
N.layer = FLOAT_LAYER
for(var/i=1;i<=len;i++)
N.icon_state = "[text2ascii(text,i)]"
N.pixel_x += 8
name_label.overlays += N
src.overlays += name_label
Ahh kk didn't know you meant b4 but now I do, played around with it :P
Learned a lot today, ty guys ^_^
In response to 8BitParagon
8BitParagon wrote:
Anita Sarkeesian

How much effort did you go through just to put that in there?
In response to Mightymo
Mightymo wrote:
8BitParagon wrote:
Anita Sarkeesian

How much effort did you go through just to put that in there?

Didn't think anyone else would see it.