Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Bots

Development::Bots Forum for bots.

Reply
 
Thread Tools Display Modes
  #61  
Old 04-04-2016, 11:21 PM
starblight's Avatar
starblight
Sarnak
 
Join Date: Jan 2007
Posts: 76
Default

I just updated my source last night and found "^attack" by it self did not do anything but "^attack all" worked. I am starting to get how the commands work but I sadly did not find them intuitive. I did find the command list and that helped a lot. I also used the help option a lot but found the help to be almost more confusing.

Anyways I will keep working at it and I am sure I will get a better understanding of how they work.

(edit) My god I read over my post and realized how negative it was. So to be more even with my remarks. I have only had one day to play with them so I am sure I will find more things good to say later but for now I love how a lot of the commands are much shorter then before. I also love how a lot of the command augments are the same for multiple commands. like "all" for example. I have also not tried a lot of the commands that I think I am going to love once I do.
Reply With Quote
  #62  
Old 04-05-2016, 05:56 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

Hehe! No harm, no foul


Yes, the new bot command system is completely different.

It's like speaking English for 20 years, then being expected to speak Russian the next day..with the instructions written in Chinese...


The key to the new system is 'Actionable Bots' .. a sub-system that determines what bots are queued for processing in any action.

A command where [actionable: target] is allowed, then ^command will work, defaulting to the client's target - if the target is of the proper type.

Code:
usage: <enemy_target> ^attack [actionable: byname | ownergroup | botgroup | namesgroup | healrotation | spawned] ([actionable_name])
But, in the case of ^attack, target is not allowed and an argument(s) must be passed.

Another indicator that an argument is required is the lack of '( )' surrounding the argument list.


Make sure that you check out the updated wiki page as well: http://wiki.eqemulator.org/p?Bot_Commands&frm=Main
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote
  #63  
Old 04-05-2016, 06:47 PM
ionhsmith
Discordant
 
Join Date: Jun 2014
Posts: 284
Default

Uleat it says ... this command does not allow Actionablebot criteria target
Reply With Quote
  #64  
Old 04-05-2016, 07:02 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

Yes, that is missing the 'actionable' argument.


If you want all of your spawned bots to attack your target, use the ^attacked spawned invocation.

Or, maybe ^attack ownergroup for only the bots in your group.
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote
  #65  
Old 04-06-2016, 09:34 AM
AsmoTiC
Sarnak
 
Join Date: Aug 2004
Posts: 50
Default

Uleat -

First, really fantastic work with the bots as of late. I've personally noticed huge improvements with them since the rework. Thanks you!

Thought i'd post a quick request and see if it was reasonable, or require to much coding. Would it be possible to save a healrotation group/settings once it's been setup. That way you could just do a ^healrotationload?

As it is now I generally:
^botgroupload <cleric group>
^healrotationcreate <leader>
^healrotationaddmember <member> (x4 times)
^healrotationaddtarget <tank>
^healrotationchangeinterval <time>
^healrotationstart <leader> (just to make sure it's running).

I've gotten pretty fast with setting it up, but it's still alot of typing, or multiple social buttons since all that doesn't fit in one. Figured it would be nice if we could do a ^healrotationsave <name> and ^healrotationload <name> similar to how groups are done.

In additional, I would have liked ^healrotationstart <leader> to actually get the rotation going. Perhaps have healrotationstart have them actually start healing regardless of the tanks status. Then healrotationstop <leader> would work like it does now and stop it, then maybe have a new one "healrotationauto <leader> for example that gets it running like it does currently. Just an extra suggestion since I was already going on about the healing rotation.

Thanks again, very excellent work!
Reply With Quote
  #66  
Old 04-06-2016, 03:24 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

I'm still mulling over how to load/save heal rotations..it wasn't something that I intentionally left out.

For the interim, try these:
^bgload <cleric group>
^hrcreate <leader>
^hraddmr <member> (x4 times)
^hraddt <tank>
^hrinterval <time>
^hrstart <leader> (just to make sure it's running).

You can use ^alias command to see if any aliases are available for that particular command..or look to see what aliases are registered for a command in the `aliases`
field of the `bot_command_settings` table in the database.


I'm pretty sure that the heal rotation turns active as soon as you add a member - the first member being the bot who created the hr:
https://github.com/EQEmu/Server/blob...tation.cpp#L92
https://github.com/EQEmu/Server/blob...ation.cpp#L507
https://github.com/EQEmu/Server/blob...ation.cpp#L526

The current state can be verified by using the ^hrlist command.

You can stop the hr..but, it will start again if you add/remove a healer member while it is inactive.
(If this is too 'streamlined' .. I can modify that behavior.)


The way the system checks for a 'valid' heal target is to sort the target list by a series of criteria.

Each set of checks will either set 'm_active_heal_target' to true or false. A final 'false' will only be applied if no criteria are met.

That target state (and target, if state is 'true') will remain active for 250ms. So, even with a 1-second interval on the hr, the target will be checked,
and possibly updated, 3-4 times.


If you don't mind experimenting, you could try something like this on your hr:
^hrinterval 2 (or 1)
^hrsafe 0 100 EDIT: The maximum allowed value is hard-coded to '95.0'
^hrcrit 0 50 (or higher)

For non-adaptive healing, the types are prioritized as follows: main tanks, healers, everyone


With the new system, heal rotations are definitely reactive as opposed to proactive.

There are a lot of options to experiment with.

I'll consider implementing a proactive option, though, I'd like to hear how changing those options perform.


My only problem with testing is that I can only test the functionality of the code..not the real-world application of it..so, feedback is the key to
improvements
__________________
Uleat of Bertoxxulous

Compilin' Dirty

Last edited by Uleat; 04-06-2016 at 03:37 PM..
Reply With Quote
  #67  
Old 04-06-2016, 07:19 PM
AsmoTiC
Sarnak
 
Join Date: Aug 2004
Posts: 50
Default

wow, thanks for all the information!

The alias works great, will need to get used to them like I have with the full command, but they will certainly help until a load/save option comes available (if it's possible).

Went ahead and tested the HR. Using a 65 Ogre Warrior (6100hp 1400ac) running Defensive Disc against Derakor the Vindicator (Red con). HR was 5 Clerics, all 65. No restrictions on spells.

Heal Rotation Settings:
Current stat: active
Casting interval: 2 seconds
Fast Heals: off
Adaptive targeting: off
Casting override: off
Base hp limits - Crit: 10%, Safe: 95%
Cloth hp limits - Crit: 30%, Safe: 95%
Leather hp limits - Crit: 25%, Safe: 90%
Chain hp limits - Crit: 15%, Safe: 80%
Plate hp limits - Crit: 10%, Safe: 75%
Heal Rotataion Members:
(1) CLR1
(2) CLR2
(3) CLR3
(4) CLR4
(5) CLR5
Heal Rotataion Targets:
(1) WAR

This results in my death before the first CH lands. The first 4 CH's get started, but i'm dead before the 5th and final one starts (giving you a time frame from start to finish). Now if I have a boxed cleric put a Hot on me, and land a Fast heal on me, the rotation works great keeping me up for the remainder of the fight. This is why I was hoping for a proactive start to the rotation, so I wouldn't have to wait the full 10+ seconds before the first heal lands from the hr group.

Testing out your ^hrsafe and ^hrcrit, same values (95% locked as you said, and 50% adjusted), Made sure the percents were for both Base and Plate. Result was the same as above; first 4 CH's get started, but none land.

Did try one more thing. Added a Bot Shaman to the Warriors group, outside of the HR. This adjusted the stats a little (6640hp, 1425ac). With the spotheal from the Bot Shaman, it bought enough time for the rotation to start running cleanly.

Anyway, i'm happy to test a bunch of different scenarios for you, just let me know. Thanks again for taking a look at my earlier suggestion and for your detailed response.
Reply With Quote
  #68  
Old 04-06-2016, 10:15 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

With the way that main tanks now work (each hr target is checked against being main tank of its own group..not against the hr,) would it be feasible to select a main-main
tank for the hr itself?

I could implement the hr-main tank as being the trigger itself..if set, then proactive healing occurs - but, that tank must be a member of the hr already..

..or something like that?


So, having the hr-main tank (target) set would enable proactive healing and clear would enable reactive?


I'm taking your encounter scenario home to see if I can replicate it..do you have a list of other bot classes that were used in this encounter?
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote
  #69  
Old 04-07-2016, 08:17 AM
AsmoTiC
Sarnak
 
Join Date: Aug 2004
Posts: 50
Default

Quote:
Originally Posted by Uleat View Post
... I'm taking your encounter scenario home to see if I can replicate it..do you have a list of other bot classes that were used in this encounter?
I was just running a test to help give some information on how the HR was performing. For the test it was the Warrior groupless, with the HR group (Brd + Clr x5). Only the 5x Clerics are part of the HR (as shown in my earlier post of the ^hrlist), with the War as the only HR target.

In addition I did run that last test with a Shaman bot grouped with the Warrior, same HR group of course.

One quick note, which may or may not be important. I haven't been selecting the Warrior as "Maintank" via the group window. No reason I couldn't, just haven't been. If that's causing a problem, let me know. If there is something in the code that checks for someone to be flagged as Maintank, I'll run another couple tests for you this evening when I get home from the office.

Alternativly, your suggestion of having the first HR target activate Proactive healing would work great. Then having it work as it does now when no target has been defined. Or, perhaps leave the targeting alone and allow the Safe range to be set at 100%, which would get them started healing even at full life. Setting that above 95% might cause other problems though, if the HR group tries to heal people outside the assigned target.

Anyway, let me know how I can help. Happy to run through some iterations with you.
Reply With Quote
  #70  
Old 04-07-2016, 03:58 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

Thanks for the feedback on this, btw!


Yeah, no..if your tank was the only target, he should have been picked up on the 'everyone' check. So, it's probably the delay in casting, like you said,
with a bit of safe-value influence.

An all cleric healing rotation was something that I didn't test. I just used the bots that I had on-hand.


On percentages, I probably won't change their defaults..but, I can bump the max up to 100% - which will probably be needed for a proactive target anyway.

Note on percentages:
- Non-adaptive healing will use the 'base' ('0') armor type for safe-crit determinations explicitly.
- Adaptive healing will check the target's armor type and use the current value for safe-crit determinations ('base' becomes the absolute min-max in this case.)


I'm working on some convergence coding for another system atm..but, it's a quick thing and I'll work on this change as soon as I finish.
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote
  #71  
Old 04-07-2016, 11:00 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

I am having a little issue getting the current code to trigger..meaning, it not heal rotation code-related.

I'll dig deeper into the actual bot healing code and see if there's an issue there.


EDIT: Uleat..err, user error... Bots must be grouped before their AI's kick in :P
__________________
Uleat of Bertoxxulous

Compilin' Dirty

Last edited by Uleat; 04-08-2016 at 03:12 PM..
Reply With Quote
  #72  
Old 04-08-2016, 09:11 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

Heal Rotations now have a HOT for proactive healing and some limited load/save/delete capabilities.


[For HOTs]
Select your HOT from the current hr target pool and the cycle will begin automatically.

Clear your HOT and the system reverts to its previous state.


[For load/save/delete]
Use ^hrcreate on a bot that has a saved hr profile and it will be automatically loaded from the database.

A query failure, or use on a non-profiled bot, will default to the standard hr create process.

Non-local (not in zone) members and targets will be reported during load processing.


I could not do an auto-load feature due to the way that groups are currently handled currently. That will take a rework of that system.
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote
  #73  
Old 04-09-2016, 10:45 AM
AsmoTiC
Sarnak
 
Join Date: Aug 2004
Posts: 50
Default

right on, that's awesome, thanks Uleat!

Managed to get the code updated and recompiled, updated the database, and got underway. Couple quick notes before the first pull.

^bglist reports my two groups:
(1)Bot-group name: Clerics|Leader: <bard>
(2)Bot-group name: Rogues|Leader: <shaman>

I have no trouble ^bgload Clerics, however after the update the Rogues won't come out as a group. ^bgload Rogues returns "Failed to load bot-group id for load bot-group for 'Rogues'". This is different than if I tried to load a group I don't have. ^bgload Enchanters, for example, returns "Bot-group Enchanters does not exist".

In addition, if I try to start a new group (^bgcreate Temp) the shaman reports "... is already the current leader of a bot-group", and the rogues report "... is already a current member of a bot-group". If I try (^bgremove) each of them report "... is not a current member of a group.

I assume something got goofed in the DB or something.

The HoT stuff works great for getting the rotation started. However I noticed they don't keep the loop running. Each Cleric in turn casts Complete Heal, however Cleric 1 doesn't start a new CH until after Cleric 5's CH lands. So there is a 10sec gap in heals. The first cleric just needs to start her next Complete Heal at the set interval after the last cleric starts to cast hers. Would be a perfect CH rotataion at that point!

I have good backups from right before I dropped the new compile and DB update. Let me know if you have any thoughts about the broken Rogue group (bot group 2 for me), or anythink you wanted to try on the rotation.
Reply With Quote
  #74  
Old 04-10-2016, 02:41 PM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

I don't 'think' that I changed any of the command/database code for bot-groups in the HR save/HOT code.

If it's truly a bug, then it's probably pre-existing.


Double-check the actual name of the bot-group to see if its all lower, per chance. I did some work with the bot loading code in regard to capitalization..but, I know
that bot-groups will not load 'Rogues' if the case doesn't match 'rogues.'

Also, you can double-check by camping them all out and trying again. (If all else fails, run a query to verify the name of the bot-group.)
Code:
SELECT `group_name` FROM `bot_groups`

The database code is basically set up to 'fail' an action if the criteria is absent (or out of range,) or if there is an actual query error.

Since the logging system will (generally) pass on a failed query to the client, a lack of one accompanying the fail message usually indicates a criteria problem.


I'll wait until I hear back from you before I start looking into the code..but, I will if it definitely turns out to be a bug.

-----

I'm not 100% sure of the differences between fast heal and non-fast heal code..that is built into the bot class itself and is one of the things that I haven't really touched yet.

I do believe there are two distinct paths for choosing spells, however.


Heal rotation code is not tied to any of the actual spell casting code..it is not used to determine when a healer should cast.


Since the hot bypasses all 'standard' heal rotation criteria, there's really only two things that should keep a healer from casting:

- Not enough mana ..or..
- Target's 'DontHealMeBefore' time

Assuming enough mana, it's possible to have another cleric's spell land and the next caster(s) be processed during this 'cool off' period.

That could 'skip' all casters for the remainder of the cycle..and depending on the length of your interval...


I'll set up a 5-cleric group and see if I can pinpoint exactly what's going on..and make adjustments, if necessary.


EDIT:

Ran a 5-cleric bg with a bard and setup the hr for the 5 clerics as members and me as the target - as a level 65...

There is something going on with non-fast heals healing..but, there is something even bigger for 'fast heals'


I ran the HOT cycle for 4 minutes with fh off..then started to run an fh on cycle for the same to compare.

There were no reports of any healing with fast heals on..which, most likely, means that there are no bot healing spells available in that range.


Others have reported issues with bot (merc) healers at these higher levels..so, the above observation may not be conclusive.


I will do a spell casting log dump and see why the non-fast heal spells are not finishing..but..it will most likely involve the bot spell casting code and not
the actual heal rotation code.


EDIT2:

Unfortunately, some spell casting failures are not reported in the logs.


What I did see was the all of the fast heal casts were failures and all of the non-fast heal were successes.

Since the heal rotation code only invokes the spell casting and does not process it, the apparent 'failure' should actually be in the 'finish spell' code and not the invocation of
the spell itself.


I may add some debugging code to help trace the issue. Would be nice to know if this is the same problem that others have reported with 'normal' casting.
__________________
Uleat of Bertoxxulous

Compilin' Dirty

Last edited by Uleat; 04-10-2016 at 04:33 PM..
Reply With Quote
  #75  
Old 04-11-2016, 07:33 PM
AsmoTiC
Sarnak
 
Join Date: Aug 2004
Posts: 50
Default

Quote:
Originally Posted by Uleat View Post
I don't 'think' that I changed any of the command/database code for bot-groups in the HR save/HOT code.

If it's truly a bug, then it's probably pre-existing.


Double-check the actual name of the bot-group to see if its all lower, per chance. I did some work with the bot loading code in regard to capitalization..but, I know
that bot-groups will not load 'Rogues' if the case doesn't match 'rogues.'

Also, you can double-check by camping them all out and trying again. (If all else fails, run a query to verify the name of the bot-group.)
Code:
SELECT `group_name` FROM `bot_groups`

The database code is basically set up to 'fail' an action if the criteria is absent (or out of range,) or if there is an actual query error.

Since the logging system will (generally) pass on a failed query to the client, a lack of one accompanying the fail message usually indicates a criteria problem.


I'll wait until I hear back from you before I start looking into the code..but, I will if it definitely turns out to be a bug.
Sorry it's taken this long to get back to you. Pulled the Git from a couple hours ago, and made new binaries, these include the changes you did to Spell AI code.

So, same problems with the Rogues (my second group). Database looks good, bot_groups has two entries:
groups_index 1, group_leader_id 15, group_name Clerics. Leader ID checks for the Bard
groups_index 2, group_leader_id 1, group_name Rogues. Leader ID checks for the Shaman.
In addition, I checked bot_data and bot_group_members and they check against each other (i.e. groups_index checks for bot_id)

I won't repost all the messages, but they report the same as my earlier post. I did try ^bgdelete Rogues, which I don't think I tried last time. This returns "Could not locate group id for 'Rogues'.

I'm pretty sure I can restore my back up, delete the rogues, and recreate them without a problem. Haven't does it yet, as I wanted to keep a state where they were broken incase you wanted to try anything else. Also, if it is a bug somewhere, it could affect others without the means of restoring to an earlier backup.

----
In regards to HR. I went ahead and ran several cycles through the log so I could get timestamps. Here is a start of the rotation showing the 5x casts 2sec apart, then the gap between last CH landing and next cycle starting. Also, I saw at 17:08:03 Bonnet (Cleric4) cast a spell I couldn't identify, right after her CH landed.

Note: Meat is the Warrior, Bubbles, Blossom, Buttercup, Bonnet & Bunny are the Clerics
Code:
[17:07:06] Logging to 'eqlog.txt' is now *ON*.
[17:07:16] You say, '^hrlist Bubbles'
[17:07:16] Heal Rotation Settings:
[17:07:16] Current state: active
[17:07:16] Casting interval: 2 seconds
[17:07:16] Fast heals: 'off'
[17:07:16] Adaptive targeting: 'off'
[17:07:16] Casting override: 'off'
[17:07:16] HOT state: inactive
[17:07:16] HOT target: null
[17:07:16] Base hp limits - critical: 65.0%, safe: 95.0%
[17:07:16] Cloth hp limits - critical: 45.0%, safe: 95.0%
[17:07:16] Leather hp limits - critical: 40.0%, safe: 90.0%
[17:07:16] Chain hp limits - critical: 35.0%, safe: 80.0%
[17:07:16] Plate hp limits - critical: 30.0%, safe: 75.0%
[17:07:16] Heal Rotation Members:
[17:07:16] (1) Bubbles
[17:07:16] (2) Blossom
[17:07:16] (3) Buttercup
[17:07:16] (4) Bonnet
[17:07:16] (5) Bunny
[17:07:16] Heal Rotation Targets:
[17:07:16] (1) Meat
[17:07:28] You say, '^hrsethot Meat'
[17:07:29] Succeeded in setting Meat as the HOT in Bubbles's Heal Rotation
[17:07:29] Bubbles begins to cast a spell.
[17:07:29] Bubbles says 'Casting Complete Heal on Meat, please stay in range!'
[17:07:31] Blossom begins to cast a spell.
[17:07:31] Blossom says 'Casting Complete Heal on Meat, please stay in range!'
[17:07:33] Buttercup begins to cast a spell.
[17:07:33] Buttercup says 'Casting Complete Heal on Meat, please stay in range!'
[17:07:35] Bonnet begins to cast a spell.
[17:07:35] Bonnet says 'Casting Complete Heal on Meat, please stay in range!'
[17:07:37] Bunny begins to cast a spell.
[17:07:37] Bunny says 'Casting Complete Heal on Meat, please stay in range!'
[17:07:39] You are completely healed.
[17:07:41] Blossom performs an exceptional heal! (15000)
[17:07:41] You are completely healed.
[17:07:43] Buttercup performs an exceptional heal! (15000)
[17:07:43] You are completely healed.
[17:07:45] Bonnet performs an exceptional heal! (15000)
[17:07:45] You are completely healed.
[17:07:47] You are completely healed.
[17:07:47] Bubbles begins to cast a spell.
[17:07:47] Bubbles says 'Casting Complete Heal on Meat, please stay in range!'
[17:07:49] Blossom begins to cast a spell.
[17:07:49] Blossom says 'Casting Complete Heal on Meat, please stay in range!'
[17:07:51] Buttercup begins to cast a spell.
[17:07:51] Buttercup says 'Casting Complete Heal on Meat, please stay in range!'
[17:07:53] Bonnet begins to cast a spell.
[17:07:53] Bonnet says 'Casting Complete Heal on Meat, please stay in range!'
[17:07:55] Bunny begins to cast a spell.
[17:07:55] Bunny says 'Casting Complete Heal on Meat, please stay in range!'
[17:07:57] Bubbles performs an exceptional heal! (15000)
[17:07:57] You are completely healed.
[17:07:59] You are completely healed.
[17:08:01] Buttercup performs an exceptional heal! (15000)
[17:08:01] You are completely healed.
[17:08:03] Bonnet performs an exceptional heal! (15000)
[17:08:03] You are completely healed.
[17:08:03] Bonnet begins to cast a spell.
[17:08:05] You are completely healed.
[17:08:05] Bubbles begins to cast a spell.
[17:08:05] Bubbles says 'Casting Complete Heal on Meat, please stay in range!'
[17:08:07] Blossom begins to cast a spell.
[17:08:07] Blossom says 'Casting Complete Heal on Meat, please stay in range!'
[17:08:09] Buttercup begins to cast a spell.
[17:08:09] Buttercup says 'Casting Complete Heal on Meat, please stay in range!'
[17:08:11] Bonnet begins to cast a spell.
[17:08:11] Bonnet says 'Casting Complete Heal on Meat, please stay in range!'
[17:08:13] Bunny begins to cast a spell.
[17:08:13] Bunny says 'Casting Complete Heal on Meat, please stay in range!'
[17:08:15] You are completely healed.
[17:08:17] Blossom performs an exceptional heal! (15000)
[17:08:17] You are completely healed.
[17:08:19] You are completely healed.
[17:08:21] Bonnet performs an exceptional heal! (15000)
[17:08:21] You are completely healed.
[17:08:22] You say, '^hrclearhot Bubbles'
[17:08:22] Succeeded in clearing Bubbles's Heal Rotation HOT
[17:08:23] You are completely healed.
[17:08:34] You say, '^camp spawned'
*footnote* I cleaned up the log a tad to strip bard song, and get a clean time instead of Month, Day, Year, etc.
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 01:36 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3