Implementing new Ability Factories and Card Support Code
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins
Re: Considerations and Questions: Ability Factories
by Sloth » 07 Nov 2012, 16:43
This looks good. It should probably be included in TargetSelection.Agetian wrote:I'm working on an experimental version of the code which may later become a part of a new AF that deals with choosing a source (for Circles of Protection and whatever other cards may refer to "source"). I need a little consultation in this regard. Currently my mockup version of a source chooser does the following:
1) If there are any effects on the stack, it adds the cards that were the sources of those effects into the list, marking them with "(From stack)".
2) To the list of effects on the stack, it adds all the permanents currently in play.
It lists all of that and lets the user pick one.
From the comprehensive rules:Agetian wrote:I have a question: does the above cover all the possible scenarios of a "source"? I just can't possibly imagine what else there could be - if it's neither visible on the stack nor in play as a permanent, what else can it be?
- 119.7. | Open
- 119.7. The source of damage is the object that dealt it. If an effect requires a player to choose a source
of damage, he or she may choose a permanent; a spell on the stack (including a permanent spell);
any object referred to by an object on the stack, by a prevention or replacement effect that’s waiting
to apply, or by a delayed triggered ability that’s waiting to trigger (even if that object is no longer in
the zone it used to be in); or, in certain casual variant games, a face-up card in the command zone.
A source doesn’t need to be capable of dealing damage to be a legal choice. See rule 609.7,
“Sources of Damage.”
I think this can be handled with storing "Remembered" objects. A CoP will create an Effect (these fake cards created by AF Effect) which remembers the target of the ability. I think the script of Awe Strike does all we want already.Agetian wrote:Also, another question is: is there any implementation of "Prevent damage from <...>" currently in Forge? I looked at the damage prevention facilities in the current ability factory but could only find code related to preventing damage *to* a card, not coming *from* a card - if there is any code like that, I'd like to take a look at it, can you please tell me where I can find it? If there's no such implementation yet, can you please tell me what would be the easiest way to detect if a card has any damage-dealing effects (which includes combat damage and spell abilities and whatnot)?
-

Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Considerations and Questions: Ability Factories
by Agetian » 07 Nov 2012, 17:06
Nice. Thanks a lot, Sloth!
Continuing our meditations on "source", do you mean that the command zone is sometimes included in the list? I'm not sure if Forge supports command zone yet, I'll take a look... By the description of rule 119.7, I don't see how a card can be chosen in another zone except for the battlefield, the command zone, or indirectly via the effect placed on the stack... Please, if possible, clarify what other zones may be included in the selection except the battlefield and the command zone (and the stack effects).
P.S. I was looking at TargetSelection but couldn't understand much of how it works... can you please clarify how exactly targeting starts and what function triggers it, in case you know? I'd like to, if possible, make the selection interactive (as in "let the user click either on the ability on the stack or on the permanent card"), but I have difficulties with how to approach this problem... The GUI selection window and the implementation of a ChooseCard-like AF seems feasible though.
- Agetian
Continuing our meditations on "source", do you mean that the command zone is sometimes included in the list? I'm not sure if Forge supports command zone yet, I'll take a look... By the description of rule 119.7, I don't see how a card can be chosen in another zone except for the battlefield, the command zone, or indirectly via the effect placed on the stack... Please, if possible, clarify what other zones may be included in the selection except the battlefield and the command zone (and the stack effects).
P.S. I was looking at TargetSelection but couldn't understand much of how it works... can you please clarify how exactly targeting starts and what function triggers it, in case you know? I'd like to, if possible, make the selection interactive (as in "let the user click either on the ability on the stack or on the permanent card"), but I have difficulties with how to approach this problem... The GUI selection window and the implementation of a ChooseCard-like AF seems feasible though.
- Agetian
- Agetian
- Programmer
- Posts: 3490
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Considerations and Questions: Ability Factories
by friarsol » 07 Nov 2012, 17:16
I think you are also missing any card referenced by an SA on the stack.Agetian wrote:1) If there are any effects on the stack, it adds the cards that were the sources of those effects into the list, marking them with "(From stack)".
2) To the list of effects on the stack, it adds all the permanents currently in play.
It lists all of that and lets the user pick one.
I have a question: does the above cover all the possible scenarios of a "source"? I just can't possibly imagine what else there could be - if it's neither visible on the stack nor in play as a permanent, what else can it be?
Example: Electropotence is in play, and you cast Force of Savagery. Electropotence triggers for the Force ETB, but immediately goes to the graveyard. If I want to use my COP:Green to prevent that damage, since it's originating creature is neither on the battlefield, or the source of the SA. I wouldn't be able to choose the Force.
Edit: Fixing COP card that is relevant
Last edited by friarsol on 07 Nov 2012, 18:15, edited 1 time in total.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Considerations and Questions: Ability Factories
by Agetian » 07 Nov 2012, 17:27
Hmm yeah, I can see that happening. I'm not sure what can be done to enumerate cards like that though, do you have any advice related to how card effects like that can be enumerated? Also, would this situation warrant a COP:Red or a COP:Green? I'm not sure what the damage dealer is going to be in this case - if it's Force of Savagery, it's going to be a green damage source, and if it's Electropotence, it's going to be a red damage source.friarsol wrote:I think you are also missing any card referenced by an SA on the stack.
Example: Electropotence is in play, and you cast Force of Savagery. Electropotence triggers for the Force ETB, but immediately goes to the graveyard. If I want to use my COP:Red to prevent that damage, since it's originating creature is neither on the battlefield, or the source of the SA. I wouldn't be able to choose the Force.
P.S. Electropotence is going to appear on the stack per se, but probably it's not going to be the damage dealing card in that case (thus I'm also not sure that the damage dealt would count as coming from a red or a green source :\ )
- Agetian
- Agetian
- Programmer
- Posts: 3490
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Considerations and Questions: Ability Factories
by friarsol » 07 Nov 2012, 17:50
Oh right, it should be COP:Green because the source is definitely the Force (unlike something like Fling).Agetian wrote:P.S. Electropotence is going to appear on the stack per se, but probably it's not going to be the damage dealing card in that case (thus I'm also not sure that the damage dealt would count as coming from a red or a green source :\ )
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Considerations and Questions: Ability Factories
by Agetian » 07 Nov 2012, 18:05
Yeah, makes sense. As of right now, the best idea would be to enumerate all the cards in zones where an affected card could possibly be - which might actually be a bunch of zones (not sure if e.g. exile or one's hand could be affected in that manner). Does anyone know of a more optimal way to enumerate referenced cards for effects on the stack (or for other cards in general)?friarsol wrote:Oh right, it should be COP:Green because the source is definitely the Force (unlike something like Fling).Agetian wrote:P.S. Electropotence is going to appear on the stack per se, but probably it's not going to be the damage dealing card in that case (thus I'm also not sure that the damage dealt would count as coming from a red or a green source :\ )
- Agetian
- Agetian
- Programmer
- Posts: 3490
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Considerations and Questions: Ability Factories
by Agetian » 07 Nov 2012, 19:34
Ok, here's my first mockup of the code that enumerates different sources and presents a choice. For the referenced effects, the best I could have done at the moment was iterate over getTriggeringObjects, hoping that that would provide a list of cards that are referenced. I'm afraid that it might not always be the case, I need some help in this regard (what would be the optimal way to enumerate all referenced cards?)
Currently this script allows you to pick where you're going to be choosing from (permanents, stack, or referenced cards) and then gives you the list of cards to choose from based on that criterion.
As of right now, this code is just linked to a custom button in the dev mode that I implemented for experiments in my local experimental SVN copy. Please, if possible, tell me where this code should normally go - should it become the basis of targeting for a new Ability Factory (like AF ChooseSource) or somehow be implemented in TargetingSelection (in the case of the latter, I have a rather vague idea how it works...) Any help you can provide is highly welcome.
Here's the first mockup code I came up with (EDIT: removed some useless code from it):
Currently this script allows you to pick where you're going to be choosing from (permanents, stack, or referenced cards) and then gives you the list of cards to choose from based on that criterion.
As of right now, this code is just linked to a custom button in the dev mode that I implemented for experiments in my local experimental SVN copy. Please, if possible, tell me where this code should normally go - should it become the basis of targeting for a new Ability Factory (like AF ChooseSource) or somehow be implemented in TargetingSelection (in the case of the latter, I have a rather vague idea how it works...) Any help you can provide is highly welcome.
Here's the first mockup code I came up with (EDIT: removed some useless code from it):
- Code: Select all
Stack<SpellAbilityStackInstance> stack = Singletons.getModel().getGame().getStack().getStack();
List<Card> permanentCards = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
List<Card> stackCards = new ArrayList<Card>();
List<Card> referencedCards = new ArrayList<Card>();
List<Card> cardsToChooseFrom = new ArrayList<Card>();
if (stack != null) {
for (SpellAbilityStackInstance stackinst : stack) {
if (!stackCards.contains(stackinst.getSourceCard())) {
stackCards.add(stackinst.getSourceCard());
}
if (null != stackinst.getSpellAbility().getTriggeringObjects()) {
for (Object c : (Collection<Object>)stackinst.getSpellAbility().getTriggeringObjects().values())
if (c instanceof Card)
referencedCards.add((Card)c);
}
}
}
String choices[] = {"Permanent", "Stack", "Referenced"};
String choice = GuiChoose.one("Choose a source from...", choices);
if (choice.equals("Permanent")) {
cardsToChooseFrom.addAll(permanentCards);
} else if (choice.equals("Stack")) {
cardsToChooseFrom.addAll(stackCards);
} else if (choice.equals("Referenced")) {
cardsToChooseFrom.addAll(referencedCards);
}
if (cardsToChooseFrom.size() > 0) {
Card chosen = GuiChoose.one("Choose a source", cardsToChooseFrom);
- Agetian
- Programmer
- Posts: 3490
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Considerations and Questions: Ability Factories
by Agetian » 08 Nov 2012, 06:18
Currently I'm in the middle of a dilemma that I need someone's help to solve... Before I begin the actual implementation of the ability factory (or a targeting mode, if that'd be possible), I need opinions on the following:
1. Would choosing from the list be OK or would targeting with a mouse be the option I should go for? I'd assume the latter would be more intuitive, but it seems it'd be hell to implement (at least currently I'm clueless as to how mouse targeting works and how I should best approach the implementation, so any advice at all is highly welcome).
2. How should the limitation by color and by type be best implemented? Am I correct in assumption that it's done via filtering the list of possible choices through CardLists.getValidCards(...)? (in this case, the parameters will come from the script and the filter command will do the magic) EDIT: Did some tests and it seems like this statement is true.
3. Is there anything to add to the blueprint of the algorithm I posted above? I'm especially curious about the "objects referenced by other objects" part, because I have no idea how that is best enumerated (I've found a way to enumerate at least a part of those objects, but probably that's not all - if it isn't, your suggestions are highly welcome).
As soon as these three questions are resolved, I'll begin implementing the code that will power the CoP/RoP cards.
EDIT: Here's the latest version of the mockup blueprint of the code, currently filtered through CardLists.getValidCards to get only red cards, as well as only showing choice options that are valid at the current time.
1. Would choosing from the list be OK or would targeting with a mouse be the option I should go for? I'd assume the latter would be more intuitive, but it seems it'd be hell to implement (at least currently I'm clueless as to how mouse targeting works and how I should best approach the implementation, so any advice at all is highly welcome).
2. How should the limitation by color and by type be best implemented? Am I correct in assumption that it's done via filtering the list of possible choices through CardLists.getValidCards(...)? (in this case, the parameters will come from the script and the filter command will do the magic) EDIT: Did some tests and it seems like this statement is true.
3. Is there anything to add to the blueprint of the algorithm I posted above? I'm especially curious about the "objects referenced by other objects" part, because I have no idea how that is best enumerated (I've found a way to enumerate at least a part of those objects, but probably that's not all - if it isn't, your suggestions are highly welcome).
As soon as these three questions are resolved, I'll begin implementing the code that will power the CoP/RoP cards.
EDIT: Here's the latest version of the mockup blueprint of the code, currently filtered through CardLists.getValidCards to get only red cards, as well as only showing choice options that are valid at the current time.
- Code: Select all
Stack<SpellAbilityStackInstance> stack = Singletons.getModel().getGame().getStack().getStack();
List<Card> permanentCards = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
List<Card> stackCards = new ArrayList<Card>();
List<Card> referencedCards = new ArrayList<Card>();
List<Card> cardsToChooseFrom = new ArrayList<Card>();
if (stack != null) {
for (SpellAbilityStackInstance stackinst : stack) {
if (!stackCards.contains(stackinst.getSourceCard())) {
stackCards.add(stackinst.getSourceCard());
}
if (null != stackinst.getSpellAbility().getTriggeringObjects()) {
for (Object c : (Collection<Object>) stackinst.getSpellAbility().getTriggeringObjects().values()) {
if (c instanceof Card) {
referencedCards.add((Card) c);
}
}
}
}
}
// + FILTER TEST +
permanentCards = CardLists.getValidCards(permanentCards, "Card.Red", null, null);
stackCards = CardLists.getValidCards(stackCards, "Card.Red", null, null);
referencedCards = CardLists.getValidCards(referencedCards, "Card.Red", null, null);
// - FILTER TEST -
ArrayList<String> choices = new ArrayList<String>();
if (permanentCards.size() > 0)
choices.add("Permanent");
if (stackCards.size() > 0)
choices.add("Stack");
if (referencedCards.size() > 0)
choices.add("Referenced By Another Object");
String choice = GuiChoose.one("Choose a source from...", choices);
if (choice.equals("Permanent")) {
cardsToChooseFrom.addAll(permanentCards);
} else if (choice.equals("Stack")) {
cardsToChooseFrom.addAll(stackCards);
} else if (choice.equals("Referenced By Another Object")) {
cardsToChooseFrom.addAll(referencedCards);
}
if (cardsToChooseFrom.size() > 0) {
Card chosen = GuiChoose.one("Choose a source", cardsToChooseFrom);
}
- Agetian
- Programmer
- Posts: 3490
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Considerations and Questions: Ability Factories
by Sloth » 08 Nov 2012, 08:36
Choosing from lists is ok. Look at chooseCardFromList in the TargetSelection class. Most of what you want is already there.Agetian wrote:1. Would choosing from the list be OK or would targeting with a mouse be the option I should go for? I'd assume the latter would be more intuitive, but it seems it'd be hell to implement (at least currently I'm clueless as to how mouse targeting works and how I should best approach the implementation, so any advice at all is highly welcome).
Yes. This is the way to go.Agetian wrote:2. How should the limitation by color and by type be best implemented? Am I correct in assumption that it's done via filtering the list of possible choices through CardLists.getValidCards(...)? (in this case, the parameters will come from the script and the filter command will do the magic) EDIT: Did some tests and it seems like this statement is true.
I haven't looked at your code, because i guess chooseCardFromList already does most of the stuff and can be expanded as needed.Agetian wrote:3. Is there anything to add to the blueprint of the algorithm I posted above? I'm especially curious about the "objects referenced by other objects" part, because I have no idea how that is best enumerated (I've found a way to enumerate at least a part of those objects, but probably that's not all - if it isn't, your suggestions are highly welcome).
-

Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Considerations and Questions: Ability Factories
by Agetian » 08 Nov 2012, 09:30
Thanks for help, Sloth!Sloth wrote:I haven't looked at your code, because i guess chooseCardFromList already does most of the stuff and can be expanded as needed.
I'm currently trying to come up with a working script for CoP:Red that would prevent damage from a red source (initially - from a red card) that is chosen from a list of possibilities. However, the following script, based on a mockup referenced in another thread, does not work (it creates the effect but the effect does not prevent damage; also, the card chosen is remembered not on the effect, but on CoP itself, and when the effect goes away at the end of the turn, the chosen card is still remembered on CoP):
- Code: Select all
Name:Circle of Protection Red
ManaCost:1 W
Types:Enchantment
Text:no text
A:AB$ ChooseCard | Cost$ 1 | Choices$ Card.Red | RememberChosen$ True | AILogic$ NeedsPrevention | SubAbility$ DBEffect | SVars$ DBEffect,RPreventNextFromSource,ExileEffect
SVar:DBEffect:DB$ Effect | ReplacementEffects$ RPreventNextFromSource | RememberObjects$ Chosen | SVars$ RPreventNextFromSource
SVar:RPreventNextFromSource:Event$ DamageDone | ValidSource$ Card.IsRemembered | ValidTarget$ You | ReplaceWith$ ExileEffect | PreventionEffect$ True | Description$ The next time the chosen source deals damage to you, prevent that damage.
SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Exile
SetInfo:4ED|Common|http://no.picture.yet
End
P.S. I also tried to adapt the script of "Awe Strike" to the needs of CoP cards, but it uses mouse targeting instead of list-based card selection, and I'm not sure how to switch it over to a list. :\
- Agetian
- Agetian
- Programmer
- Posts: 3490
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Considerations and Questions: Ability Factories
by friarsol » 08 Nov 2012, 13:59
I made some small changes to your script. Basically, RememberObjects$ Chosen doesn't work, so you have to remember it (like you did) and then reference the Remembered Object down below.
- Code: Select all
A:AB$ ChooseCard | Cost$ 1 | Choices$ Card.Red | RememberChosen$ True | AILogic$ NeedsPrevention | SubAbility$ DBEffect | SVars$ DBEffect,RPreventNextFromSource,ExileEffect
SVar:DBEffect:DB$ Effect | ReplacementEffects$ RPreventNextFromSource | RememberObjects$ Remembered | SVars$ RPreventNextFromSource,ExileEffect | SubAbility$ DBCleanup
SVar:RPreventNextFromSource:Event$ DamageDone | ValidSource$ Card.IsRemembered | ValidTarget$ You | ReplaceWith$ ExileEffect | PreventionEffect$ True | Description$ The next time the chosen source deals damage to you, prevent that damage.
SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Exile
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Considerations and Questions: Ability Factories
by Agetian » 08 Nov 2012, 16:47
Thanks, Sol, that works perfectly fine! Ok, now on to writing the support code for choosing sources...
- Agetian
- Agetian
- Agetian
- Programmer
- Posts: 3490
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Considerations and Questions: Ability Factories
by friarsol » 08 Nov 2012, 17:06
There may be a few more cards out there where you have to worry about an SA reference being able to deal damage. But here's a basic list (obviously not all of these deal damage, but it's a start) for your testing.
I think generally, you'll want to grab the source of an object that's targeted, defined, or a triggerObject as your potential wildcard sources.
http://magiccards.info/query?q=%28%28o% ... rd&s=cname
I think generally, you'll want to grab the source of an object that's targeted, defined, or a triggerObject as your potential wildcard sources.
http://magiccards.info/query?q=%28%28o% ... rd&s=cname
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Considerations and Questions: Ability Factories
by Agetian » 08 Nov 2012, 19:15
Nice, thanks for the tip, I'll use that checklist for testing!
- Agetian
- Agetian
- Agetian
- Programmer
- Posts: 3490
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Considerations and Questions: Ability Factories
by Agetian » 09 Nov 2012, 08:34
Ok I'm well on my way towards implementing a good enough source chooser, the current test version indicates the possibility of choosing e.g. effects on the stack coming from cards of the given color, with the CoP card implemented with the above-mentioned script successfully preventing the damage from a source on the stack, and I'm currently working on implementing the possibility to choose a referenced object as well, so eventually I'll have a working implementation ready, hopefully within a few days.
However, that raises another important point: how do I teach the AI to properly use this source-choosing AF? I looked at the card-choosing AF canPlayAI and I believe it can be adapted to choosing sources, but somehow the AI needs to be aware of the initial check which asks the player where he wants to choose the source from (which can be either a permanent, or the stack, or an indirectly referenced object). I haven't found a way to implement this choice as a part of TargetSelection, no one has clarified how that works and even when it is triggered (and via what means) or how that is related to e.g. the ChooseCard AF, so instead I implemented a custom choice box for the origin of the source as a part of the ChooseSource AF. Since no choice boxes should ever appear when AI is deciding, and it may be tricky for the AI to distinguish between different origins, should I maybe "flatten" that list for the AI then, allowing it to pick a source from a list of all possibilities without necessarily subdividing it to stack/permanent/referenced?..
And another related question, what needs to be done to teach the AI to use CoPs in a logical fashion? Is there already a foundation which can be used to implement that via scripting (so, the AI can be made aware of the fact that CoPs are damage prevention cards and that it should activate their abilities on targets of specific color/type (e.g. CoP Red vs. CoP Artifacts) that deal damage to it), or should it be scripted completely from scratch, and if so, how would one go about it? (I've never touched the AI code of Forge, so I have a very vague idea about how it works and what needs to be done with it).
P.S. If it's too much of a difficulty to code on my own (which it might be, given the complexity of the AI code), would anyone be willing to volunteer to provide the AI backing for either the AF ChooseSource I'm writing or the CoP AI logic? (I think the latter may be an even bigger problem for me than the former).
Thanks in advance for help.
- Agetian
However, that raises another important point: how do I teach the AI to properly use this source-choosing AF? I looked at the card-choosing AF canPlayAI and I believe it can be adapted to choosing sources, but somehow the AI needs to be aware of the initial check which asks the player where he wants to choose the source from (which can be either a permanent, or the stack, or an indirectly referenced object). I haven't found a way to implement this choice as a part of TargetSelection, no one has clarified how that works and even when it is triggered (and via what means) or how that is related to e.g. the ChooseCard AF, so instead I implemented a custom choice box for the origin of the source as a part of the ChooseSource AF. Since no choice boxes should ever appear when AI is deciding, and it may be tricky for the AI to distinguish between different origins, should I maybe "flatten" that list for the AI then, allowing it to pick a source from a list of all possibilities without necessarily subdividing it to stack/permanent/referenced?..
And another related question, what needs to be done to teach the AI to use CoPs in a logical fashion? Is there already a foundation which can be used to implement that via scripting (so, the AI can be made aware of the fact that CoPs are damage prevention cards and that it should activate their abilities on targets of specific color/type (e.g. CoP Red vs. CoP Artifacts) that deal damage to it), or should it be scripted completely from scratch, and if so, how would one go about it? (I've never touched the AI code of Forge, so I have a very vague idea about how it works and what needs to be done with it).
P.S. If it's too much of a difficulty to code on my own (which it might be, given the complexity of the AI code), would anyone be willing to volunteer to provide the AI backing for either the AF ChooseSource I'm writing or the CoP AI logic? (I think the latter may be an even bigger problem for me than the former).
Thanks in advance for help.
- Agetian
- Agetian
- Programmer
- Posts: 3490
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Who is online
Users browsing this forum: No registered users and 9 guests