maps/python/maps/darcap/manor.py

181 lines
5.4 KiB
Python
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

import random
# -*- coding: utf-8 -*-
# Script handling various things for Darcap Manor.
#
# It is used:
# - in the blue zone, to count how many kobolds are on the map
# - for the potion, to explode walls in the treasure room
# - in the brown zone, to prevent Kaptel's death or trigger the opening of the exit
# - in the white zone, to check if the player knows how many of a certain jewel there are
import Crossfire
def blue_count_kobolds():
map = Crossfire.WhoAmI().Map
count = 0
for x in range(map.Width):
for y in range(map.Height):
below = map.ObjectAt(x, y)
while below:
if below.Name == 'kobold':
count = count + 1
break
below = below.Above
return count
def blue_check():
'''Player triggered the lever, check if correct number of kobolds. '''
if blue_count_kobolds() != 4:
Crossfire.SetReturnValue(1)
Crossfire.WhoIsActivator().Message('The level will only activate if there are exactly 4 kobolds on the map')
return
def potion_find_wall(map, x, y, name):
'''Find the wall of a given archetype at the specified location.'''
item = map.ObjectAt(x, y)
while item:
if item.ArchName == name:
return item
item = item.Above
return None
def potion_check():
"""Handle the Darcap Manor's potion being thrown. Check if walls to destroy in the treasure room."""
# note: duplication with /CFMove.py, should be factorised at some point
dir_x = [ 0, 0, 1, 1, 1, 0, -1, -1, -1 ]
dir_y = [ 0, -1, -1, 0, 1, 1, 1, 0, -1 ]
env = Crossfire.WhoAmI().Env
if env.Map.Path != '/darcap/darcap/manor.treasure':
return
x = env.X + dir_x[ env.Direction ]
y = env.Y + dir_y[ env.Direction ]
if y != 4 and y != 8 and y != 12:
return
if x != 9 and x != 10:
return
left = potion_find_wall(env.Map, 9, y, 'cwall_mural_1_1')
right = potion_find_wall(env.Map, 10, y, 'cwall_mural_1_2')
if left == None or right == None:
# hu?
return
left.Remove()
right.Remove()
env.Map.CreateObject('rubble', 9, y)
env.Map.CreateObject('rubble', 10, y)
Crossfire.WhoAmI().Remove()
env.Map.Print('The wall explodes!')
def kaptel_death():
'''
Handle Kaptel's death event. Depending on whether the player triggered the lever,
either prevent death or trigger the opening of the exit.
'''
who = Crossfire.WhoAmI()
floor = who.Map.ObjectAt(24, 1)
while floor != None and floor.Above != None:
floor = floor.Above
if floor.Name == 'boulder':
who.Say('AAAAAAAAAaaaaahhhhhhhhhhhhhh!!!!!!!!!')
who.Map.TriggerConnected(11, 1)
return
who.Map.Print("%s roars and seems to regenerate!"%(Crossfire.WhoAmI().Name))
who.HP = who.MaxHP / 2
Crossfire.SetReturnValue(1)
def challenge_correct_reply(count, msg):
if count == 0:
return msg == '0' or msg == 'none'
return count == int(msg)
def check_arch(map, x, y, arch):
below = map.ObjectAt(x, y)
while below:
if below.ArchName == arch:
return 1
below = below.Above
return 0
def white_challenge():
'''
Say handler for the final white challenge.
Player must know how many jewel piles of a certain kind were on the map, else failure.
'''
msg = Crossfire.WhatIsMessage()
ear = Crossfire.WhoAmI()
status = ear.ReadKey('challenge')
if status == 'done':
ear.Say('You already replied!')
return
if status == '':
if msg == 'ready':
ear.WriteKey('challenge', 'ready', 1)
ear.Say('To get the white key, reply to the following question:')
archs = [ 'gem', 'amethyst', 'emerald', 'ruby', 'sapphire', 'pearl' ]
names = [ 'diamonds', 'amethysts', 'emeralds', 'rubies', 'sapphires', 'pearls' ]
choice = random.randint(0, 5)
location = random.randint(1, 3)
if location == 1:
positions = [ [8, 2], [10, 7], [10, 9], [28, 18] ]
where = 'behind windows'
elif location == 2:
positions = [ [10, 7], [10, 9], [2, 23], [16, 21], [8, 2], [24, 6], [23, 7], [25, 7], [19, 26], [20, 26], [19, 28] ]
where = 'behind grates'
else:
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] ]
where = 'in this dungeon'
count = 0
for pos in positions:
count += check_arch(ear.Map, pos[0], pos[1], archs[choice])
ear.Say('How many piles of %s did you see %s?'%(names[choice],where))
ear.Say('Reply with a number in digits please.')
# keep reply in the ear, easier
ear.WriteKey('reply', str(count), 1)
return
# check answer
ear.WriteKey('challenge', 'done')
count = int(ear.ReadKey('reply'))
if challenge_correct_reply(count, msg):
ear.Map.TriggerConnected(60, 1)
ear.Say('Correct!')
else:
ear.Say('Sorry, that is not the correct reply. Please try again later.')
if Crossfire.ScriptParameters() == 'blue':
blue_check()
elif Crossfire.ScriptParameters() == 'potion':
potion_check()
elif Crossfire.ScriptParameters() == 'kaptel':
kaptel_death()
elif Crossfire.ScriptParameters() == 'white':
white_challenge()