Final steps and scripts for the Lursendis quest.

git-svn-id: svn://svn.code.sf.net/p/crossfire/code/maps/trunk@6405 282e977c-c81d-0410-88c4-b93c2d0d6712
master
ryo_saeba 2007-06-03 16:02:23 +00:00
parent 3ccfe258be
commit d366678c26
5 changed files with 580 additions and 99 deletions

View File

@ -0,0 +1,184 @@
# Script for the Unforgettable Banquet of Lursendis item.
# Idea courtesy Yann Chachkoff.
#
# Copyright 2007 Nicolas Weeger
# Released as GPL
#
# This script will teleport the player to a food-filled map. It only works
# once a (ingame) day.
# Applying the tome while in the map will teleport the player back to his starting place.
# Book can only be applied when in player's inventory, so player can get back to the world.
#
# Map is generated by the script itself, and given a unique name to avoid collision.
#
# Player is replaced with a statue so the spot stays free during his trip.
# To avoid colliding with an existing map, created map will have a unique map.
# Everything in the map is randomly chosen.
import Crossfire
import random
import os.path
# map sizes
size_x = 15
size_y = 15
# what foods to put in the map
foods = [ 'fishfood', 'food', 'bag_popcorn', 'apple', 'cheeseburger', 'loaf', 'tomato', 'waybread', 'roast_bird', 'orange', 'leg_mutton' ]
# what floors can be used
floors = [ 'woodfloor', 'flagstone', 'dirtfloor' ]
# what walls can be used - only put the base name
walls = [ 'flagstone', 'dwall', 'timberwall', 'stwall' ]
# what to replace the player with. Should block all movement
replace_with = [ 'd_statue', 'statue', 'statue2' ]
def get_one(what):
'''Return a random choice in what, which should be an array.'''
return what[ random.randint( 1, len(what) ) - 1 ]
def return_to_bed():
'''Teleport player back to bed of reality. Only in emergency.'''
flags = 0
if (act.BedMap.find(Crossfire.PlayerDirectory()) != -1):
# Unique map
flags = 2
dest = Crossfire.ReadyMap(act.BedMap, flags)
if (dest == None):
# Ok, this is real bad. Let player handle the situation - worse case, call to DMs or WoR manually.
act.Message('The %s whines really loudly.'%l.Name)
return
act.Teleport(dest, act.BedX, act.BedY)
def do_back():
'''Teleport the player back to his starting point.'''
x = l.ReadKey('banquet_x')
y = l.ReadKey('banquet_y')
mn = l.ReadKey('banquet_map')
rw = l.ReadKey('banquet_rw')
l.WriteKey('banquet_x', '', 0)
l.WriteKey('banquet_y', '', 0)
l.WriteKey('banquet_map', '', 0)
l.WriteKey('banquet_rw', '', 0)
if x == '' or y == '' or mn == '':
# Logic error, but can't be helped - teleport player back to his bed of reality
act.Message('You feel a distorsion of reality!')
return_to_bed()
return
# find and remove statue in the map
dest = Crossfire.ReadyMap(mn)
if (dest == None):
# Random map, probably? Let the player teleport back him/herself.
act.Message('The %s whines something. You barely understand it can\'t take you back to your starting point.'%l.Name)
return_to_bed()
return
# Remove statue - let's assume it's found, or was removed due to map reset.
st = dest.ObjectAt(int(x), int(y))
while st != None:
if (st.ArchName != rw):
st = st.Above
continue;
st.Remove()
break;
act.Message('You feel a powerful force engulf you.')
act.Teleport(dest, int(x), int(y))
def do_banquet():
'''Teleports the player to the banquet map, if not used since one day. '''
now = str(Crossfire.GetTime()[0]) + '-' + str(Crossfire.GetTime()[1]) + '-' + str(Crossfire.GetTime()[2])
l = Crossfire.WhoAmI()
act = Crossfire.WhoIsActivator()
last = l.ReadKey('banquet_last')
if (last == now):
act.Message('You read the %s but nothing happens.'%l.Name)
return;
l.WriteKey('banquet_last', now, 1)
# map generation
m = Crossfire.CreateMap(size_x, size_y)
m.Path = os.path.join(Crossfire.ScriptName(), Crossfire.WhoIsActivator().Name)
floor = get_one(floors)
# First, let's put the floors
for x in range(size_x):
for y in range(size_y):
fl = Crossfire.CreateObjectByName(floor)
fl.Teleport(m, x, y)
# Put walls.
wall = get_one(walls)
# top left
w = Crossfire.CreateObjectByName(wall + '_2_2_2')
w.Teleport(m, 0, 0)
# top right
w = Crossfire.CreateObjectByName(wall + '_2_2_3')
w.Teleport(m, size_x - 1, 0)
# bottom left
w = Crossfire.CreateObjectByName(wall + '_2_2_1')
w.Teleport(m, 0, size_y - 1)
# bottom right
w = Crossfire.CreateObjectByName(wall + '_2_2_4')
w.Teleport(m, size_x - 1, size_y - 1)
# top and bottom parts
for x in range(size_x - 2):
w = Crossfire.CreateObjectByName(wall + '_2_1_2')
w.Teleport(m, x + 1, 0)
w = Crossfire.CreateObjectByName(wall + '_2_1_2')
w.Teleport(m, x + 1, size_y - 1)
# left and right parts
for y in range(size_y - 2):
w = Crossfire.CreateObjectByName(wall + '_2_1_1')
w.Teleport(m, 0, y + 1)
w = Crossfire.CreateObjectByName(wall + '_2_1_1')
w.Teleport(m, size_x - 1, y + 1)
# Food itself
for x in range(size_x-2):
for y in range(size_y-2):
fo = Crossfire.CreateObjectByName(get_one(foods))
fo.GodGiven = 1
fo.Teleport(m, x + 1, y + 1)
# Store player's current location
x = act.X
y = act.Y
im = act.Map
rw = get_one(replace_with)
l.WriteKey('banquet_x', str(x), 1)
l.WriteKey('banquet_y', str(y), 1)
l.WriteKey('banquet_map', im.Path, 1)
l.WriteKey('banquet_rw', rw, 1)
# Teleport
act.Message('You feel grabbed by some powerful force.')
act.Teleport(m, int(( size_x - 1 ) / 2), int( size_y - 1 ) / 2)
# Keep free spot by putting a statue
statue = im.CreateObject(rw, x, y)
statue.Name = '%s\'s statue'%act.Name
statue.Message = 'Gone eating.'
l = Crossfire.WhoAmI()
act = Crossfire.WhoIsActivator()
if l.Env != act:
act.Message('You try to open the %s, but it seems to flee from you.'%l.Name)
elif (act.Map.Path.find(Crossfire.ScriptName()) != -1):
do_back()
else:
do_banquet()
Crossfire.SetReturnValue(1)

View File

@ -0,0 +1,182 @@
# Script for Farnass the cook (/scorn/misc/scorn_kitchen).
#
# The script assumes you have:
# * a cook
# * a recipient where the player will put the ingredients
# * a stove where Farnass will go to cook
#
# Copyright 2007 Nicolas Weeger
# Released as GPL
#
# This script is supposed to be called for the say and time events of the cook,
# and the close event of the recipient.
import Crossfire
import random
import CFMove
key_status = 'cook_status'
st_getting = 'getting' # moving to recipient to get the ingredients
st_stove = 'stove' # moving to the stove to cook
st_cooking = 'cooking' # actually cooking
key_cooking_step = 'cooking_step' # when st_cooking, what cooking step
key_need_check = 'check_ingredients' # used to signal, after recipient was closed, to check contents
color = Crossfire.MessageFlag.NDI_GREEN # color to display messages
recipe_arch = 'caramel' # archetype generated when recipe is complete
eggs_count = 4
failure_chance = 15
recipient_x = 3 # position of the recipient to drop ingredients into
recipient_y = 8
stove_x = 4 # position of the stove the cook will use
stove_y = 8
def check_ingredients():
''' Finds the ingredients in the recipient. Used when recipient is closed, and when Farnass
arrives on the recipient (to avoid player picking up items)'''
mushroom = None
eggs = None
# whoami.Say('before')
obj = whoami.Map.ObjectAt(recipient_x, recipient_y)
while obj != None:
if obj.Type == Crossfire.Type.CONTAINER:
# whoami.Say('got container %s'%obj.Name)
inv = obj.Inventory
while inv != None:
if inv.Slaying == 'bunion' and inv.ArchName == 'mushroom_3':
mushroom = inv
elif inv.ArchName == 'chicken_egg' and inv.NamePl == 'Combat Chicken eggs':
eggs = inv
if mushroom != None and eggs != None:
break
inv = inv.Below
break
obj = obj.Above
#whoami.Say('after')
#if mushroom != None:
# whoami.Say('got mushroom')
#if eggs != None:
# whoami.Say('got eggs')
if mushroom == None or eggs == None or eggs.Quantity < eggs_count:
if whoami.ReadKey(key_status) == st_getting:
whoami.Say('Haha, you tried to trick me!')
whoami.WriteKey(key_status, '', 1)
return
if whoami.ReadKey(key_status) != st_getting:
whoami.Say('Oh, great, you found what I need to make my special caramel!')
whoami.WriteKey(key_status, st_getting, 1);
return
# if called here, Farnass moved to the recipient, and can pick the ingredients
whoami.Map.Print('%s expertly opens the frypan with a leg, and grabs the ingredient using two sticks in his mouth!'%whoami.Name, color)
mushroom.Quantity = mushroom.Quantity - 1
eggs.Quantity = eggs.Quantity - eggs_count
Crossfire.SetReturnValue(1)
whoami.WriteKey(key_status, st_stove, 1)
def end_cooking(success):
''' Everything is finish, let's decide if cooking was successful or not.'''
whoami.WriteKey(key_status, '', 1)
whoami.WriteKey(key_cooking_step, '', 1)
if success == 0:
return
if random.randint(1, 100) < failure_chance:
whoami.Map.Print('%s throws the ingredients in the bin.'%whoami.Name)
whoami.Say('I can *tell* you shook the eggs. The yellows were so badly stressed inside that this could not work, even in my own hands... err, teeth.')
else:
whoami.Say('The caramel is ready!')
omelet = whoami.Map.CreateObject(recipe_arch, whoami.X, whoami.Y)
omelet.Name = 'Farnass\'s Special Caramel'
omelet.NamePl = 'Farnass\'s Special Caramels'
omelet.Slaying = 'Farnass\'s Special Caramel'
omelet.Quantity = 1
def close_boiler():
'''Just tell the cook to check next time.'''
Crossfire.GetPrivateDictionary()[key_need_check] = 'yes'
def clean_check():
'''Cancel next check.'''
d = Crossfire.GetPrivateDictionary()
if d.has_key(key_need_check):
del d[key_need_check]
def move_cook():
'''Main moving routine.'''
#whoami.Say('move')
status = whoami.ReadKey(key_status)
if status == st_getting:
clean_check()
Crossfire.SetReturnValue(1)
m = CFMove.get_object_to(whoami, recipient_x, recipient_y)
if m == 0:
check_ingredients()
elif m == 2:
whoami.Say('Get off my way! You want me to cook this caramel or what?')
return
if status == st_cooking:
clean_check()
Crossfire.SetReturnValue(1)
if whoami.X != stove_x or whoami.Y != stove_y:
whoami.Say('You fool! The ingredients are wasted, now!')
end_cooking(0)
return
step = int(whoami.ReadKey(key_cooking_step)) - 1
if step == 0:
end_cooking(1)
return
elif step == 15:
whoami.Map.Print('%s skillfully mixes the ingredients with his left toe while controlling the fire under the boiler with his right one!'%whoami.Name, color)
elif step == 40:
whoami.Map.Print('Knife griped by the mouth, %s cuts the mushroom in small slices, and puts them in the stove!'%whoami.Name, color)
whoami.WriteKey(key_cooking_step, str(random.randint(25, 35)), 1)
elif step == 50:
whoami.Say('Let\'s pour the sulphur in now! Hey, wait, did I say sulphur? Ok, getting some dwarven shampoo to neutralize this!')
elif step == 70:
whoami.Map.Print('%s breaks the eggs over the stove by expertly throwing them, the shells bouncing away!'%whoami.Name, color)
whoami.WriteKey(key_cooking_step, str(random.randint(60, 69)), 1)
whoami.WriteKey(key_cooking_step, str(step), 1)
return
if status == st_stove:
clean_check()
move = CFMove.get_object_to(whoami, stove_x, stove_y)
if move == 0:
whoami.WriteKey(key_cooking_step, str(random.randint(80, 100)), 1)
whoami.Map.Print('%s makes the stove hotter.'%whoami.Name, color)
whoami.WriteKey(key_status, st_cooking, 1)
elif move == 2:
whoami.Say('Get off my way, I need to get to the stove!')
Crossfire.SetReturnValue(1)
return
d = Crossfire.GetPrivateDictionary()
if d.has_key(key_need_check):
whoami.Map.Print('You see %s look at the frypan.'%whoami.Name, color)
del d[key_need_check]
check_ingredients()
return
whoami = Crossfire.WhoAmI()
if Crossfire.WhatIsEvent().Subtype == Crossfire.EventType.SAY:
if whoami.ReadKey(key_cooking_step) != '':
whoami.Say('Keep quiet, this recipe requires concentration!')
Crossfire.SetReturnValue(1)
elif Crossfire.WhatIsEvent().Subtype == Crossfire.EventType.TIME:
move_cook()
elif Crossfire.WhatIsEvent().Subtype == Crossfire.EventType.CLOSE:
close_boiler()

View File

@ -0,0 +1,88 @@
# Script for Lursendis the gourmet (/wolfsburg/lursendis).
# Idea courtesy Yann Chachkoff.
#
# The script assumes you have:
# * Lursendis
# * a place where the player will drop the special omelet
#
# Copyright 2007 Nicolas Weeger
# Released as GPL
#
# This script is supposed to be called for the time event of Lursendis.
import Crossfire
import CFMove
import random
key_status = 'gourmet_status'
st_getting = 'getting'
st_eating = 'eating'
key_eating_step = 'eating_step'
plate_x = 2
plate_y = 6
banquet_path = '/python/items/banquet.py'
banquet_archetype = 'tome'
event_archetype = 'event_apply'
color = Crossfire.MessageFlag.NDI_GREEN # color to display messages
def check_plate():
obj = whoami.Map.ObjectAt(plate_x, plate_y)
while obj != None:
if obj.NamePl == 'Farnass\'s Special Caramels' and obj.Slaying == 'Farnass\'s Special Caramel':
if whoami.ReadKey(key_status) == st_getting:
whoami.Map.Print('%s grabs %s and starts eating with an obvious pleasure.'%(whoami.Name, obj.Name))
obj.Quantity = obj.Quantity - 1
whoami.WriteKey(key_status, st_eating, 1)
whoami.WriteKey(key_eating_step, str(random.randint(5, 10)), 1)
Crossfire.SetReturnValue(1)
return
whoami.Say('Oh! Could this be...')
whoami.WriteKey(key_status, st_getting, 1)
Crossfire.SetReturnValue(1)
return
obj = obj.Above
if whoami.ReadKey(key_status) == st_getting:
# we were on the spot, but no more omelet...
whoami.WriteKey(key_status, '', 1)
def create_book():
book = whoami.Map.CreateObject(banquet_archetype, whoami.X, whoami.Y)
book.Name = 'Unforgettable Banquet of %s'%whoami.Name
book.NamePl = 'Unforgettable Banquets of %s'%whoami.Name
event = book.CreateObject(event_archetype)
event.Slaying = banquet_path
event.Title = Crossfire.WhatIsEvent().Title
def move_gourmet():
st = whoami.ReadKey(key_status)
if st == st_getting:
move = CFMove.get_object_to(whoami, plate_x, plate_y)
if move == 0:
check_plate()
return
elif move == 2:
whoami.Say('Get outta my way!')
Crossfire.SetReturnValue(1)
return
elif st == st_eating:
step = int(whoami.ReadKey(key_eating_step)) - 1
if step == 0:
whoami.WriteKey(key_eating_step, '', 1)
whoami.WriteKey(key_status, '', 1)
whoami.Say('Now that\'s what I call a caramel! Thank you very much!')
whoami.Say('Here, take this as a token of my gratitude.')
create_book()
return
whoami.WriteKey(key_eating_step, str(step), 1)
Crossfire.SetReturnValue(1)
return
check_plate()
whoami = Crossfire.WhoAmI()
move_gourmet()

View File

@ -72,11 +72,7 @@ end
arch stwall_2_1_2
x 1
end
arch marble
x 1
y 1
end
arch table_1x2
arch beigemarble
x 1
y 1
end
@ -85,7 +81,11 @@ x 1
y 1
no_pick 1
end
arch marble
arch table_1x2
x 1
y 1
end
arch beigemarble
x 1
y 2
end
@ -94,11 +94,7 @@ x 1
y 2
no_pick 1
end
arch marble
x 1
y 3
end
arch table_1x2
arch beigemarble
x 1
y 3
end
@ -107,7 +103,11 @@ x 1
y 3
no_pick 1
end
arch marble
arch table_1x2
x 1
y 3
end
arch beigemarble
x 1
y 4
end
@ -116,11 +116,7 @@ x 1
y 4
no_pick 1
end
arch marble
x 1
y 5
end
arch table_1x2
arch beigemarble
x 1
y 5
end
@ -129,7 +125,11 @@ x 1
y 5
no_pick 1
end
arch marble
arch table_1x2
x 1
y 5
end
arch beigemarble
x 1
y 6
end
@ -138,11 +138,7 @@ x 1
y 6
no_pick 1
end
arch marble
x 1
y 7
end
arch table_1x2
arch beigemarble
x 1
y 7
end
@ -151,7 +147,11 @@ x 1
y 7
no_pick 1
end
arch marble
arch table_1x2
x 1
y 7
end
arch beigemarble
x 1
y 8
end
@ -174,11 +174,11 @@ end
arch stwall_2_1_2
x 2
end
arch marble
arch beigemarble
x 2
y 1
end
arch marble
arch beigemarble
x 2
y 2
end
@ -186,23 +186,23 @@ arch light4
x 2
y 2
end
arch marble
arch beigemarble
x 2
y 3
end
arch marble
arch beigemarble
x 2
y 4
end
arch marble
arch beigemarble
x 2
y 5
end
arch marble
arch beigemarble
x 2
y 6
end
arch marble
arch beigemarble
x 2
y 7
end
@ -210,11 +210,7 @@ arch light4
x 2
y 7
end
arch marble
x 2
y 8
end
arch table_2x1
arch beigemarble
x 2
y 8
end
@ -223,6 +219,10 @@ x 2
y 8
no_pick 1
end
arch table_2x1
x 2
y 8
end
arch cobblestones2
x 2
y 9
@ -270,30 +270,34 @@ arch stwall_1_2
x 3
y 3
end
arch marble
arch beigemarble
x 3
y 4
end
arch marble
arch beigemarble
x 3
y 5
end
arch marble
arch beigemarble
x 3
y 6
end
arch marble
arch beigemarble
x 3
y 7
end
arch marble
arch beigemarble
x 3
y 8
end
arch chocolate
arch frypan_closed
x 3
y 8
no_pick 1
arch event_close
title Python
slaying /python/monsters/farnass.py
end
end
arch cobblestones2
x 3
@ -339,15 +343,15 @@ x 4
y 3
connected 1
end
arch marble
arch beigemarble
x 4
y 4
end
arch marble
arch beigemarble
x 4
y 5
end
arch fatwoman
arch armless_cook
name Farnass
msg
@match sentrio|egg|eggs
@ -361,10 +365,14 @@ Yes, it's a blue one, I think it grows in a marsh in the west. I've heard it can
You need the following:
- 4 eggs from my friend Sentrio's chicken
- a special mushroom
@match omelet
So you want an omelet, he?
@match caramel
So you want a caramel, he?
Then you'll have to bring me the ingredients.
As you can see, I've lost my both arms during the last war against the Gnolls, so would you be kind enough to put whatever you found during your travel to make the recipe in the frypan, please?
You wonder how I cook without arms? Heh, rookie, that's what makes the difference between a cooker and me, Farnass! I told you already: I'm simply wonderful.
@match lursendis
Ha, this old friend of me. I haven't seen him in years, I wonder how he's doing...
@match *
@ -372,16 +380,26 @@ Please don't disturb me, I'm trying a really hard recipe.
endmsg
x 4
y 5
speed 0.25
random_movement 1
arch event_say
title Python
slaying /python/monsters/farnass.py
end
arch marble
arch event_time
title Python
slaying /python/monsters/farnass.py
end
end
arch beigemarble
x 4
y 6
end
arch marble
arch beigemarble
x 4
y 7
end
arch marble
arch beigemarble
x 4
y 8
end
@ -435,23 +453,23 @@ x 5
y 3
connected 1
end
arch marble
arch beigemarble
x 5
y 4
end
arch marble
arch beigemarble
x 5
y 5
end
arch marble
arch beigemarble
x 5
y 6
end
arch marble
arch beigemarble
x 5
y 7
end
arch marble
arch beigemarble
x 5
y 8
end
@ -499,27 +517,23 @@ arch stwall_1_2
x 6
y 3
end
arch marble
arch beigemarble
x 6
y 4
end
arch marble
arch beigemarble
x 6
y 5
end
arch marble
arch beigemarble
x 6
y 6
end
arch marble
arch beigemarble
x 6
y 7
end
arch marble
x 6
y 8
end
arch table_2x1
arch beigemarble
x 6
y 8
end
@ -528,6 +542,10 @@ x 6
y 8
no_pick 1
end
arch table_2x1
x 6
y 8
end
arch cobblestones2
x 6
y 9
@ -542,11 +560,11 @@ end
arch stwall_2_1_2
x 7
end
arch marble
arch beigemarble
x 7
y 1
end
arch marble
arch beigemarble
x 7
y 2
end
@ -554,23 +572,23 @@ arch light4
x 7
y 2
end
arch marble
arch beigemarble
x 7
y 3
end
arch marble
arch beigemarble
x 7
y 4
end
arch marble
arch beigemarble
x 7
y 5
end
arch marble
arch beigemarble
x 7
y 6
end
arch marble
arch beigemarble
x 7
y 7
end
@ -578,7 +596,7 @@ arch light4
x 7
y 7
end
arch marble
arch beigemarble
x 7
y 8
end
@ -601,11 +619,7 @@ end
arch stwall_2_1_2
x 8
end
arch marble
x 8
y 1
end
arch table_1x2
arch beigemarble
x 8
y 1
end
@ -614,7 +628,11 @@ x 8
y 1
no_pick 1
end
arch marble
arch table_1x2
x 8
y 1
end
arch beigemarble
x 8
y 2
end
@ -623,11 +641,7 @@ x 8
y 2
no_pick 1
end
arch marble
x 8
y 3
end
arch table_1x2
arch beigemarble
x 8
y 3
end
@ -636,7 +650,11 @@ x 8
y 3
no_pick 1
end
arch marble
arch table_1x2
x 8
y 3
end
arch beigemarble
x 8
y 4
end
@ -645,11 +663,7 @@ x 8
y 4
no_pick 1
end
arch marble
x 8
y 5
end
arch table_1x2
arch beigemarble
x 8
y 5
end
@ -658,7 +672,11 @@ x 8
y 5
no_pick 1
end
arch marble
arch table_1x2
x 8
y 5
end
arch beigemarble
x 8
y 6
end
@ -667,11 +685,7 @@ x 8
y 6
no_pick 1
end
arch marble
x 8
y 7
end
arch table_1x2
arch beigemarble
x 8
y 7
end
@ -680,7 +694,11 @@ x 8
y 7
no_pick 1
end
arch marble
arch table_1x2
x 8
y 7
end
arch beigemarble
x 8
y 8
end

View File

@ -155,17 +155,21 @@ Ha yes, Farnass 'The Recipe Spellcrafter'. Good friend, haven't seen him in 15 y
I think he lived in Scorn, or some island around.
@match omelet
Yes, but I would only eat an omelet made by my friend Farnass.
@match caramel
Yes, but I would only eat a caramel made by my friend Farnass.
@match hungry|food|cook
Yes, I'm always hungry. And I eat all the time!
Right now, I'd like to eat an omelet.
Right now, I'd like to eat a caramel.
@match *
Leave me alone, I need to cook something.
endmsg
x 2
y 4
arch event_time
title Python
slaying /python/monsters/lursendis.py
end
end
arch bluemarblemedium
x 2
@ -183,6 +187,11 @@ arch table_2x2
x 2
y 6
end
arch platter1_bro
x 2
y 6
no_pick 1
end
arch bluemarblemedium
x 2
y 7