ID:2189045
 
(See the best response by Ter13.)
Code:
var/list/a = list("a")
var/list/b = list("a", "b")
proc
example()
if(b in a)
return TRUE


Problem description:

What I expected was that it would check A, for anything that is in B. Instead, I have to use "b[1] in a", which means it will only look for "a".

I want it to look for anything that matches; so if a has ("a", "b") and b has ("a", "c") it would return TRUE.

I believe you could do something like:

var a[] = list("a", "b")
var b[] = list("a", "c")
var c[] = a & b
if(c)
// success; the list c contains like-items from both lists
Best response
if(length(a&b))


for completeness, there's the | and ^ operator as well.

a|b: a OR b

list("a","b")|list("b","c") = list("a","b","c")


a^b: a XOR b (eXclusive OR)
list("a","b")^list("b","c") = list("a","c")


a&b: a AND b

list("a","b")&list("b","c") = list("b")
In response to Ter13
Thanks!

Though, since you're here - one thing. I'm using a list attached to a mob for effects, rather than defining states - is this a bad idea?

A player can have a theoretical maximum of 40 states, though odds are that would never happen in an actual match.
Though, since you're here - one thing. I'm using a list attached to a mob for effects, rather than defining states - is this a bad idea?

Gonna need more information.
In response to Ter13
Rather than

#define STATE_FIRE
#define STATE_STUN
// etc


mob/var/list/effects = list()
mob/var/list/binds = list()


This is because I need to account for multiple effects and binds at once, from many different people at once.
I follow now.

I was actually just working on that the other day. I haven't fully fleshed out my approach yet, but I'll let you see my scraps.

Basically, I have a datum called /effect

It's sort of a blank slate to do a bunch of common things:

effect
Added() //when added
Removed() //when removed
Override() //when overriding another effect
Overridden() //when has been overridden by another effect


But there are also different kinds of effects:

//timed effects have a duration that they are active for.
effect/timed
Expire() //when the time limit has run out

//ticker effects are like a timer, but will call Tick() a number of times based on duration, separation, and the number of ticks specified
effect/timed/ticker
Tick() //when a tick happens

//stackable effects have a stack number and a max stack number.
effect/stacking
Stacked() //when the stack has been increased
Unstacked() //when the stack has been decreased
Full() //when the stack count is empty
Empty() //when the stack count is full

//timed stackable effects are configurable based on what happens when the stack is increased, decreased, or the timer runs out.

//timer_action values:
//ACTION_STACK = add a stack
//ACTION_UNSTACK = remove a stack
//ACTION_RESTACK = set stacks to max
//ACTION_DESTACK = remove all stacks

//stack/unstack_action values:
//ACTION_RESET_TIMER = restart the timer
//ACTION_STOP_TIMER = stop the timer
//ACTION_NONE = do nothing

effect/stacking/timed
Expire() //when the time limit has run out

//timed ticker also adds a tick_action variable, which takes the same values as timer_action.

effect/stacking/timed/ticker
Tick() //called periodically


Here's more or less how I'm handling these effect datums implementation-wise:

This one is just a quick invisibility effect. But this one has a counter-play. The mage class has an ability that prevents invisibility:
effect/timed/invisibility
id = "invisibility"

Added(mob/m)
if(!m.invisible++)
m.invisibility = 101
m.alpha = 128
..()

Removed(mob/m)
if(--m.invisible==0)
m.invisibility = 0
m.alpha = 255
..()


effect/timed/reveal
id = "reveal"

Added(mob/m)
if(--m.invisible==0)
m.invisibility = 0
m.alpha = 255
..()

Removed(mob/m)
if(!m.invisible++)
m.invisibility = 101
m.alpha = 128
..()


The reveal effect counters the invisible effect.


You don't need to keep track of the binds in a list at all, though. Check this out:

mob
var/tmp
can_walk = 1
can_attack = 1
can_cast = 1
can_move = 1

Move()
if(can_move<1) return 0
return ..()

proc
Attack()
if(can_attack<1) return 0

Cast()
if(can_cast<1) return 0

client
Move()
if(mob.can_walk<1) return 0
return ..()


You can use an increment decrement counter system and that way, having multiple binds on the player at the same time doesn't require that you search through every single bind every time you want to know whether a player can move. Provided your code is stable and balanced on the counter, it'll be less buggy than just using boolean states and actually save you a lot of work.