Adds the nation of The Huns (#4311)

* Added the nation of The Huns

* Added unique units of The Huns

* Removed MountedRanged unitType

* Implemented requested changes

* Fixed some typo's, split up a very long function for redability

Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
This commit is contained in:
Xander Lenstra
2021-07-01 21:53:00 +02:00
committed by GitHub
parent c6fac03067
commit afdc2ffbd5
14 changed files with 845 additions and 718 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -53,667 +53,681 @@ Ballista
orig: 100, 100
offset: 0, 0
index: -1
Battleship
Battering Ram
rotate: false
xy: 112, 652
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Berserker
Battleship
rotate: false
xy: 220, 760
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Bomber
Berserker
rotate: false
xy: 328, 868
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Bowman
Bomber
rotate: false
xy: 4, 436
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Brute
Bowman
rotate: false
xy: 112, 544
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Camel Archer
Brute
rotate: false
xy: 220, 652
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Cannon
Camel Archer
rotate: false
xy: 328, 760
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Caravel
Cannon
rotate: false
xy: 436, 868
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Carrier
Caravel
rotate: false
xy: 4, 328
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Catapult
Carrier
rotate: false
xy: 112, 436
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Cavalry
Catapult
rotate: false
xy: 220, 544
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Chariot Archer
Cavalry
rotate: false
xy: 328, 652
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Chu-Ko-Nu
Chariot Archer
rotate: false
xy: 436, 760
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Companion Cavalry
Chu-Ko-Nu
rotate: false
xy: 544, 868
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Composite Bowman
Companion Cavalry
rotate: false
xy: 4, 220
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Conquistador
Composite Bowman
rotate: false
xy: 112, 328
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Cossack
Conquistador
rotate: false
xy: 220, 436
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Crossbowman
Cossack
rotate: false
xy: 328, 544
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Destroyer
Crossbowman
rotate: false
xy: 436, 652
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Fighter
Destroyer
rotate: false
xy: 544, 760
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Foreign Legion
Fighter
rotate: false
xy: 652, 868
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Frigate
Foreign Legion
rotate: false
xy: 4, 112
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Galleass
Frigate
rotate: false
xy: 112, 220
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Gatling Gun
Galleass
rotate: false
xy: 220, 328
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Giant Death Robot
Gatling Gun
rotate: false
xy: 328, 436
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Great Artist
Giant Death Robot
rotate: false
xy: 436, 544
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Great Engineer
Great Artist
rotate: false
xy: 544, 652
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Great Engineer
rotate: false
xy: 652, 760
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Great General
rotate: false
xy: 652, 766
xy: 760, 874
size: 100, 94
orig: 100, 94
offset: 0, 0
index: -1
Great Merchant
rotate: false
xy: 760, 868
xy: 4, 4
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Great Scientist
rotate: false
xy: 4, 4
xy: 112, 112
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Great War Bomber
rotate: false
xy: 112, 112
xy: 220, 220
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Great War Infantry
rotate: false
xy: 220, 220
xy: 328, 328
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Guided Missile
rotate: false
xy: 328, 328
xy: 436, 436
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Helicopter Gunship
rotate: false
xy: 436, 436
xy: 544, 544
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Hoplite
rotate: false
xy: 544, 544
xy: 652, 652
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Horse Archer
rotate: false
xy: 760, 766
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Horseman
rotate: false
xy: 652, 658
xy: 868, 868
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Hwach'a
rotate: false
xy: 760, 760
xy: 112, 4
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Infantry
rotate: false
xy: 868, 868
xy: 220, 112
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Ironclad
rotate: false
xy: 112, 4
xy: 328, 220
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Jaguar
rotate: false
xy: 220, 112
xy: 436, 328
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Janissary
rotate: false
xy: 328, 220
xy: 544, 436
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Jet Fighter
rotate: false
xy: 436, 328
xy: 652, 544
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Keshik
rotate: false
xy: 544, 436
xy: 760, 658
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Khan
rotate: false
xy: 652, 550
xy: 868, 760
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Knight
rotate: false
xy: 760, 652
xy: 976, 868
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Lancer
rotate: false
xy: 868, 760
xy: 220, 4
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Landship
rotate: false
xy: 976, 868
xy: 328, 112
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Landsknecht
rotate: false
xy: 220, 4
xy: 436, 220
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Legion
rotate: false
xy: 328, 112
xy: 544, 328
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Longbowman
rotate: false
xy: 436, 220
xy: 652, 436
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Longswordsman
rotate: false
xy: 544, 328
xy: 760, 550
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Machine Gun
rotate: false
xy: 652, 442
xy: 868, 652
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Mandekalu Cavalry
rotate: false
xy: 760, 544
xy: 976, 760
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Maori Warrior
rotate: false
xy: 868, 652
xy: 1084, 868
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Marine
rotate: false
xy: 976, 760
xy: 328, 4
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Mechanized Infantry
rotate: false
xy: 1084, 868
xy: 436, 112
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Minuteman
rotate: false
xy: 328, 4
xy: 544, 220
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Missile Cruiser
rotate: false
xy: 436, 112
xy: 652, 328
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Mobile SAM
rotate: false
xy: 544, 220
xy: 760, 442
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Modern Armor
rotate: false
xy: 652, 334
xy: 868, 544
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Mohawk Warrior
rotate: false
xy: 760, 436
xy: 976, 652
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Musketeer
rotate: false
xy: 868, 544
xy: 1084, 760
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Musketman
rotate: false
xy: 976, 653
xy: 1192, 869
size: 100, 99
orig: 100, 99
offset: 0, 0
index: -1
Naresuan's Elephant
rotate: false
xy: 1084, 760
xy: 436, 4
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Norwegian Ski Infantry
rotate: false
xy: 1192, 868
xy: 544, 112
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Nuclear Missile
rotate: false
xy: 436, 4
xy: 652, 220
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Nuclear Submarine
rotate: false
xy: 544, 112
xy: 760, 334
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Panzer
rotate: false
xy: 652, 226
xy: 868, 436
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Paratrooper
rotate: false
xy: 760, 328
xy: 976, 544
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Persian Immortal
rotate: false
xy: 868, 436
xy: 1084, 652
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Pikeman
rotate: false
xy: 976, 545
xy: 1192, 761
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Rifleman
rotate: false
xy: 1084, 652
xy: 1300, 868
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Rocket Artillery
rotate: false
xy: 1192, 760
xy: 544, 4
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Samurai
rotate: false
xy: 1300, 868
xy: 652, 112
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Scout
rotate: false
xy: 544, 4
xy: 760, 226
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Settler
rotate: false
xy: 652, 118
xy: 868, 328
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Ship of the Line
rotate: false
xy: 760, 220
xy: 976, 436
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Sipahi
rotate: false
xy: 868, 328
xy: 1084, 544
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Slinger
rotate: false
xy: 976, 437
xy: 1192, 653
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Spearman
rotate: false
xy: 1084, 544
xy: 1300, 760
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Stealth Bomber
rotate: false
xy: 1192, 652
xy: 1408, 868
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Submarine
rotate: false
xy: 1300, 760
xy: 652, 4
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Swordsman
rotate: false
xy: 1408, 868
xy: 760, 118
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Tank
rotate: false
xy: 652, 10
xy: 868, 220
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Tercio
rotate: false
xy: 760, 112
xy: 976, 328
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Trebuchet
rotate: false
xy: 868, 220
xy: 1084, 436
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Triplane
rotate: false
xy: 976, 329
xy: 1192, 545
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Trireme
rotate: false
xy: 1084, 435
xy: 1300, 651
size: 100, 101
orig: 100, 101
offset: 0, 0
index: -1
Turtle Ship
rotate: false
xy: 1192, 544
xy: 1408, 760
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
War Chariot
rotate: false
xy: 1300, 652
xy: 1516, 868
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
War Elephant
rotate: false
xy: 1408, 760
xy: 760, 10
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Warrior
rotate: false
xy: 1516, 868
xy: 868, 112
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Work Boats
rotate: false
xy: 868, 112
xy: 976, 220
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Worker
rotate: false
xy: 976, 221
xy: 1084, 328
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
Zero
rotate: false
xy: 1084, 327
xy: 1192, 437
size: 100, 100
orig: 100, 100
offset: 0, 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

After

Width:  |  Height:  |  Size: 325 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1017 KiB

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@ -670,6 +670,27 @@
"Fredrikstad","Kolding","Horsens","Tromsoe","Vejle","Koge","Sandnes","Holstebro","Slagelse","Drammen",
"Hillerod","Sonderborg","Skien","Svendborg","Holbaek","Hjorring","Fladstrand","Haderslev","Ringsted","Skrive"]
},
{
"name": "The Huns",
"leaderName": "Attila the Hun",
"adjective": ["Hunnic"],
"startBias": ["Avoid [Jungle]", "Avoid [Forest]"],
"preferredVictorType": "Domination",
"startIntroPart1": "Your men stand proudly to greet you, Great Attila, grand warrior and ruler of the Hunnic empire. Together with your brother Bleda you expanded the boundaries of your empire, becoming the most powerful and frightening force of the 5th century. You bowed the Eastern Roman Emperors to your will and took kingdom after kingdom along the Danube and Nisava Rivers. As the sovereign ruler of the Huns, you marched your army across Europe into Gaul, planning to extend your already impressive lands all the way to the Atlantic Ocean. Your untimely death led to the quick disintegration and downfall of your empire, but your name and deeds have created an everlasting legacy for your people. ",
"startIntroPart2": "Fearsome General, your people call for the recreation of a new Hunnic Empire, one which will make the exploits and histories of the former seem like the faded dreaming of a dying sun. Will you answer their call to regain your rightful prominence and glory? Will you mount your steadfast steed and lead your armies to victory? Will you build a civilization that stands the test of time? ",
"declaringWar": "I grow tired of this throne. I think I should like to have yours instead.",
"attacked": "Now what is this?! You ask me to add your riches to my great avails. The invitation is accepted.",
"introduction": "You are in the presence of Attila, scourge of Rome. Do not let hubris be your downfall as well.",
"neutralHello": "Good day to you.",
"hateHello": "What do you want?",
"tradeRequest": "This is better than you deserve, but let it not be said that I am an unfair man.",
"outerColor": [180, 178, 164],
"innerColor": [70, 0, 4],
"uniqueName": "Scourge of God",
"uniques": ["[+1 Production] from every [Pasture]", "Cities are razed [2] times as fast", "Starts with [Animal Husbandry]", "\"Borrows\" city names from other civilizations in the game"],
"cities": ["Atilla's Court"]
},
/*
{
"name": "Sweden",

View File

@ -199,6 +199,22 @@
"uniques": ["No defensive terrain bonus", "Rough terrain penalty"],
"attackSound": "arrow"
},
{
"name": "Horse Archer",
"unitType": "Ranged",
"uniqueTo": "The Huns",
"replaces": "Chariot Archer",
"movement": 4,
"strength": 7,
"rangedStrength": 10,
"cost": 56,
"requiredTech": "The Wheel",
"upgradesTo": "Knight",
"obsoleteTech": "Chivalry",
"uniques": ["No defensive terrain bonus"],
"promotions": ["Accuracy I"],
"attackSound": "arrow"
},
{
"name": "War Elephant",
"unitType": "Ranged",
@ -254,6 +270,22 @@
"uniques": ["+[50]% Strength vs [Mounted]","+[10] HP when healing"],
"attackSound": "metalhit"
},
{
"name": "Battering Ram",
"replaces": "Spearman",
"uniqueTo": "Huns",
"unitType": "Melee",
"movement": 2,
"strength": 10,
"cost": 75,
"requiredTech": "Bronze Working",
"obsoleteTech": "Physics",
"upgradesTo": "Trebuchet",
"uniques": ["+[300]% Strength vs [City]", "No defensive terrain bonus", "+[-33]% Strength when defending",
"-[1] Visibility Range", "Can only attack [City] units"],
"promotions": ["Cover I"],
"attackSound": "throw"
}
/*
{
"name": "Spearman",
@ -937,7 +969,7 @@
"cost": 325,
"requiredTech": "Refrigeration",
"upgradesTo": "Nuclear Submarine",
"uniques": ["+[75]% Strength when attacking", "Invisible to others", "Can only attack water", "Can attack submarines", "Can enter ice tiles"]
"uniques": ["+[75]% Strength when attacking", "Invisible to others", "Can only attack [Water] units", "Can attack submarines", "Can enter ice tiles"]
},
{
"name": "Great War Infantry",
@ -1288,7 +1320,7 @@
"rangedStrength": 85,
"cost": 425,
"requiredTech": "Telecommunications",
"uniques": ["+[75]% Strength when attacking", "Invisible to others", "Can only attack water",
"uniques": ["+[75]% Strength when attacking", "Invisible to others", "Can only attack [Water] units",
"Can attack submarines", "Can enter ice tiles", "[+1] Visibility Range", "Can carry [2] [Missile] units"]
},
{

View File

@ -80,8 +80,11 @@ object BattleHelper {
if (tile.isWater) return false // can't attack water units while embarked, only land
if (combatant.isRanged()) return false
}
if (combatant.unit.hasUnique("Can only attack water")) {
if (tile.isLand) return false
// "Can only attack water" unique deprecated since 3.15.7
if (combatant.unit.hasUnique("Can only attack water")) {
if (tile.isLand) return false
//
// trying to attack lake-to-coast or vice versa
if ((tile.baseTerrain == Constants.lakes) != (combatant.getTile().baseTerrain == Constants.lakes))
@ -93,6 +96,11 @@ object BattleHelper {
if (tileCombatant.getCivInfo() == combatant.getCivInfo()) return false
if (!combatant.getCivInfo().isAtWarWith(tileCombatant.getCivInfo())) return false
if (combatant is MapUnitCombatant &&
combatant.unit.hasUnique("Can only attack [] units") &&
combatant.unit.getMatchingUniques("Can only attack [] units").none { tileCombatant.matchesCategory(it.params[0]) })
return false
//only submarine and destroyer can attack submarine
//garrisoned submarine can be attacked by anyone, or the city will be in invincible
if (tileCombatant.isInvisible() && !tile.isCityCenter()) {

View File

@ -122,6 +122,9 @@ class CityInfo {
val cityName = nationCities[cityNameIndex]
val cityNameRounds = civInfo.citiesCreated / nationCities.size
if (cityNameRounds > 0 && civInfo.hasUnique("\"Borrows\" city names from other civilizations in the game")) {
name = borrowCityName()
}
val cityNamePrefix = when (cityNameRounds) {
0 -> ""
1 -> "New "
@ -130,6 +133,39 @@ class CityInfo {
name = cityNamePrefix + cityName
}
private fun borrowCityName(): String {
val usedCityNames =
civInfo.gameInfo.civilizations.flatMap { it.cities.map { city -> city.name } }
// We take the last unused city name for each other civ in this game, skipping civs whose
// names are exhausted, and choose a random one from that pool if it's not empty.
var newNames = civInfo.gameInfo.civilizations
.filter { it.isMajorCiv() && it != civInfo }
.mapNotNull { it.nation.cities
.lastOrNull { city -> city !in usedCityNames }
}
if (newNames.isNotEmpty()) {
return newNames.random()
}
// As per fandom wiki, once the names from the other nations in the game are exhausted,
// names are taken from the rest of the nations in the ruleset
newNames = getRuleset()
.nations
.filter { it.key !in civInfo.gameInfo.civilizations.map { civ -> civ.nation.name } }
.values
.map {
it.cities
.filter { city -> city !in usedCityNames }
}.flatten()
if (newNames.isNotEmpty()) {
return newNames.random()
}
// If for some reason we have used every single city name in the game,
// (are we using some sort of baserule mod without city names?)
// just return something so we at least have a name
return "The City without a Name"
}
//region pure functions
@ -360,8 +396,9 @@ class CityInfo {
cityConstructions.endTurn(stats)
expansion.nextTurn(stats.culture)
if (isBeingRazed) {
population.addPopulation(-1)
if (population.population <= 0) { // there are strange cases where we get to -1
val removedPopulation = 1 + civInfo.getMatchingUniques("Cities are razed [] times as fast").sumBy { it.params[0].toInt() }
population.addPopulation(-1 * removedPopulation)
if (population.population <= 0) {
civInfo.addNotification("[$name] has been razed to the ground!", location, "OtherIcons/Fire")
destroyCity()
} else { //if not razed yet:

View File

@ -243,13 +243,18 @@ class BaseUnit : INamed, IConstruction {
unitType.name -> true
name -> true
"All" -> true
"Melee" -> unitType.isMelee()
"Ranged" -> unitType.isRanged()
"Land", "land units" -> unitType.isLandUnit()
"Civilian" -> unitType.isCivilian()
"Military", "military units" -> unitType.isMilitary()
"Water", "water units", "Water units" -> unitType.isWaterUnit()
"Air", "air units" -> unitType.isAirUnit()
"Missile" -> unitType.isMissile()
"Submarine", "submarine units" -> unitType == UnitType.WaterSubmarine
"non-air" -> !unitType.isAirUnit() && !unitType.isMissile()
"Military", "military units" -> unitType.isMilitary()
"Missile" -> unitType.isMissile()
"Submarine", "submarine units" -> unitType == UnitType.WaterSubmarine
"Nuclear Weapon" -> isNuclearWeapon()
// Deprecated as of 3.15.2
"military water" -> unitType.isMilitary() && unitType.isWaterUnit()

View File

@ -27,7 +27,7 @@ enum class UnitType{
|| this == Armor
|| this == Scout
|| this == WaterMelee
fun isRanged() =
this == Ranged
|| this == Siege

View File

@ -32,8 +32,10 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
* [Greek Trireme](https://thenounproject.com/search/?q=ancient%20boat&i=1626303) By Zachary McCune for Trireme
* [Chariot](https://thenounproject.com/search/?q=Chariot&i=1189930) By Andrew Doane for Chariot Archer
* [Elephant](https://thenounproject.com/Luis/uploads/?i=14048) By Luis Prado for War Elephant
* [Centaur](https://thenounproject.com/search/?q=horse+archer&i=1791296) by Michael Wohlwend for Horse Archer
* [Spear](https://thenounproject.com/search/?q=Spear&i=11432) By Stephen Copinger for Spearman
* [Greek shield](https://thenounproject.com/search/?q=hoplite&i=440135) for Hoplite
* [Transparent Medieval Battering Ram Png Logo](https://www.pngimages.pics/275495/transparent-medieval-battering-ram-png.php) for Battering Ram
* [Spiked club](https://thenounproject.com/search/?q=club%20weapon&creator=1933477&i=831794) for Brute
* [Hoplite](https://www.flaticon.com/free-icon/hoplite_659126#term=hoplite&page=1&position=20) by Eucalyp for Immortal
* [Slingshot](https://thenounproject.com/term/slingshot/9106/) by James Keuning for Slinger
@ -509,6 +511,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
* [Spiral](https://www.shutterstock.com/image-vector/maori-symbol-spiral-shape-based-on-1145645057?id=1145645057) by bc21 for Polynesia
* [Dharmachakra](https://thenounproject.com/search/?q=dharmachakra&i=740796) by Parkjisun for Siam
* [Sun](https://thenounproject.com/search/?q=inca&i=910770) by Made x Made for Inca
* [Sun symbol black](https://en.wikiquote.org/wiki/File:Sun_symbol_black.svg) by Eddo for the Huns
## Promotions