Crossfire Server, Trunk
manor.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 # Script handling various things for Darcap Manor.
3 #
4 # It is used:
5 # - in the blue zone, to count how many kobolds are on the map
6 # - in the brown zone, to prevent Kaptel's death or trigger the opening of the exit
7 # - in the white zone, to check if the player knows how many of a certain jewel there are
8 # - for the potion, to explode walls in the treasure room
9 # - in the treasure room, to select the reward
10 
11 import random
12 import Crossfire
13 
15  '''Count the number of kobolds on the map for the blue zone.'''
16  map = Crossfire.WhoAmI().Map
17  count = 0
18  for x in range(map.Width):
19  for y in range(map.Height):
20  below = map.ObjectAt(x, y)
21  while below:
22  if below.Name == 'kobold' or below.Name == 'Second Chance kobold':
23  count = count + 1
24  break
25  below = below.Above
26 
27  return count
28 
29 def blue_check():
30  '''Player triggered the lever, check if correct number of kobolds.'''
31 
32  if blue_count_kobolds() != 4:
33  Crossfire.SetReturnValue(1)
34  Crossfire.WhoIsActivator().Message('The level will only activate if there are exactly 4 kobolds on the map')
35  return
36 
38  """Handle the Darcap Manor's potion being thrown. Check if walls to destroy in the treasure room."""
39 
40  # note: duplication with /CFMove.py, should be factorised at some point
41  dir_x = [ 0, 0, 1, 1, 1, 0, -1, -1, -1 ]
42  dir_y = [ 0, -1, -1, 0, 1, 1, 1, 0, -1 ]
43 
44  env = Crossfire.WhoAmI().Env
45 
46  if env.Map.Path != '/darcap/darcap/manor.treasure':
47  return
48 
49  x = env.X + dir_x[ env.Direction ]
50  y = env.Y + dir_y[ env.Direction ]
51 
52  if y != 4 and y != 8 and y != 12:
53  return
54 
55  if x != 4 and x != 5:
56  return
57 
58  left = env.Map.Check('cwall_mural_1_1', (4, y))
59  right = env.Map.Check('cwall_mural_1_2', (5, y))
60 
61  if left == None or right == None:
62  # hu?
63  return
64 
65  left.Remove()
66  right.Remove()
67 
68  env.Map.CreateObject('rubble', 4, y)
69  env.Map.CreateObject('rubble', 5, y)
70  env.Map.CreateObject('explosion2', 4, y)
71  env.Map.CreateObject('explosion2', 5, y)
72 
73  Crossfire.WhoAmI().Remove()
74 
75  env.Map.Print('The wall explodes!')
76 
78  '''
79  Handle Kaptel's death event. Depending on whether the player triggered the lever,
80  either prevent death or trigger the opening of the exit.
81  '''
82  who = Crossfire.WhoAmI()
83 
84  floor = who.Map.ObjectAt(24, 1)
85  while floor != None and floor.Above != None:
86  floor = floor.Above
87 
88  if floor.Name == 'boulder':
89  who.Say('AAAAAAAAAaaaaahhhhhhhhhhhhhh!!!!!!!!!')
90  who.Map.TriggerConnected(11, 1)
91  return
92 
93  who.Map.Print("%s roars and seems to regenerate!"%(Crossfire.WhoAmI().Name))
94  who.HP = int(who.MaxHP / 2)
95  Crossfire.SetReturnValue(1)
96 
97 def challenge_correct_reply(count, msg):
98  '''Check if the reply to the challenge is correct.'''
99  if count == 0:
100  return msg == '0' or msg == 'none'
101  return count == int(msg)
102 
103 def check_arch(map, x, y, arch):
104  below = map.ObjectAt(x, y)
105  while below:
106  if below.ArchName == arch:
107  return 1
108  below = below.Above
109 
110  return 0
111 
113  '''
114  Say handler for the final white challenge.
115  Player must know how many jewel piles of a certain kind were on the map, else failure.
116  '''
117 
118  msg = Crossfire.WhatIsMessage()
119  ear = Crossfire.WhoAmI()
120  status = ear.ReadKey('challenge')
121 
122  if status == 'done':
123  ear.Say('You already replied!')
124  return
125 
126  if status == '':
127  if msg == 'ready':
128  ear.WriteKey('challenge', 'ready', 1)
129  ear.Say('To get the white key, reply to the following question:')
130 
131  archs = [ 'gem', 'amethyst', 'emerald', 'ruby', 'sapphire', 'pearl' ]
132  names = [ 'diamonds', 'amethysts', 'emeralds', 'rubies', 'sapphires', 'pearls' ]
133  choice = random.randint(0, 5)
134 
135  behind_windows = { (8, 2), (10, 7), (10, 9), (28, 18) }
136  behind_grates = { (2, 23), (10, 7), (10, 9), (16, 21), (19, 26), (19, 28), (20, 26), (23, 7), (24, 1), (24, 6), (25, 7) }
137 
138  location = random.randint(1, 3)
139  if location == 1:
140  positions = behind_windows
141  where = 'behind windows'
142  elif location == 2:
143  positions = behind_grates
144  where = 'behind grates'
145  else:
146  positions = behind_windows.union(behind_grates)
147  where = 'in this dungeon'
148 
149  count = 0
150  for pos in positions:
151  count += check_arch(ear.Map, pos[0], pos[1], archs[choice])
152 
153  ear.Say('How many piles of %s did you see %s?'%(names[choice],where))
154  ear.Say('Reply with a number in digits please.')
155 
156  # keep reply in the ear, easier
157  ear.WriteKey('reply', str(count), 1)
158  return
159 
160  # check answer
161 
162  ear.WriteKey('challenge', 'done')
163 
164  count = int(ear.ReadKey('reply'))
165  if challenge_correct_reply(count, msg):
166  ear.Map.TriggerConnected(60, 1)
167  ear.Say('Correct!')
168  else:
169  ear.Say('Sorry, that is not the correct reply. Please try again later.')
170 
172  '''Handle the player applying the lever to get her reward.'''
173  rewards = { # Gate positions for the rewards
174  'amethysts': [2, 15],
175  'glowing_crystal': [2, 17],
176  'potion': [3, 18],
177  'townportal': [5, 18],
178  'lunar_shield': [7, 18],
179  'wizard_gloves': [10, 15],
180  'black_dragon_mail': [10, 17],
181  }
182  chances = [ # Possible rewards, one is selected in the list so some items are repeated to make them more probably
183  'amethysts',
184  'amethysts',
185  'amethysts',
186  'amethysts',
187  'glowing_crystal',
188  'glowing_crystal',
189  'glowing_crystal',
190  'potion',
191  'potion',
192  'townportal',
193  'townportal',
194  'lunar_shield',
195  'wizard_gloves',
196  'black_dragon_mail',
197  ]
198 
199  def swap_gate(item, delete = False):
200  # lever.Map.Print('item = %d'%(item))
201  x = rewards[chances[item]][0]
202  y = rewards[chances[item]][1]
203  gate = lever.Map.ObjectAt(x, y).Above.Above
204  replace = ''
205  glow = 0
206  if gate.ArchName == 'grate_closed_1':
207  replace = 'igate_closed_1'
208  elif gate.ArchName == 'grate_closed_2':
209  replace = 'igate_closed_2'
210  elif gate.ArchName == 'igate_closed_1':
211  replace = 'grate_closed_1'
212  glow = 5
213  elif gate.ArchName == 'igate_closed_2':
214  replace = 'grate_closed_2'
215  glow = 5
216  else:
217  # lever.Map.Print('found %s'%(gate.ArchName))
218  return
219  # lever.Map.Print('%d %d %s => %s'%(x, y, gate.ArchName, replace))
220  gate.Remove()
221  if delete:
222  return
223  ob = lever.Map.CreateObject(replace, x, y)
224  if glow != 0:
225  ob.GlowRadius = glow
226 
227 
228  Crossfire.SetReturnValue(1)
229  lever = Crossfire.WhoAmI()
230  event = Crossfire.WhatIsEvent()
231  status = lever.ReadKey('status')
232  if event.Subtype == Crossfire.EventType.APPLY:
233  if status == '':
234  lever.Map.Print('And now you shall get your reward!')
235  lever.WriteKey('status', 'start', 1)
236  lever.WriteKey('reward', str(random.randint(0, len(chances))), 1)
237  lever.WriteKey('left', str(random.randint(1, 3) + random.randint(1, 3) + random.randint(1, 3)), 1)
238  lever.WriteKey('current', '-1', 1)
239  lever.CreateTimer(1 + random.randint(1, 3), 2)
240  return
241  elif event.Subtype == Crossfire.EventType.TIMER:
242  if lever.Map.Darkness < 5:
243  lever.Map.ChangeLight(1)
244  lever.CreateTimer(1 + random.randint(1, 3), 2)
245  return
246 
247  left = int(lever.ReadKey('left'))
248  current = int(lever.ReadKey('current'))
249  if left == 0:
250  lever.Map.Print("Yes! Congratulations!")
251  while lever.Map.Darkness > 0:
252  lever.Map.ChangeLight(-1)
253  swap_gate(current, True)
254 
255  else:
256  if current != -1:
257  lever.Map.Print('No!')
258  # lever.Map.Print('restoring')
259  swap_gate(current)
260  lever.WriteKey('current', '-1', 1)
261  lever.CreateTimer(1 + random.randint(1, 3), 2)
262  return
263 
264  left -= 1
265  lever.WriteKey('left', str(left), 1)
266 
267  current = random.randint(0, len(chances) - 1)
268  swap_gate(current)
269  lever.WriteKey('current', str(current), 1)
270  lever.CreateTimer(1 + random.randint(1, 2), 1)
271  lever.Map.Print('Will it be this reward?')
272 
273 def politos():
274  '''Handle Politos's dialog in the entrance.'''
275  msg = Crossfire.WhatIsMessage()
276  politos = Crossfire.WhoAmI()
277  pl = Crossfire.WhoIsActivator()
278  status = politos.ReadKey('opened')
279 
280  if msg == 'potion':
281  politos.Say("This potion will replace any of the three keys, but you have to figure out how to use it yourself.")
282  elif msg == 'yes' and status == '':
283  politos.Say('Ok, good luck')
284  politos.Map.TriggerConnected(1, 1)
285  politos.WriteKey('opened', 'yes', 1)
286  elif status != '':
287  politos.Say('Feel free to go try get the keys now.')
288  else:
289  politos.Say(
290  'Welcome to Darcap Manor. Here you can attempt to find some exclusive rewards!\n'
291  'To get a treasure from upstairs, you need to find three keys: blue, white, brown.\n'
292  'You can get one from each of the corners of this room, provided you are strong or smart enough, of course.\n'
293  # 'If you go downstairs, you can attempt to get a random key, but you must be lucky.\n\n'
294  'So do you wish to enter?'
295  )
296  Crossfire.SetReturnValue(1)
297 
298 params = Crossfire.ScriptParameters()
299 
300 if params == 'blue':
301  blue_check()
302 elif params == 'potion':
303  potion_check()
304 elif params == 'kaptel':
305  kaptel_death()
306 elif params == 'white':
308 elif params == 'reward':
309  claim_reward()
310 elif params == 'politos':
311  politos()
receive.Message
Message
Definition: receive.py:26
manor.claim_reward
def claim_reward()
Definition: manor.py:171
manor.challenge_correct_reply
def challenge_correct_reply(count, msg)
Definition: manor.py:97
manor.politos
def politos()
Definition: manor.py:273
manor.white_challenge
def white_challenge()
Definition: manor.py:112
manor.blue_count_kobolds
def blue_count_kobolds()
Definition: manor.py:14
manor.check_arch
def check_arch(map, x, y, arch)
Definition: manor.py:103
make_face_from_files.str
str
Definition: make_face_from_files.py:30
manor.potion_check
def potion_check()
Definition: manor.py:37
make_face_from_files.int
int
Definition: make_face_from_files.py:32
manor.kaptel_death
def kaptel_death()
Definition: manor.py:77
manor.blue_check
def blue_check()
Definition: manor.py:29