ID:1628680
 
(See the best response by Ter13.)
Clan
var
name
tmp
list/online = list()
list/members
owner
level = 1

proc
ClanInvite(var/mob/inviter, var/mob/invited)
if(inviter.clan==src&&invited.clan==null)
switch(alert("[inviter] invites you to join the clan [name].", "Yes","No"))
if("Yes")
Joined(invited)
if("No") return

Joined(var/mob/m)
m.clan = src
m.clan_name = src.name
src.online += m
src.members += m.name
m.Save()
SaveClan()

Leave(var/mob/m)
if(owner == m.name)
if(members.len > 1)
. = null
while(!(. in members))
. = ChooseLeader(m)
if(.==null)
return
owner = .
else
var/mob/s = owner
s.clan_name = null
s.clan = null
fdel("saves/clans/[ckey(src.name)].sav")
clans -= src.name
src.name = null
del src
src.members -= m.name
m.clan_name = null
m.clan = null
src.Logout(m)
SaveClan()

Remove(var/player)
if(player in members)
for(var/mob/p in online)
if(p.name == player)
Leave(p)
return

if(owner == player)
return 0
members -= player
SaveClan()

ChooseLeader(var/mob/m)
var/list/l = src.members.Copy(1,0)
l -= owner
return input(m, "Change Leader", "Who should become owner of [src.name]?") as text| anything in l

Login(var/mob/m)
if(m.name in members)
online += m
m.clan = src
else
m.clan_name = null
m.clan = null
if(src.online.len == 0)
clans -= src.name
src.name = null
del src

Logout(var/mob/m)
online -= m
if(src.online.len==0)
del src

Create(var/mob/m)
owner = m.name
members += m.name

while(src.name == null)
src.name = input("What is your clan's surname?") as text|null
if(fexists("saves/clans/[ckey(src.name)].sav"))
src.name = null

SaveClan()
clans[src.name] = src

SaveClan()
var/savefile/F = new/savefile("saves/clans/[ckey(src.name)].sav")
F << src

Read(var/savefile/F)
.=..()
if(src.name)
clans[src.name] = src

Del()
if(src.name)
SaveClan()
clans -= src.name
return ..()

var
list
clans = list()


proc
getClan(var/name)
if(name == null) return null
if(name in clans)
return clans[name]
else if(fexists("saves/clans/[ckey(name)].sav"))
var/savefile/F = new/savefile("saves/clans/[ckey(name)].sav")
var/Clan/c
F >> c
return c
else
return null

mob
var
clan_name = null
tmp
Clan/clan

Login()
.=..()
src.clan = getClan(src.clan_name)
if(src.clan)
src << "[src.clan]"
src.clan.Login(src)

Logout()
if(src.clan)
src.clan.Logout(src)
.=..()


verb
Form_Clan()
src.clan.Create(src)


When I use the Form_Clan verb it gives me an error;

runtime error: Cannot execute null.Create().
proc name: Form Clan (/mob/verb/Form_Clan)
usr: Gluscap (/mob)
src: Gluscap (/mob)
call stack:
Gluscap (/mob): Form Clan()

Any reason why it would do that?
Best response
Yeah, the reason it does that, is that in my clan setup, clan is null until a user joins a clan.

verb
Form_Clan()
if(src.clan)
alert(src,"You must leave your clan first!","Clan error","OK")
return
src.clan = new/Clan()
clan.Create(src)


As you can see, you have to initialize a new clan in order to call a proc on it the first time.
Been acting weird, can't exactly pin point the problem.

        Login(var/mob/m)
usr << "name:[m.name], [members], [m.name in members]"
if((m.name in members) == 0)
online += m
m << "test"
m.clan = src
else
m.clan_name = null
m.clan = null
if(src.online.len == 0)
clans -= src.name
src.name = null
del src


Set up something to help me find the problem, yet I can't. When I log in I get the message;
Gluscap, Gluscap, 0
Just set it to if((m.name in members) == 0) to make it easier for testing purposes. If its returning Gluscap as my name, Gluscap for the list, how does m.name in members return 0??

Tried a
if(m.name in members || m.name == members)

but it only checks the first condition..

Fixed it, had to put brackets around both statements.
Just to explain why this didn't work:

Currently 'in' has the a lower operator standing than || and other operators; thus, without the brackets you mentioned, it was being treated as:
if(m.name in members || m.name == members)
// which translates to
if(m.name in (members || m.name == members))
// Which equals to
if(m.name in 1) // 1 if 'members' exists
// which returns
if(0) // It's FALSE so the if() is not executed


I doubt that m.name == members would work since members is a /list thus a direct comparison like that is comparing "string" == /list

As you may know already, the character name is not the best security (especially if you do not have a unique name checker programmed in). I recommend using key/ckey or combining both the name & key with a separator.
In response to GhostAnime
I wasted 5-6 hours of my time before another developer told me this, lol. Is there any mention of it in the reference? Not that I looked anyways. =/

I just know a few other developers that had a similar period where a lot of time was wasted before they understood why it wasn't working.
In response to Lavitiz
I think everyone found out the hard way, including myself :P

It does sound like Tom may increase the priority of in so it will become a problem of past... in the future at some point ;p