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':
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  location = random.randint(1, 3)
136  if location == 1:
137  positions = [ [8, 2], [10, 7], [10, 9], [28, 18] ]
138  where = 'behind windows'
139  elif location == 2:
140  positions = [ [10, 7], [10, 9], [2, 23], [16, 21], [8, 2], [24, 6], [23, 7], [25, 7], [19, 26], [20, 26], [19, 28] ]
141  where = 'behind grates'
142  else:
143  positions = [ [8, 2], [10, 7], [10, 9], [2, 23], [16, 21], [8, 2], [24, 6], [23, 7], [25, 7], [28, 18], [19, 26], [20, 26], [19, 28] ]
144  where = 'in this dungeon'
145 
146  count = 0
147  for pos in positions:
148  count += check_arch(ear.Map, pos[0], pos[1], archs[choice])
149 
150  ear.Say('How many piles of %s did you see %s?'%(names[choice],where))
151  ear.Say('Reply with a number in digits please.')
152 
153  # keep reply in the ear, easier
154  ear.WriteKey('reply', str(count), 1)
155  return
156 
157  # check answer
158 
159  ear.WriteKey('challenge', 'done')
160 
161  count = int(ear.ReadKey('reply'))
162  if challenge_correct_reply(count, msg):
163  ear.Map.TriggerConnected(60, 1)
164  ear.Say('Correct!')
165  else:
166  ear.Say('Sorry, that is not the correct reply. Please try again later.')
167 
169  '''Handle the player applying the lever to get her reward.'''
170  rewards = { # Gate positions for the rewards
171  'amethysts': [2, 15],
172  'glowing_crystal': [2, 17],
173  'potion': [3, 18],
174  'townportal': [5, 18],
175  'lunar_shield': [7, 18],
176  'wizard_gloves': [10, 15],
177  'black_dragon_mail': [10, 17],
178  }
179  chances = [ # Possible rewards, one is selected in the list so some items are repeated to make them more probably
180  'amethysts',
181  'amethysts',
182  'amethysts',
183  'amethysts',
184  'glowing_crystal',
185  'glowing_crystal',
186  'glowing_crystal',
187  'potion',
188  'potion',
189  'townportal',
190  'townportal',
191  'lunar_shield',
192  'wizard_gloves',
193  'black_dragon_mail',
194  ]
195 
196  def swap_gate(item, delete = False):
197  # lever.Map.Print('item = %d'%(item))
198  x = rewards[chances[item]][0]
199  y = rewards[chances[item]][1]
200  gate = lever.Map.ObjectAt(x, y).Above.Above
201  replace = ''
202  glow = 0
203  if gate.ArchName == 'grate_closed_1':
204  replace = 'igate_closed_1'
205  elif gate.ArchName == 'grate_closed_2':
206  replace = 'igate_closed_2'
207  elif gate.ArchName == 'igate_closed_1':
208  replace = 'grate_closed_1'
209  glow = 5
210  elif gate.ArchName == 'igate_closed_2':
211  replace = 'grate_closed_2'
212  glow = 5
213  else:
214  # lever.Map.Print('found %s'%(gate.ArchName))
215  return
216  # lever.Map.Print('%d %d %s => %s'%(x, y, gate.ArchName, replace))
217  gate.Remove()
218  if delete:
219  return
220  ob = lever.Map.CreateObject(replace, x, y)
221  if glow != 0:
222  ob.GlowRadius = glow
223 
224 
225  Crossfire.SetReturnValue(1)
226  lever = Crossfire.WhoAmI()
227  event = Crossfire.WhatIsEvent()
228  status = lever.ReadKey('status')
229  if event.Subtype == Crossfire.EventType.APPLY:
230  if status == '':
231  lever.Map.Print('And now you shall get your reward!')
232  lever.WriteKey('status', 'start', 1)
233  lever.WriteKey('reward', str(random.randint(0, len(chances))), 1)
234  lever.WriteKey('left', str(random.randint(1, 3) + random.randint(1, 3) + random.randint(1, 3)), 1)
235  lever.WriteKey('current', '-1', 1)
236  lever.CreateTimer(1 + random.randint(1, 3), 2)
237  return
238  elif event.Subtype == Crossfire.EventType.TIMER:
239  if lever.Map.Darkness < 5:
240  lever.Map.ChangeLight(1)
241  lever.CreateTimer(1 + random.randint(1, 3), 2)
242  return
243 
244  left = int(lever.ReadKey('left'))
245  current = int(lever.ReadKey('current'))
246  if left == 0:
247  lever.Map.Print("Yes! Congratulations!")
248  while lever.Map.Darkness > 0:
249  lever.Map.ChangeLight(-1)
250  swap_gate(current, True)
251 
252  else:
253  if current != -1:
254  lever.Map.Print('No!')
255  # lever.Map.Print('restoring')
256  swap_gate(current)
257  lever.WriteKey('current', '-1', 1)
258  lever.CreateTimer(1 + random.randint(1, 3), 2)
259  return
260 
261  left -= 1
262  lever.WriteKey('left', str(left), 1)
263 
264  current = random.randint(0, len(chances) - 1)
265  swap_gate(current)
266  lever.WriteKey('current', str(current), 1)
267  lever.CreateTimer(1 + random.randint(1, 2), 1)
268  lever.Map.Print('Will it be this reward?')
269 
270 def politos():
271  '''Handle Politos's dialog in the entrance.'''
272  msg = Crossfire.WhatIsMessage()
273  politos = Crossfire.WhoAmI()
274  pl = Crossfire.WhoIsActivator()
275  status = politos.ReadKey('opened')
276 
277  if msg == 'potion':
278  politos.Say("This potion will replace any of the three keys, but you have to figure out how to use it yourself.")
279  elif msg == 'yes' and status == '':
280  politos.Say('Ok, good luck')
281  politos.Map.TriggerConnected(1, 1)
282  politos.WriteKey('opened', 'yes', 1)
283  elif status != '':
284  politos.Say('Feel free to go try get the keys now.')
285  else:
286  politos.Say(
287  'Welcome to Darcap Manor. Here you can attempt to find some exclusive rewards!\n'
288  'To get a treasure from upstairs, you need to find three keys: blue, white, brown.\n'
289  'You can get one from each of the corners of this room, provided you are strong or smart enough, of course.\n'
290  # 'If you go downstairs, you can attempt to get a random key, but you must be lucky.\n\n'
291  'So do you wish to enter?'
292  )
293  Crossfire.SetReturnValue(1)
294 
295 params = Crossfire.ScriptParameters()
296 
297 if params == 'blue':
298  blue_check()
299 elif params == 'potion':
300  potion_check()
301 elif params == 'kaptel':
302  kaptel_death()
303 elif params == 'white':
305 elif params == 'reward':
306  claim_reward()
307 elif params == 'politos':
308  politos()
receive.Message
Message
Definition: receive.py:26
manor.claim_reward
def claim_reward()
Definition: manor.py:168
manor.challenge_correct_reply
def challenge_correct_reply(count, msg)
Definition: manor.py:97
manor.politos
def politos()
Definition: manor.py:270
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:24
manor.potion_check
def potion_check()
Definition: manor.py:37
make_face_from_files.int
int
Definition: make_face_from_files.py:26
manor.kaptel_death
def kaptel_death()
Definition: manor.py:77
manor.blue_check
def blue_check()
Definition: manor.py:29