ID:1335679
 
(See the best response by Rushnut.)
Please bare with me as there is quite a bit of code, but it revolves mainly around 4 procedures:

mob/proc/New()
--> Purpose: When a newly created Mob appears on the map, it checks if that mob is an AI / Player, and if it is the former, it then proceeds into the AI_StartUp() and AI_Wander()

mob/proc/AI_StartUp()
--> Purpose: Performs various "house-keeping" on the AI (clothing it, giving it a random name and age, generating its shop, giving it hair and possible skin-tone and eye-color, and generating an AI Family for it should it not have any Family Members).

mob/proc/AI_Wander()
--> Purpose: Basic AI Movement around a general area.

mob/proc/Fill_In(var/mob/M)
--> Purpose: Called by the AI_StartUp(), to fill in the information of a newly created AI Mob, based upon the var/mob/M passed through the procedure as an argument / parameter.

Note:

The AI_StartUp() is quite a bulky piece of code as it is very repetitive, and unfortunately, where the issue probably occurs. As such, I've labelled the sections of it to help with navigation.

Code:
mob/proc/AI_Wander()
while(src.Player == "AI")
var/Dir = rand(1,4)
sleep(2)
if(Dir == 1)
step(src, NORTH)
if(Dir == 2)
step(src, EAST)
if(Dir == 3)
step(src, SOUTH)
if(Dir == 4)
step(src, WEST)

mob/proc/AI_StartUp()
// ----- Assorting Genders and Age ----- //
if(src.icon == 'MaleBase.dmi')
src.Gender = "Male"
else if(src.icon == 'FemaleBase.dmi')
src.Gender = "Female"
if(src.Age == 0)
var/Num = rand(1,3)
if(Num == 1)
src.Age = rand(15, 30)
else
src.Age = rand(30, 70)

// ----- Generate Random Names ----- //
if(src.Name != "None" && src.House != "None")
if(FirstNames.Find(src.Name) == 0)
FirstNames.Add(src.Name)
if(HouseNames.Find(src.House) == 0)
HouseNames.Add(src.House)
else if(src.Name == "None")
if(src.icon == 'MaleBase.dmi')
src.Name = Male_RNG.Create()
else if(src.icon == 'FemaleBase.dmi')
src.Name = Female_RNG.Create()
else if(src.House == "None" && src.Liege != "None")
src.House = House_RNG.Create()

// ----- Clothe the AI ----- //
if(src.Clothing.len == 0)
if(src.Gender == "Male")
var/Num = rand(1,3)
if(Num == 1)
var/obj/Clothing/Shirt/SH = new(src)
src.contents += SH
else if(Num == 2)
var/obj/Clothing/SleevelessShirt/SH = new(src)
src.contents += SH
else if(Num == 3)
var/obj/Clothing/LongSleeveShirt/SH = new(src)
src.contents += SH
var/obj/Clothing/Pants/P = new(src)
src.contents += P
if(src.Gender == "Female")
var/Num = rand(1,2)
if(Num == 1)
var/obj/Clothing/Dress/D = new(src)
src.contents += D
else
Num = rand(1,3)
if(Num == 1)
var/obj/Clothing/Shirt/SH = new(src)
src.contents += SH
else if(Num == 2)
var/obj/Clothing/SleevelessShirt/SH = new(src)
src.contents += SH
else if(Num == 3)
var/obj/Clothing/LongSleeveShirt/SH = new(src)
src.contents += SH
var/obj/Clothing/Pants/P = new(src)
src.contents += P
var/Num = rand(1,3)
if(Num == 1)
var/obj/Clothing/Coat/SH = new(src)
src.contents += SH
else if(Num == 2)
var/obj/Clothing/Cape/SH = new(src)
src.contents += SH
else if(Num == 3)
var/obj/Clothing/Scarf/SH = new(src)
src.contents += SH
var/obj/Clothing/Shoes/S = new(src)
src.contents += S
for(var/obj/Clothing/C in src.contents)
if(C.Stackable == 0 && C.Quantity == 1)
src.overlays.Add(C)
src.Clothing.Add(C)

// ----- Populate the AI Store ----- //
for(var/atom/A in src.contents)
if(istype(A,/obj/Clothing))
var/obj/Clothing/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)
if(istype(A,/obj/Armour))
var/obj/Armour/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)
if(istype(A,/obj/Weapon))
var/obj/Weapon/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)
if(istype(A,/obj/Potion))
var/obj/Potion/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)
if(istype(A,/obj/Item))
var/obj/Item/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)
if(istype(A,/obj/Material))
var/obj/Material/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)

// ----- Giving AIs Hair + Skin Tone ----- //
if(src.Hair == "")
var/Num = rand(1,5)
if(src.Gender == "Male")
if(Num == 1)
var/obj/Hair/I = new()
I.icon = 'Short Curly Hair.dmi'
src.Hair = "Short Curly Hair"
src.overlays.Add(I)
if(Num == 2)
var/obj/Hair/I = new()
I.icon = 'Short Combed Hair.dmi'
src.Hair = "Short Combed Hair"
src.overlays.Add(I)
if(Num == 3)
var/obj/Hair/I = new()
I.icon = 'Long Curly Hair.dmi'
src.Hair = "Long Curly Hair"
src.overlays.Add(I)
if(Num == 4)
var/obj/Hair/I = new()
I.icon = 'Long Combed Hair.dmi'
src.Hair = "Long Combed Hair"
src.overlays.Add(I)
if(Num == 5)
var/obj/Hair/I = new()
I.icon = 'Low Cut Hair.dmi'
src.Hair = "Low Cut Hair"
src.overlays.Add(I)
if(src.Gender == "Female")
if(Num == 1)
var/obj/Hair/I = new()
I.icon = 'Short Curly Hair with Bangs.dmi'
src.Hair = "Short Curly Hair with Bangs"
src.overlays.Add(I)
if(Num == 2)
var/obj/Hair/I = new()
I.icon = 'Short Ponytail Hair.dmi'
src.Hair = "Short Ponytail Hair"
src.overlays.Add(I)
if(Num == 3)
var/obj/Hair/I = new()
I.icon = 'Long Hair with Bangs.dmi'
src.Hair = "Long Hair with Bangs"
src.overlays.Add(I)
if(Num == 4)
var/obj/Hair/I = new()
I.icon = 'Long Ponytail Hair.dmi'
src.Hair = "Long Ponytail Hair"
src.overlays.Add(I)
if(Num == 5)
var/obj/Hair/I = new()
I.icon = 'Free-Flowing Long Hair.dmi'
src.Hair = "Free-Flowing Long Hair"
src.overlays.Add(I)
if(src.Capital == "Garoh")
if(src.Gender == "Female")
src.icon = 'Nomad MaleBase.dmi'
else if(src.Gender == "Male")
src.icon = 'Nomad FemaleBase.dmi'

// ----- Create Family for the AI ----- //
if(src.House != "None")
if(src.Family.len == 0)
src.Family.Add(src)
var/Num = rand(1,5)
var/Mem = 0
for(var/x = 1; x <= Num; x++)
Mem = rand(1,5)
src.State = "Amnt: [Num] | Mem: [Mem] | Cycle: [x]"
if(Mem == 1)
if(src.Gender == "Male")
if(src.Misc[0] == 0)
var/mob/Lady_Wife/A = new(src.loc)
A.Name = Male_RNG.Create()
A.Age = src.Age + rand(-5,5)
A.Fill_In(src)
src.Family.Add(A)
src.Misc[0] = 1
if(src.Gender == "Female")
if(src.Misc[1] == 0)
var/mob/Lord_Husband/A = new(src.loc)
A.Name = Female_RNG.Create()
A.Age = src.Age + rand(-5,5)
A.Fill_In(src)
src.Family.Add(A)
src.Misc[1] = 1
if(Mem == 2)
var/mob/Lady_Daughter/A = new(src.loc)
A.Name = Female_RNG.Create()
A.Age = rand(5, src.Age/2)
A.Fill_In(src)
src.Family.Add(A)
if(Mem == 3)
var/mob/Lord_Son/A = new(src.loc)
A.Name = Male_RNG.Create()
A.Age = rand(5, src.Age/2)
A.Fill_In(src)
src.Family.Add(A)
if(Mem == 4)
if(src.Misc[2] == 0)
var/mob/Lady_Mother/A = new(src.loc)
A.Name = Female_RNG.Create()
A.Age = src.Age + rand(18,25)
A.Fill_In(src)
src.Family.Add(A)
src.Misc[2] = 1
if(Mem == 5)
if(src.Misc[3] == 0)
var/mob/Lord_Father/A = new(src.loc)
A.Name = Male_RNG.Create()
A.Age = src.Age + rand(18,25)
A.Fill_In(src)
src.Family.Add(A)
src.Misc[3] = 1
if(x == Num)
src.State = "Cycle Break | Cycle: [x]"
break
for(var/mob/A in src.Family)
if(A != src)
A.Family = src.Family
return

mob/proc/Fill_In(var/mob/M)
src.House = M.House
src.Sigil = M.Sigil
src.Words = M.Words
src.Capital = M.Capital
src.Liege = M
src.x += rand(3,5)
src.y += rand(3,5)

mob/New()
if(src.Player == "AI")
src.AI_StartUp()
src.AI_Wander()


Note:
Any statements concerning "src.Misc[x]" is simply a miscellaneous list variable I created to handle miscellaneous code bugs (in this case, avoiding an AI-Mob from having 2 wives, 2 husbands, 2 mothers, and 2 fathers).

Problem description:
Finally, the issue that I am getting here is that only the first Family-Created AI-Mob (FC-AM) is being created, despite the random variables within the "Family Creation Section" of the AI_StartUp() may be more than 1 (I've verified this through the statement "src.State = Amnt: [Num] | Mem: [Mem] | Cycle: [x]" and looking at the values). Furthermore, the FC-AM does not go through the the Fill_In(), the for-loop statement terminates at the first Cycle, the Original AI-Mob (O-AM) on which all of this procedure is based upon does not go through to AI_Wander() while the FC-AM does, and finally, the FC-AM does not gain its "Family Members" in its Family-List.

My Belief:
I believe the issue lies in the fact that upon the creation of the FC-AM, it too will be subject to go through the AI_StartUp() (as was intended, as it allows for the newly created FC-AM to go through the other "house-cleaning" sections of the code). I think this somehow creates the problem, though what it is? I am uncertain... (An endless loop? Though, I think it'd be a different type of reaction...)

Any form of guidance on this matter would be greatly appreciated.

P.S.
I cannot go through the process of creating pre-defined AIs for everything as the list of AIs I've pre-defined are already around 50+, some of which actually requires Family Members; hence why I've developed this code. I am also aware that depending on the amount of Mobs created through this, I could very well be looking at intense server issues related to lag and/or bugs, but, I'll deal with that when the time comes.
Wow nice code.
I'm working on an explanation, but its taking some time. Bare with me.
No problem Albro1. The fact that you're even making an explanation, regardless of how long it takes, is good enough for me.
Okay, I have no idea what's wrong with your code there, because it's way too long (and the indentation got messed up when you copy-pasted, which doesn't help).

I suspect you have no idea what's wrong with your code because it's way too long as well. I think before you go looking for the bug you should try to simplify what you've written, and the bug will probably become obvious in the process. You need to find points of commonality in what you're doing, make it a procedure, and then call that procedure.

For example, each family-member-creation section is essentially the same - you're making a thing of a given gender, out of a certain typepath. You could turn 'make a family member' into a procedure and just call it with different arguments.

Another thing you could do is split your procedure up. You've got several distinct bits that are conceptually different (such as figuring out what to put in the store, and assigning hair). They shouldn't be in the same procedure.

You should look for where you're duplicating bits of code and try to come up with ways to prevent that duplication. For example, the store bit:
for(var/atom/A in src.contents)
if(istype(A,/obj/Clothing))
var/obj/Clothing/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)
if(istype(A,/obj/Armour))
var/obj/Armour/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)
if(istype(A,/obj/Weapon))
var/obj/Weapon/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)
if(istype(A,/obj/Potion))
var/obj/Potion/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)
if(istype(A,/obj/Item))
var/obj/Item/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)
if(istype(A,/obj/Material))
var/obj/Material/O = A
if(O.Stackable == 1 && O.Quantity > 1)
src.Selling.Add(O)


If everything that could be sold was a subclass of some /obj/Sellable type, then you could just do this:

for (var/obj/Sellable/o in src) if (o.Stackable && o.Quantity > 1) Selling.Add(o)


which is somewhat simpler.

You might want to loop up the pick and prob procedure, because it looks to me like you're duplicating their functions using rand() and a bunch of if statements and you'd be better off just using them directly (in particular, you could just pick() the hair directly).

From a design standpoint I think you'd be better off generating a family and then generating mobs under that, rather than generating a mob and then incidentally giving them a family (which might then generate their own family?). That is, you'd go:

- Make a family!
- Make a dad
- Make a mum
- Make three children

instead of:
- Make a guy
- Make a wife
- Make three children

Depending on how this is all used, of course. In your use case it might make sense to have a 'primary' family member that everyone else is relative to, in which case maybe you'd be better of generating them like you are.

EDIT: Oh, and atoms already have a 'gender' variable, which you can set to MALE, FEMALE, NEUTER or PLURAL. And there are text macros to use the right gendered pronouns and things when referring to objects if you've set their gender correctly. Maybe have a look at using that instead of your own variable.
I'll just go ahead and post what I have typed, since Jittai went. lol

I'll point out things I see wrong.

Funky indentation on the HouseNames.Add()?


This part isn't going to create a name and a house, because you are using else if. I'd advise doing the checks for if they don't have a name or house first, then using else if to see if they are lacking those. Also, since in the block before this you set their gender based on their icon, it would be my preference to then check their gender in everything else, rather than having to type out that whole icon check. The less you have to type (While still maintaining readability), the better in my book.


I'm not going to screenshot this whole block to save space, but this has a lot of wacky indentation. Also, the repetitiveness is bad. Take a step back and look at how you can minimize it. My suggestion?
Define the Num variable before the if statements. Go ahead and do your rand(), because only one of these if statements is going to run anyways (obviously). Create your object variable - var/obj/Clothing/c. (Note that with the variable typecasted like this, you can set it to any subset of /obj/Clothing you want.) Go ahead and assign the variable to the right type according to Num. Then, add an if statement to see if it is a woman. Run the quick check to see if you need a dress instead, otherwise put the clothes on them.


More repetitiveness here. It looks like you are only searching for objects, so you don't need to do for(var/atom/A in src.contents). You can do for(var/obj/O in src.contents) (In fact, I'm 99% sure you don't need src.contents - just src should achieve the same result). It also seems like you are checking the same variables for all of these, so there is no need to typecast every one. Just simply seeing if O's variables are what you need, and adding O to the Selling will do the same with less space used.


Some more repetitiveness. I'm going to give you ways to shorten this, and also an alternative to shorten it more. I didn't screenshot this whole section. This one may be lengthy, so I'll let you see the part I'm talking about first, then explain below the picture:

At first glance, there isn't a whole lot you can do to shorten this because you are dealing with icons. However, when you examine a little closer...
Look for repetitive things. The first thing that stands out to me is constantly seeing var/obj/Hair/I = new() and src.overlays.Add(I). How can you change this? Easy. Define I before all of the checks. Only one of these if statements is going to pass. Then, after all of your checks, put the src.overlays.Add(I). These two lines are only being executed once each in your code, so there is no sense in typing them out that many times. Now, for the part I mentioned about squeezing this down smaller. I'm recommending a list.
In case you don't know some details about using lists and accessing the items as well as associative lists, I'll explain a bit here.
Say you have a list.
var/list/l = list()

Now say you put some text in the first spot in this list.
var/list/l = list("hi")

Now, if you want to access this element of the list, you simply need to do this:
src << l[1]

l[1] grabs the first element in the list. Now what if you did this with the list:
var/list/l = list("hi" = "bye")

By typing l[1], it would return "hi", but if you do l["hi"], it will return "bye". You can also grab the associated value when you don't know what the first value is like so:
// We don't know that the first element is "hi", but that doesn't matter.
var/list/l = list("hi" = "bye")
var/element_one = l[1]
src << l[element_one]
// If you want to possibly confuse yourself later, you can do it in one line:
src << l[l[1]]

So now that you know about associative lists, you can shorten this code you have. I'm not going to use your exact code, but here is an example:
var/list/male_hairs = list("Male Hair 1" = 'malehair1.dmi', "Male Hair 2" = 'malehair2.dmi')
var/r = rand(1,2)
if(src.Gender = "Male")
src.hair = male_hairs[r]
src.hair_icon = male_hairs[src.hair]

Just create a separate list for the female hairs as well. This means you only have to type out those pesky icon file names once.


I'm trying to read through your family generation, but the indentation is too wonky for me to be able to see the problem. I can tell you that lists don't start at element 0 in DM, so Misc[0] probably won't work out too well for you.
I'm going to add this as a separate comment to make sure you see it.

Use a custom named parameter in mob/New(). I think your problem lies in mob/New() running the AI_Startup() and then that mob being the target of Fill_In(), resulting in redundancies and possibly unexpected results.
1 -- The indentation issue is because of the copy & paste, so for that, I apologize.

2 -- I already know of how to shorten the code in the ways you guys have pointed out, but for me personally -- seeing everything like this, line-for-line, is easier to understand, and as I'm the only person working on this project, I never saw the need to go about making it super-short not to mention that as I'm testing the code still, it's easier for me like this.

3 -- I used my own Gender variable for the simple reason that I'm a semi-lit (you'll notice all my variables start with an upper-case letter).

4 -- I get that you guys are trying to help, but to be quite frank, you haven't helped me yet, lol. It's more like you just sifted through the code to try to standardize everything that isn't. Trust me though, it's not needed, I can do all of that (if I even feel the need to, since I'm solo) later.

5 -- Albro1: Thanks, I actually drifted into normal programming practises with that, haha. I need to make that adjustment. Ironically though, it actually works fine thus far with it like that, not sure if it's because it has never found itself in an instance of having multiple wives or not though...

P.S.
Yes, yes, I am aware there are a lot of things that can be done differently / more efficiently to prevent repetition, but I like clarity in all things I do (and repetition allows me to see it all clearly), you'll even notice I went "src.contents" instead of "src" (because of clarity). Please, do not focus on these things and just try to help me out here with my main issue. I'll also try to re-post the code with correct indentation.

EDIT:
The reason why I used, "var/atom/A" a few times is because at first, one of those "objs" variables were in fact an, "image" variable, I simply never changed it from "var/atom/A" as it worked fine that way, anyway.

2nd EDIT:
Albro1 -- I get why adding a custom named parameter to mob/New() might be useful, so as to try controlling all of the possible looping into Ai_StartUp, but like I said -- the FC-AM also needs to go through 4/5ths of those "house-cleaning" processes... Unless I separate - .... Actually, I've an idea thanks to you Albro1, haha. Thanks, I'll test something here and get back to you.
Repetition is an issue in and of itself. How confident are you that every time you tried to write the same bit of code you got it right?

You're correct in that I've looked for ways in which your code is nonstandard and suggested you change that. There are a few reasons for that:
One, your code is very difficult to understand as a result of being so long and repetitive. I appreciate that for you, having written it and worked with it recently, it's different. But as someone who occasionally helps people on this forum, I don't want to expend the time and mental effort required to figure out what is wrong with your code in detail.

Two, sometimes things are standard for a reason. The reason I'm suggesting things like using the built in gender variable or reducing code repetition is because the practises you have gotten into here are likely to cause you bugs in the future if they haven't caused them now. Writing repetitive code is a very good way to accidentally get it wrong once and end up with a bug that's difficult to reproduce, understand, and find. Not using the built-in gender variables and constants means you have to write more code if you want to do things like use correctly-gendered pronouns, and writing more code means more bugs.
Oh, I completely get what you're saying Jp, but this is merely my own way of writing and testing code. I also understand why most people think that doing things this way increases the chances of getting errors and bugs, but for me, it has actually decreased them, haha.

There's a saying that goes something like, "do not reinvent the wheel" quite often used in the programming world, and I simply took it to a new extreme. My point here is that, most "standardized methods" or "shorthand methods" are pretty much a reinvention of the wheel, and sometimes that wheel is so complex, that I end up using it wrong. I've also learned that it is MUCH easier to do something in a VERY basic format first, for clarity, and THEN go over it to make it more efficient afterwards!

It is simply that way in which I code everything -- Granted, I'll give you that my semi-lit nature is something that has 'caused me issues in the past, haha. But trust me, I'm definitely covered with everything else, mate.

P.S.
Don't get me wrong, I'm not trying to be difficult with you / anything for offering the help with the things you did. I get that most people on here sometimes are not fully aware, but I was just trying to let you know you could exclude myself for it so you could focus on my main issue, I guess, haha. Now then... I have an idea I'd like to try.
You seem to be missing the point Youko, your code on the forefront doesn't seem to have any issues but because of the way it's laid out and executed it's difficult to tell.

You need to help us help you.
Oh I get that Rushnut. My apologies for not stating this sooner but I've tested and cleared all of the code I posted but the "Family Creation Section". That is the sole piece of code that is currently giving me issues. The only reason you guys have the entire procedure there now is because I copy-&-pasted it in its entirety for clarity -- as well as, there is the possibility that despite everything else in the code functions fine, it might still be the reason why the "Family Creation Section" doesn't.

The only thing I can think of that would prevent a person from understanding it would be because of the spacing/tabs. I figured as it is mostly repetitions, you'd all be able to understand it with clarity, as I do. Unless somehow, that's not the case?

At any rate, I'll repost the code with better spacing/tabbing in a second so you guys can read it through properly.
Code; Version 2:
mob/New(var/Loc, var/Family)
if(src.Player == "AI")
src.loc = Loc
if(Family == 1)
src.AI_GenerateFamily()
src.AI_StartUp()
else
src.AI_StartUp()
src.AI_Wander()

mob/proc/AI_GenerateFamily()
// ----- Create Family for the AI ----- //
if(src.House != "None")
if(src.Family.len == 0)
src.Family.Add(src)
var/Num = rand(1,5)
var/Mem = 0
for(var/x = 1; x <= Num; x++)
Mem = rand(1,5)
src.State = "Amnt: [Num] | Mem: [Mem] | Cycle: [x]"
if(Mem == 1)
if(src.Gender == "Male")
if(src.Misc[0] == 0)
var/mob/Lady_Wife/A = new(src.loc, 0)
A.Name = Male_RNG.Create()
A.Age = src.Age + rand(-5,5)
A.Fill_In(src)
src.Family.Add(A)
src.Misc[0] = 1
if(src.Gender == "Female")
if(src.Misc[1] == 0)
var/mob/Lord_Husband/A = new(src.loc, 0)
A.Name = Female_RNG.Create()
A.Age = src.Age + rand(-5,5)
A.Fill_In(src)
src.Family.Add(A)
src.Misc[1] = 1
if(Mem == 2)
var/mob/Lady_Daughter/A = new(src.loc, 0)
A.Name = Female_RNG.Create()
A.Age = rand(5, src.Age/2)
A.Fill_In(src)
src.Family.Add(A)
if(Mem == 3)
var/mob/Lord_Son/A = new(src.loc, 0)
A.Name = Male_RNG.Create()
A.Age = rand(5, src.Age/2)
A.Fill_In(src)
src.Family.Add(A)
if(Mem == 4)
if(src.Misc[2] == 0)
var/mob/Lady_Mother/A = new(src.loc, 0)
A.Name = Female_RNG.Create()
A.Age = src.Age + rand(18,25)
A.Fill_In(src)
src.Family.Add(A)
src.Misc[2] = 1
if(Mem == 5)
if(src.Misc[3] == 0)
var/mob/Lord_Father/A = new(src.loc, 0)
A.Name = Male_RNG.Create()
A.Age = src.Age + rand(18,25)
A.Fill_In(src)
src.Family.Add(A)
src.Misc[3] = 1
if(x == Num)
src.State = "Cycle Break | Cycle: [x]"
break
for(var/mob/A in src.Family)
if(A != src)
A.Family = src.Family
return

mob/proc/AI_Wander()
while(src.Player == "AI")
var/Dir = rand(1,4)
sleep(2)
if(Dir == 1)
step(src, NORTH)
if(Dir == 2)
step(src, EAST)
if(Dir == 3)
step(src, SOUTH)
if(Dir == 4)
step(src, WEST)

mob/proc/Fill_In(var/mob/M)
src.House = M.House
src.Sigil = M.Sigil
src.Words = M.Words
src.Capital = M.Capital
src.Liege = M
src.x += rand(3,5)
src.y += rand(3,5)


What I've Done:
So, based upon Albro1's suggestion, I tried to see if I could control which Mobs went through the process of having a Family be created on it to avoid any possible anomalies. Unfortunately however, the issue(s) still persists.

Issues:
o -- The Original Mob that the Family is centered around does not move while the Family-Created Mobs do.
o -- None of the Mobs take on their "Family Members" into their respective Family-list variable.
o -- The for-loop cycle stops after the first iteration, therefore only creating one Mob, despite there being possibly more than 1.
o -- The Family-Created Mob does not take on the variables from the Original Mob inside the Fill_In().

P.S.
I hope the code is orderly this time around so you guys can follow it properly now.
The problem is that to fully peruse the code that you (or anyone!) provides when asking for help to find errors, the rest of us need to read that code almost line-by-line.

When we see code of that length, with that much repetition, it feels like a wall-o-text, and it's hard to even figure out where to get into it.

If that code were condensed in all of the ways it could/should be, it would be much simpler and easier for outsiders to read through to look for problems.

In short, easier for you to read and understand, in this case actually makes it harder for the rest of us to read and understand. And we need to be able to read and understand it in order to provide any kind of help.
SSGX -- Like I said, I understand my code better if it is as basic as possible; which will very often lead to repetitions. So that's a bad assumption on your part, haha.

Personally, I thought that by having the code like that, would make it simple for ANYONE to read and understand; as it is repetitive. You literally couldn't get any more basic than that. At any rate, I've posted an updated version of the code without all those apparently "controversial" repetitions, haha. It should be loads easier to read and follow through now, especially since its correctly spaced as well, no?
If you have ten times as many lines of code, we have to read ten times as much to have a chance of understanding it. We can't assume you've done the same thing each time. You can't assume you've done the same thing each time. Given the amount of code, you probably haven't.
In response to YoukoSieg
YoukoSieg wrote:
SSGX -- Like I said, I understand my code better if it is as basic as possible; which will very often lead to repetitions. So that's a bad assumption on your part, haha.

Personally, I thought that by having the code like that, would make it simple for ANYONE to read and understand; as it is repetitive. You literally couldn't get any more basic than that. At any rate, I've posted an updated version of the code without all those apparently "controversial" repetitions, haha. It should be loads easier to read and follow through now, especially since its correctly spaced as well, no?

No, no, I understand that it is easier for you to read it in that format. And you're right that it is simple and very straight-forward when written out that way.

However, in doing so, it has become incredibly long. It's not so much an issue of not being able to comprehend it, it's an issue of not wanting to take the time to read it all. It becomes a problem of not really knowing where to jump in, and no one in their right mind is going to read code that long from beginning to end to hunt for the bug.

If we apply a needle-in-a-haystack analogy here, you're doing the equivalent of asking us to find the needle in a haystack that is much larger than it needs to be. When we should be looking for a needle in something more like a haybale. Every extra line, especially the repetitions, is just added noise to sift through.

But yes, you did post another (improved) version at almost the same time I was typing my previous response.
Hmmm, fair enough. I can agree with the annoyance of having to look for a needle in a haystack. For future reference, I'll know next time -- But this has digressed far enough! Haha

So -- with my updated version of the code, can anyone come up with any new ideas, theories, or quite possibly, a work-around towards the entire thing? I mean, there's certainly more than one way to skin this cat, right?
Do for() loops in DM work with semicolons? I never tried, I always thought commas were required.

Two things I would recommend doing: Take out the break you have in there, it has no purpose. for() loops end themselves based on the condition - you're pointlessly double-checking that condition.

Also, with your AI_Wander() - Directional values are all bits. In short, NORTH, SOUTH, EAST, WEST, NORTHEAST, SOUTHEAST, NORTHWEST, and SOUTHWEST are all associated with a number value.

I haven't committed the diagonals to memory, but the cardinal directions are so:
NORTH: 1
SOUTH: 2
EAST: 4
WEST: 8

You don't need this knowledge for my suggestion, but it is good to know. My suggestion is to use pick() rather than rand().
var/x = pick(NORTH, EAST, SOUTH, WEST)
step(src, x)
Also, doesn't your AI_Startup() do all of your naming and house stuff? Your AI_GenerateFamily() takes the House into account, so I am wondering if this is an issue.

Also, you don't need a return at the end of AI_GenerateFamily(). Procs return on their own when they end.

I'll also say that you should change your Misc list a bit. Seeing Misc[0] makes me want to scream because DM indices start at 1, not 0.
Page: 1 2 3