185 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Python
		
	
	
| # 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)
 |