dialog.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. // dialog.go
  2. package server
  3. /* This file contains dialogs for the client. The dialog helpers are in ask.go. */
  4. import "gitlab.com/beoran/woe/monolog"
  5. import "gitlab.com/beoran/woe/world"
  6. const NEW_CHARACTER_PRICE = 4
  7. func (me *Client) ExistingAccountDialog() bool {
  8. pass := me.AskPassword()
  9. for pass == nil {
  10. me.Printf("Password may not be empty!\n")
  11. pass = me.AskPassword()
  12. }
  13. if !me.account.Challenge(string(pass)) {
  14. me.Printf("Password not correct!\n")
  15. me.Printf("Disconnecting!\n")
  16. return false
  17. }
  18. return true
  19. }
  20. func (me *Client) NewAccountDialog(login string) bool {
  21. for me.account == nil {
  22. me.Printf("\nWelcome, %s! Creating new account...\n", login)
  23. pass1 := me.AskPassword()
  24. if pass1 == nil {
  25. return false
  26. }
  27. pass2 := me.AskRepeatPassword()
  28. if pass1 == nil {
  29. return false
  30. }
  31. if string(pass1) != string(pass2) {
  32. me.Printf("\nPasswords do not match! Please try again!\n")
  33. continue
  34. }
  35. email := me.AskEmail()
  36. if email == nil {
  37. return false
  38. }
  39. me.account = world.NewAccount(login, string(pass1), string(email), 7)
  40. err := me.account.Save(me.server.DataPath())
  41. if err != nil {
  42. monolog.Error("Could not save account %s: %v", login, err)
  43. me.Printf("\nFailed to save your account!\nPlease contact a WOE administrator!\n")
  44. return false
  45. }
  46. monolog.Info("Created new account %s", login)
  47. me.Printf("\nSaved your account.\n")
  48. return true
  49. }
  50. return false
  51. }
  52. func (me *Client) AccountDialog() bool {
  53. login := me.AskLogin()
  54. if login == nil {
  55. return false
  56. }
  57. var err error
  58. if me.server.World.GetAccount(string(login)) != nil {
  59. me.Printf("Account already logged in!\n")
  60. me.Printf("Disconnecting!\n")
  61. return false
  62. }
  63. me.account, err = me.server.World.LoadAccount(string(login))
  64. if err != nil {
  65. monolog.Warning("Could not load account %s: %v", login, err)
  66. }
  67. if me.account != nil {
  68. return me.ExistingAccountDialog()
  69. } else {
  70. return me.NewAccountDialog(string(login))
  71. }
  72. }
  73. func (me *Client) NewCharacterDialog() bool {
  74. noconfirm := true
  75. extra := TrivialAskOptionList{TrivialAskOption("Cancel")}
  76. me.Printf("New character:\n")
  77. charname := me.AskCharacterName()
  78. existing, aname, _ := world.LoadCharacterByName(me.server.DataPath(), string(charname))
  79. for existing != nil {
  80. if aname == me.account.Name {
  81. me.Printf("You already have a character with a similar name!\n")
  82. } else {
  83. me.Printf("That character name is already taken by someone else.\n")
  84. }
  85. charname := me.AskCharacterName()
  86. existing, aname, _ = world.LoadCharacterByName(me.server.DataPath(), string(charname))
  87. }
  88. kinres := me.AskOptionListExtra("Please choose the kin of this character", "Kin?> ", false, noconfirm, KinListAsker(world.KinList), extra)
  89. if sopt, ok := kinres.(TrivialAskOption); ok {
  90. if string(sopt) == "Cancel" {
  91. me.Printf("Character creation canceled.\n")
  92. return true
  93. } else {
  94. return true
  95. }
  96. }
  97. kin := kinres.(world.Kin)
  98. genres := me.AskOptionListExtra("Please choose the gender of this character", "Gender?> ", false, noconfirm, GenderListAsker(world.GenderList), extra)
  99. if sopt, ok := kinres.(TrivialAskOption); ok {
  100. if string(sopt) == "Cancel" {
  101. me.Printf("Character creation canceled.\n")
  102. return true
  103. } else {
  104. return true
  105. }
  106. }
  107. gender := genres.(world.Gender)
  108. jobres := me.AskOptionListExtra("Please choose the job of this character", "Gender?> ", false, noconfirm, JobListAsker(world.JobList), extra)
  109. if sopt, ok := kinres.(TrivialAskOption); ok {
  110. if string(sopt) == "Cancel" {
  111. me.Printf("Character creation canceled.\n")
  112. return true
  113. } else {
  114. return true
  115. }
  116. }
  117. job := jobres.(world.Job)
  118. character := world.NewCharacter(me.account,
  119. string(charname), &kin, &gender, &job)
  120. me.Printf("%s", character.Being.ToStatus())
  121. ok := me.AskYesNo("Is this character ok?")
  122. if !ok {
  123. me.Printf("Character creation canceled.\n")
  124. return true
  125. }
  126. me.account.AddCharacter(character)
  127. me.account.Points -= NEW_CHARACTER_PRICE
  128. me.account.Save(me.server.DataPath())
  129. character.Save(me.server.DataPath())
  130. me.Printf("Character %s saved.\n", character.Being.Name)
  131. return true
  132. }
  133. func (me *Client) DeleteCharacterDialog() bool {
  134. extra := []AskOption{TrivialAskOption("Cancel"), TrivialAskOption("Disconnect")}
  135. els := me.AccountCharacterList()
  136. els = append(els, extra...)
  137. result := me.AskOptionList("Character to delete?",
  138. "Character?>", false, false, els)
  139. if alt, ok := result.(TrivialAskOption); ok {
  140. if string(alt) == "Disconnect" {
  141. me.Printf("Disconnecting")
  142. return false
  143. } else if string(alt) == "Cancel" {
  144. me.Printf("Canceled")
  145. return true
  146. } else {
  147. monolog.Warning("Internal error, unhandled case.")
  148. return true
  149. }
  150. }
  151. character := result.(*world.Character)
  152. /* A character that is deleted gives NEW_CHARACTER_PRICE +
  153. * level / (NEW_CHARACTER_PRICE * 2) points, but only after the delete. */
  154. np := NEW_CHARACTER_PRICE + character.Level/(NEW_CHARACTER_PRICE*2)
  155. me.account.DeleteCharacter(me.server.DataPath(), character)
  156. me.account.Points += np
  157. return true
  158. }
  159. func (me *Client) AccountCharacterList() AskOptionSlice {
  160. els := make(AskOptionSlice, 0, 16)
  161. for i := 0; i < me.account.NumCharacters(); i++ {
  162. chara := me.account.GetCharacter(i)
  163. els = append(els, chara)
  164. }
  165. return els
  166. }
  167. func (me *Client) ChooseCharacterDialog() bool {
  168. extra := []AskOption{
  169. SimpleAskOption{"New", "Create New character",
  170. "Create a new character. This option costs 4 points.",
  171. world.PRIVILEGE_ZERO},
  172. SimpleAskOption{"Disconnect", "Disconnect from server",
  173. "Disconnect your client from this server.",
  174. world.PRIVILEGE_ZERO},
  175. SimpleAskOption{"Delete", "Delete character",
  176. "Delete a character. A character that has been deleted cannot be reinstated. You will receive point bonuses for deleting your characters that depend on their level.",
  177. world.PRIVILEGE_ZERO},
  178. }
  179. var pchara *world.Character = nil
  180. for pchara == nil {
  181. els := me.AccountCharacterList()
  182. els = append(els, extra...)
  183. result := me.AskOptionList("Choose a character?", "Character?>", false, true, els)
  184. switch opt := result.(type) {
  185. case SimpleAskOption:
  186. if opt.Name == "New" {
  187. if me.account.Points >= NEW_CHARACTER_PRICE {
  188. if !me.NewCharacterDialog() {
  189. return false
  190. }
  191. } else {
  192. me.Printf("Sorry, you have no points left to make new characters!\n")
  193. }
  194. } else if opt.Name == "Disconnect" {
  195. me.Printf("Disconnecting\n")
  196. return false
  197. } else if opt.Name == "Delete" {
  198. if !me.DeleteCharacterDialog() {
  199. return false
  200. }
  201. } else {
  202. me.Printf("Internal error, alt not valid: %v.", opt)
  203. }
  204. case *world.Character:
  205. pchara = opt
  206. default:
  207. me.Printf("What???")
  208. }
  209. me.Printf("You have %d points left.\n", me.account.Points)
  210. }
  211. me.character = pchara
  212. me.Printf("%s\n", me.character.Being.ToStatus())
  213. me.Printf("Welcome, %s!\n", me.character.Name)
  214. return true
  215. }
  216. func (me *Client) CharacterDialog() bool {
  217. me.Printf("You have %d remaining points.\n", me.account.Points)
  218. for me.account.NumCharacters() < 1 {
  219. me.Printf("You have no characters yet!\n")
  220. if me.account.Points >= NEW_CHARACTER_PRICE {
  221. if !me.NewCharacterDialog() {
  222. return false
  223. }
  224. } else {
  225. me.Printf("Sorry, you have no characters, and no points left to make new characters!\n")
  226. me.Printf("Please contact the staff of WOE if you think this is a mistake.\n")
  227. me.Printf("Disconnecting!\n")
  228. return false
  229. }
  230. }
  231. return me.ChooseCharacterDialog()
  232. }