ID:1674062
 
(See the best response by Sir Lazarus.)
Problem description:

Okay, I can add someones name to the mute list, but it won't let me remove them. I'm using names instead of the mob itself so that re-logging won't undo the mute.

When I attempt to unmute, i get the error:
runtime error: type mismatch: "Larduck" -= "Larduck"

Can anyone help me out with this?

Code:
mob
verb
mute()
//set hidden = 1
var/list/choose=new/list()
for(var/mob/m in world)
if(m.key/*&&m.key!=key*/)
if(m.name in list(mutelist))
choose+="[m.name] (Unmute)"
else
choose+="[m.name]"
choose+="Cancel"
if(choose.len<2)
src << "There are no players you can mute"
return
var/mute=input("Who would you like to mute / unmute?","Mute / Unmute","Cancel") in choose
if(mute=="Cancel")
return
else
for(var/mob/m in world)
if(m.key)
if(mute=="[m.name] (Unmute)")
mutelist-="[m.name]"
src << "Unmuted [mute]"
if(mute=="[m.name]")
src << "Muted [mute]"
mutelist+="[mute]"




Best response
Your mutelist list seems to start off as null. If you use += on a null variable it will set the variable to the string you're adding. IIRC using -= on a string will produce the error you described.

// wrong; IIRC this is your bug
var/list/mutelist

/proc/mute(mob/M)
mutelist += M.name

/proc/unmute(mob/M)
mutelist -= M.name

// fixed
var/list/mutelist = new/list() // need to initialize the list

/proc/mute(mob/M)
mutelist += M.name

/proc/unmute(mob/M)
mutelist -= M.name


There are also a few tips I can give you. From your code snippet I notice that you're adding names to the list of muted players instead of keys. This would allow me to bypass the mute simply by recreating my character.

AFAIK you can also use an associative list to find the value you want instead of manually looking up players.

Your approach also doesn't allow you to remove players from the list once their mob goes away (i.e., they logged out, since a lot of games delete mobs when players log out).

You might want to try an approach like this one:

// Danger! Untested code.

var/list/mutelist

/proc/addMute(key)
if (!mutelist) mutelist = new/list()
mutelist.Add(key)

/proc/removeMute(key)
if (mutelist)
key = ckey(key)
for (var/item in mutelist)
if (ckey(item) == key)
mutelist.Remove(item)

if (mutelist.len == 0)
mutelist = null

/proc/isMuted(key)
if (mutelist)
key = ckey(key)
for (var/item in mutelist)
if (ckey(item) == key) return TRUE

return FALSE

/mob/verb/mute()
var/list/items = new/list()

for (var/key in mutelist)
items[key + " (muted)"] = key

for (var/client/C)
if (!isMuted(C.key)) items[C.key] = C.key

// TODO: Sort the list alphabetically

var/item = input(src, "Who would you like to mute / unmute?","Mute / Unmute") as null|anything in items

if (item != null)
var/key = items[item]

if (isMuted(key))
removeMute(key)
sendMessage(src, "Unmuted [key]")
else
addMute(key)
sendMessage(src, "Muted [key]")

/proc/sendMessage(recipients, message)
recipients << message
Haha, yeah, I realized the null list eventually, before I went to bed, but thanks very much for rest the advice! I'd rather keep my code from scratch, but I'll try and incorporate your tips :)

Oh, and players can't change their name in this project - It's the same as their key anyways.

[Edit] Oh, and also, the mutelist is a mob/var - each player can ignore who they want. Thanks again for the help, it's working perfectly now!