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.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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. if ply.CorporealForces == 6 {
  74. continue
  75. }
  76. ply.CorporealForces = ply.CorporealForces + 1
  77. } else if r == 1 {
  78. if ply.EtherealForces == 6 {
  79. continue
  80. }
  81. ply.EtherealForces = ply.EtherealForces + 1
  82. } else {
  83. if ply.CelestialForces == 6 {
  84. continue
  85. }
  86. ply.CelestialForces = ply.CelestialForces + 1
  87. }
  88. i--
  89. }
  90. cp, corBrk, ethBrk := ply.TotalForces*4, ply.CorporealForces, ply.CorporealForces+ply.EtherealForces
  91. sklBrk := 12
  92. // Corporeal
  93. coratt := (ply.CorporealForces * 4) - (ply.Strength + ply.Agility)
  94. for coratt > 0 {
  95. r := rand.Intn(2)
  96. if r == 0 {
  97. if ply.Strength == 12 || (ply.Strength >= (ply.Agility*2) && rand.Intn(3) == 0) {
  98. continue
  99. }
  100. ply.Strength = ply.Strength + 1
  101. } else {
  102. if ply.Agility == 12 || (ply.Agility >= (ply.Strength*2) && rand.Intn(3) == 0) {
  103. continue
  104. }
  105. ply.Agility = ply.Agility + 1
  106. }
  107. coratt--
  108. }
  109. // Ethereal
  110. ethatt := (ply.EtherealForces * 4) - (ply.Intellect + ply.Precision)
  111. for ethatt > 0 {
  112. r := rand.Intn(2)
  113. if r == 0 {
  114. if ply.Intellect == 12 || (ply.Intellect >= (ply.Precision*2) && rand.Intn(3) == 0) {
  115. continue
  116. }
  117. ply.Intellect = ply.Intellect + 1
  118. } else {
  119. if ply.Precision == 12 || (ply.Precision >= (ply.Intellect*2) && rand.Intn(3) == 0) {
  120. continue
  121. }
  122. ply.Precision = ply.Precision + 1
  123. }
  124. ethatt--
  125. }
  126. // Celestial
  127. celatt := (ply.CelestialForces * 4) - (ply.Will + ply.Perception)
  128. for celatt > 0 {
  129. r := rand.Intn(2)
  130. if r == 0 {
  131. if ply.Will == 12 || (ply.Will >= (ply.Perception*2) && rand.Intn(3) == 0) {
  132. continue
  133. }
  134. ply.Will = ply.Will + 1
  135. } else {
  136. if ply.Perception == 12 || (ply.Perception >= (ply.Will*2) && rand.Intn(3) == 0) {
  137. continue
  138. }
  139. ply.Perception = ply.Perception + 1
  140. }
  141. celatt--
  142. }
  143. b := 7 + rand.Intn(6)
  144. for i := cp; i > b; i-- {
  145. r := rand.Intn(15)
  146. if r < sklBrk { // it's a skill
  147. if rand.Intn(3) == 0 && len(ply.Skills) != 0 {
  148. key, val := util.ChoiceMap(ply.Skills)
  149. if ply.Skills[key] == 6 {
  150. i++
  151. } else {
  152. ply.Skills[key] = val + 1
  153. }
  154. } else {
  155. q := rand.Intn(ply.TotalForces)
  156. skl := ""
  157. if q < corBrk { // it's a corporeal skill
  158. skl = util.ChoiceStr(corSkills)
  159. // fmt.Println("Selected Corporeal skill: ", skl)
  160. } else if q < ethBrk { // it's an ethereal skill
  161. skl = util.ChoiceStr(ethSkills)
  162. if skl == "Lying" && (ply.Kind == "Seraph" || ply.Kind == "Balseraph") {
  163. i++
  164. continue
  165. }
  166. if skl == "Knowledge" {
  167. subskl := util.ChoiceStr(knowList)
  168. skl = "Knowledge (" + subskl + ")"
  169. } else if skl == "Area Knowledge" {
  170. subskl := util.ChoiceStr(akList)
  171. skl = "Area Knowledge (" + subskl + ")"
  172. } else if skl == "Language" {
  173. subskl := util.ChoiceStr(langList)
  174. skl = "Language (" + subskl + ")"
  175. }
  176. // fmt.Println("Selected Ethereal skill: ", skl)
  177. } else { // it's a celestial skill
  178. skl = util.ChoiceStr(celSkills)
  179. // fmt.Println("Selected Celestial skill: ", skl)
  180. }
  181. if ply.Skills[skl] == 6 {
  182. i++
  183. } else {
  184. ply.Skills[skl] = ply.Skills[skl] + 1
  185. }
  186. }
  187. } else { // Songs
  188. if rand.Intn(3) == 0 && len(ply.Songs) != 0 {
  189. key, val := util.ChoiceMap(ply.Songs)
  190. if ply.Songs[key] == 6 {
  191. i++
  192. } else {
  193. ply.Songs[key] = val + 1
  194. }
  195. } else {
  196. skl := util.ChoiceStr(songList)
  197. // fmt.Println("Selected song: ", skl)
  198. if ply.Songs[skl] == 6 {
  199. i++
  200. } else {
  201. ply.Songs[skl] = ply.Songs[skl] + 1
  202. }
  203. }
  204. }
  205. }
  206. skills := make([]string, 0, len(ply.Skills))
  207. songs := make([]string, 0, len(ply.Songs))
  208. // fmt.Println(len(ply.Skills), len(ply.Songs), ply.Skills, ply.Songs)
  209. for k, v := range ply.Skills {
  210. skills = append(skills, k+"/"+strconv.Itoa(v))
  211. }
  212. for k, v := range ply.Songs {
  213. songs = append(songs, k+"/"+strconv.Itoa(v))
  214. }
  215. sort.Strings(skills)
  216. sort.Strings(songs)
  217. sklout := strings.Join(skills[:], ", ")
  218. sngout := strings.Join(songs[:], ", ")
  219. fmt.Println("=== Generated In Nomine character ===")
  220. fmt.Println(ply.Name)
  221. fmt.Printf("%s of %s\n", ply.Kind, ply.Word)
  222. fmt.Printf("Cor %d\tEth %d\tCel %d\n",
  223. ply.CorporealForces,
  224. ply.EtherealForces,
  225. ply.CelestialForces)
  226. fmt.Printf("Str %d\tInt %d\tCel %d\n",
  227. ply.Strength,
  228. ply.Intellect,
  229. ply.Will)
  230. fmt.Printf("Agi %d\tPre %d\tPer %d\n",
  231. ply.Agility,
  232. ply.Precision,
  233. ply.Perception)
  234. fmt.Println("Skills:", sklout)
  235. fmt.Println("Songs:", sngout)
  236. fmt.Println("Attunements:", strings.Join(ply.Attunements, ", "))
  237. fmt.Println("CP Remaining:", b)
  238. }