ID:141245
 
Code:
Declare_War(T as text, M as mob in world)
{
world << "[usr] has declared war on [M]! Casus belli: [T].";
var/War/W = new/War(usr, M);
usr.wars.Add(W); // Error

}

mob/nation
{
var
{
.
.
.
list/wars[4];
}
}


Problem description:

When I try to compile, the last line (flagged with error) gives the following error: verbs.dm:28:error:usr.wars.Add:undefined var.

The verb is defined under type /mob/nation (the player mob).

Note: the periods are simply to avoid posting irrelevant code.

The problem's probably obvious, but I'm extremely out of practice in DM coding.

Any help would be appreciated.

Could we see your whole Declare_War verb, including where you define its path?

Because normally it shouldn't error, as long as the verb is defined under /mob/nation

Alternatively you could try to add;
var/mob/nation/X = usr
X.wars.Add(W)

// Or
usr:wars.Add(w) // (Note; high chance of erroring in-game)
I'd recommend getting rid of the braces, since they're not really "standard" BYOND syntax and they'll just end up getting confusing.

As to the issue you're having, you declared the wars var under /mob/nation but usr is considered by the compiler just to be a generic /mob. Since regular mobs don't have the wars var, the compiler is telling you it can't find the var.

There are two solutions to this problem. One is to declare the wars var under all mobs instead of just /mob/nation. The other is to type-cast:

var/mob/nation/N = usr
var/War/W = new(N, M)
if(!N.wars) N.wars = new
N.wars += W


I also recommend not declaring the list as wars[4], since you don't really need to know in advance how big the list will be, and the space is just being filled with nulls. I'd just leave it as list/wars. That will be uninitialized by default, but the if(!N.wars) line in my example above will initialize the list if it doesn't exist.

Lummox JR
In response to Lummox JR
Thanks for the help. The code now compiles, but I get the following runtime error:

runtime error: list index out of bounds
proc name: New (/War/New)
usr: Drafonis (/mob/nation)
src: /War (/War)
call stack:
/War (/War): New(Drafonis (/mob/nation), Drafonis (/mob/nation))
Drafonis (/mob/nation): Declare War("Test.", Drafonis (/mob/nation)).

(I realize I'm declaring war on myself, but this is just to test the verb).

This is the new code (including the path for the verb).

mob

nation

verb

Declare_War(T as text, M as mob in world)

world << "[usr] has declared war on [M]! Casus belli: [T].";
var/mob/nation/U = usr;
var/War/W = new/War(U, M);
if(!U.wars) U.wars = new;
U.wars.Add(W);


The braces (and semicolons) I put in out of habit.

The list is defined as:
 mob/nation/var/list/wars[]

In response to Drafonis
In DreamMaker, in preferences, you can enable it to show the error line in runtime errors. It's quite handy.

There seems to be an error in your War/New() proc. Could we see that, please? Might be you're adding to the War list there, without initializing it like you did in the verb (Checking if the list is active, if not, list = new/list)
In response to Mysame
War
{
var
{
list/belligerents[2]; // The nations involved.
}

New(b1, b2)
{
belligerents[0] = b1;
belligerents[1] = b2;
}
}


This is the entire declaration of the War datum.
In response to Drafonis
At a quick guess I'd say the [] notation and the explicit /list are confusing the compiler when used together. Best to use only one or the other. I never use the [] notation myself; I far prefer the type format. Also, using the [] notation is going to auto-initialize your list, which isn't necessarily desirable in all cases.

Lummox JR
In response to Drafonis
Your problem is that list elements indexes in DM begin at 1, not 0. List[1] is the first item in List; so if you use 0, it's out-of-bounds.
In response to Lummox JR
Lummox JR wrote:
At a quick guess I'd say the [] notation and the explicit /list are confusing the compiler when used together. Best to use only one or the other.

Nah, I'm pretty sure it works fine even when you use both, even tho it's indeed redundant.
If you double-initialize a list (not double-define):
var/L[0] = list()
var/X[0] = new()

...the compiler actually catches it and gives you a warning. ;P Useful seeing as it can have adverse effects, unlike a double-type-definition.

I never use the [] notation myself; I far prefer the type format.

Same; why should lists be treated specially in that regard? :P "/list" is also far more readable as far as implying "this is a list", hehe.

Also, using the [] notation is going to auto-initialize your list, which isn't necessarily desirable in all cases.

Well, this is actually inaccurate, as the list won't be initialized if you don't you put a number inside the []; that just defines it as /list.