familiar.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. __filename__ = "familiar.py"
  2. __author__ = "Bob Mottram"
  3. __credits__ = ["Bob Mottram"]
  4. __license__ = "AGPL3+"
  5. __version__ = "1.0.0"
  6. __maintainer__ = "Bob Mottram"
  7. __email__ = "bob@freedombone.net"
  8. __status__ = "Production"
  9. #!/usr/bin/python
  10. # -*- coding: utf-8 -*-
  11. import os
  12. from functions import log
  13. from functions import randomDescription
  14. from random import randint
  15. from copy import deepcopy
  16. import time
  17. # Movement modes for familiars
  18. familiarModes = ("follow","scout","hide","see")
  19. def getFamiliarModes():
  20. return familiarModes
  21. def getFamiliarName(players,id,npcs):
  22. """Returns the name of the familiar of the given player
  23. """
  24. if players[id]['familiar']!=-1:
  25. for (nid, pl) in list(npcs.items()):
  26. if npcs[nid]['familiarOf'] == players[id]['name']:
  27. return npcs[nid]['name']
  28. return ''
  29. def familiarRecall(mud, players, id, npcs, npcsDB):
  30. """Move any familiar to the player's location
  31. """
  32. # remove any existing familiars
  33. removals = []
  34. for (nid, pl) in list(npcs.items()):
  35. if pl['familiarOf'] == players[id]['name']:
  36. removals.append(nid)
  37. for index in removals:
  38. del npcs[index]
  39. # By default player has no familiar
  40. players[id]['familiar'] = -1
  41. # Find familiar and set its room to that of the player
  42. for (nid, pl) in list(npcsDB.items()):
  43. if pl['familiarOf'] == players[id]['name']:
  44. players[id]['familiar'] = int(nid)
  45. if not npcs.get(nid):
  46. npcs[nid] = deepcopy(npcsDB[nid])
  47. npcs[nid]['room'] = players[id]['room']
  48. mud.send_message(id, "Your familiar is recalled.\n\n")
  49. break
  50. def familiarDefaultMode(nid, npcs, npcsDB):
  51. npcs[nid]['familiarMode']="follow"
  52. npcsDB[nid]['familiarMode']="follow"
  53. npcs[nid]['moveType']=""
  54. npcsDB[nid]['moveType']=""
  55. npcs[nid]['path']=[]
  56. npcsDB[nid]['path']=[]
  57. def familiarSight(mud, nid, npcs, npcsDB, rooms, players, id, items, itemsDB):
  58. """familiar reports what it sees
  59. """
  60. startRoomID = npcs[nid]['room']
  61. roomExits = rooms[startRoomID]['exits']
  62. mud.send_message(id, "Your familiar says:\n")
  63. if len(roomExits)==0:
  64. mud.send_message(id, "There are no exits.")
  65. else:
  66. if len(roomExits)>1:
  67. mud.send_message(id, "There are " + str(len(roomExits)) + " exits.")
  68. else:
  69. exitDescription=randomDescription("a single|one")
  70. mud.send_message(id, "There is " + exitDescription + " exit.")
  71. creaturesCount=0
  72. creaturesFriendly=0
  73. creaturesRaces=[]
  74. for p in players:
  75. if players[p]['name'] is None:
  76. continue
  77. if players[p]['room']==npcs[nid]['room']:
  78. creaturesCount=creaturesCount+1
  79. if players[p]['race'] not in creaturesRaces:
  80. creaturesRaces.append(players[p]['race'])
  81. for name,value in players[p]['affinity'].items():
  82. if npcs[nid]['familiarOf']==name:
  83. if value>=0:
  84. creaturesFriendly=creaturesFriendly+1
  85. for n in npcs:
  86. if n != nid:
  87. if npcs[n]['room']==npcs[nid]['room']:
  88. creaturesCount=creaturesCount+1
  89. if npcs[n].get('race'):
  90. if npcs[n]['race'] not in creaturesRaces:
  91. creaturesRaces.append(npcs[n]['race'])
  92. if npcs[n].get('affinity'):
  93. for name,value in npcs[n]['affinity'].items():
  94. if npcs[nid]['familiarOf']==name:
  95. if value>=0:
  96. creaturesFriendly=creaturesFriendly+1
  97. if creaturesCount>0:
  98. creatureStr=randomDescription("creature|being|entity")
  99. creaturesMsg='I see '
  100. if creaturesCount>1:
  101. creaturesMsg=creaturesMsg + str(creaturesCount) + ' ' + creatureStr + 's'
  102. else:
  103. creaturesMsg=creaturesMsg+'one ' + creatureStr
  104. creaturesMsg=creaturesMsg+' here.'
  105. friendlyWord=randomDescription("friendly|nice|pleasing|not threatening")
  106. if creaturesFriendly>0:
  107. if creaturesFriendly>1:
  108. creaturesMsg=creaturesMsg + ' ' + \
  109. str(creaturesFriendly) + ' are ' + friendlyWord + '.'
  110. else:
  111. if creaturesFriendly==creaturesCount:
  112. creaturesMsg=creaturesMsg + ' They are ' + friendlyWord + '.'
  113. else:
  114. creaturesMsg=creaturesMsg + ' One is ' + friendlyWord + '.'
  115. creaturesMsg=creaturesMsg + '\n'
  116. if len(creaturesRaces)>0:
  117. creaturesMsg=creaturesMsg + 'They are '
  118. if len(creaturesRaces)==1:
  119. creaturesMsg=creaturesMsg + '<f220>' + creaturesRaces[0] + 's<r>.'
  120. else:
  121. if len(creaturesRaces)==2:
  122. creaturesMsg=creaturesMsg + '<f220>' + creaturesRaces[0] + 's<r> and <f220>' + creaturesRaces[1] + 's<r>.'
  123. else:
  124. ctr=0
  125. for r in creaturesRaces:
  126. if ctr==0:
  127. creaturesMsg=creaturesMsg + '<f220>' + r + 's<r>'
  128. if ctr>0:
  129. if ctr<len(creaturesRaces)-1:
  130. creaturesMsg= creaturesMsg + ', <f220>' + r + 's<r>'
  131. else:
  132. creaturesMsg=creaturesMsg + ' and <f220>' + r + 's<r>.'
  133. ctr=ctr+1
  134. mud.send_message(id,creaturesMsg)
  135. itemsInRoom=0
  136. weaponsInRoom=0
  137. armorInRoom=0
  138. edibleInRoom=0
  139. for (iid, pl) in list(items.items()):
  140. if items[iid]['room'] == npcs[nid]['room']:
  141. if items[iid].get('weight'):
  142. if items[iid]['weight']>0:
  143. itemsInRoom += 1
  144. if items[iid]['mod_str']>0 and \
  145. (items[iid]['clo_lhand']>0 or items[iid]['clo_rhand']>0):
  146. weaponsInRoom += 1
  147. if items[iid]['mod_endu']>0 and \
  148. items[iid]['clo_chest']>0:
  149. armorInRoom += 1
  150. if items[iid]['edible']!=0:
  151. edibleInRoom += 1
  152. if armorInRoom>0 and weaponsInRoom>0:
  153. mud.send_message(id,'There are some weapons and armor here.')
  154. else:
  155. if armorInRoom>0:
  156. mud.send_message(id,'There is some armor here.')
  157. else:
  158. if weaponsInRoom>0:
  159. mud.send_message(id,'There are some weapons here.')
  160. else:
  161. mud.send_message(id,'There are some items here.')
  162. if edibleInRoom:
  163. mud.send_message(id,'There are some edibles here.')
  164. mud.send_message(id,'\n\n')
  165. def familiarHide(nid, npcs, npcsDB):
  166. """Causes a familiar to hide
  167. """
  168. npcs[nid]['familiarMode']="hide"
  169. npcsDB[nid]['familiarMode']="hide"
  170. def familiarIsHidden(players, id, npcs):
  171. """Returns true if the familiar of the player is hidden
  172. """
  173. if players[id]['familiar']!=-1:
  174. for (nid, pl) in list(npcs.items()):
  175. if npcs[nid]['familiarOf'] == players[id]['name']:
  176. if npcs[nid]['familiarMode'] == 'hide':
  177. return True
  178. return False
  179. def familiarScoutAnyDirection(familiarSize, startRoomID, roomExits, rooms):
  180. """Scout in any direction
  181. """
  182. newPath=[startRoomID]
  183. for ex,rm in roomExits.items():
  184. if rooms[rm]['maxPlayerSize']>-1:
  185. if familiarSize > rooms[rm]['maxPlayerSize']:
  186. continue
  187. newPath.append(rm)
  188. newPath.append(startRoomID)
  189. if len(newPath)==1:
  190. newPath.clear()
  191. return newPath
  192. def familiarScoutInDirection(mud, players, id, startRoomID, roomExits, direction, rooms):
  193. """Scout in the given direction
  194. """
  195. newPath=[]
  196. if roomExits.get(direction):
  197. if rooms[roomExits[direction]]['maxPlayerSize']>-1:
  198. if players[id]['siz'] <= rooms[roomExits[direction]]['maxPlayerSize']:
  199. newPath=[startRoomID, roomExits[direction]]
  200. else:
  201. mud.send_message(id, "It's too small to enter!\n\n")
  202. else:
  203. newPath=[startRoomID, roomExits[direction]]
  204. else:
  205. mud.send_message(id, "I can't go that way!\n\n")
  206. return newPath
  207. def familiarScout(mud, players, id, nid, npcs, npcsDB, rooms, direction):
  208. """familiar begins scouting the surrounding rooms
  209. """
  210. startRoomID = npcs[nid]['room']
  211. roomExits = rooms[startRoomID]['exits']
  212. newPath=[]
  213. if direction=='any' or direction=='all' or len(direction)==0:
  214. newPath=familiarScoutAnyDirection(npcs[nid]['siz'], startRoomID, roomExits, rooms)
  215. else:
  216. newPath=familiarScoutInDirection(mud, players, id, startRoomID, roomExits, direction, rooms)
  217. if len(newPath)>0:
  218. npcs[nid]['familiarMode']="scout"
  219. npcs[nid]['moveType']="patrol"
  220. npcs[nid]['path']=deepcopy(newPath)
  221. npcsDB[nid]['familiarMode']="scout"
  222. npcsDB[nid]['moveType']="patrol"
  223. npcsDB[nid]['path']=deepcopy(newPath)
  224. else:
  225. familiarDefaultMode(nid, npcs, npcsDB)