Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ SMAUG ➜ Compiling the server ➜ Source Code

Source Code

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1  2  3 4  5  

Posted by Kris   USA  (198 posts)  Bio
Date Reply #30 on Wed 27 Jun 2001 01:23 AM (UTC)
Message
*continued from last post*

*in mud_comm.c, the entirety of do_mptransformcat as it is now*

void do_mptransformcat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
int level;
int iLevel;
int iLang;
int tempwaitb;
int tempwaitc;

if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ))
{
send_to_char( "Huh?\n\r", ch );
return;
}


argument = one_argument( argument, arg );

if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}

if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}

if ( IS_NPC(victim) )
{
progbug( "Mptransform - Victim is NPC", ch );
return;
}

/* To remember where in the message sequence the player is; part of the institution of a delay
Please excuse the spaghetti code =) --Kris */
victim = arg;
if ( tempwaitb == 1 )
goto cat_a;
if ( tempwaitb == 2 )
goto cat_b;
if ( tempwaitb == 3 )
goto cat_c;
if ( tempwaitb == 4 )
goto cat_d;
if ( tempwaitb == 5 )
goto cat_e;
if ( tempwaitb == 6 )
goto cat_f;
if ( tempwaitb == 7 )
goto cat_g;
if ( tempwaitb == 8 )
goto cat_h;
if ( tempwaitb == 9 )
goto cat_i;
if ( tempwaitb == 10 )
goto cat_j;
if ( tempwaitb == 11 )
goto cat_k;
if ( tempwaitb == 12 )
goto cat_l;
if ( tempwaitb == 13 )
goto cat_m;
if ( tempwaitb == 14 )
goto cat_n;
if ( tempwaitb == 15 )
goto cat_o;
if ( tempwaitb == 16 )
goto cat_p;
if ( tempwaitb == 17 )
goto cat_q;
if ( tempwaitb == 18 )
goto cat_r;
if ( tempwaitb == 19 )
goto cat_s;
if ( tempwaitb == 20 )
goto cat_t;
if ( tempwaitb == 21 )
goto cat_u;
if ( tempwaitb == 22 )
goto cat_v;
if ( tempwaitb == 23 )
goto cat_w;


if ( victim->race == RACE_CAT )
{
send_to_char( "A mystical voice says: You're already a cat, you mook!", victim );
return;
}

/* Now that we're done with some standard ifchecks, let's get to the transformation coding */

send_to_char( "You start to feel a strange sensation in your body....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 1;
tempwaitc = 1;
return;
cat_a:
send_to_char( "\nWhat the bloody hell?!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 2;
tempwaitc = 1;
return;
cat_b:
send_to_char( "\n\n\nA vast, open field flashes before your eyes....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 3;
tempwaitc = 1;
return;
cat_c:
send_to_char( "\nYou are standing in this field....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 4;
tempwaitc = 1;
return;
cat_d:
send_to_char( "\nYour ears perk-up, your eyes focus, and you crouch down low in the grass....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 5;
tempwaitc = 1;
return;
cat_e:
send_to_char( "\nPatience is a virtue.... You wait calmly....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 6;
tempwaitc = 1;
return;
cat_f:
send_to_char( "\n\nYou *LEAP* out of your hiding place, and land upon your unsuspecting victim!!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 7;
tempwaitc = 1;
return;
cat_g:
send_to_char( "\nYour prey tries to escape, but to no avail!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 8;
tempwaitc = 1;
return;
cat_h:
send_to_char( "\nThe helpless mouse struggles as you bat it around playfully....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 9;
tempwaitc = 1;
return;
cat_i:
send_to_char( "\n\nThe rodent bolts!\n", victim );
send_to_char( "\nYour spring-loaded legs ZIP into action! The chase is on....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 10;
tempwaitc = 1;
return;

Another post to go... sorry bout the lengthyness
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #31 on Wed 27 Jun 2001 01:23 AM (UTC)
Message
*continued from last post*

cat_j:
send_to_char( "\nYour superior dexterity is no match for the mouse, and you swiftly overtake it!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 11;
tempwaitc = 1;
return;
cat_k:
send_to_char( "\nWith a quick bite to the neck, you kill your prey.\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 12;
tempwaitc = 1;
return;
cat_l:
send_to_char( "\nYou take your catch deep into the woods, where hundreds of cats are waiting for your arrival....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 13;
tempwaitc = 1;
return;
cat_m:
send_to_char( "\n\nAn orange-yellow tabby steps forth from the group.\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 14;
tempwaitc = 1;
return;
cat_n:
send_to_char( "\nYou open your mouth and let the mouse fall upon the ground for the tabby to see....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 15;
tempwaitc = 1;
return;
cat_o:
send_to_char( "\nThe tabby nods approvingly.\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 16;
tempwaitc = 1;
return;
cat_p:
send_to_char( "\nThe tabby says: You came to know our ways and our tongue. You have found much more than that. You have the heart of a tiger within you.... You are one of us.... We shall always be with you, my friend.... My brother....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 17;
tempwaitc = 1;
return;
cat_q:
send_to_char( "\nThe tabby purrs. Soon, the rest of the group starts purring as well.... The sound resonates your ears, and your heart....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 18;
tempwaitc = 1;
return;

cat_r:
send_to_char( "\nThe tabby lovingly rubs his cheek against yours, and disappears, along with the rest of the vision....\n", victim );
victim->race = RACE_CAT;
victim->perm_str += race_table[victim->race]->str_plus;
victim->perm_int += race_table[victim->race]->int_plus;
victim->perm_wis += race_table[victim->race]->wis_plus;
victim->perm_dex += race_table[victim->race]->dex_plus;
victim->perm_con += race_table[victim->race]->con_plus;
victim->perm_cha += race_table[victim->race]->cha_plus;
victim->affected_by = race_table[victim->race]->affected;
victim->perm_lck += race_table[victim->race]->lck_plus;

victim->armor += race_table[victim->race]->ac_plus;
victim->alignment += race_table[victim->race]->alignment;
victim->attacks = race_table[victim->race]->attacks;
victim->defenses = race_table[victim->race]->defenses;
victim->saving_poison_death = race_table[victim->race]->saving_poison_death;
victim->saving_wand = race_table[victim->race]->saving_wand;
victim->saving_para_petri = race_table[victim->race]->saving_para_petri;
victim->saving_breath = race_table[victim->race]->saving_breath;
victim->saving_spell_staff = race_table[victim->race]->saving_spell_staff;

victim->height = number_range(race_table[victim->race]->height *.9, race_table[victim->race]->height *1.1);
victim->weight = number_range(race_table[victim->race]->weight *.9, race_table[victim->race]->weight *1.1);

if ( (iLang = skill_lookup( "common" )) < 0 )
bug( "Nanny: cannot find common language." );
else
victim->pcdata->learned[iLang] = 100;

for ( iLang = 0; lang_array[iLang] != LANG_UNKNOWN; iLang++ )
if ( lang_array[iLang] == race_table[victim->race]->language )
break;
if ( lang_array[iLang] == LANG_UNKNOWN )
bug( "Nanny: invalid racial language." );
else
{
if ( (iLang = skill_lookup( lang_names[iLang] )) < 0 )
bug( "Nanny: cannot find racial language." );
else
victim->pcdata->learned[iLang] = 100;
}

victim->level += 1;
victim->exp += 5000;
victim->max_hit += race_table[victim->race]->hit;
victim->max_mana += race_table[victim->race]->mana;

TEMPWAIT_STATE(victim, 20);
tempwaitb = 19;
tempwaitc = 1;
return;
cat_s:
send_to_char( "\nBut wait a minute....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 20;
tempwaitc = 1;
return;
cat_t:
send_to_char( "\nWhy are you standing on all fours?......\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 21;
tempwaitc = 1;
return;
cat_u:
send_to_char( "\nOh my....\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 22;
tempwaitc = 1;
return;
cat_v:
send_to_char( "\n\nYou have been transformed into a CAT!!\n", victim );
TEMPWAIT_STATE(victim, 20);
tempwaitb = 23;
tempwaitc = 1;
return;
cat_w:
tempwaitb = 0;
tempwaitc = 0;
return;
}

*that's it*

Now, I know it's probably a lot sloppier and more redundant than it needs to be. I think I have the premise right, but I'm having trouble with the function declaration in comm.c, and with some variables. I assumed that by putting tempwaitb and tempwaitc in mud.h, it would remember those variables' values between functions, but I'm not sure. I hope I've provided enough information for you to be able to get me past this obstacle. Thank you for your time and help =)
Top

Posted by Nivek   (15 posts)  Bio
Date Reply #32 on Thu 28 Jun 2001 04:30 PM (UTC)
Message
You are correct, if variables are declared outside of a function, that makes them global, which means their values won't change from function to function, and all functions can see them. Another way to accomplish the same thing is to declare them in your function as static.....for
example

some_function(){
static int blah=0;

blah++;
}


Now this will set blah to 0 the FIRST time the function is called, the second time blah will be 1, third 2 and so on.If that variable doesn't change elsewhere in the code, this is a better way to do the code. I havent looked through the rest of the code, just answering your question ;)
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #33 on Thu 28 Jun 2001 09:49 PM (UTC)

Amended on Thu 28 Jun 2001 09:50 PM (UTC) by Nick Gammon

Message
Another problem is that these variables, by being in the code itself, are going to be shared between players. Thus if two of them are having this message sent to them at once, they will get out of sequence. Remembering things relevant to players can't really be done in static variables.

Another thing you might want to read up on is the switch statement. Your use of "goto" is unnecessary and confusing. You also have a lot of repeated code. Instead of:


if ( tempwaitb == 1 )
goto cat_a;
if ( tempwaitb == 2 )
goto cat_b;
if ( tempwaitb == 3 )
goto cat_c;
if ( tempwaitb == 4 )
goto cat_d;


do this:


if (tempwaitb >= 1 && tempwaitb <= 17)
    {
    switch (tempwaitb)
    {
    case 1: 
     send_to_char( "\nWhat the bloody hell?!\n", victim ); 
     break;

    case 2: 
     send_to_char
       ( "\n\n\nA vast, open field flashes before your eyes....\n", 
       victim ); 
     break;


    case 3: 
     send_to_char
       ( "\nYou are standing in this field....\n", 
       victim ); 
     break;

/* ... and so on ... */

    }  /* end of switch */

  tempwaitb++;
  tempwaitc = 1;
  return;
  }  /* end of tempwaitb in range 1 to 17 */



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #34 on Fri 29 Jun 2001 12:58 AM (UTC)
Message
Now, I'm just having to fix the function call to do_mptransformcat in comm.c. I took your advice, and made tempwaitb and tempwaitc as specific to the character (i.e. victim->tempwaitb instead of just tempwaitb). Those variables are successfully being remembered between functions :)
However, ch and victim still aren't being remembered between functions. So, in comm.c, I have no bloody idea what to put down for ch and victim when calling do_mptransformcat. I tried using the same premise as I did with tempwaitb and tempwaitc, i.e. assigning a temporary value to the victim, so it would be remembered. I think my premise is sound, and I'm not recieving any compile or runtime errors, and some debugging did confirm that it is in fact making it to the function call.... however, the function is either not being called, or the variables it's recieving are wrong, because after the delay, nothing happens. If I activate the mobprogram again (by saying 'catme' for lack of anything better), then it performs the next message in the sequence, does the delay, then nothing, as if I'm not making the call back into mptransformcat. Here is the relevant code (more concise this time):
*mud.h*
struct char_data
{
CHAR_DATA * next;
CHAR_DATA * prev;
char * tempvictim;
CHAR_DATA * tempch;

*the beginning of do_mptransformcat*
void do_mptransformcat ( CHAR_DATA *ch, char *argument )
{
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
int level;
int iLevel;
int iLang;

if ( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ))
{
send_to_char( "Huh?\n\r", ch );
return;
}


argument = one_argument( argument, arg );

if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}

if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}

if ( IS_NPC(victim) )
{
progbug( "Mptransform - Victim is NPC", ch );
return;
}

victim->tempch = ch;
victim->tempvictim = argument;

*and comm.c*
if ( d->character && d->character->wait > 0 )
{
--d->character->wait;
continue;
}

if ( d->character && d->character->tempwait > 0 )
{
--d->character->tempwait;

if (d->character->tempwait == 0)
{
write_to_descriptor( d->descriptor,
"debug1.\n\r", 0 );

/* Right here is where I'm stuck */ do_mptransformcat(d->character->tempch, d->character->tempvictim);
}

continue;
}

*that's it*
I feel I'm close, but I'm still stumped on this part. Thanks for all your help and, above all, your patience =)
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #35 on Fri 29 Jun 2001 01:04 AM (UTC)
Message
Oops, I forgot to mention. After the delay, when it makes the call back to do_mptransformcat, I get the following bug message:
Log: [*****] BUG: Mptransform - Bad syntax, Mob #20107.
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #36 on Mon 02 Jul 2001 06:59 AM (UTC)
Message
Does anybody have any insights as to how to accurately make that function call and what type I should initialize the variables as in mud.h? No combination I've tried has yielded progressive results since the last post.
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #37 on Mon 02 Jul 2001 10:32 PM (UTC)

Amended on Mon 02 Jul 2001 10:33 PM (UTC) by Nick Gammon

Message
I would like to make a suggestion. You are obviously having trouble getting this to work, and I think you are getting focussed on one minor area - namely getting messages to appear slowly, when there is a whole lot more stuff that SMAUG can do.

You said yourself in an earlier post "this is just more of an aesthetic thing" - how about leaving it for now and doing something else?

Even if you get this "delayed message" thing to work that won't be the end of your problems.

For example, you have these messages:


A vast, open field flashes before your eyes....
You are standing in this field....
Your ears perk-up, your eyes focus, and you crouch down low in the grass....
Patience is a virtue.... You wait calmly....
You *LEAP* out of your hiding place, and land upon your unsuspecting victim!!
Your prey tries to escape, but to no avail!
The helpless mouse struggles as you bat it around playfully....
The rodent bolts!
Your spring-loaded legs ZIP into action! The chase is on....
Your superior dexterity is no match for the mouse, and you swiftly overtake it!
With a quick bite to the neck, you kill your prey.
You take your catch deep into the woods, where hundreds of cats are waiting for your arrival....


There are a whole lot of problems here for a start.


  1. What if, halfway through the messages, the player goes to another room, recalls, goes into a town? Are they really "standing in this field" any more? No, and it will look silly to say so.
  2. You are effectively controlling the player, telling him what he is doing. What if he doesn't "wait calmly" but walks away? It will look silly to say "you wait calmly" when he is running from room to room.
  3. What if the player doesn't want to kill the mouse?
  4. Does he get experience points for killing it?


I think you are best of letting this idea rest for a while. If you really want the delayed message thing, there is another codebase I am investigating that has that built in, so you can achieve that effect (desirable or not) with a minimum amount of effort.

Meanwhile, I suggest concentrating on designing the rooms and areas in general, and making a fantastic MUD. :)

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #38 on Mon 02 Jul 2001 11:11 PM (UTC)
Message
it's not actual actions. It's a vision he's recieving in his mind.
I just need to know how to call that function while preserving the ch and victim variables from function-to-function; my other admins are focusing on socials and areas while I'm revamping through the source code.
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #39 on Sat 07 Jul 2001 10:45 PM (UTC)
Message
In comm.c, this is how I'm making the function call:
do_mptransformcat(d->character->tempch, d->character->tempvictim);

in mud.h, tempch is defined as CHAR_DATA *
and tempvictim is defined as char *

Tempch is working perfectly. However, tempvictim is working -somtimes-, but randomly not working. There is no pattern to this, but sometimes when the function is called, I get the bug: Log: [*****] BUG: Mptransform - Bad syntax, Mob #20107.
or the bug: Log: [*****] BUG: Mptransform - Victim not there, Mob #20107.

Both suggest that tempvictim is sometimes not being the same as the initial argument. This is how I set it in mud_comm.c:

CHAR_DATA *tempchb;
char *tempvictimb;
/* these are used to capture argument and ch, before argument is altered, as follows */

if ( ( tempchb != ch ) || ( tempvictimb != argument ) )
{
tempchb = ch;
tempvictimb = argument;
}

argument = one_argument( argument, arg );

So now, tempchb should be same as ch, and tempvictimb should be same as argument. Then the next ifchecks:

if ( arg[0] == '\0' )
{
progbug( "Mptransform - Bad syntax", ch );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
progbug( "Mptransform - Victim not there", ch );
return;
}

This is self-explanatory. Sometimes it fires, sometimes it doesn't. I've done a lot of debugging, and haven't been able to determine any pattern; it's just randomly working or not working, which makes no sense to me whatsoever. Also, the second ifcheck serves to set the victim variable for that function. Now here comes the crucial lines:

if ( ( victim->tempch != tempchb ) || ( victim->tempvictim != tempvictimb ) )
{
victim->tempch = tempchb;
victim->tempvictim = tempvictimb;
}

This states that, if victim->tempch or victim->tempvictim are not what they're supposed to be, then it sets them to what they should be. This is all the relevant code to this attempt to carry the variables globally, while having it specific to each character. Since the character is delayed, and at least at the moment there's no worry about teleports or anything (I can worry bout that later on), there's no way the character will leave the room, which he isn't. Sometimes this bug will fire after 1 or 2 messages, and sometimes it'll take like 15 messages before it fires; I can find no pattern whatsoever.
Could someone PLEASE give me some guidance with this? I've been banging my head over it for weeks, and I can't release the next backup until this coding is done, like I promised. I'm sure Nick is weary of my nagging on this problem, so if anyone else (i.e. Nivek or whomever) could help me with this, that'd prolly be best. =) Thank you :)
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #40 on Sat 07 Jul 2001 10:50 PM (UTC)
Message
Also, I'm not sure if it's relevant, but I should prolly mention it: When compiling, I get the following Warning error for mud_comm.c:

mud_comm.c:1278: warning: 'tempvictimb' might be uninitialized in this function

I'm not sure why it's saying this, because it is initialized. Yet it's saying something that may shed a light on why this isn't working, I'm not sure.
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #41 on Sun 08 Jul 2001 04:37 AM (UTC)
Message

CHAR_DATA *tempchb;
char *tempvictimb;
/* these are used to capture argument and ch, before argument is altered, as follows */

if ( ( tempchb != ch ) || ( tempvictimb != argument ) )
{
tempchb = ch;
tempvictimb = argument;
}


The if statement is fairly meaningless, because as the compiler points out, you are testing tempvictimb but tempvictimb does not have any value assigned to it - it is just what happens to be on the stack at the time.

You assign something to tempvictimb *after* testing its value. The same remark applies to tempchb.

You say:

Quote:

This states that, if victim->tempch or victim->tempvictim are not what they're supposed to be, then it sets them to what they should be.


Well, why not make sure they have the right value, like this:


CHAR_DATA *tempchb = ch;
har *tempvictimb = argument;


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #42 on Thu 12 Jul 2001 08:46 PM (UTC)
Message
I eliminated the ifcheck and did as you suggested instead. Now, the compile warning error is gone :)
However, I'm -STILL- getting that bug I described earlier, whereas for some reason, at seemingly random occurances, victim is not transferring over correctly.
Do you have any other ideas that may solve this? If nothing else, you're helping me make my code a lot cleaner =)
Eventually perhaps we'll end up hitting the root of the problem. I thank you for your continued help with this extremely perplexing matter :)
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #43 on Tue 24 Jul 2001 02:14 AM (UTC)
Message
Can anyone please help me with this? I've been trying almost 2 months now, and still can't get this bloody thing to work! Read the previous few posts if you don't know what I'm talking about. Thank you whomever decides to help me fix this once and for all :)
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #44 on Tue 24 Jul 2001 04:02 AM (UTC)
Message
Probably this is the reason it wasn't put there by the original developers.

Here is one potential problem, you have saved a victim pointer, and are sending this victim messages every second or so (quite a lot of messages, thus quite a lot of seconds).

What if the victim logs out? Then the pointer is invalid.

I still think the idea of sending messages like:


The rodent bolts!
Your spring-loaded legs ZIP into action! The chase is on....
Your superior dexterity is no match for the mouse, and you swiftly overtake it!


... while the player has gone back to town and is sleeping in the inn, or buying provision in the shop, is going to look silly. I know you say it is a vision he has in his mind, but it is a strange vision.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


196,396 views.

This is page 3, subject is 5 pages long:  [Previous page]  1  2  3 4  5  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.