familiar.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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]['room']==npcs[nid]['room']:
  76. creaturesCount=creaturesCount+1
  77. if players[p]['race'] not in creaturesRaces:
  78. creaturesRaces.append(players[p]['race'])
  79. for name,value in players[p]['affinity'].items():
  80. if npcs[nid]['familiarOf']==name:
  81. if value>=0:
  82. creaturesFriendly=creaturesFriendly+1
  83. for n in npcs:
  84. if n != nid:
  85. if npcs[n]['room']==npcs[nid]['room']:
  86. creaturesCount=creaturesCount+1
  87. if npcs[n].get('race'):
  88. if npcs[n]['race'] not in creaturesRaces:
  89. creaturesRaces.append(npcs[n]['race'])
  90. if npcs[n].get('affinity'):
  91. for name,value in npcs[n]['affinity'].items():
  92. if npcs[nid]['familiarOf']==name:
  93. if value>=0:
  94. creaturesFriendly=creaturesFriendly+1
  95. if creaturesCount>0:
  96. creatureStr=randomDescription("creature|being|entity")
  97. creaturesMsg='I see '
  98. if creaturesCount>1:
  99. creaturesMsg=creaturesMsg + str(creaturesCount) + ' ' + creatureStr + 's'
  100. else:
  101. creaturesMsg=creaturesMsg+'one ' + creatureStr
  102. creaturesMsg=creaturesMsg+' here.'
  103. friendlyWord=randomDescription("friendly|nice|pleasing|not threatening")
  104. if creaturesFriendly>0:
  105. if creaturesFriendly>1:
  106. creaturesMsg=creaturesMsg + ' ' + \
  107. str(creaturesFriendly) + ' are ' + friendlyWord + '.'
  108. else:
  109. if creaturesFriendly==creaturesCount:
  110. creaturesMsg=creaturesMsg + ' They are ' + friendlyWord + '.'
  111. else:
  112. creaturesMsg=creaturesMsg + ' One is ' + friendlyWord + '.'
  113. creaturesMsg=creaturesMsg + '\n'
  114. if len(creaturesRaces)>0:
  115. creaturesMsg=creaturesMsg + 'They are '
  116. if len(creaturesRaces)==1:
  117. creaturesMsg=creaturesMsg + '<f220>' + creaturesRaces[0] + 's<r>.'
  118. else:
  119. if len(creaturesRaces)==2:
  120. creaturesMsg=creaturesMsg + '<f220>' + creaturesRaces[0] + 's<r> and <f220>' + creaturesRaces[1] + 's<r>.'
  121. else:
  122. ctr=0
  123. for r in creaturesRaces:
  124. if ctr==0:
  125. creaturesMsg=creaturesMsg + '<f220>' + r + 's<r>'
  126. if ctr>0:
  127. if ctr<len(creaturesRaces)-1:
  128. creaturesMsg= creaturesMsg + ', <f220>' + r + 's<r>'
  129. else:
  130. creaturesMsg=creaturesMsg + ' and <f220>' + r + 's<r>.'
  131. ctr=ctr+1
  132. mud.send_message(id,creaturesMsg)
  133. itemsInRoom=0
  134. weaponsInRoom=0
  135. armorInRoom=0
  136. edibleInRoom=0
  137. for (iid, pl) in list(items.items()):
  138. if items[iid]['room'] == npcs[nid]['room']:
  139. if items[iid].get('weight'):
  140. if items[iid]['weight']>0:
  141. itemsInRoom += 1
  142. if items[iid]['mod_str']>0 and \
  143. (items[iid]['clo_lhand']>0 or items[iid]['clo_rhand']>0):
  144. weaponsInRoom += 1
  145. if items[iid]['mod_endu']>0 and \
  146. items[iid]['clo_chest']>0:
  147. armorInRoom += 1
  148. if items[iid]['edible']!=0:
  149. edibleInRoom += 1
  150. if armorInRoom>0 and weaponsInRoom>0:
  151. mud.send_message(id,'There are some weapons and armor here.')
  152. else:
  153. if armorInRoom>0:
  154. mud.send_message(id,'There is some armor here.')
  155. else:
  156. if weaponsInRoom>0:
  157. mud.send_message(id,'There are some weapons here.')
  158. else:
  159. mud.send_message(id,'There are some items here.')
  160. if edibleInRoom:
  161. mud.send_message(id,'There are some edibles here.')
  162. mud.send_message(id,'\n\n')
  163. def familiarHide(nid, npcs, npcsDB):
  164. """Causes a familiar to hide
  165. """
  166. npcs[nid]['familiarMode']="hide"
  167. npcsDB[nid]['familiarMode']="hide"
  168. def familiarIsHidden(players, id, npcs):
  169. """Returns true if the familiar of the player is hidden
  170. """
  171. if players[id]['familiar']!=-1:
  172. for (nid, pl) in list(npcs.items()):
  173. if npcs[nid]['familiarOf'] == players[id]['name']:
  174. if npcs[nid]['familiarMode'] == 'hide':
  175. return True
  176. return False
  177. def familiarScoutAnyDirection(familiarSize, startRoomID, roomExits, rooms):
  178. """Scout in any direction
  179. """
  180. newPath=[startRoomID]
  181. for ex,rm in roomExits.items():
  182. if rooms[rm]['maxPlayerSize']>-1:
  183. if familiarSize > rooms[rm]['maxPlayerSize']:
  184. continue
  185. newPath.append(rm)
  186. newPath.append(startRoomID)
  187. if len(newPath)==1:
  188. newPath.clear()
  189. return newPath
  190. def familiarScoutInDirection(mud, players, id, startRoomID, roomExits, direction, rooms):
  191. """Scout in the given direction
  192. """
  193. newPath=[]
  194. if roomExits.get(direction):
  195. if rooms[roomExits[direction]]['maxPlayerSize']>-1:
  196. if players[id]['siz'] <= rooms[roomExits[direction]]['maxPlayerSize']:
  197. newPath=[startRoomID, roomExits[direction]]
  198. else:
  199. mud.send_message(id, "It's too small to enter!\n\n")
  200. else:
  201. newPath=[startRoomID, roomExits[direction]]
  202. else:
  203. mud.send_message(id, "I can't go that way!\n\n")
  204. return newPath
  205. def familiarScout(mud, players, id, nid, npcs, npcsDB, rooms, direction):
  206. """familiar begins scouting the surrounding rooms
  207. """
  208. startRoomID = npcs[nid]['room']
  209. roomExits = rooms[startRoomID]['exits']
  210. newPath=[]
  211. if direction=='any' or direction=='all' or len(direction)==0:
  212. newPath=familiarScoutAnyDirection(npcs[nid]['siz'], startRoomID, roomExits, rooms)
  213. else:
  214. newPath=familiarScoutInDirection(mud, players, id, startRoomID, roomExits, direction, rooms)
  215. if len(newPath)>0:
  216. npcs[nid]['familiarMode']="scout"
  217. npcs[nid]['moveType']="patrol"
  218. npcs[nid]['path']=deepcopy(newPath)
  219. npcsDB[nid]['familiarMode']="scout"
  220. npcsDB[nid]['moveType']="patrol"
  221. npcsDB[nid]['path']=deepcopy(newPath)
  222. else:
  223. familiarDefaultMode(nid, npcs, npcsDB)