mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
checking in infrastructure changes to support a refactor of the code dealing with card colors
Nothing is hooked up, so there should be no functional change in Forge at all. basics: 1) support to make Color an Enum (Colorless is not included, use card.isColorless() instead 2) make color checking a part of Card.java instead of using CardUtil.getColors(card) 3) add getConvertedManaCost functions directly in Card.java (Note: CardUtil will likely still need a copy of some of this code to get the converted mana cost of spell abilities
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -240,6 +240,7 @@ src/forge/CardListFilter.java svneol=native#text/plain
|
|||||||
src/forge/CardListUtil.java svneol=native#text/plain
|
src/forge/CardListUtil.java svneol=native#text/plain
|
||||||
src/forge/CardShopTableModel.java -text svneol=native#text/plain
|
src/forge/CardShopTableModel.java -text svneol=native#text/plain
|
||||||
src/forge/CardUtil.java svneol=native#text/plain
|
src/forge/CardUtil.java svneol=native#text/plain
|
||||||
|
src/forge/Color.java -text svneol=native#text/plain
|
||||||
src/forge/Combat.java svneol=native#text/plain
|
src/forge/Combat.java svneol=native#text/plain
|
||||||
src/forge/CombatPlaneswalker.java svneol=native#text/plain
|
src/forge/CombatPlaneswalker.java svneol=native#text/plain
|
||||||
src/forge/CombatUtil.java svneol=native#text/plain
|
src/forge/CombatUtil.java svneol=native#text/plain
|
||||||
|
|||||||
@@ -5,10 +5,15 @@ package forge;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import forge.error.ErrorViewer;
|
||||||
|
|
||||||
|
|
||||||
public class Card extends MyObservable {
|
public class Card extends MyObservable {
|
||||||
private static int nextUniqueNumber;
|
private static int nextUniqueNumber;
|
||||||
@@ -80,6 +85,10 @@ public class Card extends MyObservable {
|
|||||||
private int otherAttackBoost = 0;
|
private int otherAttackBoost = 0;
|
||||||
private int otherDefenseBoost = 0;
|
private int otherDefenseBoost = 0;
|
||||||
|
|
||||||
|
//updates for Colorness refactor
|
||||||
|
private ArrayList<Color> baseColors = new ArrayList<Color>();
|
||||||
|
private ArrayList<Color> currentColors = new ArrayList<Color>();
|
||||||
|
|
||||||
private int randomPicture = 0;
|
private int randomPicture = 0;
|
||||||
|
|
||||||
private int upkeepDamage = 0;
|
private int upkeepDamage = 0;
|
||||||
@@ -969,6 +978,261 @@ public class Card extends MyObservable {
|
|||||||
this.updateObservers();
|
this.updateObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//Color refactor begin
|
||||||
|
|
||||||
|
public ArrayList<Color> setBaseColors(ArrayList<Color> colors) {
|
||||||
|
baseColors.clear();
|
||||||
|
for(Color color:colors) {
|
||||||
|
baseColors.add(color);
|
||||||
|
}
|
||||||
|
return baseColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Color> getBaseColors() {
|
||||||
|
return baseColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Color> addColor(Color color) {
|
||||||
|
if(!currentColors.contains(color)) {
|
||||||
|
currentColors.add(color);
|
||||||
|
}
|
||||||
|
return currentColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
//maybe this should return the new currentColor list?
|
||||||
|
public boolean removeColor(Color color) {
|
||||||
|
if(currentColors.contains(color)) {
|
||||||
|
currentColors.remove(color);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Color> setColors(Color... colors) {
|
||||||
|
for(Color color:colors) {
|
||||||
|
addColor(color);
|
||||||
|
}
|
||||||
|
return currentColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Color> setColors(ArrayList<Color> colors) {
|
||||||
|
Color[] colorArray = new Color[colors.size()];
|
||||||
|
return setColors(colors.toArray(colorArray));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Color> getColorsNew() {
|
||||||
|
return currentColors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBlack() {
|
||||||
|
return currentColors.contains(Color.BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBlue() {
|
||||||
|
return currentColors.contains(Color.BLUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGreen() {
|
||||||
|
return currentColors.contains(Color.GREEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRed() {
|
||||||
|
return currentColors.contains(Color.RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWhite() {
|
||||||
|
return currentColors.contains(Color.WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isColorless() {
|
||||||
|
return currentColors.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////from CardUtil.java
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java (from CardUtil.java
|
||||||
|
*/
|
||||||
|
//returns something like Constant.Color.Green or something
|
||||||
|
/* public static String getColor(Card c) {
|
||||||
|
|
||||||
|
String manaCost = c.getManaCost();
|
||||||
|
|
||||||
|
if(-1 != manaCost.indexOf("G")) return Constant.Color.Green;
|
||||||
|
else if(-1 != manaCost.indexOf("W")) return Constant.Color.White;
|
||||||
|
else if(-1 != manaCost.indexOf("B")) return Constant.Color.Black;
|
||||||
|
else if(-1 != manaCost.indexOf("U")) return Constant.Color.Blue;
|
||||||
|
else if(-1 != manaCost.indexOf("R")) return Constant.Color.Red;
|
||||||
|
else return Constant.Color.Colorless;
|
||||||
|
return null;
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java (from CardUtil.java
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* gets a list of all of the colors that this card is based on the mana cost in cards.txt
|
||||||
|
*
|
||||||
|
* @return an ArrayList with the enumerated colors
|
||||||
|
*/
|
||||||
|
public ArrayList<Color> getColorsBasedOnManaCost() {
|
||||||
|
String m = this.getManaCost();
|
||||||
|
Set<Color> colors = new HashSet<Color>();
|
||||||
|
|
||||||
|
for(int i = 0; i < m.length(); i++) {
|
||||||
|
switch(m.charAt(i)) {
|
||||||
|
case ' ':
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
colors.add(Color.GREEN);
|
||||||
|
break;
|
||||||
|
case 'W':
|
||||||
|
colors.add(Color.WHITE);
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
colors.add(Color.BLACK);
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
colors.add(Color.BLUE);
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
colors.add(Color.RED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ArrayList<Color>(colors);
|
||||||
|
/*
|
||||||
|
for(String kw : this.getKeyword())
|
||||||
|
if(kw.startsWith(this.getName()+" is ")) {
|
||||||
|
for(Color color : Color.values())
|
||||||
|
if(kw.endsWith(color.getName()+"."))
|
||||||
|
colors.add(color);
|
||||||
|
if(kw.endsWith("is Colorless.")) {
|
||||||
|
colors.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if(colors.isEmpty()) colors.add(Constant.Color.Colorless);
|
||||||
|
*/
|
||||||
|
}//getColorsBasedOnManaCost
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java (from CardUtil.java
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* public static ArrayList<String> getOnlyColors(Card c) {
|
||||||
|
|
||||||
|
String m = c.getManaCost();
|
||||||
|
Set<String> colors = new HashSet<String>();
|
||||||
|
|
||||||
|
for(int i = 0; i < m.length(); i++) {
|
||||||
|
switch(m.charAt(i)) {
|
||||||
|
case ' ':
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
colors.add(Constant.Color.Green);
|
||||||
|
break;
|
||||||
|
case 'W':
|
||||||
|
colors.add(Constant.Color.White);
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
colors.add(Constant.Color.Black);
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
colors.add(Constant.Color.Blue);
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
colors.add(Constant.Color.Red);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(String kw : c.getKeyword())
|
||||||
|
if(kw.startsWith(c.getName()+" is "))
|
||||||
|
for(String color : Constant.Color.Colors)
|
||||||
|
if(kw.endsWith(color+"."))
|
||||||
|
colors.add(color);
|
||||||
|
return new ArrayList<String>(colors);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/////////////end from CardUtil.java
|
||||||
|
|
||||||
|
//Color refactor End
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//mana cost refactor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java (from CardUtil.java
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
//probably should put this somewhere else, but not sure where
|
||||||
|
static public int getConvertedManaCost(SpellAbility sa) {
|
||||||
|
return getConvertedManaCost(sa.getManaCost());
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java (from CardUtil.java
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
public int getConvertedManaCost() {
|
||||||
|
if (this.isToken() && !this.isCopiedToken())
|
||||||
|
return 0;
|
||||||
|
return getConvertedManaCost(this.getManaCost());
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java (from CardUtil.java
|
||||||
|
*/
|
||||||
|
public int getConvertedManaCost() {
|
||||||
|
//see if the mana cost is all colorless, like "2", "0", or "12"
|
||||||
|
|
||||||
|
if(manaCost.equals("")) return 0;
|
||||||
|
|
||||||
|
while (manaCost.startsWith("X"))
|
||||||
|
manaCost = manaCost.substring(2);
|
||||||
|
|
||||||
|
if(!manaCost.matches(".*[A-Z]+.*")) {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(manaCost);
|
||||||
|
} catch(NumberFormatException ex) {
|
||||||
|
ErrorViewer.showError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//see if mana cost is colored and colorless like "2 B" or "1 U U"
|
||||||
|
StringTokenizer tok = new StringTokenizer(manaCost);
|
||||||
|
int cost = 0;
|
||||||
|
try {
|
||||||
|
//get the int from the mana cost like "1 U", get the 1
|
||||||
|
cost = Integer.parseInt(tok.nextToken());
|
||||||
|
//count colored mana cost
|
||||||
|
cost += tok.countTokens();
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
//catches in case the cost has no colorless mana requirements like "U U"
|
||||||
|
catch(NumberFormatException ex) {}
|
||||||
|
|
||||||
|
//the mana cost is all colored mana like "U" or "B B B"
|
||||||
|
tok = new StringTokenizer(manaCost);
|
||||||
|
return tok.countTokens();
|
||||||
|
}
|
||||||
|
|
||||||
|
//end warning for moving to Card.java
|
||||||
|
|
||||||
|
//end mana cost refactor
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
public ArrayList<Card> getEquippedBy() {
|
public ArrayList<Card> getEquippedBy() {
|
||||||
return equippedBy;
|
return equippedBy;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19838,6 +19838,8 @@ public class CardFactory implements NewConstants {
|
|||||||
c.setType(sim.getType());
|
c.setType(sim.getType());
|
||||||
c.setText(sim.getSpellText());
|
c.setText(sim.getSpellText());
|
||||||
c.setManaCost(sim.getManaCost());
|
c.setManaCost(sim.getManaCost());
|
||||||
|
//for Color refactor
|
||||||
|
//c.setBaseColors(sim.getBaseColors());
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}// copyStats()
|
}// copyStats()
|
||||||
|
|||||||
@@ -3527,6 +3527,8 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
//do card1 and card2 share any colors?
|
//do card1 and card2 share any colors?
|
||||||
public static boolean sharesColorWith(Card card1, Card card2) {
|
public static boolean sharesColorWith(Card card1, Card card2) {
|
||||||
|
//slapshot5 - not sure why this needs getOnlyColors vs. getColors()
|
||||||
|
//Color refactor
|
||||||
ArrayList<String> card1Colors = CardUtil.getOnlyColors(card1);
|
ArrayList<String> card1Colors = CardUtil.getOnlyColors(card1);
|
||||||
ArrayList<String> card2Colors = CardUtil.getOnlyColors(card2);
|
ArrayList<String> card2Colors = CardUtil.getOnlyColors(card2);
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class CardUtil {
|
|||||||
a.add(c[i]);
|
a.add(c[i]);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns "G", longColor is Constant.Color.Green and the like
|
//returns "G", longColor is Constant.Color.Green and the like
|
||||||
public static String getShortColor(String longColor) {
|
public static String getShortColor(String longColor) {
|
||||||
Map<String, String> map = new HashMap<String, String>();
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
@@ -85,7 +85,10 @@ public class CardUtil {
|
|||||||
return (String) o;
|
return (String) o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java
|
||||||
|
*/
|
||||||
//returns something like Constant.Color.Green or something
|
//returns something like Constant.Color.Green or something
|
||||||
public static String getColor(Card c) {
|
public static String getColor(Card c) {
|
||||||
String manaCost = c.getManaCost();
|
String manaCost = c.getManaCost();
|
||||||
@@ -98,6 +101,10 @@ public class CardUtil {
|
|||||||
else return Constant.Color.Colorless;
|
else return Constant.Color.Colorless;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java
|
||||||
|
*/
|
||||||
public static ArrayList<String> getColors(Card c) {
|
public static ArrayList<String> getColors(Card c) {
|
||||||
String m = c.getManaCost();
|
String m = c.getManaCost();
|
||||||
Set<String> colors = new HashSet<String>();
|
Set<String> colors = new HashSet<String>();
|
||||||
@@ -135,6 +142,10 @@ public class CardUtil {
|
|||||||
return new ArrayList<String>(colors);
|
return new ArrayList<String>(colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java
|
||||||
|
*/
|
||||||
public static ArrayList<String> getOnlyColors(Card c) {
|
public static ArrayList<String> getOnlyColors(Card c) {
|
||||||
String m = c.getManaCost();
|
String m = c.getManaCost();
|
||||||
Set<String> colors = new HashSet<String>();
|
Set<String> colors = new HashSet<String>();
|
||||||
@@ -168,26 +179,19 @@ public class CardUtil {
|
|||||||
return new ArrayList<String>(colors);
|
return new ArrayList<String>(colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
public static boolean hasCardName(String cardName, ArrayList<Card> list) {
|
* properties of the card. If you make changes here, please add them to
|
||||||
Card c;
|
* the corresponding function in Card.java
|
||||||
boolean b = false;
|
*/
|
||||||
|
|
||||||
for(int i = 0; i < list.size(); i++) {
|
|
||||||
c = list.get(i);
|
|
||||||
if(c.getName().equals(cardName)) {
|
|
||||||
b = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}//hasCardName()
|
|
||||||
|
|
||||||
//probably should put this somewhere else, but not sure where
|
//probably should put this somewhere else, but not sure where
|
||||||
static public int getConvertedManaCost(SpellAbility sa) {
|
static public int getConvertedManaCost(SpellAbility sa) {
|
||||||
return getConvertedManaCost(sa.getManaCost());
|
return getConvertedManaCost(sa.getManaCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java
|
||||||
|
*/
|
||||||
static public int getConvertedManaCost(Card c)
|
static public int getConvertedManaCost(Card c)
|
||||||
{
|
{
|
||||||
if (c.isToken() && !c.isCopiedToken())
|
if (c.isToken() && !c.isCopiedToken())
|
||||||
@@ -195,6 +199,10 @@ public class CardUtil {
|
|||||||
return getConvertedManaCost(c.getManaCost());
|
return getConvertedManaCost(c.getManaCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ***Warning*** - the following functions are being refactored to be
|
||||||
|
* properties of the card. If you make changes here, please add them to
|
||||||
|
* the corresponding function in Card.java
|
||||||
|
*/
|
||||||
static public int getConvertedManaCost(String manaCost) {
|
static public int getConvertedManaCost(String manaCost) {
|
||||||
//see if the mana cost is all colorless, like "2", "0", or "12"
|
//see if the mana cost is all colorless, like "2", "0", or "12"
|
||||||
|
|
||||||
@@ -229,6 +237,22 @@ public class CardUtil {
|
|||||||
return tok.countTokens();
|
return tok.countTokens();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//end warning for moving to Card.java
|
||||||
|
|
||||||
|
public static boolean hasCardName(String cardName, ArrayList<Card> list) {
|
||||||
|
Card c;
|
||||||
|
boolean b = false;
|
||||||
|
|
||||||
|
for(int i = 0; i < list.size(); i++) {
|
||||||
|
c = list.get(i);
|
||||||
|
if(c.getName().equals(cardName)) {
|
||||||
|
b = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}//hasCardName()
|
||||||
|
|
||||||
static public String addManaCosts(String mc1, String mc2)
|
static public String addManaCosts(String mc1, String mc2)
|
||||||
{
|
{
|
||||||
String tMC = "";
|
String tMC = "";
|
||||||
|
|||||||
35
src/forge/Color.java
Normal file
35
src/forge/Color.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Color.java
|
||||||
|
*
|
||||||
|
* Created on 5.1.2010
|
||||||
|
*/
|
||||||
|
|
||||||
|
package forge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class Color.
|
||||||
|
*
|
||||||
|
* @author dennis.r.friedrichsen
|
||||||
|
*/
|
||||||
|
public enum Color {
|
||||||
|
BLACK("black"),
|
||||||
|
BLUE("blue"),
|
||||||
|
GREEN("green"),
|
||||||
|
RED("red"),
|
||||||
|
WHITE("white"); //,
|
||||||
|
//COLORLESS("colorless");
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Color() {
|
||||||
|
this.name = name().substring(0, 1).toUpperCase() + name().substring(1).toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -76,7 +76,14 @@ public class ReadCard implements Runnable, NewConstants {
|
|||||||
|
|
||||||
|
|
||||||
s = readLine();
|
s = readLine();
|
||||||
if(!s.equals("no cost")) c.setManaCost(s);
|
if(!s.equals("no cost")) {
|
||||||
|
c.setManaCost(s);
|
||||||
|
//c.setBaseColors(c.getColorsBasedOnManaCost());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//c.setBaseColors(new ArrayList<Color>());
|
||||||
|
}
|
||||||
|
//c.setColors(c.getBaseColors());
|
||||||
|
|
||||||
s = readLine();
|
s = readLine();
|
||||||
addTypes(c, s);
|
addTypes(c, s);
|
||||||
|
|||||||
Reference in New Issue
Block a user