You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.go 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "sort"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "util"
  10. )
  11. type Character struct {
  12. Name string
  13. Kind string
  14. Word string
  15. TotalForces int
  16. CorporealForces int
  17. EtherealForces int
  18. CelestialForces int
  19. Strength int
  20. Agility int
  21. Intellect int
  22. Precision int
  23. Will int
  24. Perception int
  25. Skills map[string]int
  26. Songs map[string]int
  27. Attunements []string
  28. Distinctions []string
  29. Artifacts []string
  30. Vessels map[string]int
  31. Roles map[string][]int
  32. }
  33. func main() {
  34. rand.Seed(time.Now().UnixNano()) // Keep this first in main()
  35. corSkills := []string{"Acrobatics", "Climbing", "Dodge", "Escape", "Fighting", "Large Weapon", "Move Silently", "Running", "Swimming", "Throwing"}
  36. ethSkills := []string{"Knowledge", "Knowledge", "Knowledge", "Area Knowledge", "Area Knowledge", "Area Knowledge", "Chemistry", "Computer Operation", "Driving", "Electronics", "Engineering", "Language", "Lockpicking", "Lying", "Medicine", "Ranged Weapon", "Savoir-Faire", "Small Weapon", "Tactics"}
  37. celSkills := []string{"Artistry", "Detect Lies", "Emote", "Fast-Talk", "Seduction", "Singing", "Survival", "Tracking"}
  38. akList := []string{"Heaven", "Hell", "Marches", "Caribbean", "New York", "New England", "Florida", "Atlanta", "Texas", "California", "American Southwest", "Pacific Northwest", "Portland", "Toronto", "Vancouver", "Mexico", "Central America", "Brazil", "Argentina", "England", "London", "France", "Paris", "Norway", "Scandinavia", "Greece", "Egypt", "North Africa", "Sub-Saharan Africa", "Saudi Arabia", "Middle East", "Russia", "Moscow", "China", "Shanghai", "Hong Kong", "Japan", "Hokkaido", "Tokyo", "Australia", "Sydney", "Melbourne", "Perth", "Fiji", "Antarctica"}
  39. knowList := []string{"Astronomy", "Biology", "Literature", "Aircraft", "American Football", "Football", "Baseball", "Sumo", "Giant Robot Anime", "German Cuisine", "Catholicism", "Islam", "Buddhism", "Shinto", "Architecture", "Eschatology", "Numinology", "Role-Playing Games", "Spelunking", "Parliamentary Procedure", "Olympic History", "18th-Century Botanical Manuals", "Photography", "Marine Biology", "Entomology", "Archaeology"}
  40. langList := []string{"Mandarin", "Spanish", "English", "Hindi", "Arabic", "Portuguese", "Bengali", "Russian", "Japanese", "Punjabi", "German", "Javanese", "Wu", "Malay", "Telugu", "Vietnamese", "Korean", "French", "Marathi", "Tamil", "Urdu", "Turkish", "Italian", "Yue (Cantonese)", "Thai", "Latin", "Greek", "Ancient Egyptian", "Apache", "Ainu", "Aleut", "Inuit", "Mayan"}
  41. songList := []string{"Attraction", "Charm", "Dreams", "Entropy", "Form", "Harmony", "Healing", "Motion", "Numinous Corpus", "Possession", "Projection", "Shields", "Thunder", "Tongues"}
  42. choirs := []string{"Seraph", "Cherub", "Ofanite", "Elohite", "Malakite", "Kyriotate", "Mercurian"}
  43. bands := []string{"Balseraph", "Djinn", "Calabite", "Habbalite", "Lilim", "Shedite", "Impudite"}
  44. aWords := []string{"Dreams", "Children", "Stone", "Judgment", "Creation", "Fire", "the Wind", "Lightning", "Animals", "Faith", "the Sword", "Revelation", "Trade", "War", "Flowers", "Destiny", "Protection"}
  45. iWords := []string{"Nightmares", "Lust", "the Game", "the War", "Fire", "Drugs", "Hardcore", "Secrets (shhh!)", "Gluttony", "Dark Humor", "Fate", "Freedom", "Factions", "the Media", "Death", "Theft", "Technology"}
  46. ply := Character{}
  47. ply.Name = util.Namegen()
  48. ply.TotalForces = 9
  49. ply.CorporealForces = 1
  50. ply.EtherealForces = 1
  51. ply.CelestialForces = 1
  52. ply.Strength = 1
  53. ply.Agility = 1
  54. ply.Intellect = 1
  55. ply.Precision = 1
  56. ply.Will = 1
  57. ply.Perception = 1
  58. ply.Skills = make(map[string]int)
  59. ply.Songs = make(map[string]int)
  60. ply.Skills["Language (Local)"] = 3
  61. if rand.Intn(2) == 0 {
  62. ply.Kind = util.ChoiceStr(choirs)
  63. ply.Word = util.ChoiceStr(aWords)
  64. } else {
  65. ply.Kind = util.ChoiceStr(bands)
  66. ply.Word = util.ChoiceStr(iWords)
  67. }
  68. ply.Attunements = append(ply.Attunements, ply.Kind+" of "+ply.Word)
  69. i := ply.TotalForces - (ply.CorporealForces + ply.EtherealForces + ply.CelestialForces)
  70. for i > 0 {
  71. r := rand.Intn(3)
  72. if r == 0 {
  73. ply.CorporealForces = ply.CorporealForces + 1
  74. } else if r == 1 {
  75. ply.EtherealForces = ply.EtherealForces + 1
  76. } else {
  77. ply.CelestialForces = ply.CelestialForces + 1
  78. }
  79. i--
  80. }
  81. cp, corBrk, ethBrk := ply.TotalForces*4, ply.CorporealForces, ply.CorporealForces+ply.EtherealForces
  82. sklBrk := 12
  83. // Corporeal
  84. coratt := (ply.CorporealForces * 4) - (ply.Strength + ply.Agility)
  85. for coratt > 0 {
  86. r := rand.Intn(2)
  87. if r == 0 {
  88. if ply.Strength == 12 || (ply.Strength >= (ply.Agility*2) && rand.Intn(3) == 0) {
  89. continue
  90. }
  91. ply.Strength = ply.Strength + 1
  92. } else {
  93. if ply.Agility == 12 || (ply.Agility >= (ply.Strength*2) && rand.Intn(3) == 0) {
  94. continue
  95. }
  96. ply.Agility = ply.Agility + 1
  97. }
  98. coratt--
  99. }
  100. // Ethereal
  101. ethatt := (ply.EtherealForces * 4) - (ply.Intellect + ply.Precision)
  102. for ethatt > 0 {
  103. r := rand.Intn(2)
  104. if r == 0 {
  105. if ply.Intellect == 12 || (ply.Intellect >= (ply.Precision*2) && rand.Intn(3) == 0) {
  106. continue
  107. }
  108. ply.Intellect = ply.Intellect + 1
  109. } else {
  110. if ply.Precision == 12 || (ply.Precision >= (ply.Intellect*2) && rand.Intn(3) == 0) {
  111. continue
  112. }
  113. ply.Precision = ply.Precision + 1
  114. }
  115. ethatt--
  116. }
  117. // Celestial
  118. celatt := (ply.CelestialForces * 4) - (ply.Will + ply.Perception)
  119. for celatt > 0 {
  120. r := rand.Intn(2)
  121. if r == 0 {
  122. if ply.Will == 12 || (ply.Will >= (ply.Perception*2) && rand.Intn(3) == 0) {
  123. continue
  124. }
  125. ply.Will = ply.Will + 1
  126. } else {
  127. if ply.Perception == 12 || (ply.Perception >= (ply.Will*2) && rand.Intn(3) == 0) {
  128. continue
  129. }
  130. ply.Perception = ply.Perception + 1
  131. }
  132. celatt--
  133. }
  134. b := 7 + rand.Intn(6)
  135. for i := cp; i > b; i-- {
  136. r := rand.Intn(15)
  137. if r < sklBrk { // it's a skill
  138. if rand.Intn(3) == 0 && len(ply.Skills) != 0 {
  139. key, val := util.ChoiceMap(ply.Skills)
  140. if ply.Skills[key] == 6 {
  141. i++
  142. } else {
  143. ply.Skills[key] = val + 1
  144. }
  145. } else {
  146. q := rand.Intn(ply.TotalForces)
  147. skl := ""
  148. if q < corBrk { // it's a corporeal skill
  149. skl = util.ChoiceStr(corSkills)
  150. // fmt.Println("Selected Corporeal skill: ", skl)
  151. } else if q < ethBrk { // it's an ethereal skill
  152. skl = util.ChoiceStr(ethSkills)
  153. if skl == "Knowledge" {
  154. subskl := util.ChoiceStr(knowList)
  155. skl = "Knowledge (" + subskl + ")"
  156. } else if skl == "Area Knowledge" {
  157. subskl := util.ChoiceStr(akList)
  158. skl = "Area Knowledge (" + subskl + ")"
  159. } else if skl == "Language" {
  160. subskl := util.ChoiceStr(langList)
  161. skl = "Language (" + subskl + ")"
  162. }
  163. // fmt.Println("Selected Ethereal skill: ", skl)
  164. } else { // it's a celestial skill
  165. skl = util.ChoiceStr(celSkills)
  166. // fmt.Println("Selected Celestial skill: ", skl)
  167. }
  168. if ply.Skills[skl] == 6 {
  169. i++
  170. } else {
  171. ply.Skills[skl] = ply.Skills[skl] + 1
  172. }
  173. }
  174. } else { // Songs
  175. if rand.Intn(3) == 0 && len(ply.Songs) != 0 {
  176. key, val := util.ChoiceMap(ply.Songs)
  177. if ply.Songs[key] == 6 {
  178. i++
  179. } else {
  180. ply.Songs[key] = val + 1
  181. }
  182. } else {
  183. skl := util.ChoiceStr(songList)
  184. // fmt.Println("Selected song: ", skl)
  185. if ply.Songs[skl] == 6 {
  186. i++
  187. } else {
  188. ply.Songs[skl] = ply.Songs[skl] + 1
  189. }
  190. }
  191. }
  192. }
  193. skills := make([]string, 0, len(ply.Skills))
  194. songs := make([]string, 0, len(ply.Songs))
  195. // fmt.Println(len(ply.Skills), len(ply.Songs), ply.Skills, ply.Songs)
  196. for k, v := range ply.Skills {
  197. skills = append(skills, k+"/"+strconv.Itoa(v))
  198. }
  199. for k, v := range ply.Songs {
  200. songs = append(songs, k+"/"+strconv.Itoa(v))
  201. }
  202. sort.Strings(skills)
  203. sort.Strings(songs)
  204. sklout := strings.Join(skills[:], ", ")
  205. sngout := strings.Join(songs[:], ", ")
  206. fmt.Println("=== Generated In Nomine character ===")
  207. fmt.Println(ply.Name)
  208. fmt.Printf("%s of %s\n", ply.Kind, ply.Word)
  209. fmt.Printf("Cor %d\tEth %d\tCel %d\n",
  210. ply.CorporealForces,
  211. ply.EtherealForces,
  212. ply.CelestialForces)
  213. fmt.Printf("Str %d\tInt %d\tCel %d\n",
  214. ply.Strength,
  215. ply.Intellect,
  216. ply.Will)
  217. fmt.Printf("Agi %d\tPre %d\tPer %d\n",
  218. ply.Agility,
  219. ply.Precision,
  220. ply.Perception)
  221. fmt.Println("Skills:", sklout)
  222. fmt.Println("Songs:", sngout)
  223. fmt.Println("Attunements:", strings.Join(ply.Attunements, ", "))
  224. fmt.Println("CP Remaining:", b)
  225. }